aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
authorJens Axboe <axboe@fb.com>2014-05-27 14:06:53 -0400
committerJens Axboe <axboe@fb.com>2014-05-27 14:06:53 -0400
commitf14bbe77a96bb979dc539d8308ee18a9363a544f (patch)
tree38ae39ea9002bb126aa259be0e81ffd7b32fa0d9 /block
parent3d2936f457a847d9d88a9cc127e0eb7a0ebba0ff (diff)
blk-mq: pass in suggested NUMA node to ->alloc_hctx()
Drivers currently have to figure this out on their own, and they are missing information to do it properly. The ones that did attempt to do it, do it wrong. So just pass in the suggested node directly to the alloc function. Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'block')
-rw-r--r--block/blk-mq-cpumap.c16
-rw-r--r--block/blk-mq.c26
-rw-r--r--block/blk-mq.h1
3 files changed, 32 insertions, 11 deletions
diff --git a/block/blk-mq-cpumap.c b/block/blk-mq-cpumap.c
index 5d0f93cf358c..0daacb927be1 100644
--- a/block/blk-mq-cpumap.c
+++ b/block/blk-mq-cpumap.c
@@ -96,3 +96,19 @@ unsigned int *blk_mq_make_queue_map(struct blk_mq_tag_set *set)
96 kfree(map); 96 kfree(map);
97 return NULL; 97 return NULL;
98} 98}
99
100/*
101 * We have no quick way of doing reverse lookups. This is only used at
102 * queue init time, so runtime isn't important.
103 */
104int blk_mq_hw_queue_to_node(unsigned int *mq_map, unsigned int index)
105{
106 int i;
107
108 for_each_possible_cpu(i) {
109 if (index == mq_map[i])
110 return cpu_to_node(i);
111 }
112
113 return NUMA_NO_NODE;
114}
diff --git a/block/blk-mq.c b/block/blk-mq.c
index e8b5f74dc1a1..30bad930e661 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -1297,10 +1297,10 @@ struct blk_mq_hw_ctx *blk_mq_map_queue(struct request_queue *q, const int cpu)
1297EXPORT_SYMBOL(blk_mq_map_queue); 1297EXPORT_SYMBOL(blk_mq_map_queue);
1298 1298
1299struct blk_mq_hw_ctx *blk_mq_alloc_single_hw_queue(struct blk_mq_tag_set *set, 1299struct blk_mq_hw_ctx *blk_mq_alloc_single_hw_queue(struct blk_mq_tag_set *set,
1300 unsigned int hctx_index) 1300 unsigned int hctx_index,
1301 int node)
1301{ 1302{
1302 return kzalloc_node(sizeof(struct blk_mq_hw_ctx), GFP_KERNEL, 1303 return kzalloc_node(sizeof(struct blk_mq_hw_ctx), GFP_KERNEL, node);
1303 set->numa_node);
1304} 1304}
1305EXPORT_SYMBOL(blk_mq_alloc_single_hw_queue); 1305EXPORT_SYMBOL(blk_mq_alloc_single_hw_queue);
1306 1306
@@ -1752,6 +1752,7 @@ struct request_queue *blk_mq_init_queue(struct blk_mq_tag_set *set)
1752 struct blk_mq_hw_ctx **hctxs; 1752 struct blk_mq_hw_ctx **hctxs;
1753 struct blk_mq_ctx *ctx; 1753 struct blk_mq_ctx *ctx;
1754 struct request_queue *q; 1754 struct request_queue *q;
1755 unsigned int *map;
1755 int i; 1756 int i;
1756 1757
1757 ctx = alloc_percpu(struct blk_mq_ctx); 1758 ctx = alloc_percpu(struct blk_mq_ctx);
@@ -1764,8 +1765,14 @@ struct request_queue *blk_mq_init_queue(struct blk_mq_tag_set *set)
1764 if (!hctxs) 1765 if (!hctxs)
1765 goto err_percpu; 1766 goto err_percpu;
1766 1767
1768 map = blk_mq_make_queue_map(set);
1769 if (!map)
1770 goto err_map;
1771
1767 for (i = 0; i < set->nr_hw_queues; i++) { 1772 for (i = 0; i < set->nr_hw_queues; i++) {
1768 hctxs[i] = set->ops->alloc_hctx(set, i); 1773 int node = blk_mq_hw_queue_to_node(map, i);
1774
1775 hctxs[i] = set->ops->alloc_hctx(set, i, node);
1769 if (!hctxs[i]) 1776 if (!hctxs[i])
1770 goto err_hctxs; 1777 goto err_hctxs;
1771 1778
@@ -1773,7 +1780,7 @@ struct request_queue *blk_mq_init_queue(struct blk_mq_tag_set *set)
1773 goto err_hctxs; 1780 goto err_hctxs;
1774 1781
1775 atomic_set(&hctxs[i]->nr_active, 0); 1782 atomic_set(&hctxs[i]->nr_active, 0);
1776 hctxs[i]->numa_node = NUMA_NO_NODE; 1783 hctxs[i]->numa_node = node;
1777 hctxs[i]->queue_num = i; 1784 hctxs[i]->queue_num = i;
1778 } 1785 }
1779 1786
@@ -1784,15 +1791,12 @@ struct request_queue *blk_mq_init_queue(struct blk_mq_tag_set *set)
1784 if (percpu_counter_init(&q->mq_usage_counter, 0)) 1791 if (percpu_counter_init(&q->mq_usage_counter, 0))
1785 goto err_map; 1792 goto err_map;
1786 1793
1787 q->mq_map = blk_mq_make_queue_map(set);
1788 if (!q->mq_map)
1789 goto err_map;
1790
1791 setup_timer(&q->timeout, blk_mq_rq_timer, (unsigned long) q); 1794 setup_timer(&q->timeout, blk_mq_rq_timer, (unsigned long) q);
1792 blk_queue_rq_timeout(q, 30000); 1795 blk_queue_rq_timeout(q, 30000);
1793 1796
1794 q->nr_queues = nr_cpu_ids; 1797 q->nr_queues = nr_cpu_ids;
1795 q->nr_hw_queues = set->nr_hw_queues; 1798 q->nr_hw_queues = set->nr_hw_queues;
1799 q->mq_map = map;
1796 1800
1797 q->queue_ctx = ctx; 1801 q->queue_ctx = ctx;
1798 q->queue_hw_ctx = hctxs; 1802 q->queue_hw_ctx = hctxs;
@@ -1844,16 +1848,16 @@ struct request_queue *blk_mq_init_queue(struct blk_mq_tag_set *set)
1844err_flush_rq: 1848err_flush_rq:
1845 kfree(q->flush_rq); 1849 kfree(q->flush_rq);
1846err_hw: 1850err_hw:
1847 kfree(q->mq_map);
1848err_map:
1849 blk_cleanup_queue(q); 1851 blk_cleanup_queue(q);
1850err_hctxs: 1852err_hctxs:
1853 kfree(map);
1851 for (i = 0; i < set->nr_hw_queues; i++) { 1854 for (i = 0; i < set->nr_hw_queues; i++) {
1852 if (!hctxs[i]) 1855 if (!hctxs[i])
1853 break; 1856 break;
1854 free_cpumask_var(hctxs[i]->cpumask); 1857 free_cpumask_var(hctxs[i]->cpumask);
1855 set->ops->free_hctx(hctxs[i], i); 1858 set->ops->free_hctx(hctxs[i], i);
1856 } 1859 }
1860err_map:
1857 kfree(hctxs); 1861 kfree(hctxs);
1858err_percpu: 1862err_percpu:
1859 free_percpu(ctx); 1863 free_percpu(ctx);
diff --git a/block/blk-mq.h b/block/blk-mq.h
index 491dbd4e93f5..ff5e6bf0f691 100644
--- a/block/blk-mq.h
+++ b/block/blk-mq.h
@@ -52,6 +52,7 @@ void blk_mq_disable_hotplug(void);
52 */ 52 */
53extern unsigned int *blk_mq_make_queue_map(struct blk_mq_tag_set *set); 53extern unsigned int *blk_mq_make_queue_map(struct blk_mq_tag_set *set);
54extern int blk_mq_update_queue_map(unsigned int *map, unsigned int nr_queues); 54extern int blk_mq_update_queue_map(unsigned int *map, unsigned int nr_queues);
55extern int blk_mq_hw_queue_to_node(unsigned int *map, unsigned int);
55 56
56/* 57/*
57 * Basic implementation of sparser bitmap, allowing the user to spread 58 * Basic implementation of sparser bitmap, allowing the user to spread