All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paolo Valente <paolo.valente@linaro.org>
To: Jens Axboe <axboe@kernel.dk>
Cc: Tejun Heo <tj@kernel.org>, Fabio Checconi <fchecconi@gmail.com>,
	Arianna Avanzini <avanzini.arianna@gmail.com>,
	linux-block@vger.kernel.org,
	Linux-Kernal <linux-kernel@vger.kernel.org>,
	Ulf Hansson <ulf.hansson@linaro.org>,
	Linus Walleij <linus.walleij@linaro.org>,
	broonie@kernel.org,
	Mauro Andreolini <mauro.andreolini@unimore.it>
Subject: Re: [PATCH RFC 10/14] block, bfq: add Early Queue Merge (EQM)
Date: Sat, 18 Mar 2017 10:33:59 +0000	[thread overview]
Message-ID: <A134A93F-A329-465A-B8E4-AF6D29739EAE@linaro.org> (raw)
In-Reply-To: <d41a304a-b863-5ea7-29ec-8c5a2ea5bbef@kernel.dk>


> Il giorno 15 mar 2017, alle ore 21:00, Jens Axboe <axboe@kernel.dk> ha =
scritto:
>=20
> On 03/15/2017 10:59 AM, Paolo Valente wrote:
>>=20
>>> Il giorno 15 mar 2017, alle ore 17:30, Jens Axboe <axboe@kernel.dk> =
ha scritto:
>>>=20
>>> On 03/15/2017 09:47 AM, Jens Axboe wrote:
>>>> I think you understood me correctly. Currently I think the putting =
of
>>>> the io context is somewhat of a mess. You have seemingly random =
places
>>>> where you have to use special unlock functions, to ensure that you
>>>> notice that some caller deeper down has set ->ioc_to_put. I took a =
quick
>>>> look at it, and by far most of the cases can return an io_context =
to
>>>> free quite easily. You can mark these functions __must_check to =
ensure
>>>> that we don't drop an io_context, inadvertently. That's already a =
win
>>>> over the random ->ioc_to_put store. And you can then get rid of
>>>> bfq_unlock_put_ioc and it's irq variant as well.
>>>>=20
>>>> The places where you are already returning a value, like off =
dispatch
>>>> for instance, you can just pass in a pointer to an io_context =
pointer.
>>>>=20
>>>> If you get this right, it'll be a lot less fragile and hacky than =
your
>>>> current approach.
>>>=20
>>> Even just looking a little closer, you also find cases where you
>>> potentially twice store ->ioc_to_put. That kind of mixup can't =
happen if
>>> you return it properly.
>>>=20
>>> In __bfq_dispatch_request(), for instance. You call =
bfq_select_queue(),
>>> and that in turn calls bfq_bfqq_expire(), which calls
>>> __bfq_bfqq_expire() which can set ->ioc_to_put. But later on,
>>> __bfq_dispatch_request() calls bfq_dispatch_rq_from_bfqq(), which in
>>> turn calls bfq_bfqq_expire() that can also set ->ioc_to_put. There's =
no
>>> "magic" bfq_unlock_and_put_ioc() in-between those. Maybe the former =
call
>>> never sets ->ioc_to_put if it returns with bfqq =3D=3D NULL? Hard to =
tell.
>>>=20
>>> Or __bfq_insert_request(), it calls bfq_add_request(), which may set
>>> ->ioc_to_put through bfq_bfqq_handle_idle_busy_switch() ->
>>> bfq_bfqq_expire(). And then from calling bfq_rq_enqueued() ->
>>> bfq_bfqq_expire().
>>>=20
>>=20
>> I have checked that.  Basically, since a queue can't be expired =
twice,
>> then it should never happen that ioc_to_put is set twice before being
>> used.  Yet, I do agree that using a shared field and exploiting
>> collateral effects makes code very complex and fragile (maybe even
>> buggy if my speculative check is wrong).  Just, it has been the best
>> solution I found, to avoid deferred work as you asked.  In fact, I
>> still find quite heavy the alternative of passing a pointer to an ioc
>> forth and back across seven or eight nested functions.
>=20
> It's not heavy at all, I went through all of it this morning.

Yes, sorry. I meant heavy in terms of code complexity.

> It's not
> super pretty either, since you end up passing back an io_context which
> is seemingly unrelated to what the functions otherwise do.

Exactly.

> But that's
> mostly a reflection of the implementation, not that it's a bad way to =
go
> about this in general. The worst bits are the places where you want to
> add a
>=20
> 	WARN_ON(ret !=3D NULL);
>=20
> between two calls that potentially both drop the ioc. In terms of
> overhead, it's not heavy. Punting to a workqueue would be orders of
> magnitude more expensive.
>=20
>>> There might be more, but I think the above is plenty of evidence =
that
>>> the current ->ioc_to_put solution is a bad hack, fragile, and =
already
>>> has bugs.
>>>=20
>>> How often do you expect this putting of the io_context to happen?
>>=20
>> Unfortunately often, as it must be done also every time the =
in-service
>> queue is reset.  But, in this respect, are we sure that we do need to
>> grab a reference to the ioc when we set a queue in service (as done =
in
>> cfq, and copied into bfq)?  I mean, we have the hook exit_ioc for
>> controlling the disappearing of an ioc.  Am I missing something here
>> too?
>=20
> No, in fact that'd be perfectly fine. It's easier for CFQ to just =
retain
> the reference so we know it's not going away, but for your case, it
> might in fact make more sense to simply be able to de-service a queue =
if
> the process exits. And if you do that, we can drop all this passing =
back
> of ioc (or ->ioc_to_put) craziness, without having to punt to a
> workqueue either.
>=20

Done, and ... well, it seems to work :)

I'm striving to have a new patch series ready before Monday, but I'm
not confident I'll make it.

Thanks,
Paolo

> This will be more efficient too, since it'll be a much more rare
> occurence.
>=20
> --=20
> Jens Axboe

WARNING: multiple messages have this Message-ID (diff)
From: Paolo Valente <paolo.valente@linaro.org>
To: Jens Axboe <axboe@kernel.dk>
Cc: Tejun Heo <tj@kernel.org>, Fabio Checconi <fchecconi@gmail.com>,
	Arianna Avanzini <avanzini.arianna@gmail.com>,
	linux-block@vger.kernel.org,
	Linux-Kernal <linux-kernel@vger.kernel.org>,
	Ulf Hansson <ulf.hansson@linaro.org>,
	Linus Walleij <linus.walleij@linaro.org>,
	broonie@kernel.org,
	Mauro Andreolini <mauro.andreolini@unimore.it>
Subject: Re: [PATCH RFC 10/14] block, bfq: add Early Queue Merge (EQM)
Date: Sat, 18 Mar 2017 10:33:59 +0000	[thread overview]
Message-ID: <A134A93F-A329-465A-B8E4-AF6D29739EAE@linaro.org> (raw)
In-Reply-To: <d41a304a-b863-5ea7-29ec-8c5a2ea5bbef@kernel.dk>


> Il giorno 15 mar 2017, alle ore 21:00, Jens Axboe <axboe@kernel.dk> ha scritto:
> 
> On 03/15/2017 10:59 AM, Paolo Valente wrote:
>> 
>>> Il giorno 15 mar 2017, alle ore 17:30, Jens Axboe <axboe@kernel.dk> ha scritto:
>>> 
>>> On 03/15/2017 09:47 AM, Jens Axboe wrote:
>>>> I think you understood me correctly. Currently I think the putting of
>>>> the io context is somewhat of a mess. You have seemingly random places
>>>> where you have to use special unlock functions, to ensure that you
>>>> notice that some caller deeper down has set ->ioc_to_put. I took a quick
>>>> look at it, and by far most of the cases can return an io_context to
>>>> free quite easily. You can mark these functions __must_check to ensure
>>>> that we don't drop an io_context, inadvertently. That's already a win
>>>> over the random ->ioc_to_put store. And you can then get rid of
>>>> bfq_unlock_put_ioc and it's irq variant as well.
>>>> 
>>>> The places where you are already returning a value, like off dispatch
>>>> for instance, you can just pass in a pointer to an io_context pointer.
>>>> 
>>>> If you get this right, it'll be a lot less fragile and hacky than your
>>>> current approach.
>>> 
>>> Even just looking a little closer, you also find cases where you
>>> potentially twice store ->ioc_to_put. That kind of mixup can't happen if
>>> you return it properly.
>>> 
>>> In __bfq_dispatch_request(), for instance. You call bfq_select_queue(),
>>> and that in turn calls bfq_bfqq_expire(), which calls
>>> __bfq_bfqq_expire() which can set ->ioc_to_put. But later on,
>>> __bfq_dispatch_request() calls bfq_dispatch_rq_from_bfqq(), which in
>>> turn calls bfq_bfqq_expire() that can also set ->ioc_to_put. There's no
>>> "magic" bfq_unlock_and_put_ioc() in-between those. Maybe the former call
>>> never sets ->ioc_to_put if it returns with bfqq == NULL? Hard to tell.
>>> 
>>> Or __bfq_insert_request(), it calls bfq_add_request(), which may set
>>> ->ioc_to_put through bfq_bfqq_handle_idle_busy_switch() ->
>>> bfq_bfqq_expire(). And then from calling bfq_rq_enqueued() ->
>>> bfq_bfqq_expire().
>>> 
>> 
>> I have checked that.  Basically, since a queue can't be expired twice,
>> then it should never happen that ioc_to_put is set twice before being
>> used.  Yet, I do agree that using a shared field and exploiting
>> collateral effects makes code very complex and fragile (maybe even
>> buggy if my speculative check is wrong).  Just, it has been the best
>> solution I found, to avoid deferred work as you asked.  In fact, I
>> still find quite heavy the alternative of passing a pointer to an ioc
>> forth and back across seven or eight nested functions.
> 
> It's not heavy at all, I went through all of it this morning.

Yes, sorry. I meant heavy in terms of code complexity.

> It's not
> super pretty either, since you end up passing back an io_context which
> is seemingly unrelated to what the functions otherwise do.

Exactly.

> But that's
> mostly a reflection of the implementation, not that it's a bad way to go
> about this in general. The worst bits are the places where you want to
> add a
> 
> 	WARN_ON(ret != NULL);
> 
> between two calls that potentially both drop the ioc. In terms of
> overhead, it's not heavy. Punting to a workqueue would be orders of
> magnitude more expensive.
> 
>>> There might be more, but I think the above is plenty of evidence that
>>> the current ->ioc_to_put solution is a bad hack, fragile, and already
>>> has bugs.
>>> 
>>> How often do you expect this putting of the io_context to happen?
>> 
>> Unfortunately often, as it must be done also every time the in-service
>> queue is reset.  But, in this respect, are we sure that we do need to
>> grab a reference to the ioc when we set a queue in service (as done in
>> cfq, and copied into bfq)?  I mean, we have the hook exit_ioc for
>> controlling the disappearing of an ioc.  Am I missing something here
>> too?
> 
> No, in fact that'd be perfectly fine. It's easier for CFQ to just retain
> the reference so we know it's not going away, but for your case, it
> might in fact make more sense to simply be able to de-service a queue if
> the process exits. And if you do that, we can drop all this passing back
> of ioc (or ->ioc_to_put) craziness, without having to punt to a
> workqueue either.
> 

Done, and ... well, it seems to work :)

I'm striving to have a new patch series ready before Monday, but I'm
not confident I'll make it.

Thanks,
Paolo

> This will be more efficient too, since it'll be a much more rare
> occurence.
> 
> -- 
> Jens Axboe

  reply	other threads:[~2017-03-18 10:33 UTC|newest]

Thread overview: 77+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-04 16:01 [PATCH RFC 00/14] Add the BFQ I/O Scheduler to blk-mq Paolo Valente
2017-03-04 16:01 ` [PATCH RFC 01/14] block, bfq: introduce the BFQ-v0 I/O scheduler as an extra scheduler Paolo Valente
2017-03-05 15:16   ` Jens Axboe
2017-03-05 16:02     ` Paolo Valente
2017-03-05 16:02       ` Paolo Valente
2017-03-06 20:46       ` Jens Axboe
2017-03-14 11:28         ` Paolo Valente
2017-03-14 11:28           ` Paolo Valente
2017-03-06 19:40   ` Bart Van Assche
2017-03-06 19:40     ` Bart Van Assche
2017-03-14 14:18     ` Paolo Valente
2017-03-14 14:18       ` Paolo Valente
2017-03-18 12:08     ` Paolo Valente
2017-03-18 12:08       ` Paolo Valente
2017-03-18 15:24       ` Bart Van Assche
2017-03-18 15:24         ` Bart Van Assche
2017-03-19 11:45         ` Paolo Valente
2017-03-19 11:45           ` Paolo Valente
2017-03-07 23:22   ` Jens Axboe
2017-03-18 12:41     ` Paolo Valente
2017-03-18 12:41       ` Paolo Valente
2017-03-04 16:01 ` [PATCH RFC 02/14] block, bfq: add full hierarchical scheduling and cgroups support Paolo Valente
2017-03-04 16:01 ` [PATCH RFC 03/14] block, bfq: improve throughput boosting Paolo Valente
2017-03-04 16:01 ` [PATCH RFC 04/14] block, bfq: modify the peak-rate estimator Paolo Valente
2017-03-07  0:47   ` Bart Van Assche
2017-03-07  0:47     ` Bart Van Assche
2017-03-04 16:01 ` [PATCH RFC 05/14] block, bfq: add more fairness with writes and slow processes Paolo Valente
2017-03-04 16:01 ` [PATCH RFC 06/14] block, bfq: improve responsiveness Paolo Valente
2017-03-04 16:01 ` [PATCH RFC 07/14] block, bfq: reduce I/O latency for soft real-time applications Paolo Valente
2017-03-04 16:01 ` [PATCH RFC 08/14] block, bfq: preserve a low latency also with NCQ-capable drives Paolo Valente
2017-03-04 16:01 ` [PATCH RFC 09/14] block, bfq: reduce latency during request-pool saturation Paolo Valente
2017-03-04 16:01 ` [PATCH RFC 10/14] block, bfq: add Early Queue Merge (EQM) Paolo Valente
2017-03-07 17:44   ` Jens Axboe
2017-03-15 12:01     ` Paolo Valente
2017-03-15 12:01       ` Paolo Valente
2017-03-15 15:47       ` Jens Axboe
2017-03-15 16:30         ` Jens Axboe
2017-03-15 16:59           ` Paolo Valente
2017-03-15 16:59             ` Paolo Valente
2017-03-15 21:00             ` Jens Axboe
2017-03-18 10:33               ` Paolo Valente [this message]
2017-03-18 10:33                 ` Paolo Valente
2017-03-15 16:56   ` Jens Axboe
2017-03-15 17:02     ` Paolo Valente
2017-03-15 17:02       ` Paolo Valente
2017-03-15 21:01       ` Jens Axboe
2017-03-04 16:01 ` [PATCH RFC 11/14] block, bfq: reduce idling only in symmetric scenarios Paolo Valente
2017-03-04 16:01 ` [PATCH RFC 12/14] block, bfq: boost the throughput on NCQ-capable flash-based devices Paolo Valente
2017-03-04 16:01 ` [PATCH RFC 13/14] block, bfq: boost the throughput with random I/O on NCQ-capable HDDs Paolo Valente
2017-03-07  0:54   ` Bart Van Assche
2017-03-07  0:54     ` Bart Van Assche
2017-03-14 14:12     ` Paolo Valente
2017-03-14 14:12       ` Paolo Valente
2017-03-04 16:01 ` [PATCH RFC 14/14] block, bfq: handle bursts of queue activations Paolo Valente
2017-03-06  7:43 ` [PATCH RFC 00/14] Add the BFQ I/O Scheduler to blk-mq Markus Trippelsdorf
2017-03-31 13:27   ` Paolo Valente
2017-03-31 13:27     ` Paolo Valente
2017-03-07  0:22 ` Bart Van Assche
2017-03-07  0:22   ` Bart Van Assche
2017-03-14 14:12   ` Paolo Valente
2017-03-14 14:12     ` Paolo Valente
2017-03-07  1:00 ` Bart Van Assche
2017-03-07  1:00   ` Bart Van Assche
2017-03-14 15:35   ` Paolo Valente
2017-03-14 15:35     ` Paolo Valente
2017-03-14 15:42     ` Jens Axboe
2017-03-14 16:32     ` Bart Van Assche
2017-03-14 16:32       ` Bart Van Assche
2017-03-18 10:52       ` Paolo Valente
2017-03-18 10:52         ` Paolo Valente
2017-03-18 17:09         ` Linus Walleij
2017-03-18 17:46           ` Bart Van Assche
2017-03-18 17:46             ` Bart Van Assche
2017-03-18 20:46             ` Linus Walleij
2017-03-19 12:14             ` Paolo Valente
2017-03-19 12:14               ` Paolo Valente
2017-03-20 18:40             ` Jens Axboe

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=A134A93F-A329-465A-B8E4-AF6D29739EAE@linaro.org \
    --to=paolo.valente@linaro.org \
    --cc=avanzini.arianna@gmail.com \
    --cc=axboe@kernel.dk \
    --cc=broonie@kernel.org \
    --cc=fchecconi@gmail.com \
    --cc=linus.walleij@linaro.org \
    --cc=linux-block@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mauro.andreolini@unimore.it \
    --cc=tj@kernel.org \
    --cc=ulf.hansson@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.