[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20071017194944.GB15552@kernel.dk>
Date: Wed, 17 Oct 2007 21:49:44 +0200
From: Jens Axboe <jens.axboe@...cle.com>
To: Linus Torvalds <torvalds@...ux-foundation.org>
Cc: Ingo Molnar <mingo@...e.hu>, linux-kernel@...r.kernel.org,
Jeff Garzik <jgarzik@...ox.com>,
Alan Cox <alan@...rguk.ukuu.org.uk>
Subject: Re: [bug] ata subsystem related crash with latest -git
On Wed, Oct 17 2007, Jens Axboe wrote:
> On Wed, Oct 17 2007, Linus Torvalds wrote:
> >
> >
> > On Wed, 17 Oct 2007, Ingo Molnar wrote:
> > >
> > > nope, this did not help. First bootup went fine, second bootup crashed
> > > again (see below), without hitting the BUG_ON().
> >
> > I think you'll always hit it if you have a scatter-gather list that is
> > exactly filled up.
> >
> > Why? Because those things do "sg_next()" on the last entry, and as
> > mentioned, that ends up actually accessing one past the end - even if the
> > end result is not actually ever *used* (because we just effectively
> > incremented it to past the last entry when the code was done with the SG
> > list).
Well, hang on - where does it end up doing sg_next() on the LAST sg
entry? I'd argue that this is a bug, like it was in ll_rw_blk.c. I still
agree that I should make the interface more robust, I just don't see
where libata ends up doing the sg_next() on the last entry.
I'm assuming that Ingo is using the previous patches, so that
blk_rq_map_sg() is using this construct:
new_segment:
if (!sg)
sg = sglist;
else
sg = sg_next(sg);
and the memset() in scsi_alloc_sgtable(), which I'm pretty sure he is.
I'm assuming we're not hitting pio paths, so there are no manual
sg_next() calls. Ingo, if you care, can you test this one as well?
No rush, as mentioned I'll be back tomorrow morning...
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index bbaa545..0246b61 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -4664,7 +4664,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct scatterlist *sg = qc->__sg;
- struct scatterlist *lsg = sg_last(qc->__sg, qc->n_elem);
+ struct scatterlist *lsg = &qc->__sg[qc->n_elem - 1];
int n_elem, pre_n_elem, dir, trim_sg = 0;
VPRINTK("ENTER, ata%u\n", ap->print_id);
--
Jens Axboe
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists