diff options
Diffstat (limited to 'block')
-rw-r--r-- | block/blk-mq-cpumap.c | 16 | ||||
-rw-r--r-- | block/blk-mq.c | 26 | ||||
-rw-r--r-- | block/blk-mq.h | 1 |
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 | */ | ||
104 | int 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) | |||
1297 | EXPORT_SYMBOL(blk_mq_map_queue); | 1297 | EXPORT_SYMBOL(blk_mq_map_queue); |
1298 | 1298 | ||
1299 | struct blk_mq_hw_ctx *blk_mq_alloc_single_hw_queue(struct blk_mq_tag_set *set, | 1299 | struct 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 | } |
1305 | EXPORT_SYMBOL(blk_mq_alloc_single_hw_queue); | 1305 | EXPORT_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) | |||
1844 | err_flush_rq: | 1848 | err_flush_rq: |
1845 | kfree(q->flush_rq); | 1849 | kfree(q->flush_rq); |
1846 | err_hw: | 1850 | err_hw: |
1847 | kfree(q->mq_map); | ||
1848 | err_map: | ||
1849 | blk_cleanup_queue(q); | 1851 | blk_cleanup_queue(q); |
1850 | err_hctxs: | 1852 | err_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 | } |
1860 | err_map: | ||
1857 | kfree(hctxs); | 1861 | kfree(hctxs); |
1858 | err_percpu: | 1862 | err_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 | */ |
53 | extern unsigned int *blk_mq_make_queue_map(struct blk_mq_tag_set *set); | 53 | extern unsigned int *blk_mq_make_queue_map(struct blk_mq_tag_set *set); |
54 | extern int blk_mq_update_queue_map(unsigned int *map, unsigned int nr_queues); | 54 | extern int blk_mq_update_queue_map(unsigned int *map, unsigned int nr_queues); |
55 | extern 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 |