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

Reply via email to