From: Greg Kroah-Hartman Date: Tue, 3 Dec 2024 13:48:27 +0000 (+0100) Subject: 6.11-stable patches X-Git-Tag: v4.19.325~13 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f3bb4b7821825ff9ac2df5b185ea9efa2e4e4fc6;p=thirdparty%2Fkernel%2Fstable-queue.git 6.11-stable patches added patches: block-always-verify-unfreeze-lock-on-the-owner-task.patch block-don-t-verify-io-lock-for-freeze-unfreeze-in-elevator_init_mq.patch --- diff --git a/queue-6.11/block-always-verify-unfreeze-lock-on-the-owner-task.patch b/queue-6.11/block-always-verify-unfreeze-lock-on-the-owner-task.patch new file mode 100644 index 00000000000..f6f24ff229c --- /dev/null +++ b/queue-6.11/block-always-verify-unfreeze-lock-on-the-owner-task.patch @@ -0,0 +1,177 @@ +From 6a78699838a0ddeed3620ddf50c1521f1fe1e811 Mon Sep 17 00:00:00 2001 +From: Ming Lei +Date: Thu, 31 Oct 2024 21:37:19 +0800 +Subject: block: always verify unfreeze lock on the owner task + +From: Ming Lei + +commit 6a78699838a0ddeed3620ddf50c1521f1fe1e811 upstream. + +commit f1be1788a32e ("block: model freeze & enter queue as lock for +supporting lockdep") tries to apply lockdep for verifying freeze & +unfreeze. However, the verification is only done the outmost freeze and +unfreeze. This way is actually not correct because q->mq_freeze_depth +still may drop to zero on other task instead of the freeze owner task. + +Fix this issue by always verifying the last unfreeze lock on the owner +task context, and make sure both the outmost freeze & unfreeze are +verified in the current task. + +Fixes: f1be1788a32e ("block: model freeze & enter queue as lock for supporting lockdep") +Signed-off-by: Ming Lei +Link: https://lore.kernel.org/r/20241031133723.303835-4-ming.lei@redhat.com +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + block/blk-core.c | 2 - + block/blk-mq.c | 62 ++++++++++++++++++++++++++++++++++++++++++------- + block/blk.h | 3 +- + include/linux/blkdev.h | 4 +++ + 4 files changed, 61 insertions(+), 10 deletions(-) + +--- a/block/blk-core.c ++++ b/block/blk-core.c +@@ -287,7 +287,7 @@ bool blk_queue_start_drain(struct reques + * entering queue, so we call blk_freeze_queue_start() to + * prevent I/O from crossing blk_queue_enter(). + */ +- bool freeze = __blk_freeze_queue_start(q); ++ bool freeze = __blk_freeze_queue_start(q, current); + if (queue_is_mq(q)) + blk_mq_wake_waiters(q); + /* Make blk_queue_enter() reexamine the DYING flag. */ +--- a/block/blk-mq.c ++++ b/block/blk-mq.c +@@ -120,20 +120,66 @@ void blk_mq_in_flight_rw(struct request_ + inflight[1] = mi.inflight[1]; + } + +-bool __blk_freeze_queue_start(struct request_queue *q) ++#ifdef CONFIG_LOCKDEP ++static bool blk_freeze_set_owner(struct request_queue *q, ++ struct task_struct *owner) + { +- int freeze; ++ if (!owner) ++ return false; ++ ++ if (!q->mq_freeze_depth) { ++ q->mq_freeze_owner = owner; ++ q->mq_freeze_owner_depth = 1; ++ return true; ++ } ++ ++ if (owner == q->mq_freeze_owner) ++ q->mq_freeze_owner_depth += 1; ++ return false; ++} ++ ++/* verify the last unfreeze in owner context */ ++static bool blk_unfreeze_check_owner(struct request_queue *q) ++{ ++ if (!q->mq_freeze_owner) ++ return false; ++ if (q->mq_freeze_owner != current) ++ return false; ++ if (--q->mq_freeze_owner_depth == 0) { ++ q->mq_freeze_owner = NULL; ++ return true; ++ } ++ return false; ++} ++ ++#else ++ ++static bool blk_freeze_set_owner(struct request_queue *q, ++ struct task_struct *owner) ++{ ++ return false; ++} ++ ++static bool blk_unfreeze_check_owner(struct request_queue *q) ++{ ++ return false; ++} ++#endif ++ ++bool __blk_freeze_queue_start(struct request_queue *q, ++ struct task_struct *owner) ++{ ++ bool freeze; + + mutex_lock(&q->mq_freeze_lock); ++ freeze = blk_freeze_set_owner(q, owner); + if (++q->mq_freeze_depth == 1) { + percpu_ref_kill(&q->q_usage_counter); + mutex_unlock(&q->mq_freeze_lock); + if (queue_is_mq(q)) + blk_mq_run_hw_queues(q, false); +- freeze = true; + } else { + mutex_unlock(&q->mq_freeze_lock); +- freeze = false; + } + + return freeze; +@@ -141,7 +187,7 @@ bool __blk_freeze_queue_start(struct req + + void blk_freeze_queue_start(struct request_queue *q) + { +- if (__blk_freeze_queue_start(q)) ++ if (__blk_freeze_queue_start(q, current)) + blk_freeze_acquire_lock(q, false, false); + } + EXPORT_SYMBOL_GPL(blk_freeze_queue_start); +@@ -190,7 +236,7 @@ EXPORT_SYMBOL_GPL(blk_mq_freeze_queue); + + bool __blk_mq_unfreeze_queue(struct request_queue *q, bool force_atomic) + { +- int unfreeze = false; ++ bool unfreeze; + + mutex_lock(&q->mq_freeze_lock); + if (force_atomic) +@@ -200,8 +246,8 @@ bool __blk_mq_unfreeze_queue(struct requ + if (!q->mq_freeze_depth) { + percpu_ref_resurrect(&q->q_usage_counter); + wake_up_all(&q->mq_freeze_wq); +- unfreeze = true; + } ++ unfreeze = blk_unfreeze_check_owner(q); + mutex_unlock(&q->mq_freeze_lock); + + return unfreeze; +@@ -223,7 +269,7 @@ EXPORT_SYMBOL_GPL(blk_mq_unfreeze_queue) + */ + void blk_freeze_queue_start_non_owner(struct request_queue *q) + { +- __blk_freeze_queue_start(q); ++ __blk_freeze_queue_start(q, NULL); + } + EXPORT_SYMBOL_GPL(blk_freeze_queue_start_non_owner); + +--- a/block/blk.h ++++ b/block/blk.h +@@ -38,7 +38,8 @@ void blk_free_flush_queue(struct blk_flu + void blk_freeze_queue(struct request_queue *q); + bool __blk_mq_unfreeze_queue(struct request_queue *q, bool force_atomic); + bool blk_queue_start_drain(struct request_queue *q); +-bool __blk_freeze_queue_start(struct request_queue *q); ++bool __blk_freeze_queue_start(struct request_queue *q, ++ struct task_struct *owner); + int __bio_queue_enter(struct request_queue *q, struct bio *bio); + void submit_bio_noacct_nocheck(struct bio *bio); + void bio_await_chain(struct bio *bio); +--- a/include/linux/blkdev.h ++++ b/include/linux/blkdev.h +@@ -572,6 +572,10 @@ struct request_queue { + struct throtl_data *td; + #endif + struct rcu_head rcu_head; ++#ifdef CONFIG_LOCKDEP ++ struct task_struct *mq_freeze_owner; ++ int mq_freeze_owner_depth; ++#endif + wait_queue_head_t mq_freeze_wq; + /* + * Protect concurrent access to q_usage_counter by diff --git a/queue-6.11/block-don-t-verify-io-lock-for-freeze-unfreeze-in-elevator_init_mq.patch b/queue-6.11/block-don-t-verify-io-lock-for-freeze-unfreeze-in-elevator_init_mq.patch new file mode 100644 index 00000000000..25a33fdeaad --- /dev/null +++ b/queue-6.11/block-don-t-verify-io-lock-for-freeze-unfreeze-in-elevator_init_mq.patch @@ -0,0 +1,50 @@ +From 357e1b7f730bd85a383e7afa75a3caba329c5707 Mon Sep 17 00:00:00 2001 +From: Ming Lei +Date: Thu, 31 Oct 2024 21:37:20 +0800 +Subject: block: don't verify IO lock for freeze/unfreeze in elevator_init_mq() + +From: Ming Lei + +commit 357e1b7f730bd85a383e7afa75a3caba329c5707 upstream. + +elevator_init_mq() is only called at the entry of add_disk_fwnode() when +disk IO isn't allowed yet. + +So not verify io lock(q->io_lockdep_map) for freeze & unfreeze in +elevator_init_mq(). + +Reported-by: Marek Szyprowski +Reported-by: Lai Yi +Fixes: f1be1788a32e ("block: model freeze & enter queue as lock for supporting lockdep") +Signed-off-by: Ming Lei +Link: https://lore.kernel.org/r/20241031133723.303835-5-ming.lei@redhat.com +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + block/elevator.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/block/elevator.c ++++ b/block/elevator.c +@@ -598,13 +598,19 @@ void elevator_init_mq(struct request_que + * drain any dispatch activities originated from passthrough + * requests, then no need to quiesce queue which may add long boot + * latency, especially when lots of disks are involved. ++ * ++ * Disk isn't added yet, so verifying queue lock only manually. + */ +- blk_mq_freeze_queue(q); ++ blk_freeze_queue_start_non_owner(q); ++ blk_freeze_acquire_lock(q, true, false); ++ blk_mq_freeze_queue_wait(q); ++ + blk_mq_cancel_work_sync(q); + + err = blk_mq_init_sched(q, e); + +- blk_mq_unfreeze_queue(q); ++ blk_unfreeze_release_lock(q, true, false); ++ blk_mq_unfreeze_queue_non_owner(q); + + if (err) { + pr_warn("\"%s\" elevator initialization failed, " diff --git a/queue-6.11/f2fs-fix-not-used-variable-index.patch b/queue-6.11/f2fs-fix-not-used-variable-index.patch index 4acb8d96f2d..eed3d91f361 100644 --- a/queue-6.11/f2fs-fix-not-used-variable-index.patch +++ b/queue-6.11/f2fs-fix-not-used-variable-index.patch @@ -24,14 +24,12 @@ Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Sasha Levin --- - fs/f2fs/data.c | 4 ++-- + fs/f2fs/data.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) -diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c -index be66b3a0e793f..60a5aaefc5b63 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c -@@ -2374,10 +2374,10 @@ static int f2fs_mpage_readpages(struct inode *inode, +@@ -2354,10 +2354,10 @@ static int f2fs_mpage_readpages(struct i .nr_cpages = 0, }; pgoff_t nc_cluster_idx = NULL_CLUSTER; @@ -43,7 +41,7 @@ index be66b3a0e793f..60a5aaefc5b63 100644 int ret = 0; map.m_pblk = 0; -@@ -2395,9 +2395,9 @@ static int f2fs_mpage_readpages(struct inode *inode, +@@ -2375,9 +2375,9 @@ static int f2fs_mpage_readpages(struct i prefetchw(&folio->flags); } @@ -54,6 +52,3 @@ index be66b3a0e793f..60a5aaefc5b63 100644 if (!f2fs_compressed_file(inode)) goto read_single_page; --- -2.43.0 - diff --git a/queue-6.11/series b/queue-6.11/series index 50dfcb4356e..82202bd32a4 100644 --- a/queue-6.11/series +++ b/queue-6.11/series @@ -814,3 +814,5 @@ brd-decrease-the-number-of-allocated-pages-which-dis.patch sh-intc-fix-use-after-free-bug-in-register_intc_cont.patch tools-power-turbostat-fix-trailing-n-parsing.patch tools-power-turbostat-fix-child-s-argument-forwardin.patch +block-always-verify-unfreeze-lock-on-the-owner-task.patch +block-don-t-verify-io-lock-for-freeze-unfreeze-in-elevator_init_mq.patch