aboutsummaryrefslogtreecommitdiffstats
path: root/block/blk-mq.c
diff options
context:
space:
mode:
Diffstat (limited to 'block/blk-mq.c')
-rw-r--r--block/blk-mq.c47
1 files changed, 30 insertions, 17 deletions
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 159e69bd2c3c..22db728dbe24 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -1695,7 +1695,7 @@ static int blk_mq_init_hctx(struct request_queue *q,
1695 INIT_LIST_HEAD(&hctx->dispatch); 1695 INIT_LIST_HEAD(&hctx->dispatch);
1696 hctx->queue = q; 1696 hctx->queue = q;
1697 hctx->queue_num = hctx_idx; 1697 hctx->queue_num = hctx_idx;
1698 hctx->flags = set->flags; 1698 hctx->flags = set->flags & ~BLK_MQ_F_TAG_SHARED;
1699 1699
1700 blk_mq_init_cpu_notifier(&hctx->cpu_notifier, 1700 blk_mq_init_cpu_notifier(&hctx->cpu_notifier,
1701 blk_mq_hctx_notify, hctx); 1701 blk_mq_hctx_notify, hctx);
@@ -1882,27 +1882,26 @@ static void blk_mq_map_swqueue(struct request_queue *q,
1882 } 1882 }
1883} 1883}
1884 1884
1885static void blk_mq_update_tag_set_depth(struct blk_mq_tag_set *set) 1885static void queue_set_hctx_shared(struct request_queue *q, bool shared)
1886{ 1886{
1887 struct blk_mq_hw_ctx *hctx; 1887 struct blk_mq_hw_ctx *hctx;
1888 struct request_queue *q;
1889 bool shared;
1890 int i; 1888 int i;
1891 1889
1892 if (set->tag_list.next == set->tag_list.prev) 1890 queue_for_each_hw_ctx(q, hctx, i) {
1893 shared = false; 1891 if (shared)
1894 else 1892 hctx->flags |= BLK_MQ_F_TAG_SHARED;
1895 shared = true; 1893 else
1894 hctx->flags &= ~BLK_MQ_F_TAG_SHARED;
1895 }
1896}
1897
1898static void blk_mq_update_tag_set_depth(struct blk_mq_tag_set *set, bool shared)
1899{
1900 struct request_queue *q;
1896 1901
1897 list_for_each_entry(q, &set->tag_list, tag_set_list) { 1902 list_for_each_entry(q, &set->tag_list, tag_set_list) {
1898 blk_mq_freeze_queue(q); 1903 blk_mq_freeze_queue(q);
1899 1904 queue_set_hctx_shared(q, shared);
1900 queue_for_each_hw_ctx(q, hctx, i) {
1901 if (shared)
1902 hctx->flags |= BLK_MQ_F_TAG_SHARED;
1903 else
1904 hctx->flags &= ~BLK_MQ_F_TAG_SHARED;
1905 }
1906 blk_mq_unfreeze_queue(q); 1905 blk_mq_unfreeze_queue(q);
1907 } 1906 }
1908} 1907}
@@ -1913,7 +1912,12 @@ static void blk_mq_del_queue_tag_set(struct request_queue *q)
1913 1912
1914 mutex_lock(&set->tag_list_lock); 1913 mutex_lock(&set->tag_list_lock);
1915 list_del_init(&q->tag_set_list); 1914 list_del_init(&q->tag_set_list);
1916 blk_mq_update_tag_set_depth(set); 1915 if (list_is_singular(&set->tag_list)) {
1916 /* just transitioned to unshared */
1917 set->flags &= ~BLK_MQ_F_TAG_SHARED;
1918 /* update existing queue */
1919 blk_mq_update_tag_set_depth(set, false);
1920 }
1917 mutex_unlock(&set->tag_list_lock); 1921 mutex_unlock(&set->tag_list_lock);
1918} 1922}
1919 1923
@@ -1923,8 +1927,17 @@ static void blk_mq_add_queue_tag_set(struct blk_mq_tag_set *set,
1923 q->tag_set = set; 1927 q->tag_set = set;
1924 1928
1925 mutex_lock(&set->tag_list_lock); 1929 mutex_lock(&set->tag_list_lock);
1930
1931 /* Check to see if we're transitioning to shared (from 1 to 2 queues). */
1932 if (!list_empty(&set->tag_list) && !(set->flags & BLK_MQ_F_TAG_SHARED)) {
1933 set->flags |= BLK_MQ_F_TAG_SHARED;
1934 /* update existing queue */
1935 blk_mq_update_tag_set_depth(set, true);
1936 }
1937 if (set->flags & BLK_MQ_F_TAG_SHARED)
1938 queue_set_hctx_shared(q, true);
1926 list_add_tail(&q->tag_set_list, &set->tag_list); 1939 list_add_tail(&q->tag_set_list, &set->tag_list);
1927 blk_mq_update_tag_set_depth(set); 1940
1928 mutex_unlock(&set->tag_list_lock); 1941 mutex_unlock(&set->tag_list_lock);
1929} 1942}
1930 1943