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(). */
>