Re: [PATCH 2/8] block: improve logic around when to sort a plug list

2018-11-27 Thread Jens Axboe
On 11/27/18 5:05 PM, Omar Sandoval wrote:
>> +static void blk_add_rq_to_plug(struct blk_plug *plug, struct request *rq)
>> +{
>> +list_add_tail(>queuelist, >mq_list);
>> +plug->rq_count++;
>> +if (!plug->multiple_queues && !list_is_singular(>mq_list)) {
>> +struct request *tmp;
>> +
>> +tmp = list_first_entry(>mq_list, struct request,
>> +queuelist);
>> +if (tmp->q != rq->q)
>> +plug->multiple_queues = true;
> 
> Actually, I thought we want to sort whenever there are different
> software/hardware queues on the plug list, even if they're on the same
> queue?

That was the original intent, but with the tons of testing I've done
lately, the cost of sorting batches is higher than the cost we pay for
having to do multiple inserts. So I think the only sane case is >= 3
requests, and multiple queues.

-- 
Jens Axboe



Re: [PATCH 2/8] block: improve logic around when to sort a plug list

2018-11-27 Thread Omar Sandoval
On Tue, Nov 27, 2018 at 04:59:14PM -0700, Jens Axboe wrote:
> On 11/27/18 4:49 PM, Jens Axboe wrote:
> > On 11/27/18 4:31 PM, Omar Sandoval wrote:
> >> On Mon, Nov 26, 2018 at 09:35:50AM -0700, Jens Axboe wrote:
> >>> Do it for the nr_hw_queues == 1 case, but only do it for the multi queue
> >>> case if we have requests for multiple devices in the plug.
> >>>
> >>> Signed-off-by: Jens Axboe 
> >>> ---
> >>>  block/blk-core.c   | 1 +
> >>>  block/blk-mq.c | 7 +--
> >>>  include/linux/blkdev.h | 1 +
> >>>  3 files changed, 7 insertions(+), 2 deletions(-)
> >>>
> >>> diff --git a/block/blk-core.c b/block/blk-core.c
> >>> index be9233400314..c9758d185357 100644
> >>> --- a/block/blk-core.c
> >>> +++ b/block/blk-core.c
> >>> @@ -1780,6 +1780,7 @@ void blk_start_plug(struct blk_plug *plug)
> >>>   INIT_LIST_HEAD(>mq_list);
> >>>   INIT_LIST_HEAD(>cb_list);
> >>>   plug->rq_count = 0;
> >>> + plug->do_sort = false;
> >>>  
> >>>   /*
> >>>* Store ordering should not be needed here, since a potential
> >>> diff --git a/block/blk-mq.c b/block/blk-mq.c
> >>> index 99c66823d52f..6a249bf6ed00 100644
> >>> --- a/block/blk-mq.c
> >>> +++ b/block/blk-mq.c
> >>> @@ -1678,7 +1678,8 @@ void blk_mq_flush_plug_list(struct blk_plug *plug, 
> >>> bool from_schedule)
> >>>   list_splice_init(>mq_list, );
> >>>   plug->rq_count = 0;
> >>>  
> >>> - list_sort(NULL, , plug_rq_cmp);
> >>> + if (plug->do_sort)
> >>> + list_sort(NULL, , plug_rq_cmp);
> >>>  
> >>>   this_q = NULL;
> >>>   this_hctx = NULL;
> >>> @@ -1935,6 +1936,7 @@ static blk_qc_t blk_mq_make_request(struct 
> >>> request_queue *q, struct bio *bio)
> >>>  
> >>>   list_add_tail(>queuelist, >mq_list);
> >>>   plug->rq_count++;
> >>> + plug->do_sort = true;
> >>>   } else if (plug && !blk_queue_nomerges(q)) {
> >>>   blk_mq_bio_to_request(rq, bio);
> >>>  
> >>> @@ -1958,7 +1960,8 @@ static blk_qc_t blk_mq_make_request(struct 
> >>> request_queue *q, struct bio *bio)
> >>>   data.hctx = same_queue_rq->mq_hctx;
> >>>   blk_mq_try_issue_directly(data.hctx, same_queue_rq,
> >>>   );
> >>> - }
> >>> + } else if (plug->rq_count > 1)
> >>> + plug->do_sort = true;
> >>
> >> If plug->rq_count == 2, there's no benefit to sorting, either. The
> >> nr_hw_queues == 1 case could also avoid sorting in that case. So maybe
> >> this whole patch could just be replaced with:
> > 
> > Heh yes, good point, it should be 3 at least. But if you look at the
> > later mq plug patch, we only sort for that one if we have multiple
> > queues. So the logic should be something ala:
> > 
> > if (plug->rq_count > 2 && plug->has_multiple_queues)
> > 
> > since that's the only case we want to sort for.
> 
> How about something like this?
> 
> 
> diff --git a/block/blk-core.c b/block/blk-core.c
> index be9233400314..d107d016b92b 100644
> --- a/block/blk-core.c
> +++ b/block/blk-core.c
> @@ -1780,6 +1780,7 @@ void blk_start_plug(struct blk_plug *plug)
>   INIT_LIST_HEAD(>mq_list);
>   INIT_LIST_HEAD(>cb_list);
>   plug->rq_count = 0;
> + plug->multiple_queues = false;
>  
>   /*
>* Store ordering should not be needed here, since a potential
> diff --git a/block/blk-mq.c b/block/blk-mq.c
> index 7b7dff85cf6c..02daa32c5d77 100644
> --- a/block/blk-mq.c
> +++ b/block/blk-mq.c
> @@ -1677,7 +1677,8 @@ void blk_mq_flush_plug_list(struct blk_plug *plug, bool 
> from_schedule)
>   list_splice_init(>mq_list, );
>   plug->rq_count = 0;
>  
> - list_sort(NULL, , plug_rq_cmp);
> + if (plug->rq_count > 2 && plug->multiple_queues)
> + list_sort(NULL, , plug_rq_cmp);
>  
>   this_q = NULL;
>   this_hctx = NULL;
> @@ -1866,6 +1867,20 @@ void blk_mq_try_issue_list_directly(struct 
> blk_mq_hw_ctx *hctx,
>   }
>  }
>  
> +static void blk_add_rq_to_plug(struct blk_plug *plug, struct request *rq)
> +{
> + list_add_tail(>queuelist, >mq_list);
> + plug->rq_count++;
> + if (!plug->multiple_queues && !list_is_singular(>mq_list)) {
> + struct request *tmp;
> +
> + tmp = list_first_entry(>mq_list, struct request,
> + queuelist);
> + if (tmp->q != rq->q)
> + plug->multiple_queues = true;

Actually, I thought we want to sort whenever there are different
software/hardware queues on the plug list, even if they're on the same
queue?

> + }
> +}
> +
>  static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio)
>  {
>   const int is_sync = op_is_sync(bio->bi_opf);
> @@ -1932,8 +1947,7 @@ static blk_qc_t blk_mq_make_request(struct 
> request_queue *q, struct bio *bio)
>   trace_block_plug(q);
>   }
>  
> - list_add_tail(>queuelist, >mq_list);
> - plug->rq_count++;
> + blk_add_rq_to_plug(plug, rq);
>   } else 

Re: [PATCH 2/8] block: improve logic around when to sort a plug list

2018-11-27 Thread Jens Axboe
On 11/27/18 4:49 PM, Jens Axboe wrote:
> On 11/27/18 4:31 PM, Omar Sandoval wrote:
>> On Mon, Nov 26, 2018 at 09:35:50AM -0700, Jens Axboe wrote:
>>> Do it for the nr_hw_queues == 1 case, but only do it for the multi queue
>>> case if we have requests for multiple devices in the plug.
>>>
>>> Signed-off-by: Jens Axboe 
>>> ---
>>>  block/blk-core.c   | 1 +
>>>  block/blk-mq.c | 7 +--
>>>  include/linux/blkdev.h | 1 +
>>>  3 files changed, 7 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/block/blk-core.c b/block/blk-core.c
>>> index be9233400314..c9758d185357 100644
>>> --- a/block/blk-core.c
>>> +++ b/block/blk-core.c
>>> @@ -1780,6 +1780,7 @@ void blk_start_plug(struct blk_plug *plug)
>>> INIT_LIST_HEAD(>mq_list);
>>> INIT_LIST_HEAD(>cb_list);
>>> plug->rq_count = 0;
>>> +   plug->do_sort = false;
>>>  
>>> /*
>>>  * Store ordering should not be needed here, since a potential
>>> diff --git a/block/blk-mq.c b/block/blk-mq.c
>>> index 99c66823d52f..6a249bf6ed00 100644
>>> --- a/block/blk-mq.c
>>> +++ b/block/blk-mq.c
>>> @@ -1678,7 +1678,8 @@ void blk_mq_flush_plug_list(struct blk_plug *plug, 
>>> bool from_schedule)
>>> list_splice_init(>mq_list, );
>>> plug->rq_count = 0;
>>>  
>>> -   list_sort(NULL, , plug_rq_cmp);
>>> +   if (plug->do_sort)
>>> +   list_sort(NULL, , plug_rq_cmp);
>>>  
>>> this_q = NULL;
>>> this_hctx = NULL;
>>> @@ -1935,6 +1936,7 @@ static blk_qc_t blk_mq_make_request(struct 
>>> request_queue *q, struct bio *bio)
>>>  
>>> list_add_tail(>queuelist, >mq_list);
>>> plug->rq_count++;
>>> +   plug->do_sort = true;
>>> } else if (plug && !blk_queue_nomerges(q)) {
>>> blk_mq_bio_to_request(rq, bio);
>>>  
>>> @@ -1958,7 +1960,8 @@ static blk_qc_t blk_mq_make_request(struct 
>>> request_queue *q, struct bio *bio)
>>> data.hctx = same_queue_rq->mq_hctx;
>>> blk_mq_try_issue_directly(data.hctx, same_queue_rq,
>>> );
>>> -   }
>>> +   } else if (plug->rq_count > 1)
>>> +   plug->do_sort = true;
>>
>> If plug->rq_count == 2, there's no benefit to sorting, either. The
>> nr_hw_queues == 1 case could also avoid sorting in that case. So maybe
>> this whole patch could just be replaced with:
> 
> Heh yes, good point, it should be 3 at least. But if you look at the
> later mq plug patch, we only sort for that one if we have multiple
> queues. So the logic should be something ala:
> 
> if (plug->rq_count > 2 && plug->has_multiple_queues)
> 
> since that's the only case we want to sort for.

How about something like this?


diff --git a/block/blk-core.c b/block/blk-core.c
index be9233400314..d107d016b92b 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -1780,6 +1780,7 @@ void blk_start_plug(struct blk_plug *plug)
INIT_LIST_HEAD(>mq_list);
INIT_LIST_HEAD(>cb_list);
plug->rq_count = 0;
+   plug->multiple_queues = false;
 
/*
 * Store ordering should not be needed here, since a potential
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 7b7dff85cf6c..02daa32c5d77 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -1677,7 +1677,8 @@ void blk_mq_flush_plug_list(struct blk_plug *plug, bool 
from_schedule)
list_splice_init(>mq_list, );
plug->rq_count = 0;
 
-   list_sort(NULL, , plug_rq_cmp);
+   if (plug->rq_count > 2 && plug->multiple_queues)
+   list_sort(NULL, , plug_rq_cmp);
 
this_q = NULL;
this_hctx = NULL;
@@ -1866,6 +1867,20 @@ void blk_mq_try_issue_list_directly(struct blk_mq_hw_ctx 
*hctx,
}
 }
 
+static void blk_add_rq_to_plug(struct blk_plug *plug, struct request *rq)
+{
+   list_add_tail(>queuelist, >mq_list);
+   plug->rq_count++;
+   if (!plug->multiple_queues && !list_is_singular(>mq_list)) {
+   struct request *tmp;
+
+   tmp = list_first_entry(>mq_list, struct request,
+   queuelist);
+   if (tmp->q != rq->q)
+   plug->multiple_queues = true;
+   }
+}
+
 static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio)
 {
const int is_sync = op_is_sync(bio->bi_opf);
@@ -1932,8 +1947,7 @@ static blk_qc_t blk_mq_make_request(struct request_queue 
*q, struct bio *bio)
trace_block_plug(q);
}
 
-   list_add_tail(>queuelist, >mq_list);
-   plug->rq_count++;
+   blk_add_rq_to_plug(plug, rq);
} else if (plug && !blk_queue_nomerges(q)) {
blk_mq_bio_to_request(rq, bio);
 
@@ -1948,8 +1962,7 @@ static blk_qc_t blk_mq_make_request(struct request_queue 
*q, struct bio *bio)
same_queue_rq = NULL;
if (same_queue_rq)
list_del_init(_queue_rq->queuelist);
-   

Re: [PATCH 2/8] block: improve logic around when to sort a plug list

2018-11-27 Thread Omar Sandoval
On Tue, Nov 27, 2018 at 04:49:27PM -0700, Jens Axboe wrote:
> On 11/27/18 4:31 PM, Omar Sandoval wrote:
> > On Mon, Nov 26, 2018 at 09:35:50AM -0700, Jens Axboe wrote:
> >> Do it for the nr_hw_queues == 1 case, but only do it for the multi queue
> >> case if we have requests for multiple devices in the plug.
> >>
> >> Signed-off-by: Jens Axboe 
> >> ---
> >>  block/blk-core.c   | 1 +
> >>  block/blk-mq.c | 7 +--
> >>  include/linux/blkdev.h | 1 +
> >>  3 files changed, 7 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/block/blk-core.c b/block/blk-core.c
> >> index be9233400314..c9758d185357 100644
> >> --- a/block/blk-core.c
> >> +++ b/block/blk-core.c
> >> @@ -1780,6 +1780,7 @@ void blk_start_plug(struct blk_plug *plug)
> >>INIT_LIST_HEAD(>mq_list);
> >>INIT_LIST_HEAD(>cb_list);
> >>plug->rq_count = 0;
> >> +  plug->do_sort = false;
> >>  
> >>/*
> >> * Store ordering should not be needed here, since a potential
> >> diff --git a/block/blk-mq.c b/block/blk-mq.c
> >> index 99c66823d52f..6a249bf6ed00 100644
> >> --- a/block/blk-mq.c
> >> +++ b/block/blk-mq.c
> >> @@ -1678,7 +1678,8 @@ void blk_mq_flush_plug_list(struct blk_plug *plug, 
> >> bool from_schedule)
> >>list_splice_init(>mq_list, );
> >>plug->rq_count = 0;
> >>  
> >> -  list_sort(NULL, , plug_rq_cmp);
> >> +  if (plug->do_sort)
> >> +  list_sort(NULL, , plug_rq_cmp);
> >>  
> >>this_q = NULL;
> >>this_hctx = NULL;
> >> @@ -1935,6 +1936,7 @@ static blk_qc_t blk_mq_make_request(struct 
> >> request_queue *q, struct bio *bio)
> >>  
> >>list_add_tail(>queuelist, >mq_list);
> >>plug->rq_count++;
> >> +  plug->do_sort = true;
> >>} else if (plug && !blk_queue_nomerges(q)) {
> >>blk_mq_bio_to_request(rq, bio);
> >>  
> >> @@ -1958,7 +1960,8 @@ static blk_qc_t blk_mq_make_request(struct 
> >> request_queue *q, struct bio *bio)
> >>data.hctx = same_queue_rq->mq_hctx;
> >>blk_mq_try_issue_directly(data.hctx, same_queue_rq,
> >>);
> >> -  }
> >> +  } else if (plug->rq_count > 1)
> >> +  plug->do_sort = true;
> > 
> > If plug->rq_count == 2, there's no benefit to sorting, either. The
> > nr_hw_queues == 1 case could also avoid sorting in that case. So maybe
> > this whole patch could just be replaced with:
> 
> Heh yes, good point, it should be 3 at least. But if you look at the
> later mq plug patch, we only sort for that one if we have multiple
> queues. So the logic should be something ala:
> 
> if (plug->rq_count > 2 && plug->has_multiple_queues)
> 
> since that's the only case we want to sort for.

Yeah, just got to that one. If you're going to respin this, I'll wait
for you to change that around before really looking at it.


Re: [PATCH 2/8] block: improve logic around when to sort a plug list

2018-11-27 Thread Jens Axboe
On 11/27/18 4:31 PM, Omar Sandoval wrote:
> On Mon, Nov 26, 2018 at 09:35:50AM -0700, Jens Axboe wrote:
>> Do it for the nr_hw_queues == 1 case, but only do it for the multi queue
>> case if we have requests for multiple devices in the plug.
>>
>> Signed-off-by: Jens Axboe 
>> ---
>>  block/blk-core.c   | 1 +
>>  block/blk-mq.c | 7 +--
>>  include/linux/blkdev.h | 1 +
>>  3 files changed, 7 insertions(+), 2 deletions(-)
>>
>> diff --git a/block/blk-core.c b/block/blk-core.c
>> index be9233400314..c9758d185357 100644
>> --- a/block/blk-core.c
>> +++ b/block/blk-core.c
>> @@ -1780,6 +1780,7 @@ void blk_start_plug(struct blk_plug *plug)
>>  INIT_LIST_HEAD(>mq_list);
>>  INIT_LIST_HEAD(>cb_list);
>>  plug->rq_count = 0;
>> +plug->do_sort = false;
>>  
>>  /*
>>   * Store ordering should not be needed here, since a potential
>> diff --git a/block/blk-mq.c b/block/blk-mq.c
>> index 99c66823d52f..6a249bf6ed00 100644
>> --- a/block/blk-mq.c
>> +++ b/block/blk-mq.c
>> @@ -1678,7 +1678,8 @@ void blk_mq_flush_plug_list(struct blk_plug *plug, 
>> bool from_schedule)
>>  list_splice_init(>mq_list, );
>>  plug->rq_count = 0;
>>  
>> -list_sort(NULL, , plug_rq_cmp);
>> +if (plug->do_sort)
>> +list_sort(NULL, , plug_rq_cmp);
>>  
>>  this_q = NULL;
>>  this_hctx = NULL;
>> @@ -1935,6 +1936,7 @@ static blk_qc_t blk_mq_make_request(struct 
>> request_queue *q, struct bio *bio)
>>  
>>  list_add_tail(>queuelist, >mq_list);
>>  plug->rq_count++;
>> +plug->do_sort = true;
>>  } else if (plug && !blk_queue_nomerges(q)) {
>>  blk_mq_bio_to_request(rq, bio);
>>  
>> @@ -1958,7 +1960,8 @@ static blk_qc_t blk_mq_make_request(struct 
>> request_queue *q, struct bio *bio)
>>  data.hctx = same_queue_rq->mq_hctx;
>>  blk_mq_try_issue_directly(data.hctx, same_queue_rq,
>>  );
>> -}
>> +} else if (plug->rq_count > 1)
>> +plug->do_sort = true;
> 
> If plug->rq_count == 2, there's no benefit to sorting, either. The
> nr_hw_queues == 1 case could also avoid sorting in that case. So maybe
> this whole patch could just be replaced with:

Heh yes, good point, it should be 3 at least. But if you look at the
later mq plug patch, we only sort for that one if we have multiple
queues. So the logic should be something ala:

if (plug->rq_count > 2 && plug->has_multiple_queues)

since that's the only case we want to sort for.

-- 
Jens Axboe



Re: [PATCH 2/8] block: improve logic around when to sort a plug list

2018-11-27 Thread Omar Sandoval
On Mon, Nov 26, 2018 at 09:35:50AM -0700, Jens Axboe wrote:
> Do it for the nr_hw_queues == 1 case, but only do it for the multi queue
> case if we have requests for multiple devices in the plug.
> 
> Signed-off-by: Jens Axboe 
> ---
>  block/blk-core.c   | 1 +
>  block/blk-mq.c | 7 +--
>  include/linux/blkdev.h | 1 +
>  3 files changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/block/blk-core.c b/block/blk-core.c
> index be9233400314..c9758d185357 100644
> --- a/block/blk-core.c
> +++ b/block/blk-core.c
> @@ -1780,6 +1780,7 @@ void blk_start_plug(struct blk_plug *plug)
>   INIT_LIST_HEAD(>mq_list);
>   INIT_LIST_HEAD(>cb_list);
>   plug->rq_count = 0;
> + plug->do_sort = false;
>  
>   /*
>* Store ordering should not be needed here, since a potential
> diff --git a/block/blk-mq.c b/block/blk-mq.c
> index 99c66823d52f..6a249bf6ed00 100644
> --- a/block/blk-mq.c
> +++ b/block/blk-mq.c
> @@ -1678,7 +1678,8 @@ void blk_mq_flush_plug_list(struct blk_plug *plug, bool 
> from_schedule)
>   list_splice_init(>mq_list, );
>   plug->rq_count = 0;
>  
> - list_sort(NULL, , plug_rq_cmp);
> + if (plug->do_sort)
> + list_sort(NULL, , plug_rq_cmp);
>  
>   this_q = NULL;
>   this_hctx = NULL;
> @@ -1935,6 +1936,7 @@ static blk_qc_t blk_mq_make_request(struct 
> request_queue *q, struct bio *bio)
>  
>   list_add_tail(>queuelist, >mq_list);
>   plug->rq_count++;
> + plug->do_sort = true;
>   } else if (plug && !blk_queue_nomerges(q)) {
>   blk_mq_bio_to_request(rq, bio);
>  
> @@ -1958,7 +1960,8 @@ static blk_qc_t blk_mq_make_request(struct 
> request_queue *q, struct bio *bio)
>   data.hctx = same_queue_rq->mq_hctx;
>   blk_mq_try_issue_directly(data.hctx, same_queue_rq,
>   );
> - }
> + } else if (plug->rq_count > 1)
> + plug->do_sort = true;

If plug->rq_count == 2, there's no benefit to sorting, either. The
nr_hw_queues == 1 case could also avoid sorting in that case. So maybe
this whole patch could just be replaced with:

diff --git a/block/blk-mq.c b/block/blk-mq.c
index 7b7dff85cf6c..de93c14e4700 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -1675,9 +1675,10 @@ void blk_mq_flush_plug_list(struct blk_plug *plug, bool 
from_schedule)
unsigned int depth;
 
list_splice_init(>mq_list, );
-   plug->rq_count = 0;
 
-   list_sort(NULL, , plug_rq_cmp);
+   if (plug->rq_count > 2)
+   list_sort(NULL, , plug_rq_cmp);
+   plug->rq_count = 0;
 
this_q = NULL;
this_hctx = NULL;

That will also handle the multi-queue case since we only plug one
request per multi-queue device. Thoughts?


[PATCH 2/8] block: improve logic around when to sort a plug list

2018-11-26 Thread Jens Axboe
Do it for the nr_hw_queues == 1 case, but only do it for the multi queue
case if we have requests for multiple devices in the plug.

Signed-off-by: Jens Axboe 
---
 block/blk-core.c   | 1 +
 block/blk-mq.c | 7 +--
 include/linux/blkdev.h | 1 +
 3 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/block/blk-core.c b/block/blk-core.c
index be9233400314..c9758d185357 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -1780,6 +1780,7 @@ void blk_start_plug(struct blk_plug *plug)
INIT_LIST_HEAD(>mq_list);
INIT_LIST_HEAD(>cb_list);
plug->rq_count = 0;
+   plug->do_sort = false;
 
/*
 * Store ordering should not be needed here, since a potential
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 99c66823d52f..6a249bf6ed00 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -1678,7 +1678,8 @@ void blk_mq_flush_plug_list(struct blk_plug *plug, bool 
from_schedule)
list_splice_init(>mq_list, );
plug->rq_count = 0;
 
-   list_sort(NULL, , plug_rq_cmp);
+   if (plug->do_sort)
+   list_sort(NULL, , plug_rq_cmp);
 
this_q = NULL;
this_hctx = NULL;
@@ -1935,6 +1936,7 @@ static blk_qc_t blk_mq_make_request(struct request_queue 
*q, struct bio *bio)
 
list_add_tail(>queuelist, >mq_list);
plug->rq_count++;
+   plug->do_sort = true;
} else if (plug && !blk_queue_nomerges(q)) {
blk_mq_bio_to_request(rq, bio);
 
@@ -1958,7 +1960,8 @@ static blk_qc_t blk_mq_make_request(struct request_queue 
*q, struct bio *bio)
data.hctx = same_queue_rq->mq_hctx;
blk_mq_try_issue_directly(data.hctx, same_queue_rq,
);
-   }
+   } else if (plug->rq_count > 1)
+   plug->do_sort = true;
} else if ((q->nr_hw_queues > 1 && is_sync) || (!q->elevator &&
!data.hctx->dispatch_busy)) {
blk_mq_put_ctx(data.ctx);
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 02732cae6080..b6d0b33feee7 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -1131,6 +1131,7 @@ struct blk_plug {
struct list_head mq_list; /* blk-mq requests */
struct list_head cb_list; /* md requires an unplug callback */
unsigned short rq_count;
+   bool do_sort;
 };
 #define BLK_MAX_REQUEST_COUNT 16
 #define BLK_PLUG_FLUSH_SIZE (128 * 1024)
-- 
2.17.1