On 07/05/15(Thu) 20:58, Mike Belopuhov wrote: > As I've pointed out before, on panic we can be running on any > CPU and our disk controller's interrupts can interrupt on the > other one. Since we'll most likely be holding a kernel lock, > dealing with unlocking it might get hairy very fast. Instead > what we could do to improve the chances of a clean shutdown on > panic is to instruct our disk subsystem to do polled I/O that > will be run on the same CPU with the panic.
Did you consider executing ddb's boot commands on cpu0? I mean doing an implicit "machine ddbcpu 0" before executing any "boot" command? > Initially I wanted to move "cold = 1" earlier in boot(), but > after talking to Miod, it started to look like a bad idea. > > Thoughts? > > diff --git sys/dev/ata/ata_wdc.c sys/dev/ata/ata_wdc.c > index 1f52488..aea9ec1 100644 > --- sys/dev/ata/ata_wdc.c > +++ sys/dev/ata/ata_wdc.c > @@ -199,20 +199,22 @@ wd_hibernate_io(dev_t dev, daddr_t blkno, vaddr_t addr, > size_t size, int op, voi > */ > int > wdc_ata_bio(struct ata_drive_datas *drvp, struct ata_bio *ata_bio) > { > struct wdc_xfer *xfer; > struct channel_softc *chp = drvp->chnl_softc; > > xfer = wdc_get_xfer(WDC_NOSLEEP); > if (xfer == NULL) > return WDC_TRY_AGAIN; > + if (panicstr) > + ata_bio->flags |= ATA_POLL; > if (ata_bio->flags & ATA_POLL) > xfer->c_flags |= C_POLL; > if (!(ata_bio->flags & ATA_POLL) && > (drvp->drive_flags & (DRIVE_DMA | DRIVE_UDMA)) && > (ata_bio->flags & ATA_SINGLE) == 0 && > (ata_bio->bcount > 512 || > (chp->wdc->quirks & WDC_QUIRK_NOSHORTDMA) == 0)) > xfer->c_flags |= C_DMA; > xfer->drive = drvp->drive; > xfer->cmd = ata_bio; > diff --git sys/scsi/scsi_base.c sys/scsi/scsi_base.c > index 9cf6b45..3afcc29 100644 > --- sys/scsi/scsi_base.c > +++ sys/scsi/scsi_base.c > @@ -1267,20 +1267,22 @@ scsi_report_luns(struct scsi_link *sc_link, int > selectreport, > return (error); > } > > void > scsi_xs_exec(struct scsi_xfer *xs) > { > xs->error = XS_NOERROR; > xs->resid = xs->datalen; > xs->status = 0; > CLR(xs->flags, ITSDONE); > + if (panicstr) > + SET(xs->flags, SCSI_AUTOCONF); > > #ifdef SCSIDEBUG > if (xs->sc_link->flags & SDEV_DB1) { > scsi_xs_show(xs); > if (xs->datalen && (xs->flags & SCSI_DATA_OUT)) > scsi_show_mem(xs->data, min(64, xs->datalen)); > } > #endif > > /* The adapter's scsi_cmd() is responsible for calling scsi_done(). */ >