aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
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