aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--block/blk-mq.c34
1 files changed, 13 insertions, 21 deletions
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 1fccb98aa28f..76f460e36f1d 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -1574,22 +1574,6 @@ static int blk_mq_hctx_cpu_offline(struct blk_mq_hw_ctx *hctx, int cpu)
1574 return NOTIFY_OK; 1574 return NOTIFY_OK;
1575} 1575}
1576 1576
1577static int blk_mq_hctx_cpu_online(struct blk_mq_hw_ctx *hctx, int cpu)
1578{
1579 struct request_queue *q = hctx->queue;
1580 struct blk_mq_tag_set *set = q->tag_set;
1581
1582 if (set->tags[hctx->queue_num])
1583 return NOTIFY_OK;
1584
1585 set->tags[hctx->queue_num] = blk_mq_init_rq_map(set, hctx->queue_num);
1586 if (!set->tags[hctx->queue_num])
1587 return NOTIFY_STOP;
1588
1589 hctx->tags = set->tags[hctx->queue_num];
1590 return NOTIFY_OK;
1591}
1592
1593static int blk_mq_hctx_notify(void *data, unsigned long action, 1577static int blk_mq_hctx_notify(void *data, unsigned long action,
1594 unsigned int cpu) 1578 unsigned int cpu)
1595{ 1579{
@@ -1597,8 +1581,11 @@ static int blk_mq_hctx_notify(void *data, unsigned long action,
1597 1581
1598 if (action == CPU_DEAD || action == CPU_DEAD_FROZEN) 1582 if (action == CPU_DEAD || action == CPU_DEAD_FROZEN)
1599 return blk_mq_hctx_cpu_offline(hctx, cpu); 1583 return blk_mq_hctx_cpu_offline(hctx, cpu);
1600 else if (action == CPU_ONLINE || action == CPU_ONLINE_FROZEN) 1584
1601 return blk_mq_hctx_cpu_online(hctx, cpu); 1585 /*
1586 * In case of CPU online, tags may be reallocated
1587 * in blk_mq_map_swqueue() after mapping is updated.
1588 */
1602 1589
1603 return NOTIFY_OK; 1590 return NOTIFY_OK;
1604} 1591}
@@ -1778,6 +1765,7 @@ static void blk_mq_map_swqueue(struct request_queue *q)
1778 unsigned int i; 1765 unsigned int i;
1779 struct blk_mq_hw_ctx *hctx; 1766 struct blk_mq_hw_ctx *hctx;
1780 struct blk_mq_ctx *ctx; 1767 struct blk_mq_ctx *ctx;
1768 struct blk_mq_tag_set *set = q->tag_set;
1781 1769
1782 queue_for_each_hw_ctx(q, hctx, i) { 1770 queue_for_each_hw_ctx(q, hctx, i) {
1783 cpumask_clear(hctx->cpumask); 1771 cpumask_clear(hctx->cpumask);
@@ -1806,16 +1794,20 @@ static void blk_mq_map_swqueue(struct request_queue *q)
1806 * disable it and free the request entries. 1794 * disable it and free the request entries.
1807 */ 1795 */
1808 if (!hctx->nr_ctx) { 1796 if (!hctx->nr_ctx) {
1809 struct blk_mq_tag_set *set = q->tag_set;
1810
1811 if (set->tags[i]) { 1797 if (set->tags[i]) {
1812 blk_mq_free_rq_map(set, set->tags[i], i); 1798 blk_mq_free_rq_map(set, set->tags[i], i);
1813 set->tags[i] = NULL; 1799 set->tags[i] = NULL;
1814 hctx->tags = NULL;
1815 } 1800 }
1801 hctx->tags = NULL;
1816 continue; 1802 continue;
1817 } 1803 }
1818 1804
1805 /* unmapped hw queue can be remapped after CPU topo changed */
1806 if (!set->tags[i])
1807 set->tags[i] = blk_mq_init_rq_map(set, i);
1808 hctx->tags = set->tags[i];
1809 WARN_ON(!hctx->tags);
1810
1819 /* 1811 /*
1820 * Set the map size to the number of mapped software queues. 1812 * Set the map size to the number of mapped software queues.
1821 * This is more accurate and more efficient than looping 1813 * This is more accurate and more efficient than looping