From: Linus Torvalds <torvalds@linux-foundation.org>
To: Anders Eriksson <aeriksson@fastmail.fm>
Cc: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>,
"Rafael J. Wysocki" <rjw@sisk.pl>,
Jens Axboe <jens.axboe@oracle.com>, Ingo Molnar <mingo@elte.hu>,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: Re: Linux 2.6.25-rc4
Date: Tue, 18 Mar 2008 08:41:25 -0700 (PDT) [thread overview]
Message-ID: <alpine.LFD.1.00.0803180751200.3020@woody.linux-foundation.org> (raw)
In-Reply-To: <20080318133259.E71EE2DC044@tippex.mynet.homeunix.org>
On Tue, 18 Mar 2008, Anders Eriksson wrote:
>
> Mar 18 14:18:26 tippex do_rw_taskfile(task->data_phase=1, tf->command=236
> Mar 18 14:18:26 tippex do_rw_taskfile(task->data_phase=0, tf->command=176
> Mar 18 14:18:26 tippex do_rw_taskfile(task->data_phase=1, tf->command=176
> Mar 18 14:18:26 tippex task_in_intr: hda: stat=50
Uhhuh. That's READY_STAT | SRV_STAT. No error, no DRQ, no nothing.
And I think this also explains why your bisect found that old commit
4d977e43d8ae758434e603cf2455d955f71c77c4 to be problematic.
The thing is, that commit - and the taskfile code that it then all got
replaced with - use this totally bogus check:
OK_STAT(stat, DRQ_STAT, BAD_R_STAT)
...
which basically says that the only OK situation is that no error bits are
set, and DRQ _has_ to be set.
Before that, the code did the right thing in any _combination_ of bits: if
DRQ wasn't set, it would just say "oh, ok, the command is done", but the
taskfile code and the 4d977e43d commit code thinks that DRQ not being set
is an error, and then it gets confused when the actual error bits aren't
set!
I think that whole way of writing code is totally horribly bad! It's not
only trying to tie together bits that are independent, but it actually
gets a lot harder to understand too, because now you have *four* different
cases ("no error, no drq", "error, no drq", "no error, drq", "error, drq")
but you use one test to try to find the one you expect, and then the code
easily messes up on all the other three cases!
I personally think the code should be written more like the suggested
appended patch, which checks those error and drq bits _separately_, and
doesn't try to mix them up, because they really are independent.
Anders, does this patch change any behaviour?
It basically does:
- if the error bits are set, we just error out (and expect ide_error() to
flush the data fifo if necessary)
- if the DRQ bit is *not* set, something unexpected happened, and we go
out of line to handle that.
- otherwise we just do the data in phase and see if we're all done.
Then, in the unexpected case, we try to see what is actually going on, and
that's where we do the same thing we always used to do (ie the thing that
commit 4d977e43d messed up): if the drive tells us it's all done, we just
end the command.
IOW, if we have no errors, no drq, and the drive says "ready and not
busy", we just finish the command!
I think this is much more readable, and also less fragile, than using that
OK_STAT() macro to mix up DRQ and errors in odd ways. Keep them separate
events.
Linus
---
drivers/ide/ide-taskfile.c | 36 +++++++++++++++++++++++++++---------
1 files changed, 27 insertions(+), 9 deletions(-)
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 0518a2e..4c86a8d 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -423,6 +423,25 @@ void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat)
}
/*
+ * We got an interrupt on a task_in case, but no errors and no DRQ.
+ *
+ * It might be a spurious irq (shared irq), but it might be a
+ * command that had no output.
+ */
+static ide_startstop_t task_in_unexpected(ide_drive_t *drive, struct request *rq, u8 stat)
+{
+ /* Command all done? */
+ if (OK_STAT(stat, READY_STAT, BUSY_STAT)) {
+ task_end_request(drive, rq, stat);
+ return ide_stopped;
+ }
+
+ /* Assume it was a spurious irq */
+ ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL);
+ return ide_started;
+}
+
+/*
* Handler for command with PIO data-in phase (Read/Read Multiple).
*/
static ide_startstop_t task_in_intr(ide_drive_t *drive)
@@ -431,18 +450,17 @@ static ide_startstop_t task_in_intr(ide_drive_t *drive)
struct request *rq = HWGROUP(drive)->rq;
u8 stat = ide_read_status(drive);
- /* new way for dealing with premature shared PCI interrupts */
- if (!OK_STAT(stat, DRQ_STAT, BAD_R_STAT)) {
- if (stat & (ERR_STAT | DRQ_STAT))
- return task_error(drive, rq, __FUNCTION__, stat);
- /* No data yet, so wait for another IRQ. */
- ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL);
- return ide_started;
- }
+ /* Error? */
+ if (stat & ERR_STAT)
+ return task_error(drive, rq, __FUNCTION__, stat);
+
+ /* No error, but didn't want any data either? Odd. */
+ if (!(stat & DRQ_STAT))
+ return task_in_unexpected(drive, rq, stat);
ide_pio_datablock(drive, rq, 0);
- /* If it was the last datablock check status and finish transfer. */
+ /* Are we done? Check status and finish transfer. */
if (!hwif->nleft) {
stat = wait_drive_not_busy(drive);
if (!OK_STAT(stat, 0, BAD_STAT))
next prev parent reply other threads:[~2008-03-19 19:36 UTC|newest]
Thread overview: 82+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-03-05 5:03 Linus Torvalds
2008-03-05 8:09 ` FUJITA Tomonori
2008-03-05 16:46 ` Grant Grundler
2008-03-06 9:00 ` Ingo Molnar
2008-03-06 12:59 ` Jens Axboe
2008-03-06 13:06 ` Ingo Molnar
2008-03-06 13:12 ` Jens Axboe
2008-03-07 8:53 ` Ingo Molnar
2008-03-07 8:57 ` Jens Axboe
2008-03-07 9:02 ` Ingo Molnar
2008-03-07 9:59 ` Paul Mackerras
2008-03-07 15:20 ` Valdis.Kletnieks
2008-03-08 23:36 ` Pavel Machek
2008-03-09 11:59 ` Ingo Molnar
2008-03-09 12:55 ` Andi Kleen
2008-03-10 10:10 ` Pavel Machek
2008-03-10 11:52 ` Andi Kleen
2008-03-06 13:38 ` Bartlomiej Zolnierkiewicz
2008-03-06 13:33 ` Ingo Molnar
2008-03-06 14:06 ` Bartlomiej Zolnierkiewicz
2008-03-06 13:55 ` Jens Axboe
2008-03-06 21:17 ` Anders Eriksson
2008-03-07 8:48 ` Jens Axboe
2008-03-07 22:04 ` Anders Eriksson
2008-03-08 20:22 ` Linus Torvalds
2008-03-08 21:05 ` Anders Eriksson
2008-03-10 8:55 ` Anders Eriksson
2008-03-10 12:36 ` Bartlomiej Zolnierkiewicz
2008-03-10 13:10 ` Rafael J. Wysocki
2008-03-10 14:04 ` Bartlomiej Zolnierkiewicz
2008-03-16 14:01 ` Anders Eriksson
2008-03-16 14:29 ` Bartlomiej Zolnierkiewicz
2008-03-16 14:29 ` Anders Eriksson
2008-03-16 15:14 ` Bartlomiej Zolnierkiewicz
2008-03-16 16:56 ` Linus Torvalds
2008-03-16 17:13 ` Linus Torvalds
2008-03-16 18:18 ` Anders Eriksson
2008-03-16 18:07 ` Bartlomiej Zolnierkiewicz
2008-03-16 18:13 ` Linus Torvalds
2008-03-16 18:36 ` Bartlomiej Zolnierkiewicz
2008-03-16 19:08 ` Anders Eriksson
2008-03-16 18:56 ` Alan Cox
2008-03-16 19:39 ` Linus Torvalds
2008-03-16 20:31 ` Alan Cox
2008-03-16 21:06 ` Linus Torvalds
2008-03-21 15:03 ` Mark Lord
2008-03-21 14:49 ` Alan Cox
2008-03-16 19:54 ` Bartlomiej Zolnierkiewicz
2008-03-16 22:59 ` Anders Eriksson
2008-03-16 23:27 ` Linus Torvalds
2008-03-17 21:09 ` Anders Eriksson
2008-03-17 22:52 ` Linus Torvalds
2008-03-18 0:18 ` Anders Eriksson
2008-03-18 13:03 ` Bartlomiej Zolnierkiewicz
2008-03-18 13:32 ` Anders Eriksson
2008-03-18 14:48 ` Bartlomiej Zolnierkiewicz
2008-03-18 15:10 ` Anders Eriksson
2008-03-18 15:41 ` Linus Torvalds [this message]
2008-03-18 16:30 ` Anders Eriksson
2008-03-18 16:47 ` Linus Torvalds
2008-03-18 21:02 ` Anders Eriksson
2008-03-19 1:21 ` Bartlomiej Zolnierkiewicz
2008-03-19 1:28 ` Linus Torvalds
2008-03-19 3:24 ` Bartlomiej Zolnierkiewicz
2008-03-19 3:28 ` Linus Torvalds
2008-03-19 3:56 ` Linus Torvalds
2008-03-19 4:03 ` Bartlomiej Zolnierkiewicz
2008-03-19 4:48 ` Linus Torvalds
2008-03-19 11:14 ` Bartlomiej Zolnierkiewicz
2008-03-16 18:23 ` Anders Eriksson
2008-03-16 18:26 ` Bartlomiej Zolnierkiewicz
2008-03-16 18:25 ` Anders Eriksson
2008-03-17 7:23 ` Jens Axboe
2008-03-16 18:44 ` Alan Cox
2008-03-10 13:19 ` Anders Eriksson
2008-03-10 13:56 ` Bartlomiej Zolnierkiewicz
2008-03-16 18:59 ` Andrey Borzenkov
2008-03-07 10:08 ` [patch] drivers/char/esp.c: fix bootup lockup (was: Re: Linux 2.6.25-rc4) Ingo Molnar
2008-03-09 13:41 ` [patch] drivers/char/esp.c: fix bootup lockup Jiri Slaby
2008-03-09 22:49 ` Rafael J. Wysocki
2008-03-09 23:04 ` Jiri Slaby
2008-03-05 22:30 Linux 2.6.25-rc4 Jonathan McDowell
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=alpine.LFD.1.00.0803180751200.3020@woody.linux-foundation.org \
--to=torvalds@linux-foundation.org \
--cc=aeriksson@fastmail.fm \
--cc=bzolnier@gmail.com \
--cc=jens.axboe@oracle.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=rjw@sisk.pl \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®