--- /dev/null
+From 2a34c0872adf252f23a6fef2d051a169ac796cef Mon Sep 17 00:00:00 2001
+From: Ming Lei <ming.lei@canonical.com>
+Date: Tue, 21 Apr 2015 10:00:20 +0800
+Subject: blk-mq: fix CPU hotplug handling
+
+From: Ming Lei <ming.lei@canonical.com>
+
+commit 2a34c0872adf252f23a6fef2d051a169ac796cef upstream.
+
+hctx->tags has to be set as NULL in case that it is to be unmapped
+no matter if set->tags[hctx->queue_num] is NULL or not in blk_mq_map_swqueue()
+because shared tags can be freed already from another request queue.
+
+The same situation has to be considered during handling CPU online too.
+Unmapped hw queue can be remapped after CPU topo is changed, so we need
+to allocate tags for the hw queue in blk_mq_map_swqueue(). Then tags
+allocation for hw queue can be removed in hctx cpu online notifier, and it
+is reasonable to do that after mapping is updated.
+
+Reported-by: Dongsu Park <dongsu.park@profitbricks.com>
+Tested-by: Dongsu Park <dongsu.park@profitbricks.com>
+Signed-off-by: Ming Lei <ming.lei@canonical.com>
+Signed-off-by: Jens Axboe <axboe@fb.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ block/blk-mq.c | 34 +++++++++++++---------------------
+ 1 file changed, 13 insertions(+), 21 deletions(-)
+
+--- a/block/blk-mq.c
++++ b/block/blk-mq.c
+@@ -1573,22 +1573,6 @@ static int blk_mq_hctx_cpu_offline(struc
+ return NOTIFY_OK;
+ }
+
+-static int blk_mq_hctx_cpu_online(struct blk_mq_hw_ctx *hctx, int cpu)
+-{
+- struct request_queue *q = hctx->queue;
+- struct blk_mq_tag_set *set = q->tag_set;
+-
+- if (set->tags[hctx->queue_num])
+- return NOTIFY_OK;
+-
+- set->tags[hctx->queue_num] = blk_mq_init_rq_map(set, hctx->queue_num);
+- if (!set->tags[hctx->queue_num])
+- return NOTIFY_STOP;
+-
+- hctx->tags = set->tags[hctx->queue_num];
+- return NOTIFY_OK;
+-}
+-
+ static int blk_mq_hctx_notify(void *data, unsigned long action,
+ unsigned int cpu)
+ {
+@@ -1596,8 +1580,11 @@ static int blk_mq_hctx_notify(void *data
+
+ if (action == CPU_DEAD || action == CPU_DEAD_FROZEN)
+ return blk_mq_hctx_cpu_offline(hctx, cpu);
+- else if (action == CPU_ONLINE || action == CPU_ONLINE_FROZEN)
+- return blk_mq_hctx_cpu_online(hctx, cpu);
++
++ /*
++ * In case of CPU online, tags may be reallocated
++ * in blk_mq_map_swqueue() after mapping is updated.
++ */
+
+ return NOTIFY_OK;
+ }
+@@ -1779,6 +1766,7 @@ static void blk_mq_map_swqueue(struct re
+ unsigned int i;
+ struct blk_mq_hw_ctx *hctx;
+ struct blk_mq_ctx *ctx;
++ struct blk_mq_tag_set *set = q->tag_set;
+
+ queue_for_each_hw_ctx(q, hctx, i) {
+ cpumask_clear(hctx->cpumask);
+@@ -1805,16 +1793,20 @@ static void blk_mq_map_swqueue(struct re
+ * disable it and free the request entries.
+ */
+ if (!hctx->nr_ctx) {
+- struct blk_mq_tag_set *set = q->tag_set;
+-
+ if (set->tags[i]) {
+ blk_mq_free_rq_map(set, set->tags[i], i);
+ set->tags[i] = NULL;
+- hctx->tags = NULL;
+ }
++ hctx->tags = NULL;
+ continue;
+ }
+
++ /* unmapped hw queue can be remapped after CPU topo changed */
++ if (!set->tags[i])
++ set->tags[i] = blk_mq_init_rq_map(set, i);
++ hctx->tags = set->tags[i];
++ WARN_ON(!hctx->tags);
++
+ /*
+ * Initialize batch roundrobin counts
+ */
--- /dev/null
+From f054b56c951bf1731ba7314a4c7f1cc0b2977cc9 Mon Sep 17 00:00:00 2001
+From: Ming Lei <ming.lei@canonical.com>
+Date: Tue, 21 Apr 2015 10:00:19 +0800
+Subject: blk-mq: fix race between timeout and CPU hotplug
+
+From: Ming Lei <ming.lei@canonical.com>
+
+commit f054b56c951bf1731ba7314a4c7f1cc0b2977cc9 upstream.
+
+Firstly during CPU hotplug, even queue is freezed, timeout
+handler still may come and access hctx->tags, which may cause
+use after free, so this patch deactivates timeout handler
+inside CPU hotplug notifier.
+
+Secondly, tags can be shared by more than one queues, so we
+have to check if the hctx has been unmapped, otherwise
+still use-after-free on tags can be triggered.
+
+Reported-by: Dongsu Park <dongsu.park@profitbricks.com>
+Tested-by: Dongsu Park <dongsu.park@profitbricks.com>
+Signed-off-by: Ming Lei <ming.lei@canonical.com>
+Signed-off-by: Jens Axboe <axboe@fb.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ block/blk-mq.c | 16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+--- a/block/blk-mq.c
++++ b/block/blk-mq.c
+@@ -675,8 +675,11 @@ static void blk_mq_rq_timer(unsigned lon
+ data.next = blk_rq_timeout(round_jiffies_up(data.next));
+ mod_timer(&q->timeout, data.next);
+ } else {
+- queue_for_each_hw_ctx(q, hctx, i)
+- blk_mq_tag_idle(hctx);
++ queue_for_each_hw_ctx(q, hctx, i) {
++ /* the hctx may be unmapped, so check it here */
++ if (blk_mq_hw_queue_mapped(hctx))
++ blk_mq_tag_idle(hctx);
++ }
+ }
+ }
+
+@@ -2075,9 +2078,16 @@ static int blk_mq_queue_reinit_notify(st
+ */
+ list_for_each_entry(q, &all_q_list, all_q_node)
+ blk_mq_freeze_queue_start(q);
+- list_for_each_entry(q, &all_q_list, all_q_node)
++ list_for_each_entry(q, &all_q_list, all_q_node) {
+ blk_mq_freeze_queue_wait(q);
+
++ /*
++ * timeout handler can't touch hw queue during the
++ * reinitialization
++ */
++ del_timer_sync(&q->timeout);
++ }
++
+ list_for_each_entry(q, &all_q_list, all_q_node)
+ blk_mq_queue_reinit(q);
+
--- /dev/null
+From 6cd18e711dd8075da9d78cfc1239f912ff28968a Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.de>
+Date: Mon, 27 Apr 2015 14:12:22 +1000
+Subject: block: destroy bdi before blockdev is unregistered.
+
+From: NeilBrown <neilb@suse.de>
+
+commit 6cd18e711dd8075da9d78cfc1239f912ff28968a upstream.
+
+Because of the peculiar way that md devices are created (automatically
+when the device node is opened), a new device can be created and
+registered immediately after the
+ blk_unregister_region(disk_devt(disk), disk->minors);
+call in del_gendisk().
+
+Therefore it is important that all visible artifacts of the previous
+device are removed before this call. In particular, the 'bdi'.
+
+Since:
+commit c4db59d31e39ea067c32163ac961e9c80198fd37
+Author: Christoph Hellwig <hch@lst.de>
+ fs: don't reassign dirty inodes to default_backing_dev_info
+
+moved the
+ device_unregister(bdi->dev);
+call from bdi_unregister() to bdi_destroy() it has been quite easy to
+lose a race and have a new (e.g.) "md127" be created after the
+blk_unregister_region() call and before bdi_destroy() is ultimately
+called by the final 'put_disk', which must come after del_gendisk().
+
+The new device finds that the bdi name is already registered in sysfs
+and complains
+
+> [ 9627.630029] WARNING: CPU: 18 PID: 3330 at fs/sysfs/dir.c:31 sysfs_warn_dup+0x5a/0x70()
+> [ 9627.630032] sysfs: cannot create duplicate filename '/devices/virtual/bdi/9:127'
+
+We can fix this by moving the bdi_destroy() call out of
+blk_release_queue() (which can happen very late when a refcount
+reaches zero) and into blk_cleanup_queue() - which happens exactly when the md
+device driver calls it.
+
+Then it is only necessary for md to call blk_cleanup_queue() before
+del_gendisk(). As loop.c devices are also created on demand by
+opening the device node, we make the same change there.
+
+Fixes: c4db59d31e39ea067c32163ac961e9c80198fd37
+Reported-by: Azat Khuzhin <a3at.mail@gmail.com>
+Cc: Christoph Hellwig <hch@lst.de>
+Signed-off-by: NeilBrown <neilb@suse.de>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Jens Axboe <axboe@fb.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ block/blk-core.c | 2 ++
+ block/blk-sysfs.c | 2 --
+ drivers/block/loop.c | 2 +-
+ drivers/md/md.c | 4 ++--
+ 4 files changed, 5 insertions(+), 5 deletions(-)
+
+--- a/block/blk-core.c
++++ b/block/blk-core.c
+@@ -552,6 +552,8 @@ void blk_cleanup_queue(struct request_qu
+ q->queue_lock = &q->__queue_lock;
+ spin_unlock_irq(lock);
+
++ bdi_destroy(&q->backing_dev_info);
++
+ /* @q is and will stay empty, shutdown and put */
+ blk_put_queue(q);
+ }
+--- a/block/blk-sysfs.c
++++ b/block/blk-sysfs.c
+@@ -522,8 +522,6 @@ static void blk_release_queue(struct kob
+
+ blk_trace_shutdown(q);
+
+- bdi_destroy(&q->backing_dev_info);
+-
+ ida_simple_remove(&blk_queue_ida, q->id);
+ call_rcu(&q->rcu_head, blk_free_queue_rcu);
+ }
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -1672,8 +1672,8 @@ out:
+
+ static void loop_remove(struct loop_device *lo)
+ {
+- del_gendisk(lo->lo_disk);
+ blk_cleanup_queue(lo->lo_queue);
++ del_gendisk(lo->lo_disk);
+ blk_mq_free_tag_set(&lo->tag_set);
+ put_disk(lo->lo_disk);
+ kfree(lo);
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -4754,12 +4754,12 @@ static void md_free(struct kobject *ko)
+ if (mddev->sysfs_state)
+ sysfs_put(mddev->sysfs_state);
+
++ if (mddev->queue)
++ blk_cleanup_queue(mddev->queue);
+ if (mddev->gendisk) {
+ del_gendisk(mddev->gendisk);
+ put_disk(mddev->gendisk);
+ }
+- if (mddev->queue)
+- blk_cleanup_queue(mddev->queue);
+
+ kfree(mddev);
+ }
xen-events-set-irq_info-evtchn-before-binding-the-channel-to-cpu-in-__startup_pirq.patch
xen-pciback-add-name-prefix-to-global-permissive-variable.patch
revert-dm-crypt-fix-deadlock-when-async-crypto-algorithm-returns-ebusy.patch
+block-destroy-bdi-before-blockdev-is-unregistered.patch
+blk-mq-fix-race-between-timeout-and-cpu-hotplug.patch
+blk-mq-fix-cpu-hotplug-handling.patch