Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Two changes to the dksubr interface.



details:   https://anonhg.NetBSD.org/src/rev/39ccd7cb4665
branches:  trunk
changeset: 339904:39ccd7cb4665
user:      mlelstv <mlelstv%NetBSD.org@localhost>
date:      Sun Aug 16 18:00:03 2015 +0000

description:
Two changes to the dksubr interface.

- d_diskstart callback now processes a single buffer only.
  The new wrapper function dk_start processes the queue,
  performs other buffer handling and also provides locking
  for the the data structures.

- add d_discard callback to handle device specific function inside
  the new dk_discard helper function.

Replace splbio with mutex to protect queue and disk structure.
Refactor common code in dk_strategy and dk_discard into dk_translate.

Adjust and simplify ld(4), cgd(4) and xbd(4) drivers accordingly.

ld(4) now becomes MP_SAFE.

Bump kernel version.

diffstat:

 sys/arch/xen/xen/xbd_xenbus.c |  217 ++++++++++++++++-------------------------
 sys/dev/cgd.c                 |  122 +++++++++--------------
 sys/dev/dksubr.c              |  170 ++++++++++++++++++++++++--------
 sys/dev/dkvar.h               |    5 +-
 sys/dev/ld.c                  |   67 +++---------
 sys/sys/disk.h                |    5 +-
 sys/sys/param.h               |    4 +-
 7 files changed, 288 insertions(+), 302 deletions(-)

diffs (truncated from 967 to 300 lines):

diff -r 6a4c571f4156 -r 39ccd7cb4665 sys/arch/xen/xen/xbd_xenbus.c
--- a/sys/arch/xen/xen/xbd_xenbus.c     Sun Aug 16 17:48:24 2015 +0000
+++ b/sys/arch/xen/xen/xbd_xenbus.c     Sun Aug 16 18:00:03 2015 +0000
@@ -1,4 +1,4 @@
-/*      $NetBSD: xbd_xenbus.c,v 1.71 2015/05/02 08:00:08 mlelstv Exp $      */
+/*      $NetBSD: xbd_xenbus.c,v 1.72 2015/08/16 18:00:03 mlelstv Exp $      */
 
 /*
  * Copyright (c) 2006 Manuel Bouyer.
@@ -40,7 +40,7 @@
  * - initiate request: xbdread/write/open/ioctl/..
  * - depending on operation, it is handled directly by disk(9) subsystem or
  *   goes through physio(9) first.
- * - the request is ultimately processed by xbdstart() that prepares the
+ * - the request is ultimately processed by xbd_diskstart() that prepares the
  *   xbd requests, post them in the ring I/O queue, then signal the backend.
  *
  * When a response is available in the queue, the backend signals the frontend
@@ -50,7 +50,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xbd_xenbus.c,v 1.71 2015/05/02 08:00:08 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xbd_xenbus.c,v 1.72 2015/08/16 18:00:03 mlelstv Exp $");
 
 #include "opt_xen.h"
 
@@ -168,7 +168,7 @@
 static bool xbd_xenbus_resume(device_t, const pmf_qual_t *);
 
 static int  xbd_handler(void *);
-static void xbdstart(device_t);
+static int  xbd_diskstart(device_t, struct buf *);
 static void xbd_backend_changed(void *, XenbusState);
 static void xbd_connect(struct xbd_xenbus_softc *);
 
@@ -223,7 +223,7 @@
        .d_minphys = xbdminphys,
        .d_open = xbdopen,
        .d_close = xbdclose,
-       .d_diskstart = xbdstart,
+       .d_diskstart = xbd_diskstart,
 };
 
 static int
@@ -697,7 +697,7 @@
                        bp->b_resid = bp->b_bcount;
                        goto next;
                }
-               /* b_resid was set in xbdstart */
+               /* b_resid was set in dk_start */
 next:
                if (bp->b_data != xbdreq->req_data)
                        xbd_unmap_align(xbdreq);
@@ -720,7 +720,7 @@
        if (sc->sc_xbdreq_wait)
                wakeup(&sc->sc_xbdreq_wait);
        else
-               xbdstart(sc->sc_dksc.sc_dev);
+               dk_start(&sc->sc_dksc, NULL);
        return 1;
 }
 
@@ -918,156 +918,111 @@
        return dk_dump(&sc->sc_dksc, dev, blkno, va, size);
 }
 
-static void
-xbdstart(device_t self)
+static int
+xbd_diskstart(device_t self, struct buf *bp)
 {
        struct xbd_xenbus_softc *sc = device_private(self);
-       struct dk_softc *dksc = &sc->sc_dksc;
-       struct buf *bp;
-#ifdef DIAGNOSTIC
-       struct  buf *qbp; 
-#endif
        struct xbd_req *xbdreq;
        blkif_request_t *req;
        size_t bcount, off;
        paddr_t ma;
        vaddr_t va;
        int nsects, nbytes, seg;
-       int notify;
+       int notify, error = 0;
 
-       while ((bp = bufq_peek(dksc->sc_bufq)) != NULL) {
-
-               DPRINTF(("xbdstart(%p): b_bcount = %ld\n",
-                   bp, (long)bp->b_bcount));
+       DPRINTF(("xbd_diskstart(%p): b_bcount = %ld\n",
+           bp, (long)bp->b_bcount));
 
-               if (sc->sc_shutdown != BLKIF_SHUTDOWN_RUN) {
-                       bp->b_error = EIO;
-                       goto err;
-               }
+       if (sc->sc_shutdown != BLKIF_SHUTDOWN_RUN) {
+               error = EIO;
+               goto err;
+       }
 
-               if (bp->b_rawblkno < 0 || bp->b_rawblkno > sc->sc_xbdsize) {
-                       /* invalid block number */
-                       bp->b_error = EINVAL;
-                       goto err;
-               }
+       if (bp->b_rawblkno < 0 || bp->b_rawblkno > sc->sc_xbdsize) {
+               /* invalid block number */
+               error = EINVAL;
+               goto err;
+       }
 
-               if (bp->b_rawblkno == sc->sc_xbdsize) {
-                       /* at end of disk; return short read */
-                       bp->b_resid = bp->b_bcount;
-#ifdef DIAGNOSTIC 
-                       qbp = bufq_get(dksc->sc_bufq);
-                       KASSERT(bp == qbp);
-#else
-                       (void)bufq_get(dksc->sc_bufq);
-#endif
-                       biodone(bp);
-                       continue;
-               }
+       if (__predict_false(
+           sc->sc_backend_status == BLKIF_STATE_SUSPENDED)) {
+               /* device is suspended, do not consume buffer */
+               DPRINTF(("%s: (xbd_diskstart) device suspended\n",
+                   sc->sc_dksc.sc_xname));
+               error = EAGAIN;
+               goto out;
+       }
 
-               if (__predict_false(
-                   sc->sc_backend_status == BLKIF_STATE_SUSPENDED)) {
-                       /* device is suspended, do not consume buffer */
-                       DPRINTF(("%s: (xbdstart) device suspended\n",
-                           device_xname(sc->sc_dksc.sc_dev)));
-                       goto out;
-               }
+       if (RING_FULL(&sc->sc_ring) || sc->sc_xbdreq_wait) {
+               DPRINTF(("xbd_diskstart: ring_full\n"));
+               error = EAGAIN;
+               goto out;
+       }
 
-               if (RING_FULL(&sc->sc_ring) || sc->sc_xbdreq_wait) {
-                       DPRINTF(("xbdstart: ring_full\n"));
-                       goto out;
-               }
+       xbdreq = SLIST_FIRST(&sc->sc_xbdreq_head);
+       if (__predict_false(xbdreq == NULL)) {
+               DPRINTF(("xbd_diskstart: no req\n"));
+               error = EAGAIN;
+               goto out;
+       }
 
-               xbdreq = SLIST_FIRST(&sc->sc_xbdreq_head);
-               if (__predict_false(xbdreq == NULL)) {
-                       DPRINTF(("xbdstart: no req\n"));
+       xbdreq->req_bp = bp;
+       xbdreq->req_data = bp->b_data;
+       if ((vaddr_t)bp->b_data & (XEN_BSIZE - 1)) {
+               if (__predict_false(xbd_map_align(xbdreq) != 0)) {
+                       DPRINTF(("xbd_diskstart: no align\n"));
+                       error = EAGAIN;
                        goto out;
                }
+       }
 
-               xbdreq->req_bp = bp;
-               xbdreq->req_data = bp->b_data;
-               if ((vaddr_t)bp->b_data & (XEN_BSIZE - 1)) {
-                       if (__predict_false(xbd_map_align(xbdreq) != 0)) {
-                               DPRINTF(("xbdstart: no align\n"));
-                               goto out;
-                       }
-               }
-               /* now we're sure we'll send this buf */
-#ifdef DIAGNOSTIC 
-               qbp = bufq_get(dksc->sc_bufq);
-               KASSERT(bp == qbp);
-#else
-               (void)bufq_get(dksc->sc_bufq);
-#endif
-               disk_busy(&dksc->sc_dkdev);
-
-               SLIST_REMOVE_HEAD(&sc->sc_xbdreq_head, req_next);
-               req = RING_GET_REQUEST(&sc->sc_ring, sc->sc_ring.req_prod_pvt);
-               req->id = xbdreq->req_id;
-               req->operation =
-                   bp->b_flags & B_READ ? BLKIF_OP_READ : BLKIF_OP_WRITE;
-               req->sector_number = bp->b_rawblkno;
-               req->handle = sc->sc_handle;
+       SLIST_REMOVE_HEAD(&sc->sc_xbdreq_head, req_next);
+       req = RING_GET_REQUEST(&sc->sc_ring, sc->sc_ring.req_prod_pvt);
+       req->id = xbdreq->req_id;
+       req->operation =
+           bp->b_flags & B_READ ? BLKIF_OP_READ : BLKIF_OP_WRITE;
+       req->sector_number = bp->b_rawblkno;
+       req->handle = sc->sc_handle;
 
-               va = (vaddr_t)xbdreq->req_data & ~PAGE_MASK;
-               off = (vaddr_t)xbdreq->req_data & PAGE_MASK;
-               if (bp->b_rawblkno + bp->b_bcount / DEV_BSIZE >=
-                   sc->sc_xbdsize) {
-                       bcount = (sc->sc_xbdsize - bp->b_rawblkno) * DEV_BSIZE;
-                       bp->b_resid = bp->b_bcount - bcount;
-               } else {
-                       bcount = bp->b_bcount;
-                       bp->b_resid = 0;
-               }
-               if (bcount > XBD_MAX_XFER) {
-                       bp->b_resid += bcount - XBD_MAX_XFER;
-                       bcount = XBD_MAX_XFER;
-               }
-               for (seg = 0; bcount > 0;) {
-                       pmap_extract_ma(pmap_kernel(), va, &ma);
-                       KASSERT((ma & (XEN_BSIZE - 1)) == 0);
-                       if (bcount > PAGE_SIZE - off)
-                               nbytes = PAGE_SIZE - off;
-                       else
-                               nbytes = bcount;
-                       nsects = nbytes >> XEN_BSHIFT;
-                       req->seg[seg].first_sect = off >> XEN_BSHIFT;
-                       req->seg[seg].last_sect =
-                           (off >> XEN_BSHIFT) + nsects - 1;
-                       KASSERT(req->seg[seg].first_sect <=
-                           req->seg[seg].last_sect);
-                       KASSERT(req->seg[seg].last_sect < 8);
-                       if (__predict_false(xengnt_grant_access(
-                           sc->sc_xbusd->xbusd_otherend_id, ma,
-                           (bp->b_flags & B_READ) == 0,
-                           &xbdreq->req_gntref[seg])))
-                               panic("xbdstart: xengnt_grant_access"); /* XXX XXX !!! */
-                       req->seg[seg].gref = xbdreq->req_gntref[seg];
-                       seg++;
-                       KASSERT(seg <= BLKIF_MAX_SEGMENTS_PER_REQUEST);
-                       va += PAGE_SIZE;
-                       off = 0;
-                       bcount -= nbytes;
-               }
-               xbdreq->req_nr_segments = req->nr_segments = seg;
-               sc->sc_ring.req_prod_pvt++;
+       va = (vaddr_t)xbdreq->req_data & ~PAGE_MASK;
+       off = (vaddr_t)xbdreq->req_data & PAGE_MASK;
+       bcount = bp->b_bcount;
+       bp->b_resid = 0;
+       for (seg = 0; bcount > 0;) {
+               pmap_extract_ma(pmap_kernel(), va, &ma);
+               KASSERT((ma & (XEN_BSIZE - 1)) == 0);
+               if (bcount > PAGE_SIZE - off)
+                       nbytes = PAGE_SIZE - off;
+               else
+                       nbytes = bcount;
+               nsects = nbytes >> XEN_BSHIFT;
+               req->seg[seg].first_sect = off >> XEN_BSHIFT;
+               req->seg[seg].last_sect =
+                   (off >> XEN_BSHIFT) + nsects - 1;
+               KASSERT(req->seg[seg].first_sect <=
+                   req->seg[seg].last_sect);
+               KASSERT(req->seg[seg].last_sect < 8);
+               if (__predict_false(xengnt_grant_access(
+                   sc->sc_xbusd->xbusd_otherend_id, ma,
+                   (bp->b_flags & B_READ) == 0,
+                   &xbdreq->req_gntref[seg])))
+                       panic("xbd_diskstart: xengnt_grant_access"); /* XXX XXX !!! */
+               req->seg[seg].gref = xbdreq->req_gntref[seg];
+               seg++;
+               KASSERT(seg <= BLKIF_MAX_SEGMENTS_PER_REQUEST);
+               va += PAGE_SIZE;
+               off = 0;
+               bcount -= nbytes;
        }
+       xbdreq->req_nr_segments = req->nr_segments = seg;
+       sc->sc_ring.req_prod_pvt++;
 
 out:
        RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&sc->sc_ring, notify);
        if (notify)
                hypervisor_notify_via_evtchn(sc->sc_evtchn);
-       return;
-
 err:
-#ifdef DIAGNOSTIC 
-       qbp = bufq_get(dksc->sc_bufq);
-       KASSERT(bp == qbp);
-#else
-       (void)bufq_get(dksc->sc_bufq);
-#endif
-       bp->b_resid = bp->b_bcount;
-       biodone(bp);
-       return;
+       return error;
 }
 
 static int
diff -r 6a4c571f4156 -r 39ccd7cb4665 sys/dev/cgd.c



Home | Main Index | Thread Index | Old Index