]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.12-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 8 Aug 2017 17:29:28 +0000 (10:29 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 8 Aug 2017 17:29:28 +0000 (10:29 -0700)
added patches:
blk-mq-create-hctx-for-each-present-cpu.patch
blk-mq-include-all-present-cpus-in-the-default-queue-mapping.patch
block-disable-runtime-pm-for-blk-mq.patch

queue-4.12/blk-mq-create-hctx-for-each-present-cpu.patch [new file with mode: 0644]
queue-4.12/blk-mq-include-all-present-cpus-in-the-default-queue-mapping.patch [new file with mode: 0644]
queue-4.12/block-disable-runtime-pm-for-blk-mq.patch [new file with mode: 0644]
queue-4.12/series

diff --git a/queue-4.12/blk-mq-create-hctx-for-each-present-cpu.patch b/queue-4.12/blk-mq-create-hctx-for-each-present-cpu.patch
new file mode 100644 (file)
index 0000000..f15b3dd
--- /dev/null
@@ -0,0 +1,256 @@
+From 4b855ad37194f7bdbb200ce7a1c7051fecb56a08 Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@lst.de>
+Date: Mon, 26 Jun 2017 12:20:57 +0200
+Subject: blk-mq: Create hctx for each present CPU
+
+From: Christoph Hellwig <hch@lst.de>
+
+commit 4b855ad37194f7bdbb200ce7a1c7051fecb56a08 upstream.
+
+Currently we only create hctx for online CPUs, which can lead to a lot
+of churn due to frequent soft offline / online operations.  Instead
+allocate one for each present CPU to avoid this and dramatically simplify
+the code.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Jens Axboe <axboe@kernel.dk>
+Cc: Keith Busch <keith.busch@intel.com>
+Cc: linux-block@vger.kernel.org
+Cc: linux-nvme@lists.infradead.org
+Link: http://lkml.kernel.org/r/20170626102058.10200-3-hch@lst.de
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: Oleksandr Natalenko <oleksandr@natalenko.name>
+Cc: Mike Galbraith <efault@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ block/blk-mq.c             |  120 ++++-----------------------------------------
+ block/blk-mq.h             |    5 -
+ include/linux/cpuhotplug.h |    1 
+ 3 files changed, 11 insertions(+), 115 deletions(-)
+
+--- a/block/blk-mq.c
++++ b/block/blk-mq.c
+@@ -37,9 +37,6 @@
+ #include "blk-wbt.h"
+ #include "blk-mq-sched.h"
+-static DEFINE_MUTEX(all_q_mutex);
+-static LIST_HEAD(all_q_list);
+-
+ static void blk_mq_poll_stats_start(struct request_queue *q);
+ static void blk_mq_poll_stats_fn(struct blk_stat_callback *cb);
+ static void __blk_mq_stop_hw_queues(struct request_queue *q, bool sync);
+@@ -1975,8 +1972,8 @@ static void blk_mq_init_cpu_queues(struc
+               INIT_LIST_HEAD(&__ctx->rq_list);
+               __ctx->queue = q;
+-              /* If the cpu isn't online, the cpu is mapped to first hctx */
+-              if (!cpu_online(i))
++              /* If the cpu isn't present, the cpu is mapped to first hctx */
++              if (!cpu_present(i))
+                       continue;
+               hctx = blk_mq_map_queue(q, i);
+@@ -2019,8 +2016,7 @@ static void blk_mq_free_map_and_requests
+       }
+ }
+-static void blk_mq_map_swqueue(struct request_queue *q,
+-                             const struct cpumask *online_mask)
++static void blk_mq_map_swqueue(struct request_queue *q)
+ {
+       unsigned int i, hctx_idx;
+       struct blk_mq_hw_ctx *hctx;
+@@ -2038,13 +2034,11 @@ static void blk_mq_map_swqueue(struct re
+       }
+       /*
+-       * Map software to hardware queues
++       * Map software to hardware queues.
++       *
++       * If the cpu isn't present, the cpu is mapped to first hctx.
+        */
+-      for_each_possible_cpu(i) {
+-              /* If the cpu isn't online, the cpu is mapped to first hctx */
+-              if (!cpumask_test_cpu(i, online_mask))
+-                      continue;
+-
++      for_each_present_cpu(i) {
+               hctx_idx = q->mq_map[i];
+               /* unmapped hw queue can be remapped after CPU topo changed */
+               if (!set->tags[hctx_idx] &&
+@@ -2340,16 +2334,8 @@ struct request_queue *blk_mq_init_alloca
+               blk_queue_softirq_done(q, set->ops->complete);
+       blk_mq_init_cpu_queues(q, set->nr_hw_queues);
+-
+-      get_online_cpus();
+-      mutex_lock(&all_q_mutex);
+-
+-      list_add_tail(&q->all_q_node, &all_q_list);
+       blk_mq_add_queue_tag_set(set, q);
+-      blk_mq_map_swqueue(q, cpu_online_mask);
+-
+-      mutex_unlock(&all_q_mutex);
+-      put_online_cpus();
++      blk_mq_map_swqueue(q);
+       if (!(set->flags & BLK_MQ_F_NO_SCHED)) {
+               int ret;
+@@ -2375,18 +2361,12 @@ void blk_mq_free_queue(struct request_qu
+ {
+       struct blk_mq_tag_set   *set = q->tag_set;
+-      mutex_lock(&all_q_mutex);
+-      list_del_init(&q->all_q_node);
+-      mutex_unlock(&all_q_mutex);
+-
+       blk_mq_del_queue_tag_set(q);
+-
+       blk_mq_exit_hw_queues(q, set, set->nr_hw_queues);
+ }
+ /* Basically redo blk_mq_init_queue with queue frozen */
+-static void blk_mq_queue_reinit(struct request_queue *q,
+-                              const struct cpumask *online_mask)
++static void blk_mq_queue_reinit(struct request_queue *q)
+ {
+       WARN_ON_ONCE(!atomic_read(&q->mq_freeze_depth));
+@@ -2399,76 +2379,12 @@ static void blk_mq_queue_reinit(struct r
+        * involves free and re-allocate memory, worthy doing?)
+        */
+-      blk_mq_map_swqueue(q, online_mask);
++      blk_mq_map_swqueue(q);
+       blk_mq_sysfs_register(q);
+       blk_mq_debugfs_register_hctxs(q);
+ }
+-/*
+- * New online cpumask which is going to be set in this hotplug event.
+- * Declare this cpumasks as global as cpu-hotplug operation is invoked
+- * one-by-one and dynamically allocating this could result in a failure.
+- */
+-static struct cpumask cpuhp_online_new;
+-
+-static void blk_mq_queue_reinit_work(void)
+-{
+-      struct request_queue *q;
+-
+-      mutex_lock(&all_q_mutex);
+-      /*
+-       * We need to freeze and reinit all existing queues.  Freezing
+-       * involves synchronous wait for an RCU grace period and doing it
+-       * one by one may take a long time.  Start freezing all queues in
+-       * one swoop and then wait for the completions so that freezing can
+-       * take place in parallel.
+-       */
+-      list_for_each_entry(q, &all_q_list, all_q_node)
+-              blk_freeze_queue_start(q);
+-      list_for_each_entry(q, &all_q_list, all_q_node)
+-              blk_mq_freeze_queue_wait(q);
+-
+-      list_for_each_entry(q, &all_q_list, all_q_node)
+-              blk_mq_queue_reinit(q, &cpuhp_online_new);
+-
+-      list_for_each_entry(q, &all_q_list, all_q_node)
+-              blk_mq_unfreeze_queue(q);
+-
+-      mutex_unlock(&all_q_mutex);
+-}
+-
+-static int blk_mq_queue_reinit_dead(unsigned int cpu)
+-{
+-      cpumask_copy(&cpuhp_online_new, cpu_online_mask);
+-      blk_mq_queue_reinit_work();
+-      return 0;
+-}
+-
+-/*
+- * Before hotadded cpu starts handling requests, new mappings must be
+- * established.  Otherwise, these requests in hw queue might never be
+- * dispatched.
+- *
+- * For example, there is a single hw queue (hctx) and two CPU queues (ctx0
+- * for CPU0, and ctx1 for CPU1).
+- *
+- * Now CPU1 is just onlined and a request is inserted into ctx1->rq_list
+- * and set bit0 in pending bitmap as ctx1->index_hw is still zero.
+- *
+- * And then while running hw queue, blk_mq_flush_busy_ctxs() finds bit0 is set
+- * in pending bitmap and tries to retrieve requests in hctx->ctxs[0]->rq_list.
+- * But htx->ctxs[0] is a pointer to ctx0, so the request in ctx1->rq_list is
+- * ignored.
+- */
+-static int blk_mq_queue_reinit_prepare(unsigned int cpu)
+-{
+-      cpumask_copy(&cpuhp_online_new, cpu_online_mask);
+-      cpumask_set_cpu(cpu, &cpuhp_online_new);
+-      blk_mq_queue_reinit_work();
+-      return 0;
+-}
+-
+ static int __blk_mq_alloc_rq_maps(struct blk_mq_tag_set *set)
+ {
+       int i;
+@@ -2679,7 +2595,7 @@ static void __blk_mq_update_nr_hw_queues
+       blk_mq_update_queue_map(set);
+       list_for_each_entry(q, &set->tag_list, tag_set_list) {
+               blk_mq_realloc_hw_ctxs(set, q);
+-              blk_mq_queue_reinit(q, cpu_online_mask);
++              blk_mq_queue_reinit(q);
+       }
+       list_for_each_entry(q, &set->tag_list, tag_set_list)
+@@ -2895,24 +2811,10 @@ bool blk_mq_poll(struct request_queue *q
+ }
+ EXPORT_SYMBOL_GPL(blk_mq_poll);
+-void blk_mq_disable_hotplug(void)
+-{
+-      mutex_lock(&all_q_mutex);
+-}
+-
+-void blk_mq_enable_hotplug(void)
+-{
+-      mutex_unlock(&all_q_mutex);
+-}
+-
+ static int __init blk_mq_init(void)
+ {
+       cpuhp_setup_state_multi(CPUHP_BLK_MQ_DEAD, "block/mq:dead", NULL,
+                               blk_mq_hctx_notify_dead);
+-
+-      cpuhp_setup_state_nocalls(CPUHP_BLK_MQ_PREPARE, "block/mq:prepare",
+-                                blk_mq_queue_reinit_prepare,
+-                                blk_mq_queue_reinit_dead);
+       return 0;
+ }
+ subsys_initcall(blk_mq_init);
+--- a/block/blk-mq.h
++++ b/block/blk-mq.h
+@@ -56,11 +56,6 @@ void __blk_mq_insert_request(struct blk_
+                               bool at_head);
+ void blk_mq_insert_requests(struct blk_mq_hw_ctx *hctx, struct blk_mq_ctx *ctx,
+                               struct list_head *list);
+-/*
+- * CPU hotplug helpers
+- */
+-void blk_mq_enable_hotplug(void);
+-void blk_mq_disable_hotplug(void);
+ /*
+  * CPU -> queue mappings
+--- a/include/linux/cpuhotplug.h
++++ b/include/linux/cpuhotplug.h
+@@ -58,7 +58,6 @@ enum cpuhp_state {
+       CPUHP_XEN_EVTCHN_PREPARE,
+       CPUHP_ARM_SHMOBILE_SCU_PREPARE,
+       CPUHP_SH_SH3X_PREPARE,
+-      CPUHP_BLK_MQ_PREPARE,
+       CPUHP_NET_FLOW_PREPARE,
+       CPUHP_TOPOLOGY_PREPARE,
+       CPUHP_NET_IUCV_PREPARE,
diff --git a/queue-4.12/blk-mq-include-all-present-cpus-in-the-default-queue-mapping.patch b/queue-4.12/blk-mq-include-all-present-cpus-in-the-default-queue-mapping.patch
new file mode 100644 (file)
index 0000000..b4ec8e1
--- /dev/null
@@ -0,0 +1,55 @@
+From 5f042e7cbd9ebd3580077dcdc21f35e68c2adf5f Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@lst.de>
+Date: Mon, 26 Jun 2017 12:20:56 +0200
+Subject: blk-mq: Include all present CPUs in the default queue mapping
+
+From: Christoph Hellwig <hch@lst.de>
+
+commit 5f042e7cbd9ebd3580077dcdc21f35e68c2adf5f upstream.
+
+This way we get a nice distribution independent of the current cpu
+online / offline state.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Jens Axboe <axboe@kernel.dk>
+Cc: Keith Busch <keith.busch@intel.com>
+Cc: linux-block@vger.kernel.org
+Cc: linux-nvme@lists.infradead.org
+Link: http://lkml.kernel.org/r/20170626102058.10200-2-hch@lst.de
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: Oleksandr Natalenko <oleksandr@natalenko.name>
+Cc: Mike Galbraith <efault@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ block/blk-mq-cpumap.c |    5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/block/blk-mq-cpumap.c
++++ b/block/blk-mq-cpumap.c
+@@ -35,7 +35,6 @@ int blk_mq_map_queues(struct blk_mq_tag_
+ {
+       unsigned int *map = set->mq_map;
+       unsigned int nr_queues = set->nr_hw_queues;
+-      const struct cpumask *online_mask = cpu_online_mask;
+       unsigned int i, nr_cpus, nr_uniq_cpus, queue, first_sibling;
+       cpumask_var_t cpus;
+@@ -44,7 +43,7 @@ int blk_mq_map_queues(struct blk_mq_tag_
+       cpumask_clear(cpus);
+       nr_cpus = nr_uniq_cpus = 0;
+-      for_each_cpu(i, online_mask) {
++      for_each_present_cpu(i) {
+               nr_cpus++;
+               first_sibling = get_first_sibling(i);
+               if (!cpumask_test_cpu(first_sibling, cpus))
+@@ -54,7 +53,7 @@ int blk_mq_map_queues(struct blk_mq_tag_
+       queue = 0;
+       for_each_possible_cpu(i) {
+-              if (!cpumask_test_cpu(i, online_mask)) {
++              if (!cpumask_test_cpu(i, cpu_present_mask)) {
+                       map[i] = 0;
+                       continue;
+               }
diff --git a/queue-4.12/block-disable-runtime-pm-for-blk-mq.patch b/queue-4.12/block-disable-runtime-pm-for-blk-mq.patch
new file mode 100644 (file)
index 0000000..9362148
--- /dev/null
@@ -0,0 +1,39 @@
+From 765e40b675a9566459ddcb8358ad16f3b8344bbe Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@lst.de>
+Date: Fri, 21 Jul 2017 13:46:10 +0200
+Subject: block: disable runtime-pm for blk-mq
+
+From: Christoph Hellwig <hch@lst.de>
+
+commit 765e40b675a9566459ddcb8358ad16f3b8344bbe upstream.
+
+The blk-mq code lacks support for looking at the rpm_status field, tracking
+active requests and the RQF_PM flag.
+
+Due to the default switch to blk-mq for scsi people start to run into
+suspend / resume issue due to this fact, so make sure we disable the runtime
+PM functionality until it is properly implemented.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Ming Lei <ming.lei@redhat.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Cc: Oleksandr Natalenko <oleksandr@natalenko.name>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ block/blk-core.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/block/blk-core.c
++++ b/block/blk-core.c
+@@ -3307,6 +3307,10 @@ EXPORT_SYMBOL(blk_finish_plug);
+  */
+ void blk_pm_runtime_init(struct request_queue *q, struct device *dev)
+ {
++      /* not support for RQF_PM and ->rpm_status in blk-mq yet */
++      if (q->mq_ops)
++              return;
++
+       q->dev = dev;
+       q->rpm_status = RPM_ACTIVE;
+       pm_runtime_set_autosuspend_delay(q->dev, -1);
index f8359fe8ed8631e7e63e03d938d231995932e59d..37a43416de5de3e8bcc869e9d7b45875ddc0a1ac 100644 (file)
@@ -51,3 +51,6 @@ tcmu-fix-possbile-memory-leak-oops-when-recalculating-cmd-base-size.patch
 ext4-preserve-i_mode-if-__ext4_set_acl-fails.patch
 ext4-don-t-clear-sgid-when-inheriting-acls.patch
 btrfs-fix-early-enospc-due-to-delalloc.patch
+blk-mq-include-all-present-cpus-in-the-default-queue-mapping.patch
+blk-mq-create-hctx-for-each-present-cpu.patch
+block-disable-runtime-pm-for-blk-mq.patch