History

block: sum requests in the plug structure

This isn't exactly the same as the previous count, as it includes requests for all devices. But that really doesn't matter, if we have more than the threshold (16) queued up, flush it. It's not worth it to have an expensive list loop for this.

Jens Axboe committed 7 years ago

Commit 5f0ed771 parent af78ff74 files · +10 −39Browse files

Unified · Split

4 files
  1. block/blk-core.c +4 −26
  2. block/blk-mq.c +5 −11
  3. block/blk.h +0 −2
  4. include/linux/blkdev.h +1 −0
block/blk-core.c+4−26
@@ -736,7 +736,6 @@ no_merge: · 735 unmodified lines
736 * Caller must ensure !blk_queue_nomerges(q) beforehand.736 * Caller must ensure !blk_queue_nomerges(q) beforehand.
737 */737 */
738bool blk_attempt_plug_merge(struct request_queue *q, struct bio *bio,738bool blk_attempt_plug_merge(struct request_queue *q, struct bio *bio,
739 unsigned int *request_count,
740 struct request **same_queue_rq)739 struct request **same_queue_rq)
741{740{
742 struct blk_plug *plug;741 struct blk_plug *plug;
@@ -746,22 +745,19 @@ bool blk_attempt_plug_merge(struct request_queue *q, struct bio *bio, · 3 unmodified lines
746 plug = current->plug;745 plug = current->plug;
747 if (!plug)746 if (!plug)
748 return false;747 return false;
749 *request_count = 0;
750 748
751 plug_list = &plug->mq_list;749 plug_list = &plug->mq_list;
752 750
753 list_for_each_entry_reverse(rq, plug_list, queuelist) {751 list_for_each_entry_reverse(rq, plug_list, queuelist) {
754 bool merged = false;752 bool merged = false;
755 753
756 if (rq->q == q) {754 if (rq->q == q && same_queue_rq) {
757 (*request_count)++;
758 /*755 /*
759 * Only blk-mq multiple hardware queues case checks the756 * Only blk-mq multiple hardware queues case checks the
760 * rq in the same queue, there should be only one such757 * rq in the same queue, there should be only one such
761 * rq in a queue758 * rq in a queue
762 **/759 **/
763 if (same_queue_rq)760 *same_queue_rq = rq;
764 *same_queue_rq = rq;
765 }761 }
766 762
767 if (rq->q != q || !blk_rq_merge_ok(rq, bio))763 if (rq->q != q || !blk_rq_merge_ok(rq, bio))
@@ -788,26 +784,6 @@ bool blk_attempt_plug_merge(struct request_queue *q, struct bio *bio, · 20 unmodified lines
788 return false;784 return false;
789}785}
790 786
791unsigned int blk_plug_queued_count(struct request_queue *q)
792{
793 struct blk_plug *plug;
794 struct request *rq;
795 struct list_head *plug_list;
796 unsigned int ret = 0;
797
798 plug = current->plug;
799 if (!plug)
800 goto out;
801
802 plug_list = &plug->mq_list;
803 list_for_each_entry(rq, plug_list, queuelist) {
804 if (rq->q == q)
805 ret++;
806 }
807out:
808 return ret;
809}
810
811void blk_init_request_from_bio(struct request *req, struct bio *bio)787void blk_init_request_from_bio(struct request *req, struct bio *bio)
812{788{
813 if (bio->bi_opf & REQ_RAHEAD)789 if (bio->bi_opf & REQ_RAHEAD)
@@ -1803,6 +1779,8 @@ void blk_start_plug(struct blk_plug *plug) · 989 unmodified lines
1803 1779
1804 INIT_LIST_HEAD(&plug->mq_list);1780 INIT_LIST_HEAD(&plug->mq_list);
1805 INIT_LIST_HEAD(&plug->cb_list);1781 INIT_LIST_HEAD(&plug->cb_list);
1782 plug->rq_count = 0;
1783
1806 /*1784 /*
1807 * Store ordering should not be needed here, since a potential1785 * Store ordering should not be needed here, since a potential
1808 * preempt will imply a full memory barrier1786 * preempt will imply a full memory barrier
block/blk-mq.c+5−11
@@ -1675,6 +1675,7 @@ void blk_mq_flush_plug_list(struct blk_plug *plug, bool from_schedule) · 1674 unmodified lines
1675 unsigned int depth;1675 unsigned int depth;
1676 1676
1677 list_splice_init(&plug->mq_list, &list);1677 list_splice_init(&plug->mq_list, &list);
1678 plug->rq_count = 0;
1678 1679
1679 list_sort(NULL, &list, plug_rq_cmp);1680 list_sort(NULL, &list, plug_rq_cmp);
1680 1681
@@ -1871,7 +1872,6 @@ static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio) · 190 unmodified lines
1871 const int is_flush_fua = op_is_flush(bio->bi_opf);1872 const int is_flush_fua = op_is_flush(bio->bi_opf);
1872 struct blk_mq_alloc_data data = { .flags = 0, .cmd_flags = bio->bi_opf };1873 struct blk_mq_alloc_data data = { .flags = 0, .cmd_flags = bio->bi_opf };
1873 struct request *rq;1874 struct request *rq;
1874 unsigned int request_count = 0;
1875 struct blk_plug *plug;1875 struct blk_plug *plug;
1876 struct request *same_queue_rq = NULL;1876 struct request *same_queue_rq = NULL;
1877 blk_qc_t cookie;1877 blk_qc_t cookie;
@@ -1884,7 +1884,7 @@ static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio) · 6 unmodified lines
1884 return BLK_QC_T_NONE;1884 return BLK_QC_T_NONE;
1885 1885
1886 if (!is_flush_fua && !blk_queue_nomerges(q) &&1886 if (!is_flush_fua && !blk_queue_nomerges(q) &&
1887 blk_attempt_plug_merge(q, bio, &request_count, &same_queue_rq))1887 blk_attempt_plug_merge(q, bio, &same_queue_rq))
1888 return BLK_QC_T_NONE;1888 return BLK_QC_T_NONE;
1889 1889
1890 if (blk_mq_sched_bio_merge(q, bio))1890 if (blk_mq_sched_bio_merge(q, bio))
@@ -1915,20 +1915,12 @@ static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio) · 24 unmodified lines
1915 blk_insert_flush(rq);1915 blk_insert_flush(rq);
1916 blk_mq_run_hw_queue(data.hctx, true);1916 blk_mq_run_hw_queue(data.hctx, true);
1917 } else if (plug && q->nr_hw_queues == 1) {1917 } else if (plug && q->nr_hw_queues == 1) {
1918 unsigned int request_count = plug->rq_count;
1918 struct request *last = NULL;1919 struct request *last = NULL;
1919 1920
1920 blk_mq_put_ctx(data.ctx);1921 blk_mq_put_ctx(data.ctx);
1921 blk_mq_bio_to_request(rq, bio);1922 blk_mq_bio_to_request(rq, bio);
1922 1923
1923 /*
1924 * @request_count may become stale because of schedule
1925 * out, so check the list again.
1926 */
1927 if (list_empty(&plug->mq_list))
1928 request_count = 0;
1929 else if (blk_queue_nomerges(q))
1930 request_count = blk_plug_queued_count(q);
1931
1932 if (!request_count)1924 if (!request_count)
1933 trace_block_plug(q);1925 trace_block_plug(q);
1934 else1926 else
@@ -1941,6 +1933,7 @@ static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio) · 6 unmodified lines
1941 }1933 }
1942 1934
1943 list_add_tail(&rq->queuelist, &plug->mq_list);1935 list_add_tail(&rq->queuelist, &plug->mq_list);
1936 plug->rq_count++;
1944 } else if (plug && !blk_queue_nomerges(q)) {1937 } else if (plug && !blk_queue_nomerges(q)) {
1945 blk_mq_bio_to_request(rq, bio);1938 blk_mq_bio_to_request(rq, bio);
1946 1939
@@ -1956,6 +1949,7 @@ static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio) · 9 unmodified lines
1956 if (same_queue_rq)1949 if (same_queue_rq)
1957 list_del_init(&same_queue_rq->queuelist);1950 list_del_init(&same_queue_rq->queuelist);
1958 list_add_tail(&rq->queuelist, &plug->mq_list);1951 list_add_tail(&rq->queuelist, &plug->mq_list);
1952 plug->rq_count++;
1959 1953
1960 blk_mq_put_ctx(data.ctx);1954 blk_mq_put_ctx(data.ctx);
1961 1955
block/blk.h+0−2
@@ -161,9 +161,7 @@ bool bio_attempt_back_merge(struct request_queue *q, struct request *req, · 160 unmodified lines
161bool bio_attempt_discard_merge(struct request_queue *q, struct request *req,161bool bio_attempt_discard_merge(struct request_queue *q, struct request *req,
162 struct bio *bio);162 struct bio *bio);
163bool blk_attempt_plug_merge(struct request_queue *q, struct bio *bio,163bool blk_attempt_plug_merge(struct request_queue *q, struct bio *bio,
164 unsigned int *request_count,
165 struct request **same_queue_rq);164 struct request **same_queue_rq);
166unsigned int blk_plug_queued_count(struct request_queue *q);
167 165
168void blk_account_io_start(struct request *req, bool new_io);166void blk_account_io_start(struct request *req, bool new_io);
169void blk_account_io_completion(struct request *req, unsigned int bytes);167void blk_account_io_completion(struct request *req, unsigned int bytes);
include/linux/blkdev.h+1−0
@@ -1130,6 +1130,7 @@ extern void blk_set_queue_dying(struct request_queue *); · 1129 unmodified lines
1130struct blk_plug {1130struct blk_plug {
1131 struct list_head mq_list; /* blk-mq requests */1131 struct list_head mq_list; /* blk-mq requests */
1132 struct list_head cb_list; /* md requires an unplug callback */1132 struct list_head cb_list; /* md requires an unplug callback */
1133 unsigned short rq_count;
1133};1134};
1134#define BLK_MAX_REQUEST_COUNT 161135#define BLK_MAX_REQUEST_COUNT 16
1135#define BLK_PLUG_FLUSH_SIZE (128 * 1024)1136#define BLK_PLUG_FLUSH_SIZE (128 * 1024)