From: Elias Oltmanns <eo@nebensachen.de>
To: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Cc: linux-kernel@vger.kernel.org, linux-ide@vger.kernel.org
Subject: Re: [PATCH] ide: don't execute the next queued command from the hard-IRQ context
Date: Wed, 22 Oct 2008 17:01:20 +0200 [thread overview]
Message-ID: <87od1cu11b.fsf@denkblock.local> (raw)
In-Reply-To: 200810152106.45728.bzolnier@gmail.com
Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> wrote:
> On Sunday 12 October 2008, Elias Oltmanns wrote:
>> Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> wrote:
>
>> > From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
>> > Subject: [PATCH] ide: don't execute the next queued command from the hard-IRQ context
>> >
>> > * Tell the block layer that we are not done handling requests by using
>> > blk_plug_device() in ide_do_request() (request handling function)
>> > and ide_timer_expiry() (timeout handler) if the queue is not empty.
>> >
>> > * Remove optimization which directly calls ide_do_request() for the next
>> > queued command from the ide_intr() (IRQ handler) and ide_timer_expiry().
>> >
>> > * Remove no longer needed IRQ masking from ide_do_request() - in case of
>> > IDE ports needing serialization disable_irq_nosync()/enable_irq() was
>> > used for the (possibly shared) IRQ of the other IDE port.
>> >
>> > * Put the misplaced comment in the right place in ide_do_request().
>> >
>> > * Drop no longer needed 'int masked_irq' argument from ide_do_request().
>> >
>> > * Merge ide_do_request() into do_ide_request().
>> >
>> > * Remove no longer needed IDE_NO_IRQ define.
>> >
>> > While at it:
>> >
>> > * Don't use HWGROUP() macro in do_ide_request().
>> >
>> > * Use __func__ in ide_intr().
>> >
>> > This patch reduces IRQ hadling latency for IDE and improves the system-wide
>> > handling of shared IRQs (which should result in more timeout resistant and
>> > stable IDE systems). It also makes it possible to do some further changes
>> > later (i.e. replace some busy-waiting delays with sleeping equivalents).
>> >
>> > Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
>> > ---
[...]
>> > Index: b/drivers/ide/ide-io.c
>> > ===================================================================
>> > --- a/drivers/ide/ide-io.c
>> > +++ b/drivers/ide/ide-io.c
[...]
>> > startstop = start_request(drive, rq);
>> > spin_lock_irq(&hwgroup->lock);
>> > - if (masked_irq != IDE_NO_IRQ && hwif->irq != masked_irq)
>> > - enable_irq(hwif->irq);
>> > - if (startstop == ide_stopped)
>> > +
>> > + if (startstop == ide_stopped) {
>> > hwgroup->busy = 0;
>> > + goto plug_device;
>>
>> This goto statement is wrong. Simply set ->busy to zero and be done with
>> it. This way, the loop will start again and either elv_next_request()
>> returns NULL, in which case the queue need not be plugged, or the next
>> request will be processed immediately, which is exactly what we want.
>
> The problem is that the next loop can choose the different drive than
> the current one so we can end up with the situation where we will "lose"
> the blk_plug_device() call.
>
> I fixed it by just inlining "plug_device" code for now.
Right, I had missed that. Still, I'm not really convinced yet that this
is the right way to handle things. In fact, I believe that the role of
choose_drive() has changed since it is now called directly from the
->request_fn() and it should probably be rewritten and renamed along the
way. However, this needs further discussion and the issue below has some
bearing on this too.
>
>> [...]
>> > @@ -1438,11 +1431,11 @@ irqreturn_t ide_intr (int irq, void *dev
>> > if (startstop == ide_stopped) {
>> > if (hwgroup->handler == NULL) { /* paranoia */
>> > hwgroup->busy = 0;
>> > - ide_do_request(hwgroup, hwif->irq);
>> > - } else {
>> > - printk(KERN_ERR "%s: ide_intr: huh? expected NULL handler "
>> > - "on exit\n", drive->name);
>> > - }
>> > + if (!elv_queue_empty(drive->queue))
>> > + blk_plug_device(drive->queue);
>>
>> This is perhaps not exactly what you really want. It basically means
>> that there will be a delay (q->unplug_delay) after each command which
>> may well hurt I/O performance. Instead, I'd suggest something like the
>> following:
>>
>> if (!elv_queue_empty(drive->queue))
>> blk_schedule_queue_run(drive->queue);
>>
>> and a function
>>
>> void blk_schedule_queue_run(struct request_queue *q)
>> {
>> blk_plug_device(q);
>> kblockd_schedule_work(&q->unplug_work);
>> }
>>
>> in blk-core.c. This can also be used as a helper function in blk-core.c
>> itself.
>
> Care to make a patch adding such helper to blk-core.c?
Thinking about this a bit more, I'd like to raise this issue with Jens
and discuss it in some more generality.
Regards,
Elias
next prev parent reply other threads:[~2008-10-22 15:01 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-10-11 14:17 [PATCH] ide: don't execute the next queued command from the hard-IRQ context Bartlomiej Zolnierkiewicz
2008-10-12 18:02 ` Elias Oltmanns
2008-10-15 19:06 ` Bartlomiej Zolnierkiewicz
2008-10-22 15:01 ` Elias Oltmanns [this message]
2008-10-22 20:47 ` Bartlomiej Zolnierkiewicz
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=87od1cu11b.fsf@denkblock.local \
--to=eo@nebensachen.de \
--cc=bzolnier@gmail.com \
--cc=linux-ide@vger.kernel.org \
--cc=linux-kernel@vger.kernel.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.