Merge branch 'for-4.9/block-smp' of git://git.kernel.dk/linux-block
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 10 Oct 2016 00:32:20 +0000 (17:32 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 10 Oct 2016 00:32:20 +0000 (17:32 -0700)
Pull blk-mq CPU hotplug update from Jens Axboe:
 "This is the conversion of blk-mq to the new hotplug state machine"

* 'for-4.9/block-smp' of git://git.kernel.dk/linux-block:
  blk-mq: fixup "Convert to new hotplug state machine"
  blk-mq: Convert to new hotplug state machine
  blk-mq/cpu-notif: Convert to new hotplug state machine

1  2 
block/Makefile
block/blk-mq.c
block/blk-mq.h
include/linux/blk-mq.h

diff --combined block/Makefile
@@@ -6,7 -6,7 +6,7 @@@ obj-$(CONFIG_BLOCK) := bio.o elevator.
                        blk-flush.o blk-settings.o blk-ioc.o blk-map.o \
                        blk-exec.o blk-merge.o blk-softirq.o blk-timeout.o \
                        blk-lib.o blk-mq.o blk-mq-tag.o \
-                       blk-mq-sysfs.o blk-mq-cpu.o blk-mq-cpumap.o ioctl.o \
+                       blk-mq-sysfs.o blk-mq-cpumap.o ioctl.o \
                        genhd.o scsi_ioctl.o partition-generic.o ioprio.o \
                        badblocks.o partitions/
  
@@@ -22,4 -22,4 +22,4 @@@ obj-$(CONFIG_IOSCHED_CFQ)     += cfq-iosche
  obj-$(CONFIG_BLOCK_COMPAT)    += compat_ioctl.o
  obj-$(CONFIG_BLK_CMDLINE_PARSER)      += cmdline-parser.o
  obj-$(CONFIG_BLK_DEV_INTEGRITY) += bio-integrity.o blk-integrity.o t10-pi.o
 -
 +obj-$(CONFIG_BLK_MQ_PCI)      += blk-mq-pci.o
diff --combined block/blk-mq.c
@@@ -34,6 -34,8 +34,6 @@@
  static DEFINE_MUTEX(all_q_mutex);
  static LIST_HEAD(all_q_list);
  
 -static void __blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx);
 -
  /*
   * Check if any of the ctx's have pending work in this hardware queue
   */
@@@ -224,11 -226,21 +224,11 @@@ struct request *blk_mq_alloc_request(st
                return ERR_PTR(ret);
  
        ctx = blk_mq_get_ctx(q);
 -      hctx = q->mq_ops->map_queue(q, ctx->cpu);
 +      hctx = blk_mq_map_queue(q, ctx->cpu);
        blk_mq_set_alloc_data(&alloc_data, q, flags, ctx, hctx);
 -
        rq = __blk_mq_alloc_request(&alloc_data, rw, 0);
 -      if (!rq && !(flags & BLK_MQ_REQ_NOWAIT)) {
 -              __blk_mq_run_hw_queue(hctx);
 -              blk_mq_put_ctx(ctx);
 -
 -              ctx = blk_mq_get_ctx(q);
 -              hctx = q->mq_ops->map_queue(q, ctx->cpu);
 -              blk_mq_set_alloc_data(&alloc_data, q, flags, ctx, hctx);
 -              rq =  __blk_mq_alloc_request(&alloc_data, rw, 0);
 -              ctx = alloc_data.ctx;
 -      }
        blk_mq_put_ctx(ctx);
 +
        if (!rq) {
                blk_queue_exit(q);
                return ERR_PTR(-EWOULDBLOCK);
@@@ -266,29 -278,17 +266,29 @@@ struct request *blk_mq_alloc_request_hc
        if (ret)
                return ERR_PTR(ret);
  
 +      /*
 +       * Check if the hardware context is actually mapped to anything.
 +       * If not tell the caller that it should skip this queue.
 +       */
        hctx = q->queue_hw_ctx[hctx_idx];
 +      if (!blk_mq_hw_queue_mapped(hctx)) {
 +              ret = -EXDEV;
 +              goto out_queue_exit;
 +      }
        ctx = __blk_mq_get_ctx(q, cpumask_first(hctx->cpumask));
  
        blk_mq_set_alloc_data(&alloc_data, q, flags, ctx, hctx);
        rq = __blk_mq_alloc_request(&alloc_data, rw, 0);
        if (!rq) {
 -              blk_queue_exit(q);
 -              return ERR_PTR(-EWOULDBLOCK);
 +              ret = -EWOULDBLOCK;
 +              goto out_queue_exit;
        }
  
        return rq;
 +
 +out_queue_exit:
 +      blk_queue_exit(q);
 +      return ERR_PTR(ret);
  }
  EXPORT_SYMBOL_GPL(blk_mq_alloc_request_hctx);
  
@@@ -319,7 -319,11 +319,7 @@@ EXPORT_SYMBOL_GPL(blk_mq_free_hctx_requ
  
  void blk_mq_free_request(struct request *rq)
  {
 -      struct blk_mq_hw_ctx *hctx;
 -      struct request_queue *q = rq->q;
 -
 -      hctx = q->mq_ops->map_queue(q, rq->mq_ctx->cpu);
 -      blk_mq_free_hctx_request(hctx, rq);
 +      blk_mq_free_hctx_request(blk_mq_map_queue(rq->q, rq->mq_ctx->cpu), rq);
  }
  EXPORT_SYMBOL_GPL(blk_mq_free_request);
  
@@@ -916,7 -920,7 +916,7 @@@ void blk_mq_run_hw_queue(struct blk_mq_
            !blk_mq_hw_queue_mapped(hctx)))
                return;
  
 -      if (!async) {
 +      if (!async && !(hctx->flags & BLK_MQ_F_BLOCKING)) {
                int cpu = get_cpu();
                if (cpumask_test_cpu(cpu, hctx->cpumask)) {
                        __blk_mq_run_hw_queue(hctx);
@@@ -1054,7 -1058,9 +1054,7 @@@ void blk_mq_insert_request(struct reque
  {
        struct blk_mq_ctx *ctx = rq->mq_ctx;
        struct request_queue *q = rq->q;
 -      struct blk_mq_hw_ctx *hctx;
 -
 -      hctx = q->mq_ops->map_queue(q, ctx->cpu);
 +      struct blk_mq_hw_ctx *hctx = blk_mq_map_queue(q, ctx->cpu);
  
        spin_lock(&ctx->lock);
        __blk_mq_insert_request(hctx, rq, at_head);
@@@ -1071,10 -1077,12 +1071,10 @@@ static void blk_mq_insert_requests(stru
                                     bool from_schedule)
  
  {
 -      struct blk_mq_hw_ctx *hctx;
 +      struct blk_mq_hw_ctx *hctx = blk_mq_map_queue(q, ctx->cpu);
  
        trace_block_unplug(q, depth, !from_schedule);
  
 -      hctx = q->mq_ops->map_queue(q, ctx->cpu);
 -
        /*
         * preemption doesn't flush plug list, so it's possible ctx->cpu is
         * offline now
@@@ -1208,14 -1216,26 +1208,14 @@@ static struct request *blk_mq_map_reque
  
        blk_queue_enter_live(q);
        ctx = blk_mq_get_ctx(q);
 -      hctx = q->mq_ops->map_queue(q, ctx->cpu);
 +      hctx = blk_mq_map_queue(q, ctx->cpu);
  
        if (rw_is_sync(bio_op(bio), bio->bi_opf))
                op_flags |= REQ_SYNC;
  
        trace_block_getrq(q, bio, op);
 -      blk_mq_set_alloc_data(&alloc_data, q, BLK_MQ_REQ_NOWAIT, ctx, hctx);
 +      blk_mq_set_alloc_data(&alloc_data, q, 0, ctx, hctx);
        rq = __blk_mq_alloc_request(&alloc_data, op, op_flags);
 -      if (unlikely(!rq)) {
 -              __blk_mq_run_hw_queue(hctx);
 -              blk_mq_put_ctx(ctx);
 -              trace_block_sleeprq(q, bio, op);
 -
 -              ctx = blk_mq_get_ctx(q);
 -              hctx = q->mq_ops->map_queue(q, ctx->cpu);
 -              blk_mq_set_alloc_data(&alloc_data, q, 0, ctx, hctx);
 -              rq = __blk_mq_alloc_request(&alloc_data, op, op_flags);
 -              ctx = alloc_data.ctx;
 -              hctx = alloc_data.hctx;
 -      }
  
        hctx->queued++;
        data->hctx = hctx;
@@@ -1227,7 -1247,8 +1227,7 @@@ static int blk_mq_direct_issue_request(
  {
        int ret;
        struct request_queue *q = rq->q;
 -      struct blk_mq_hw_ctx *hctx = q->mq_ops->map_queue(q,
 -                      rq->mq_ctx->cpu);
 +      struct blk_mq_hw_ctx *hctx = blk_mq_map_queue(q, rq->mq_ctx->cpu);
        struct blk_mq_queue_data bd = {
                .rq = rq,
                .list = NULL,
@@@ -1431,6 -1452,15 +1431,6 @@@ run_queue
        return cookie;
  }
  
 -/*
 - * Default mapping to a software queue, since we use one per CPU.
 - */
 -struct blk_mq_hw_ctx *blk_mq_map_queue(struct request_queue *q, const int cpu)
 -{
 -      return q->queue_hw_ctx[q->mq_map[cpu]];
 -}
 -EXPORT_SYMBOL(blk_mq_map_queue);
 -
  static void blk_mq_free_rq_map(struct blk_mq_tag_set *set,
                struct blk_mq_tags *tags, unsigned int hctx_idx)
  {
@@@ -1563,11 -1593,13 +1563,13 @@@ fail
   * software queue to the hw queue dispatch list, and ensure that it
   * gets run.
   */
- static int blk_mq_hctx_cpu_offline(struct blk_mq_hw_ctx *hctx, int cpu)
+ static int blk_mq_hctx_notify_dead(unsigned int cpu, struct hlist_node *node)
  {
+       struct blk_mq_hw_ctx *hctx;
        struct blk_mq_ctx *ctx;
        LIST_HEAD(tmp);
  
+       hctx = hlist_entry_safe(node, struct blk_mq_hw_ctx, cpuhp_dead);
        ctx = __blk_mq_get_ctx(hctx->queue, cpu);
  
        spin_lock(&ctx->lock);
        spin_unlock(&ctx->lock);
  
        if (list_empty(&tmp))
-               return NOTIFY_OK;
+               return 0;
  
        spin_lock(&hctx->lock);
        list_splice_tail_init(&tmp, &hctx->dispatch);
        spin_unlock(&hctx->lock);
  
        blk_mq_run_hw_queue(hctx, true);
-       return NOTIFY_OK;
+       return 0;
  }
  
- static int blk_mq_hctx_notify(void *data, unsigned long action,
-                             unsigned int cpu)
+ static void blk_mq_remove_cpuhp(struct blk_mq_hw_ctx *hctx)
  {
-       struct blk_mq_hw_ctx *hctx = data;
-       if (action == CPU_DEAD || action == CPU_DEAD_FROZEN)
-               return blk_mq_hctx_cpu_offline(hctx, cpu);
-       /*
-        * In case of CPU online, tags may be reallocated
-        * in blk_mq_map_swqueue() after mapping is updated.
-        */
-       return NOTIFY_OK;
+       cpuhp_state_remove_instance_nocalls(CPUHP_BLK_MQ_DEAD,
+                                           &hctx->cpuhp_dead);
  }
  
  /* hctx->ctxs will be freed in queue's release handler */
@@@ -1621,7 -1643,7 +1613,7 @@@ static void blk_mq_exit_hctx(struct req
        if (set->ops->exit_hctx)
                set->ops->exit_hctx(hctx, hctx_idx);
  
-       blk_mq_unregister_cpu_notifier(&hctx->cpu_notifier);
+       blk_mq_remove_cpuhp(hctx);
        blk_free_flush_queue(hctx->fq);
        sbitmap_free(&hctx->ctx_map);
  }
@@@ -1668,9 -1690,7 +1660,7 @@@ static int blk_mq_init_hctx(struct requ
        hctx->queue_num = hctx_idx;
        hctx->flags = set->flags & ~BLK_MQ_F_TAG_SHARED;
  
-       blk_mq_init_cpu_notifier(&hctx->cpu_notifier,
-                                       blk_mq_hctx_notify, hctx);
-       blk_mq_register_cpu_notifier(&hctx->cpu_notifier);
+       cpuhp_state_add_instance_nocalls(CPUHP_BLK_MQ_DEAD, &hctx->cpuhp_dead);
  
        hctx->tags = set->tags[hctx_idx];
  
   free_ctxs:
        kfree(hctx->ctxs);
   unregister_cpu_notifier:
-       blk_mq_unregister_cpu_notifier(&hctx->cpu_notifier);
+       blk_mq_remove_cpuhp(hctx);
        return -1;
  }
  
@@@ -1739,7 -1758,7 +1728,7 @@@ static void blk_mq_init_cpu_queues(stru
                if (!cpu_online(i))
                        continue;
  
 -              hctx = q->mq_ops->map_queue(q, i);
 +              hctx = blk_mq_map_queue(q, i);
  
                /*
                 * Set local node, IFF we have more than one hw queue. If
@@@ -1777,7 -1796,7 +1766,7 @@@ static void blk_mq_map_swqueue(struct r
                        continue;
  
                ctx = per_cpu_ptr(q->queue_ctx, i);
 -              hctx = q->mq_ops->map_queue(q, i);
 +              hctx = blk_mq_map_queue(q, i);
  
                cpumask_set_cpu(i, hctx->cpumask);
                ctx->index_hw = hctx->nr_ctx;
                hctx->tags = set->tags[i];
                WARN_ON(!hctx->tags);
  
 -              cpumask_copy(hctx->tags->cpumask, hctx->cpumask);
                /*
                 * Set the map size to the number of mapped software queues.
                 * This is more accurate and more efficient than looping
@@@ -1899,6 -1919,7 +1888,6 @@@ void blk_mq_release(struct request_queu
                kfree(hctx);
        }
  
 -      kfree(q->mq_map);
        q->mq_map = NULL;
  
        kfree(q->queue_hw_ctx);
@@@ -1997,7 -2018,9 +1986,7 @@@ struct request_queue *blk_mq_init_alloc
        if (!q->queue_hw_ctx)
                goto err_percpu;
  
 -      q->mq_map = blk_mq_make_queue_map(set);
 -      if (!q->mq_map)
 -              goto err_map;
 +      q->mq_map = set->mq_map;
  
        blk_mq_realloc_hw_ctxs(set, q);
        if (!q->nr_hw_queues)
        return q;
  
  err_hctxs:
 -      kfree(q->mq_map);
 -err_map:
        kfree(q->queue_hw_ctx);
  err_percpu:
        free_percpu(q->queue_ctx);
@@@ -2078,6 -2103,8 +2067,6 @@@ static void blk_mq_queue_reinit(struct 
  
        blk_mq_sysfs_unregister(q);
  
 -      blk_mq_update_queue_map(q->mq_map, q->nr_hw_queues, online_mask);
 -
        /*
         * redo blk_mq_init_cpu_queues and blk_mq_init_hw_queues. FIXME: maybe
         * we should change hctx numa_node according to new topology (this
        blk_mq_sysfs_register(q);
  }
  
- static int blk_mq_queue_reinit_notify(struct notifier_block *nb,
-                                     unsigned long action, void *hcpu)
+ /*
+  * 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;
-       int cpu = (unsigned long)hcpu;
-       /*
-        * 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 online_new;
-       /*
-        * 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, 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.
-        */
-       switch (action & ~CPU_TASKS_FROZEN) {
-       case CPU_DEAD:
-       case CPU_UP_CANCELED:
-               cpumask_copy(&online_new, cpu_online_mask);
-               break;
-       case CPU_UP_PREPARE:
-               cpumask_copy(&online_new, cpu_online_mask);
-               cpumask_set_cpu(cpu, &online_new);
-               break;
-       default:
-               return NOTIFY_OK;
-       }
  
        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
        }
  
        list_for_each_entry(q, &all_q_list, all_q_node)
-               blk_mq_queue_reinit(q, &online_new);
+               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);
-       return NOTIFY_OK;
+ }
+ 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, 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)
@@@ -2216,6 -2241,12 +2203,6 @@@ static int blk_mq_alloc_rq_maps(struct 
        return 0;
  }
  
 -struct cpumask *blk_mq_tags_cpumask(struct blk_mq_tags *tags)
 -{
 -      return tags->cpumask;
 -}
 -EXPORT_SYMBOL_GPL(blk_mq_tags_cpumask);
 -
  /*
   * Alloc a tag set to be associated with one or more request queues.
   * May fail with EINVAL for various error conditions. May adjust the
   */
  int blk_mq_alloc_tag_set(struct blk_mq_tag_set *set)
  {
 +      int ret;
 +
        BUILD_BUG_ON(BLK_MQ_MAX_DEPTH > 1 << BLK_MQ_UNIQUE_TAG_BITS);
  
        if (!set->nr_hw_queues)
        if (set->queue_depth < set->reserved_tags + BLK_MQ_TAG_MIN)
                return -EINVAL;
  
 -      if (!set->ops->queue_rq || !set->ops->map_queue)
 +      if (!set->ops->queue_rq)
                return -EINVAL;
  
        if (set->queue_depth > BLK_MQ_MAX_DEPTH) {
        if (!set->tags)
                return -ENOMEM;
  
 -      if (blk_mq_alloc_rq_maps(set))
 -              goto enomem;
 +      ret = -ENOMEM;
 +      set->mq_map = kzalloc_node(sizeof(*set->mq_map) * nr_cpu_ids,
 +                      GFP_KERNEL, set->numa_node);
 +      if (!set->mq_map)
 +              goto out_free_tags;
 +
 +      if (set->ops->map_queues)
 +              ret = set->ops->map_queues(set);
 +      else
 +              ret = blk_mq_map_queues(set);
 +      if (ret)
 +              goto out_free_mq_map;
 +
 +      ret = blk_mq_alloc_rq_maps(set);
 +      if (ret)
 +              goto out_free_mq_map;
  
        mutex_init(&set->tag_list_lock);
        INIT_LIST_HEAD(&set->tag_list);
  
        return 0;
 -enomem:
 +
 +out_free_mq_map:
 +      kfree(set->mq_map);
 +      set->mq_map = NULL;
 +out_free_tags:
        kfree(set->tags);
        set->tags = NULL;
 -      return -ENOMEM;
 +      return ret;
  }
  EXPORT_SYMBOL(blk_mq_alloc_tag_set);
  
@@@ -2305,9 -2316,6 +2292,9 @@@ void blk_mq_free_tag_set(struct blk_mq_
                        blk_mq_free_rq_map(set, set->tags[i], i);
        }
  
 +      kfree(set->mq_map);
 +      set->mq_map = NULL;
 +
        kfree(set->tags);
        set->tags = NULL;
  }
@@@ -2378,10 -2386,12 +2365,12 @@@ void blk_mq_enable_hotplug(void
  
  static int __init blk_mq_init(void)
  {
-       blk_mq_cpu_init();
-       hotcpu_notifier(blk_mq_queue_reinit_notify, 0);
+       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);
diff --combined block/blk-mq.h
@@@ -32,28 -32,17 +32,21 @@@ void blk_mq_wake_waiters(struct request
  /*
   * CPU hotplug helpers
   */
- struct blk_mq_cpu_notifier;
- void blk_mq_init_cpu_notifier(struct blk_mq_cpu_notifier *notifier,
-                             int (*fn)(void *, unsigned long, unsigned int),
-                             void *data);
- void blk_mq_register_cpu_notifier(struct blk_mq_cpu_notifier *notifier);
- void blk_mq_unregister_cpu_notifier(struct blk_mq_cpu_notifier *notifier);
- void blk_mq_cpu_init(void);
  void blk_mq_enable_hotplug(void);
  void blk_mq_disable_hotplug(void);
  
  /*
   * CPU -> queue mappings
   */
 -extern unsigned int *blk_mq_make_queue_map(struct blk_mq_tag_set *set);
 -extern int blk_mq_update_queue_map(unsigned int *map, unsigned int nr_queues,
 -                                 const struct cpumask *online_mask);
 +int blk_mq_map_queues(struct blk_mq_tag_set *set);
  extern int blk_mq_hw_queue_to_node(unsigned int *map, unsigned int);
  
 +static inline struct blk_mq_hw_ctx *blk_mq_map_queue(struct request_queue *q,
 +              int cpu)
 +{
 +      return q->queue_hw_ctx[q->mq_map[cpu]];
 +}
 +
  /*
   * sysfs helpers
   */
diff --combined include/linux/blk-mq.h
@@@ -7,12 -7,6 +7,6 @@@
  struct blk_mq_tags;
  struct blk_flush_queue;
  
- struct blk_mq_cpu_notifier {
-       struct list_head list;
-       void *data;
-       int (*notify)(void *data, unsigned long action, unsigned int cpu);
- };
  struct blk_mq_hw_ctx {
        struct {
                spinlock_t              lock;
@@@ -53,7 -47,7 +47,7 @@@
  
        struct delayed_work     delay_work;
  
-       struct blk_mq_cpu_notifier      cpu_notifier;
+       struct hlist_node       cpuhp_dead;
        struct kobject          kobj;
  
        unsigned long           poll_considered;
@@@ -62,7 -56,6 +56,7 @@@
  };
  
  struct blk_mq_tag_set {
 +      unsigned int            *mq_map;
        struct blk_mq_ops       *ops;
        unsigned int            nr_hw_queues;
        unsigned int            queue_depth;    /* max hw supported */
@@@ -86,6 -79,7 +80,6 @@@ struct blk_mq_queue_data 
  };
  
  typedef int (queue_rq_fn)(struct blk_mq_hw_ctx *, const struct blk_mq_queue_data *);
 -typedef struct blk_mq_hw_ctx *(map_queue_fn)(struct request_queue *, const int);
  typedef enum blk_eh_timer_return (timeout_fn)(struct request *, bool);
  typedef int (init_hctx_fn)(struct blk_mq_hw_ctx *, void *, unsigned int);
  typedef void (exit_hctx_fn)(struct blk_mq_hw_ctx *, unsigned int);
@@@ -99,7 -93,6 +93,7 @@@ typedef void (busy_iter_fn)(struct blk_
                bool);
  typedef void (busy_tag_iter_fn)(struct request *, void *, bool);
  typedef int (poll_fn)(struct blk_mq_hw_ctx *, unsigned int);
 +typedef int (map_queues_fn)(struct blk_mq_tag_set *set);
  
  
  struct blk_mq_ops {
         */
        queue_rq_fn             *queue_rq;
  
 -      /*
 -       * Map to specific hardware queue
 -       */
 -      map_queue_fn            *map_queue;
 -
        /*
         * Called on request timeout
         */
        init_request_fn         *init_request;
        exit_request_fn         *exit_request;
        reinit_request_fn       *reinit_request;
 +
 +      map_queues_fn           *map_queues;
  };
  
  enum {
        BLK_MQ_F_TAG_SHARED     = 1 << 1,
        BLK_MQ_F_SG_MERGE       = 1 << 2,
        BLK_MQ_F_DEFER_ISSUE    = 1 << 4,
 +      BLK_MQ_F_BLOCKING       = 1 << 5,
        BLK_MQ_F_ALLOC_POLICY_START_BIT = 8,
        BLK_MQ_F_ALLOC_POLICY_BITS = 1,
  
@@@ -197,6 -192,7 +191,6 @@@ struct request *blk_mq_alloc_request(st
  struct request *blk_mq_alloc_request_hctx(struct request_queue *q, int op,
                unsigned int flags, unsigned int hctx_idx);
  struct request *blk_mq_tag_to_rq(struct blk_mq_tags *tags, unsigned int tag);
 -struct cpumask *blk_mq_tags_cpumask(struct blk_mq_tags *tags);
  
  enum {
        BLK_MQ_UNIQUE_TAG_BITS = 16,
@@@ -215,6 -211,7 +209,6 @@@ static inline u16 blk_mq_unique_tag_to_
        return unique_tag & BLK_MQ_UNIQUE_TAG_MASK;
  }
  
 -struct blk_mq_hw_ctx *blk_mq_map_queue(struct request_queue *, const int ctx_index);
  
  int blk_mq_request_started(struct request *rq);
  void blk_mq_start_request(struct request *rq);