On Sun, Aug 29, 2010 at 10:26:14PM +1000, David Gwynne wrote:
> this diff is largely a mechanical change.
> 
> firstly, it makes struct bufq a member of the softc for devices
> that use it, rather than it being a pointer to something that needs
> to be allocated at attach. since all these devices need a bufq to
> operate, it makes sense to have it allocated as part of the softc
> and get bufq_init to just initialise all its fields. it also gets
> rid of the possibility that you wont be able to allocate teh bufq
> struct during attach, which is something you dont want to happen.
> 
> secondly, it consistently implements a split between wrapper functions
> and the per discipline implementation of the bufq handlers. it
> consistently does the locking in the wrappers rather than doing
> half in the wrappers and the other half in the implementations.
> 
> it also consistently handles the outstanding bufq bq pointer in the
> wrappers.
> 
> this hides most of the implementation inside kern_bufq.c. the only
> stuff left in buf.h is for the bits each implementation needs to
> put bufs on their queues.
> 
> ive tested this extensively on sd(4) and thib has tested this on
> wd(4). we'd like some wider exposure, especially over suspends and
> resumes on a variety of machines. i have tried to preserve the
> locking semantics, but testing would be lovely.
> 
> ok?

I like this a lot, and I will do some testing on st and cd at least as
soon as I can rebuild the appropriate box.

.... Ken

> 
> dlg
> 
> Index: dev/ata/wd.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/ata/wd.c,v
> retrieving revision 1.85
> diff -u -p -r1.85 wd.c
> --- dev/ata/wd.c      28 Jun 2010 08:35:46 -0000      1.85
> +++ dev/ata/wd.c      25 Aug 2010 12:05:33 -0000
> @@ -121,7 +121,7 @@ struct wd_softc {
>       /* General disk infos */
>       struct device sc_dev;
>       struct disk sc_dk;
> -     struct bufq     *sc_bufq;
> +     struct bufq sc_bufq;
>  
>       /* IDE disk soft states */
>       struct ata_bio sc_wdc_bio; /* current transfer */
> @@ -369,7 +369,7 @@ wdattach(struct device *parent, struct d
>        */
>       wd->sc_dk.dk_driver = &wddkdriver;
>       wd->sc_dk.dk_name = wd->sc_dev.dv_xname;
> -     wd->sc_bufq = bufq_init(BUFQ_DEFAULT);
> +     bufq_init(&wd->sc_bufq, BUFQ_DEFAULT);
>       wd->sc_sdhook = shutdownhook_establish(wd_shutdown, wd);
>       if (wd->sc_sdhook == NULL)
>               printf("%s: WARNING: unable to establish shutdown hook\n",
> @@ -413,7 +413,7 @@ wddetach(struct device *self, int flags)
>  
>       /* Remove unprocessed buffers from queue */
>       s = splbio();
> -     while ((bp = BUFQ_DEQUEUE(sc->sc_bufq)) != NULL) {
> +     while ((bp = bufq_dequeue(&sc->sc_bufq)) != NULL) {
>               bp->b_error = ENXIO;
>               bp->b_flags |= B_ERROR;
>               biodone(bp);
> @@ -435,7 +435,7 @@ wddetach(struct device *self, int flags)
>               shutdownhook_disestablish(sc->sc_sdhook);
>  
>       /* Detach disk. */
> -     bufq_destroy(sc->sc_bufq);
> +     bufq_destroy(&sc->sc_bufq);
>       disk_detach(&sc->sc_dk);
>  
>       return (0);
> @@ -486,7 +486,7 @@ wdstrategy(struct buf *bp)
>           (wd->sc_flags & (WDF_WLABEL|WDF_LABELLING)) != 0) <= 0)
>               goto done;
>       /* Queue transfer on drive, activate drive and controller if idle. */
> -     BUFQ_QUEUE(wd->sc_bufq, bp);
> +     bufq_queue(&wd->sc_bufq, bp);
>       s = splbio();
>       wdstart(wd);
>       splx(s);
> @@ -518,7 +518,7 @@ wdstart(void *arg)
>       while (wd->openings > 0) {
>  
>               /* Is there a buf for us ? */
> -             if ((bp = BUFQ_DEQUEUE(wd->sc_bufq)) == NULL)
> +             if ((bp = bufq_dequeue(&wd->sc_bufq)) == NULL)
>                       return;
>               /*
>                * Make the command. First lock the device
> Index: kern/kern_bufq.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/kern_bufq.c,v
> retrieving revision 1.14
> diff -u -p -r1.14 kern_bufq.c
> --- kern/kern_bufq.c  19 Jul 2010 21:39:15 -0000      1.14
> +++ kern/kern_bufq.c  25 Aug 2010 12:05:33 -0000
> @@ -30,45 +30,70 @@ SLIST_HEAD(, bufq)        bufqs = SLIST_HEAD_IN
>  struct mutex         bufqs_mtx = MUTEX_INITIALIZER(IPL_NONE);
>  int                  bufqs_stop;
>  
> -struct buf *(*bufq_dequeuev[BUFQ_HOWMANY])(struct bufq *, int) = {
> -     bufq_disksort_dequeue,
> -     bufq_fifo_dequeue
> +struct bufq_impl {
> +     void            *(*impl_create)(void);
> +     void             (*impl_destroy)(void *);
> +
> +     void             (*impl_queue)(void *, struct buf *);
> +     struct buf      *(*impl_dequeue)(void *);
> +     void             (*impl_requeue)(void *, struct buf *);
> +     int              (*impl_peek)(void *);
>  };
> -void (*bufq_queuev[BUFQ_HOWMANY])(struct bufq *, struct buf *) = {
> +
> +void         *bufq_disksort_create(void);
> +void          bufq_disksort_destroy(void *);
> +void          bufq_disksort_queue(void *, struct buf *);
> +struct buf   *bufq_disksort_dequeue(void *);
> +void          bufq_disksort_requeue(void *, struct buf *);
> +int           bufq_disksort_peek(void *);
> +
> +struct bufq_impl bufq_impl_disksort = {
> +     bufq_disksort_create,
> +     bufq_disksort_destroy,
>       bufq_disksort_queue,
> -     bufq_fifo_queue
> -};
> -void (*bufq_requeuev[BUFQ_HOWMANY])(struct bufq *, struct buf *) = {
> +     bufq_disksort_dequeue,
>       bufq_disksort_requeue,
> -     bufq_fifo_requeue
> +     bufq_disksort_peek
>  };
>  
> +void         *bufq_fifo_create(void);
> +void          bufq_fifo_destroy(void *);
> +void          bufq_fifo_queue(void *, struct buf *);
> +struct buf   *bufq_fifo_dequeue(void *);
> +void          bufq_fifo_requeue(void *, struct buf *);
> +int           bufq_fifo_peek(void *);
> +
> +struct bufq_impl bufq_impl_fifo = {
> +     bufq_fifo_create,
> +     bufq_fifo_destroy,
> +     bufq_fifo_queue,
> +     bufq_fifo_dequeue,
> +     bufq_fifo_requeue,
> +     bufq_fifo_peek
> +};
>  
> -struct bufq *
> -bufq_init(int type)
> -{
> -     struct bufq     *bq;
> -     int              error;
> +struct bufq_impl *bufq_impls[BUFQ_HOWMANY] = {
> +     &bufq_impl_disksort,
> +     &bufq_impl_fifo
> +};
>  
> -     bq = malloc(sizeof(*bq), M_DEVBUF, M_NOWAIT|M_ZERO);
> -     KASSERT(bq != NULL);
> +int
> +bufq_init(struct bufq *bq, int type)
> +{
> +     if (type > BUFQ_HOWMANY)
> +             panic("bufq_init: type %i unknown", type);
>  
>       mtx_init(&bq->bufq_mtx, IPL_BIO);
>       bq->bufq_type = type;
> -
> -     switch (type) {
> -     case BUFQ_DISKSORT:
> -             error = bufq_disksort_init(bq);
> -             break;
> -     case BUFQ_FIFO:
> -             error = bufq_fifo_init(bq);
> -             break;
> -     default:
> -             panic("bufq_init: type %i unknown", type);
> -             break;
> -     };
> -
> -     KASSERT(error == 0);
> +     bq->bufq_impl = bufq_impls[type];
> +     bq->bufq_data = bq->bufq_impl->impl_create();
> +     if (bq->bufq_data == NULL) {
> +             /*
> +              * we should actually return failure so disks attaching after
> +              * boot in low memory situations dont panic the system.
> +              */
> +             panic("bufq init fail");
> +     }
>  
>       mtx_enter(&bufqs_mtx);
>       while (bufqs_stop) {
> @@ -77,7 +102,48 @@ bufq_init(int type)
>       SLIST_INSERT_HEAD(&bufqs, bq, bufq_entries);
>       mtx_leave(&bufqs_mtx);
>  
> -     return (bq);
> +     return (0);
> +}
> +
> +int
> +bufq_switch(struct bufq *bq, int type)
> +{
> +     void            *data;
> +     void            *odata;
> +     int             otype;
> +     struct buf      *bp;
> +     int             ret;
> +
> +     mtx_enter(&bq->bufq_mtx);
> +     ret = (bq->bufq_type == type);
> +     mtx_leave(&bq->bufq_mtx);
> +     if (ret)
> +             return (0);
> +
> +     data = bufq_impls[type]->impl_create();
> +     if (data == NULL)
> +             return (ENOMEM);
> +
> +     mtx_enter(&bq->bufq_mtx);
> +     if (bq->bufq_type != type) { /* might have changed during create */
> +             odata = bq->bufq_data;
> +             otype = bq->bufq_type;
> +
> +             while ((bp = bufq_impls[otype]->impl_dequeue(odata)) != NULL)
> +                     bufq_impls[type]->impl_queue(data, bp);
> +
> +             bq->bufq_data = data;
> +             bq->bufq_type = type;
> +             bq->bufq_impl = bufq_impls[type];
> +     } else {
> +             otype = type;
> +             odata = data;
> +     }
> +     mtx_leave(&bq->bufq_mtx);
> +
> +     bufq_impls[otype]->impl_destroy(odata);
> +
> +     return (0);
>  }
>  
>  void
> @@ -85,8 +151,8 @@ bufq_destroy(struct bufq *bq)
>  {
>       bufq_drain(bq);
>  
> -     if (bq->bufq_data != NULL)
> -             free(bq->bufq_data, M_DEVBUF);
> +     bq->bufq_impl->impl_destroy(bq->bufq_data);
> +     bq->bufq_data = NULL;
>  
>       mtx_enter(&bufqs_mtx);
>       while (bufqs_stop) {
> @@ -94,10 +160,9 @@ bufq_destroy(struct bufq *bq)
>       }
>       SLIST_REMOVE(&bufqs, bq, bufq, bufq_entries);
>       mtx_leave(&bufqs_mtx);
> -
> -     free(bq, M_DEVBUF);
>  }
>  
> +
>  void
>  bufq_queue(struct bufq *bq, struct buf *bp)
>  {
> @@ -105,16 +170,43 @@ bufq_queue(struct bufq *bq, struct buf *
>       while (bq->bufq_stop) {
>               msleep(&bq->bufq_stop, &bq->bufq_mtx, PRIBIO, "bqqueue", 0);
>       }
> -     bufq_queuev[bq->bufq_type](bq, bp);
> +
> +     bp->b_bq = bq;
> +     bq->bufq_outstanding++;
> +     bq->bufq_impl->impl_queue(bq->bufq_data, bp);
> +     mtx_leave(&bq->bufq_mtx);
> +}
> +
> +struct buf *
> +bufq_dequeue(struct bufq *bq)
> +{
> +     struct buf      *bp;
> +
> +     mtx_enter(&bq->bufq_mtx);
> +     bp = bq->bufq_impl->impl_dequeue(bq->bufq_data);
>       mtx_leave(&bq->bufq_mtx);
> +
> +     return (bp);
>  }
>  
>  void
>  bufq_requeue(struct bufq *bq, struct buf *bp)
>  {
>       mtx_enter(&bq->bufq_mtx);
> -     bufq_requeuev[bq->bufq_type](bq, bp);
> +     bq->bufq_impl->impl_requeue(bq->bufq_data, bp);
> +     mtx_leave(&bq->bufq_mtx);
> +}
> +
> +int
> +bufq_peek(struct bufq *bq)
> +{
> +     int             rv;
> +
> +     mtx_enter(&bq->bufq_mtx);
> +     rv = bq->bufq_impl->impl_peek(bq->bufq_data);
>       mtx_leave(&bq->bufq_mtx);
> +
> +     return (rv);
>  }
>  
>  void
> @@ -123,7 +215,7 @@ bufq_drain(struct bufq *bq)
>       struct buf      *bp;
>       int              s;
>  
> -     while ((bp = BUFQ_DEQUEUE(bq)) != NULL) {
> +     while ((bp = bufq_dequeue(bq)) != NULL) {
>               bp->b_error = ENXIO;
>               bp->b_flags |= B_ERROR;
>               s = splbio();
> @@ -138,7 +230,7 @@ bufq_done(struct bufq *bq, struct buf *b
>       mtx_enter(&bq->bufq_mtx);
>       bq->bufq_outstanding--;
>       KASSERT(bq->bufq_outstanding >= 0);
> -     if (bq->bufq_outstanding == 0)
> +     if (bq->bufq_outstanding == 0 /* XXX and quiesced */)
>               wakeup(&bq->bufq_outstanding);
>       mtx_leave(&bq->bufq_mtx);
>       bp->b_bq = NULL;
> @@ -152,7 +244,7 @@ bufq_quiesce(void)
>       mtx_enter(&bufqs_mtx);
>       bufqs_stop = 1;
>       mtx_leave(&bufqs_mtx);
> -     SLIST_FOREACH(bq, &bufqs, bufq_entries) {
> +     SLIST_FOREACH(bq, &bufqs, bufq_entries) { /* XXX */
>               mtx_enter(&bq->bufq_mtx);
>               bq->bufq_stop = 1;
>               while (bq->bufq_outstanding) {
> @@ -180,24 +272,47 @@ bufq_restart(void)
>       mtx_leave(&bufqs_mtx);
>  }
>  
> +/*
> + * disksort implementation.
> + */
> +
> +void *
> +bufq_disksort_create(void)
> +{
> +     return (malloc(sizeof(struct buf), M_DEVBUF, M_NOWAIT | M_ZERO));
> +}
> +
>  void
> -bufq_disksort_queue(struct bufq *bq, struct buf *bp)
> +bufq_disksort_destroy(void *data)
>  {
> -     struct buf      *bufq;
> +     free(data, M_DEVBUF);
> +}
>  
> -     bufq = (struct buf *)bq->bufq_data;
> +void
> +bufq_disksort_queue(void *data, struct buf *bp)
> +{
> +     disksort((struct buf *)data, bp);
> +}
>  
> -     bq->bufq_outstanding++;
> -     bp->b_bq = bq;
> -     disksort(bufq, bp);
> +struct buf *
> +bufq_disksort_dequeue(void *data)
> +{
> +     struct buf      *bufq = data;
> +     struct buf      *bp;
> +
> +     bp = bufq->b_actf;
> +     if (bp != NULL)
> +             bufq->b_actf = bp->b_actf;
> +     if (bufq->b_actf == NULL)
> +             bufq->b_actb = &bufq->b_actf;
> +
> +     return (bp);
>  }
>  
>  void
> -bufq_disksort_requeue(struct bufq *bq, struct buf *bp)
> +bufq_disksort_requeue(void *data, struct buf *bp)
>  {
> -     struct buf      *bufq;
> -
> -     bufq = (struct buf *)bq->bufq_data;
> +     struct buf      *bufq = data;
>  
>       bp->b_actf = bufq->b_actf;
>       bufq->b_actf = bp;
> @@ -205,83 +320,71 @@ bufq_disksort_requeue(struct bufq *bq, s
>               bufq->b_actb = &bp->b_actf;
>  }
>  
> -struct buf *
> -bufq_disksort_dequeue(struct bufq *bq, int peeking)
> +int
> +bufq_disksort_peek(void *data)
>  {
> -     struct buf      *bufq, *bp;
> +     struct buf      *bufq = data;
>  
> -     mtx_enter(&bq->bufq_mtx);
> -     bufq = (struct buf *)bq->bufq_data;
> -     bp = bufq->b_actf;
> -     if (!peeking) {
> -             if (bp != NULL)
> -                     bufq->b_actf = bp->b_actf;
> -             if (bufq->b_actf == NULL)
> -                     bufq->b_actb = &bufq->b_actf;
> -     }
> -     mtx_leave(&bq->bufq_mtx);
> -
> -     return (bp);
> +     return (bufq->b_actf != NULL);
>  }
>  
> -int
> -bufq_disksort_init(struct bufq *bq)
> +/*
> + * fifo implementation
> + */
> +
> +void *
> +bufq_fifo_create(void)
>  {
> -     int     error = 0;
> +     struct bufq_fifo_head   *head;
>  
> -     bq->bufq_data = malloc(sizeof(struct buf), M_DEVBUF,
> -         M_NOWAIT|M_ZERO);
> +     head = malloc(sizeof(*head), M_DEVBUF, M_NOWAIT | M_ZERO);
> +     if (head == NULL)
> +             return (NULL);
>  
> -     if (bq->bufq_data == NULL)
> -             error = ENOMEM;
> +     SIMPLEQ_INIT(head);
>  
> -     return (error);
> +     return (head);
>  }
>  
>  void
> -bufq_fifo_queue(struct bufq *bq, struct buf *bp)
> +bufq_fifo_destroy(void *data)
>  {
> -     struct bufq_fifo_head   *head = bq->bufq_data;
> -
> -     bq->bufq_outstanding++;
> -     bp->b_bq = bq;
> -     SIMPLEQ_INSERT_TAIL(head, bp, b_bufq.bufq_data_fifo.bqf_entries);
> +     free(data, M_DEVBUF);
>  }
>  
>  void
> -bufq_fifo_requeue(struct bufq *bq, struct buf *bp)
> +bufq_fifo_queue(void *data, struct buf *bp)
>  {
> -     struct bufq_fifo_head   *head = bq->bufq_data;
> +     struct bufq_fifo_head   *head = data;
>  
> -     SIMPLEQ_INSERT_HEAD(head, bp, b_bufq.bufq_data_fifo.bqf_entries);
> +     SIMPLEQ_INSERT_TAIL(head, bp, b_bufq.bufq_data_fifo.bqf_entries);
>  }
>  
>  struct buf *
> -bufq_fifo_dequeue(struct bufq *bq, int peeking)
> +bufq_fifo_dequeue(void *data)
>  {
> -     struct  bufq_fifo_head  *head = bq->bufq_data;
> -     struct  buf             *bp;
> +     struct bufq_fifo_head   *head = data;
> +     struct buf              *bp;
>  
> -     mtx_enter(&bq->bufq_mtx);
>       bp = SIMPLEQ_FIRST(head);
> -     if (bp != NULL && !peeking)
> +     if (bp != NULL)
>               SIMPLEQ_REMOVE_HEAD(head, b_bufq.bufq_data_fifo.bqf_entries);
> -     mtx_leave(&bq->bufq_mtx);
>  
>       return (bp);
>  }
>  
> -int
> -bufq_fifo_init(struct bufq *bq)
> +void
> +bufq_fifo_requeue(void *data, struct buf *bp)
>  {
> -     struct bufq_fifo_head   *head;
> +     struct bufq_fifo_head   *head = data;
>  
> -     head = malloc(sizeof(*head), M_DEVBUF, M_NOWAIT);
> -     if (head == NULL)
> -             return (ENOMEM);
> +     SIMPLEQ_INSERT_HEAD(head, bp, b_bufq.bufq_data_fifo.bqf_entries);
> +}
>  
> -     SIMPLEQ_INIT(head);
> -     bq->bufq_data = head;
> +int
> +bufq_fifo_peek(void *data)
> +{
> +     struct bufq_fifo_head   *head = data;
>  
> -     return (0);
> +     return (SIMPLEQ_FIRST(head) != NULL);
>  }
> Index: scsi/cd.c
> ===================================================================
> RCS file: /cvs/src/sys/scsi/cd.c,v
> retrieving revision 1.181
> diff -u -p -r1.181 cd.c
> --- scsi/cd.c 28 Jul 2010 23:47:43 -0000      1.181
> +++ scsi/cd.c 25 Aug 2010 12:05:33 -0000
> @@ -111,7 +111,7 @@ struct cd_softc {
>               u_int32_t blksize;
>               daddr64_t disksize;     /* total number sectors */
>       } sc_params;
> -     struct bufq     *sc_bufq;
> +     struct bufq     sc_bufq;
>       struct scsi_xshandler sc_xsh;
>       struct timeout sc_timeout;
>       void *sc_cdpwrhook;             /* our power hook */
> @@ -219,7 +219,7 @@ cdattach(struct device *parent, struct d
>        */
>       sc->sc_dk.dk_driver = &cddkdriver;
>       sc->sc_dk.dk_name = sc->sc_dev.dv_xname;
> -     sc->sc_bufq = bufq_init(BUFQ_DEFAULT);
> +     bufq_init(&sc->sc_bufq, BUFQ_DEFAULT);
>  
>       /*
>        * Note if this device is ancient.  This is used in cdminphys().
> @@ -255,7 +255,7 @@ cdactivate(struct device *self, int act)
>  
>       case DVACT_DEACTIVATE:
>               sc->sc_flags |= CDF_DYING;
> -             bufq_drain(sc->sc_bufq);
> +             bufq_drain(&sc->sc_bufq);
>               break;
>       }
>       return (rv);
> @@ -268,7 +268,7 @@ cddetach(struct device *self, int flags)
>       struct cd_softc *sc = (struct cd_softc *)self;
>       int bmaj, cmaj, mn;
>  
> -     bufq_drain(sc->sc_bufq);
> +     bufq_drain(&sc->sc_bufq);
>  
>       /* Locate the lowest minor number to be detached. */
>       mn = DISKMINOR(self->dv_unit, 0);
> @@ -285,7 +285,7 @@ cddetach(struct device *self, int flags)
>               powerhook_disestablish(sc->sc_cdpwrhook);
>  
>       /* Detach disk. */
> -     bufq_destroy(sc->sc_bufq);
> +     bufq_destroy(&sc->sc_bufq);
>       disk_detach(&sc->sc_dk);
>  
>       return (0);
> @@ -530,7 +530,7 @@ cdstrategy(struct buf *bp)
>               goto done;
>  
>       /* Place it in the queue of disk activities for this disk. */
> -     BUFQ_QUEUE(sc->sc_bufq, bp);    
> +     bufq_queue(&sc->sc_bufq, bp);   
>  
>       /*
>        * Tell the device to get going on the transfer if it's
> @@ -596,12 +596,12 @@ cdstart(struct scsi_xfer *xs)
>        * re-opened
>        */
>       if ((sc_link->flags & SDEV_MEDIA_LOADED) == 0) {
> -             bufq_drain(sc->sc_bufq);
> +             bufq_drain(&sc->sc_bufq);
>               scsi_xs_put(xs);
>               return;
>       }
>  
> -     bp = BUFQ_DEQUEUE(sc->sc_bufq);
> +     bp = bufq_dequeue(&sc->sc_bufq);
>       if (bp == NULL) {
>               scsi_xs_put(xs);
>               return;
> @@ -665,7 +665,7 @@ cdstart(struct scsi_xfer *xs)
>  
>       if (ISSET(sc->sc_flags, CDF_WAITING))
>               CLR(sc->sc_flags, CDF_WAITING);
> -     else if (BUFQ_PEEK(sc->sc_bufq))
> +     else if (bufq_peek(&sc->sc_bufq))
>               scsi_xsh_add(&sc->sc_xsh);
>  }
>  
> @@ -686,7 +686,7 @@ cd_buf_done(struct scsi_xfer *xs)
>               /* The adapter is busy, requeue the buf and try it later. */
>               disk_unbusy(&sc->sc_dk, bp->b_bcount - xs->resid,
>                   bp->b_flags & B_READ);
> -             BUFQ_REQUEUE(sc->sc_bufq, bp);
> +             bufq_requeue(&sc->sc_bufq, bp);
>               scsi_xs_put(xs);
>               SET(sc->sc_flags, CDF_WAITING);
>               timeout_add(&sc->sc_timeout, 1);
> Index: scsi/sd.c
> ===================================================================
> RCS file: /cvs/src/sys/scsi/sd.c,v
> retrieving revision 1.205
> diff -u -p -r1.205 sd.c
> --- scsi/sd.c 3 Aug 2010 19:37:17 -0000       1.205
> +++ scsi/sd.c 25 Aug 2010 12:05:33 -0000
> @@ -175,7 +175,7 @@ sdattach(struct device *parent, struct d
>        */
>       sc->sc_dk.dk_driver = &sddkdriver;
>       sc->sc_dk.dk_name = sc->sc_dev.dv_xname;
> -     sc->sc_bufq = bufq_init(BUFQ_DEFAULT);
> +     bufq_init(&sc->sc_bufq, BUFQ_DEFAULT);
>  
>       if ((sc_link->flags & SDEV_ATAPI) && (sc_link->flags & SDEV_REMOVABLE))
>               sc_link->quirks |= SDEV_NOSYNCCACHE;
> @@ -279,7 +279,7 @@ sdactivate(struct device *self, int act)
>  
>       case DVACT_DEACTIVATE:
>               sc->flags |= SDF_DYING;
> -             bufq_drain(sc->sc_bufq);
> +             bufq_drain(&sc->sc_bufq);
>               break;
>  
>       case DVACT_SUSPEND:
> @@ -309,7 +309,7 @@ sddetach(struct device *self, int flags)
>       struct sd_softc *sc = (struct sd_softc *)self;
>       int bmaj, cmaj, mn;
>  
> -     bufq_drain(sc->sc_bufq);
> +     bufq_drain(&sc->sc_bufq);
>  
>       /* Locate the lowest minor number to be detached. */
>       mn = DISKMINOR(self->dv_unit, 0);
> @@ -326,7 +326,7 @@ sddetach(struct device *self, int flags)
>               shutdownhook_disestablish(sc->sc_sdhook);
>  
>       /* Detach disk. */
> -     bufq_destroy(sc->sc_bufq);
> +     bufq_destroy(&sc->sc_bufq);
>       disk_detach(&sc->sc_dk);
>  
>       return (0);
> @@ -581,7 +581,7 @@ sdstrategy(struct buf *bp)
>               goto done;
>  
>       /* Place it in the queue of disk activities for this disk. */
> -     BUFQ_QUEUE(sc->sc_bufq, bp);
> +     bufq_queue(&sc->sc_bufq, bp);
>  
>       /*
>        * Tell the device to get going on the transfer if it's
> @@ -683,12 +683,12 @@ sdstart(struct scsi_xfer *xs)
>               return;
>       }
>       if ((link->flags & SDEV_MEDIA_LOADED) == 0) {
> -             bufq_drain(sc->sc_bufq);
> +             bufq_drain(&sc->sc_bufq);
>               scsi_xs_put(xs);
>               return;
>       }
>  
> -     bp = BUFQ_DEQUEUE(sc->sc_bufq);
> +     bp = bufq_dequeue(&sc->sc_bufq);
>       if (bp == NULL) {
>               scsi_xs_put(xs);
>               return;
> @@ -739,7 +739,7 @@ sdstart(struct scsi_xfer *xs)
>       /* move onto the next io */
>       if (ISSET(sc->flags, SDF_WAITING))
>               CLR(sc->flags, SDF_WAITING);
> -     else if (BUFQ_PEEK(sc->sc_bufq) != NULL)
> +     else if (bufq_peek(&sc->sc_bufq) != NULL)
>               scsi_xsh_add(&sc->sc_xsh);
>  }
>  
> @@ -760,7 +760,7 @@ sd_buf_done(struct scsi_xfer *xs)
>               /* The adapter is busy, requeue the buf and try it later. */
>               disk_unbusy(&sc->sc_dk, bp->b_bcount - xs->resid,
>                   bp->b_flags & B_READ);
> -             BUFQ_REQUEUE(sc->sc_bufq, bp);
> +             bufq_requeue(&sc->sc_bufq, bp);
>               scsi_xs_put(xs);
>               SET(sc->flags, SDF_WAITING);
>               timeout_add(&sc->sc_timeout, 1);
> Index: scsi/sdvar.h
> ===================================================================
> RCS file: /cvs/src/sys/scsi/sdvar.h,v
> retrieving revision 1.31
> diff -u -p -r1.31 sdvar.h
> --- scsi/sdvar.h      2 Jun 2010 13:32:13 -0000       1.31
> +++ scsi/sdvar.h      25 Aug 2010 12:05:33 -0000
> @@ -51,7 +51,7 @@
>  struct sd_softc {
>       struct device           sc_dev;
>       struct disk             sc_dk;
> -     struct bufq             *sc_bufq;
> +     struct bufq             sc_bufq;
>  
>       int                     flags;
>  #define      SDF_LOCKED      0x01
> Index: scsi/st.c
> ===================================================================
> RCS file: /cvs/src/sys/scsi/st.c,v
> retrieving revision 1.106
> diff -u -p -r1.106 st.c
> --- scsi/st.c 22 Jul 2010 05:26:34 -0000      1.106
> +++ scsi/st.c 25 Aug 2010 12:05:33 -0000
> @@ -215,7 +215,7 @@ struct st_softc {
>  #define BLKSIZE_SET_BY_USER  0x04
>  #define BLKSIZE_SET_BY_QUIRK 0x08
>  
> -     struct bufq *sc_bufq;
> +     struct bufq sc_bufq;
>       struct timeout sc_timeout;
>       struct scsi_xshandler sc_xsh;
>  };
> @@ -331,7 +331,7 @@ stattach(struct device *parent, struct d
>           &st->sc_xsh);
>       
>       /* Set up the buf queue for this device. */
> -     st->sc_bufq = bufq_init(BUFQ_FIFO);
> +     bufq_init(&st->sc_bufq, BUFQ_FIFO);
>  
>       /* Start up with media position unknown. */
>       st->media_fileno = -1;
> @@ -357,7 +357,7 @@ stactivate(struct device *self, int act)
>  
>       case DVACT_DEACTIVATE:
>               st->flags |= ST_DYING;
> -             bufq_drain(st->sc_bufq);
> +             bufq_drain(&st->sc_bufq);
>               break;
>       }
>  
> @@ -370,7 +370,7 @@ stdetach(struct device *self, int flags)
>       struct st_softc *st = (struct st_softc *)self;
>       int bmaj, cmaj, mn;
>  
> -     bufq_drain(st->sc_bufq);
> +     bufq_drain(&st->sc_bufq);
>  
>       /* Locate the lowest minor number to be detached. */
>       mn = STUNIT(self->dv_unit);
> @@ -390,7 +390,7 @@ stdetach(struct device *self, int flags)
>                       vdevgone(cmaj, mn, mn + 3, VCHR);
>               }
>  
> -     bufq_destroy(st->sc_bufq);
> +     bufq_destroy(&st->sc_bufq);
>  
>       return (0);
>  }
> @@ -877,7 +877,7 @@ ststrategy(struct buf *bp)
>        * at the end (a bit silly because we only have on user..
>        * (but it could fork()))
>        */
> -     BUFQ_QUEUE(st->sc_bufq, bp);
> +     bufq_queue(&st->sc_bufq, bp);
>  
>       /*
>        * Tell the device to get going on the transfer if it's
> @@ -922,13 +922,13 @@ ststart(struct scsi_xfer *xs)
>           !(sc_link->flags & SDEV_MEDIA_LOADED)) {
>               /* make sure that one implies the other.. */
>               sc_link->flags &= ~SDEV_MEDIA_LOADED;
> -             bufq_drain(st->sc_bufq);
> +             bufq_drain(&st->sc_bufq);
>               scsi_xs_put(xs);
>               return;
>       }
>  
>       for (;;) {
> -             bp = BUFQ_DEQUEUE(st->sc_bufq);
> +             bp = bufq_dequeue(&st->sc_bufq);
>               if (bp == NULL) {
>                       scsi_xs_put(xs);
>                       return;
> @@ -1041,7 +1041,7 @@ ststart(struct scsi_xfer *xs)
>        */
>       if (ISSET(st->flags, ST_WAITING))
>               CLR(st->flags, ST_WAITING);
> -     else if (BUFQ_PEEK(st->sc_bufq))
> +     else if (bufq_peek(&st->sc_bufq))
>               scsi_xsh_add(&st->sc_xsh);
>  }
>  
> @@ -1060,7 +1060,7 @@ st_buf_done(struct scsi_xfer *xs)
>  
>       case XS_NO_CCB:
>               /* The adapter is busy, requeue the buf and try it later. */
> -             BUFQ_REQUEUE(st->sc_bufq, bp);
> +             bufq_requeue(&st->sc_bufq, bp);
>               scsi_xs_put(xs);
>               SET(st->flags, ST_WAITING); /* dont let ststart xsh_add */
>               timeout_add(&st->sc_timeout, 1);
> Index: sys/buf.h
> ===================================================================
> RCS file: /cvs/src/sys/sys/buf.h,v
> retrieving revision 1.70
> diff -u -p -r1.70 buf.h
> --- sys/buf.h 30 Jun 2010 02:26:58 -0000      1.70
> +++ sys/buf.h 25 Aug 2010 12:05:33 -0000
> @@ -67,6 +67,8 @@ LIST_HEAD(workhead, worklist);
>  #define BUFQ_DEFAULT BUFQ_DISKSORT
>  #define BUFQ_HOWMANY 2
>  
> +struct bufq_impl;
> +
>  struct bufq {
>       SLIST_ENTRY(bufq)        bufq_entries;
>       struct mutex             bufq_mtx;
> @@ -74,51 +76,40 @@ struct bufq {
>       u_int                    bufq_outstanding;
>       int                      bufq_stop;
>       int                      bufq_type;
> +     struct bufq_impl        *bufq_impl;
>  };
>  
> -struct buf   *bufq_disksort_dequeue(struct bufq *, int);
> -void          bufq_disksort_queue(struct bufq *, struct buf *);
> -void          bufq_disksort_requeue(struct bufq *, struct buf *);
> -int           bufq_disksort_init(struct bufq *);
> +int           bufq_init(struct bufq *, int);
> +int           bufq_switch(struct bufq *, int);
> +void          bufq_destroy(struct bufq *);
> +
> +void          bufq_queue(struct bufq *, struct buf *);
> +struct buf   *bufq_dequeue(struct bufq *);
> +void          bufq_requeue(struct bufq *, struct buf *);
> +int           bufq_peek(struct bufq *);
> +void          bufq_drain(struct bufq *);
> +
> +void          bufq_done(struct bufq *, struct buf *);
> +void          bufq_quiesce(void);
> +void          bufq_restart(void);
> +
> +/* disksort */
>  struct bufq_disksort {
>       struct buf       *bqd_actf;
>       struct buf      **bqd_actb;
>  };
>  
> -struct buf   *bufq_fifo_dequeue(struct bufq *, int);
> -void          bufq_fifo_queue(struct bufq *, struct buf *);
> -void          bufq_fifo_requeue(struct bufq *, struct buf *);
> -int           bufq_fifo_init(struct bufq *);
> +/* fifo */
>  SIMPLEQ_HEAD(bufq_fifo_head, buf);
>  struct bufq_fifo {
>       SIMPLEQ_ENTRY(buf)      bqf_entries;
>  };
>  
> +/* bufq link in struct buf */
>  union bufq_data {
>       struct bufq_disksort    bufq_data_disksort;
>       struct bufq_fifo        bufq_data_fifo;
>  };
> -
> -extern struct buf *(*bufq_dequeuev[BUFQ_HOWMANY])(struct bufq *, int);
> -extern void (*bufq_queuev[BUFQ_HOWMANY])(struct bufq *, struct buf *);
> -extern void (*bufq_requeuev[BUFQ_HOWMANY])(struct bufq *, struct buf *);
> -
> -#define      BUFQ_QUEUE(_bufq, _bp)   bufq_queue(_bufq, _bp)
> -#define BUFQ_REQUEUE(_bufq, _bp) bufq_requeue(_bufq, _bp)
> -#define      BUFQ_DEQUEUE(_bufq)             \
> -         bufq_dequeuev[(_bufq)->bufq_type](_bufq, 0)
> -#define      BUFQ_PEEK(_bufq)                \
> -     bufq_dequeuev[(_bufq)->bufq_type](_bufq, 1)
> -
> -struct bufq  *bufq_init(int);
> -void          bufq_queue(struct bufq *, struct buf *);
> -void          bufq_requeue(struct bufq *, struct buf *);
> -void          bufq_destroy(struct bufq *);
> -void          bufq_drain(struct bufq *);
> -void          bufq_done(struct bufq *, struct buf *);
> -void          bufq_quiesce(void);
> -void          bufq_restart(void);
> -
>  
>  /*
>   * These are currently used only by the soft dependency code, hence

Reply via email to