]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.11-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 18 Jul 2017 09:12:36 +0000 (11:12 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 18 Jul 2017 09:12:36 +0000 (11:12 +0200)
added patches:
block-fix-a-blk_exit_rl-regression.patch

queue-4.11/block-fix-a-blk_exit_rl-regression.patch [new file with mode: 0644]
queue-4.11/series

diff --git a/queue-4.11/block-fix-a-blk_exit_rl-regression.patch b/queue-4.11/block-fix-a-blk_exit_rl-regression.patch
new file mode 100644 (file)
index 0000000..e137bf8
--- /dev/null
@@ -0,0 +1,114 @@
+From dc9edc44de6cd7cc8cc7f5b36c1adb221eda3207 Mon Sep 17 00:00:00 2001
+From: Bart Van Assche <bart.vanassche@sandisk.com>
+Date: Wed, 14 Jun 2017 13:27:50 -0600
+Subject: block: Fix a blk_exit_rl() regression
+
+From: Bart Van Assche <bart.vanassche@sandisk.com>
+
+commit dc9edc44de6cd7cc8cc7f5b36c1adb221eda3207 upstream.
+
+Avoid that the following complaint is reported:
+
+ BUG: sleeping function called from invalid context at kernel/workqueue.c:2790
+ in_atomic(): 1, irqs_disabled(): 0, pid: 41, name: rcuop/3
+ 1 lock held by rcuop/3/41:
+  #0:  (rcu_callback){......}, at: [<ffffffff8111f9a2>] rcu_nocb_kthread+0x282/0x500
+ Call Trace:
+  dump_stack+0x86/0xcf
+  ___might_sleep+0x174/0x260
+  __might_sleep+0x4a/0x80
+  flush_work+0x7e/0x2e0
+  __cancel_work_timer+0x143/0x1c0
+  cancel_work_sync+0x10/0x20
+  blk_throtl_exit+0x25/0x60
+  blkcg_exit_queue+0x35/0x40
+  blk_release_queue+0x42/0x130
+  kobject_put+0xa9/0x190
+
+This happens since we invoke callbacks that need to block from the
+queue release handler. Fix this by pushing the final release to
+a workqueue.
+
+Reported-by: Ross Zwisler <zwisler@gmail.com>
+Fixes: commit b425e5049258 ("block: Avoid that blk_exit_rl() triggers a use-after-free")
+Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
+Tested-by: Ross Zwisler <ross.zwisler@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Updated changelog
+Signed-off-by: Jens Axboe <axboe@fb.com>
+Cc: Laura Abbott <labbott@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ block/blk-sysfs.c      |   34 ++++++++++++++++++++++------------
+ include/linux/blkdev.h |    2 ++
+ 2 files changed, 24 insertions(+), 12 deletions(-)
+
+--- a/block/blk-sysfs.c
++++ b/block/blk-sysfs.c
+@@ -791,24 +791,25 @@ static void blk_free_queue_rcu(struct rc
+ }
+ /**
+- * blk_release_queue: - release a &struct request_queue when it is no longer needed
+- * @kobj:    the kobj belonging to the request queue to be released
++ * __blk_release_queue - release a request queue when it is no longer needed
++ * @work: pointer to the release_work member of the request queue to be released
+  *
+  * Description:
+- *     blk_release_queue is the pair to blk_init_queue() or
+- *     blk_queue_make_request().  It should be called when a request queue is
+- *     being released; typically when a block device is being de-registered.
+- *     Currently, its primary task it to free all the &struct request
+- *     structures that were allocated to the queue and the queue itself.
++ *     blk_release_queue is the counterpart of blk_init_queue(). It should be
++ *     called when a request queue is being released; typically when a block
++ *     device is being de-registered. Its primary task it to free the queue
++ *     itself.
+  *
+- * Note:
++ * Notes:
+  *     The low level driver must have finished any outstanding requests first
+  *     via blk_cleanup_queue().
+- **/
+-static void blk_release_queue(struct kobject *kobj)
++ *
++ *     Although blk_release_queue() may be called with preemption disabled,
++ *     __blk_release_queue() may sleep.
++ */
++static void __blk_release_queue(struct work_struct *work)
+ {
+-      struct request_queue *q =
+-              container_of(kobj, struct request_queue, kobj);
++      struct request_queue *q = container_of(work, typeof(*q), release_work);
+       wbt_exit(q);
+       bdi_put(q->backing_dev_info);
+@@ -844,6 +845,15 @@ static void blk_release_queue(struct kob
+       call_rcu(&q->rcu_head, blk_free_queue_rcu);
+ }
++static void blk_release_queue(struct kobject *kobj)
++{
++      struct request_queue *q =
++              container_of(kobj, struct request_queue, kobj);
++
++      INIT_WORK(&q->release_work, __blk_release_queue);
++      schedule_work(&q->release_work);
++}
++
+ static const struct sysfs_ops queue_sysfs_ops = {
+       .show   = queue_attr_show,
+       .store  = queue_attr_store,
+--- a/include/linux/blkdev.h
++++ b/include/linux/blkdev.h
+@@ -580,6 +580,8 @@ struct request_queue {
+       size_t                  cmd_size;
+       void                    *rq_alloc_data;
++
++      struct work_struct      release_work;
+ };
+ #define QUEUE_FLAG_QUEUED     1       /* uses generic tag queueing */
index 4ceac0b4c240d09749c0b8339cfc55cf4bee369a..f4f7616d9c2f8122e05f71305a63f34cc92c35c3 100644 (file)
@@ -32,3 +32,4 @@ adding-asm-prototypes.h-for-genksyms-to-generate-crc.patch
 sed-regex-in-makefile.build-requires-line-break-between-exported-symbols.patch
 adding-the-type-of-exported-symbols.patch
 sparc64-fix-gup_huge_pmd.patch
+block-fix-a-blk_exit_rl-regression.patch