> Date: Sun, 5 Sep 2010 14:07:03 +0000
> From: Thordur I Bjornsson <[email protected]>
> 
> On Fri, Sep 03, 2010 at 09:11:39AM +0000, Thordur I Bjornsson wrote:
> > Hi gang,
> 
>     Gabriel Kihlman spotted a small problem, swd_active was not
>     being incremented.
> 
>     Here's an updated diff.

Hmm, bufq means that things are quiesced; is that what we want here?

> Index: sys/buf.h
> ===================================================================
> RCS file: /home/cvs/src/sys/sys/buf.h,v
> retrieving revision 1.72
> diff -u -p -r1.72 buf.h
> --- sys/buf.h 2 Sep 2010 07:05:39 -0000       1.72
> +++ sys/buf.h 5 Sep 2010 14:00:49 -0000
> @@ -42,6 +42,7 @@
>  #include <sys/queue.h>
>  #include <sys/tree.h>
>  #include <sys/mutex.h>
> +#include <sys/workq.h>
>  
>  #define NOLIST ((struct buf *)0x87654321)
>  
> @@ -105,10 +106,18 @@ struct bufq_fifo {
>       SIMPLEQ_ENTRY(buf)      bqf_entries;
>  };
>  
> +/* Abuse bufq_fifo, for swapping to regular files. */
> +struct bufq_swapreg {
> +     SIMPLEQ_ENTRY(buf)      bqf_entries;
> +     struct workq_task       bqf_wqtask;
> +
> +};
> +
>  /* bufq link in struct buf */
>  union bufq_data {
>       struct bufq_disksort    bufq_data_disksort;
>       struct bufq_fifo        bufq_data_fifo;
> +     struct bufq_swapreg     bufq_swapreg;
>  };
>  
>  /*
> Index: uvm/uvm_swap.c
> ===================================================================
> RCS file: /home/cvs/src/sys/uvm/uvm_swap.c,v
> retrieving revision 1.94
> diff -u -p -r1.94 uvm_swap.c
> --- uvm/uvm_swap.c    3 Jul 2010 20:28:51 -0000       1.94
> +++ uvm/uvm_swap.c    5 Sep 2010 14:03:17 -0000
> @@ -138,7 +138,8 @@ struct swapdev {
>  
>       int                     swd_bsize;      /* blocksize (bytes) */
>       int                     swd_maxactive;  /* max active i/o reqs */
> -     struct buf              swd_tab;        /* buffer list */
> +     int                     swd_active;     /* # of active i/o reqs */
> +     struct bufq             swd_bufq;
>       struct ucred            *swd_cred;      /* cred for file access */
>  #ifdef UVM_SWAP_ENCRYPT
>  #define SWD_KEY_SHIFT                7               /* One key per 0.5 
> MByte */
> @@ -241,7 +242,8 @@ static int swap_on(struct proc *, struct
>  static int swap_off(struct proc *, struct swapdev *);
>  
>  static void sw_reg_strategy(struct swapdev *, struct buf *, int);
> -static void sw_reg_iodone(struct buf *);
> +void sw_reg_iodone(struct buf *);
> +void sw_reg_iodone_internal(void *, void *);
>  static void sw_reg_start(struct swapdev *);
>  
>  static int uvm_swap_io(struct vm_page **, int, int, int);
> @@ -968,6 +970,7 @@ swap_on(struct proc *p, struct swapdev *
>               else
>  #endif /* defined(NFSCLIENT) */
>                       sdp->swd_maxactive = 8; /* XXX */
> +             bufq_init(&sdp->swd_bufq, BUFQ_FIFO);
>               break;
>  
>       default:
> @@ -1372,10 +1375,9 @@ sw_reg_strategy(struct swapdev *sdp, str
>  
>               nbp->vb_xfer = vnx;     /* patch it back in to vnx */
>  
> -             /*
> -              * Just sort by block number
> -              */
> +             /* XXX: In case the underlying bufq is disksort: */
>               nbp->vb_buf.b_cylinder = nbp->vb_buf.b_blkno;
> +
>               s = splbio();
>               if (vnx->vx_error != 0) {
>                       putvndbuf(nbp);
> @@ -1386,8 +1388,8 @@ sw_reg_strategy(struct swapdev *sdp, str
>               /* assoc new buffer with underlying vnode */
>               bgetvp(vp, &nbp->vb_buf);
>  
> -             /* sort it in and start I/O if we are not over our limit */
> -             disksort(&sdp->swd_tab, &nbp->vb_buf);
> +             /* start I/O if we are not over our limit */
> +             bufq_queue(&sdp->swd_bufq, &nbp->vb_buf);
>               sw_reg_start(sdp);
>               splx(s);
>  
> @@ -1413,29 +1415,25 @@ out: /* Arrive here at splbio */
>       splx(s);
>  }
>  
> -/*
> - * sw_reg_start: start an I/O request on the requested swapdev
> - *
> - * => reqs are sorted by disksort (above)
> - */
> +/* sw_reg_start: start an I/O request on the requested swapdev. */
>  static void
>  sw_reg_start(struct swapdev *sdp)
>  {
>       struct buf      *bp;
>       UVMHIST_FUNC("sw_reg_start"); UVMHIST_CALLED(pdhist);
>  
> -     /* recursion control */
> +     /* XXX: recursion control */
>       if ((sdp->swd_flags & SWF_BUSY) != 0)
>               return;
>  
>       sdp->swd_flags |= SWF_BUSY;
>  
> -     while (sdp->swd_tab.b_active < sdp->swd_maxactive) {
> -             bp = sdp->swd_tab.b_actf;
> +     while (sdp->swd_active < sdp->swd_maxactive) {
> +             bp = bufq_dequeue(&sdp->swd_bufq);
>               if (bp == NULL)
>                       break;
> -             sdp->swd_tab.b_actf = bp->b_actf;
> -             sdp->swd_tab.b_active++;
> +
> +             sdp->swd_active++;
>  
>               UVMHIST_LOG(pdhist,
>                   "sw_reg_start:  bp %p vp %p blkno 0x%lx cnt 0x%lx",
> @@ -1452,15 +1450,31 @@ sw_reg_start(struct swapdev *sdp)
>   * sw_reg_iodone: one of our i/o's has completed and needs post-i/o cleanup
>   *
>   * => note that we can recover the vndbuf struct by casting the buf ptr
> + *
> + * XXX:
> + * We only put this onto a workq here, because of the maxactive game since
> + * it basically requires us to call back into VOP_STRATEGY() (where we must
> + * be able to sleep) via sw_reg_start().
>   */
> -static void
> +void
>  sw_reg_iodone(struct buf *bp)
>  {
> -     struct vndbuf *vbp = (struct vndbuf *) bp;
> +     struct bufq_swapreg     *bq;
> +
> +     bq = (struct bufq_swapreg *)&bp->b_bufq;
> +
> +     workq_queue_task(NULL, &bq->bqf_wqtask, 0,
> +         (workq_fn)sw_reg_iodone_internal, bp, NULL);
> +}
> +
> +void
> +sw_reg_iodone_internal(void *arg0, void *unused)
> +{
> +     struct vndbuf *vbp = (struct vndbuf *)arg0;
>       struct vndxfer *vnx = vbp->vb_xfer;
>       struct buf *pbp = vnx->vx_bp;           /* parent buffer */
>       struct swapdev  *sdp = vnx->vx_sdp;
> -     int resid;
> +     int resid, s;
>       UVMHIST_FUNC("sw_reg_iodone"); UVMHIST_CALLED(pdhist);
>  
>       UVMHIST_LOG(pdhist, "  vbp=%p vp=%p blkno=0x%lx addr=%p",
> @@ -1468,7 +1482,7 @@ sw_reg_iodone(struct buf *bp)
>       UVMHIST_LOG(pdhist, "  cnt=%lx resid=%lx",
>           vbp->vb_buf.b_bcount, vbp->vb_buf.b_resid, 0, 0);
>  
> -     splassert(IPL_BIO);
> +     s = splbio();
>  
>       resid = vbp->vb_buf.b_bcount - vbp->vb_buf.b_resid;
>       pbp->b_resid -= resid;
> @@ -1519,8 +1533,9 @@ sw_reg_iodone(struct buf *bp)
>       /*
>        * done!   start next swapdev I/O if one is pending
>        */
> -     sdp->swd_tab.b_active--;
> +     sdp->swd_active--;
>       sw_reg_start(sdp);
> +     splx(s);
>  }

Reply via email to