NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kern/40569: Faild RAIDframe parity rewrite prevents system shutdown



The following reply was made to PR kern/40569; it has been noted by GNATS.

From: Manuel Bouyer <bouyer%antioche.eu.org@localhost>
To: Matthias Scheler <tron%zhadum.org.uk@localhost>
Cc: gnats-bugs%NetBSD.org@localhost
Subject: Re: kern/40569: Faild RAIDframe parity rewrite prevents system shutdown
Date: Tue, 10 Feb 2009 23:24:40 +0100

 --ZPt4rx8FFjLCG7dd
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 
 On Tue, Feb 10, 2009 at 10:17:06PM +0000, Matthias Scheler wrote:
 > On Tue, Feb 10, 2009 at 11:12:38PM +0100, Manuel Bouyer wrote:
 > > I've reproduced it on a system here and I think I've a fix.
 > 
 > That's great news.
 > 
 > > Just to confirm; you're using a AHCI controller, right ?
 > 
 > Yes, I do:
 > 
 > atabus4 at ahcisata0 channel 2
 > atabus5 at ahcisata0 channel 3
 > [...]
 > ahcisata0 port 2: device present, speed: 1.5Gb/s
 > ahcisata0 port 3: device present, speed: 3.0Gb/s
 
 OK, so it's probably an issue with the ahci controller: b_resid was set to
 0 even in case of failure; and it's used in the LBA48 workaround detection
 to see if we crossed the boundary ... I think the attached patch fixes it but
 unfortunably my test box didn't reboot after panic to I can't test before
 tomorow.
 
 -- 
 Manuel Bouyer <bouyer%antioche.eu.org@localhost>
      NetBSD: 26 ans d'experience feront toujours la difference
 --
 
 --ZPt4rx8FFjLCG7dd
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: attachment; filename=diff
 
 Index: ahcisata_core.c
 ===================================================================
 RCS file: /cvsroot/src/sys/dev/ic/ahcisata_core.c,v
 retrieving revision 1.18
 diff -u -p -u -r1.18 ahcisata_core.c
 --- ahcisata_core.c    3 Oct 2008 13:02:08 -0000       1.18
 +++ ahcisata_core.c    10 Feb 2009 22:22:42 -0000
 @@ -1065,7 +1065,7 @@ ahci_bio_complete(struct ata_channel *ch
                ata_bio->error = TIMEOUT;
        } else {
                callout_stop(&chp->ch_callout);
 -              ata_bio->error = 0;
 +              ata_bio->error = NOERROR;
        }
  
        chp->ch_queue->active_xfer = NULL;
 @@ -1095,7 +1095,14 @@ ahci_bio_complete(struct ata_channel *ch
            BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
        AHCIDEBUG_PRINT(("ahci_bio_complete bcount %ld",
            ata_bio->bcount), DEBUG_XFERS);
 -      ata_bio->bcount -= le32toh(achp->ahcic_cmdh[slot].cmdh_prdbc);
 +      /* 
 +       * if it was a write, complete data buffer may have been transfered
 +       * before error detection; in this case don't use cmdh_prdbc
 +       * as it won't reflect what was written to media. Assume nothing
 +       * was transfered and leave bcount as-is.
 +       */
 +      if ((ata_bio->flags & ATA_READ) || ata_bio->error != NOERROR)
 +              ata_bio->bcount -= le32toh(achp->ahcic_cmdh[slot].cmdh_prdbc);
        AHCIDEBUG_PRINT((" now %ld\n", ata_bio->bcount), DEBUG_XFERS);
        (*chp->ch_drive[drive].drv_done)(chp->ch_drive[drive].drv_softc);
        atastart(chp);
 
 --ZPt4rx8FFjLCG7dd--
 


Home | Main Index | Thread Index | Old Index