diff options
Diffstat (limited to 'block/blk-mq.c')
-rw-r--r-- | block/blk-mq.c | 47 |
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 | ||
1885 | static void blk_mq_update_tag_set_depth(struct blk_mq_tag_set *set) | 1885 | static 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 | |||
1898 | static 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 | ||