kernel -- virtio: Implement virtio-layer lwkt_serializer for devices
authorVenkatesh Srinivas <me@endeavour.zapto.org>
Sat, 19 Jan 2013 09:43:03 +0000 (01:43 -0800)
committerSamuel J. Greear <sjg@thesjg.com>
Thu, 24 Jan 2013 06:44:57 +0000 (23:44 -0700)
* Switch virtio device targets (currently only -blk) to use a
  serializer for synchronizing per-target state. Thread the
  serializer through virtqueue_notify (release around kick) and
  into the bus interrupt setup code.

* Remove dump support from virtio-blk for now; it doesn't work and
  results in further panics from an incorrectly setup bio.

* Other cleanups of virtio-blk (de-indirect locks).

sys/dev/virtual/virtio/block/virtio_blk.c
sys/dev/virtual/virtio/pci/virtio_pci.c
sys/dev/virtual/virtio/virtio/virtio.c
sys/dev/virtual/virtio/virtio/virtio.h
sys/dev/virtual/virtio/virtio/virtio_bus_if.m
sys/dev/virtual/virtio/virtio/virtqueue.c
sys/dev/virtual/virtio/virtio/virtqueue.h

index 68680dc..0fbe745 100644 (file)
 #include <sys/sglist.h>
 #include <sys/lock.h>
 #include <sys/queue.h>
 #include <sys/sglist.h>
 #include <sys/lock.h>
 #include <sys/queue.h>
-#include <sys/taskqueue.h>
-
+#include <sys/serialize.h>
 #include <sys/buf2.h>
 #include <sys/rman.h>
 #include <sys/disk.h>
 #include <sys/buf2.h>
 #include <sys/rman.h>
 #include <sys/disk.h>
-#include <sys/spinlock.h>
-#include <sys/spinlock2.h>
 #include <sys/devicestat.h>
 
 #include <dev/virtual/virtio/virtio/virtio.h>
 #include <sys/devicestat.h>
 
 #include <dev/virtual/virtio/virtio/virtio.h>
@@ -62,13 +59,12 @@ struct vtblk_request {
 
 struct vtblk_softc {
        device_t                        vtblk_dev;
 
 struct vtblk_softc {
        device_t                        vtblk_dev;
-       struct spinlock                 vtblk_mtx;
+       struct lwkt_serialize           vtblk_slz;
        uint64_t                        vtblk_features;
 
 #define VTBLK_FLAG_READONLY            0x0002
 #define VTBLK_FLAG_DETACH              0x0004
 #define VTBLK_FLAG_SUSPEND             0x0008
        uint64_t                        vtblk_features;
 
 #define VTBLK_FLAG_READONLY            0x0002
 #define VTBLK_FLAG_DETACH              0x0004
 #define VTBLK_FLAG_SUSPEND             0x0008
-#define VTBLK_FLAG_DUMPING             0x0010
        uint32_t                        vtblk_flags;
 
        struct virtqueue                *vtblk_vq;
        uint32_t                        vtblk_flags;
 
        struct virtqueue                *vtblk_vq;
@@ -81,8 +77,6 @@ struct vtblk_softc {
        TAILQ_HEAD(, vtblk_request)     vtblk_req_free;
        TAILQ_HEAD(, vtblk_request)     vtblk_req_ready;
 
        TAILQ_HEAD(, vtblk_request)     vtblk_req_free;
        TAILQ_HEAD(, vtblk_request)     vtblk_req_ready;
 
-       struct task                     vtblk_intr_task;
-
        int                             vtblk_sector_size;
        int                             vtblk_max_nsegs;
        int                             vtblk_unit;
        int                             vtblk_sector_size;
        int                             vtblk_max_nsegs;
        int                             vtblk_unit;
@@ -137,22 +131,15 @@ static struct dev_ops vbd_disk_ops = {
        .d_dump         = vtblk_dump,
 };
 
        .d_dump         = vtblk_dump,
 };
 
-static void            vtblk_startio(struct vtblk_softc *);
+static void vtblk_startio(struct vtblk_softc *);
 static struct vtblk_request *vtblk_bio_request(struct vtblk_softc *);
 static struct vtblk_request *vtblk_bio_request(struct vtblk_softc *);
-static int             vtblk_execute_request(struct vtblk_softc *,
-                                             struct vtblk_request *);
+static int vtblk_execute_request(struct vtblk_softc *, struct vtblk_request *);
 
 static int             vtblk_vq_intr(void *);
 
 static int             vtblk_vq_intr(void *);
-static void            vtblk_complete(void *, int);
+static void            vtblk_complete(void *);
 
 static void            vtblk_stop(struct vtblk_softc *);
 
 
 static void            vtblk_stop(struct vtblk_softc *);
 
-static void            vtblk_prepare_dump(struct vtblk_softc *);
-static int             vtblk_write_dump(struct vtblk_softc *, void *, off_t, size_t);
-static int             vtblk_flush_dump(struct vtblk_softc *);
-static int             vtblk_poll_request(struct vtblk_softc *,
-                                          struct vtblk_request *);
-
 static void            vtblk_drain_vq(struct vtblk_softc *, int);
 static void            vtblk_drain(struct vtblk_softc *);
 
 static void            vtblk_drain_vq(struct vtblk_softc *, int);
 static void            vtblk_drain(struct vtblk_softc *);
 
@@ -182,16 +169,6 @@ TUNABLE_INT("hw.vtblk.no_ident", &vtblk_no_ident);
      VIRTIO_BLK_F_BLK_SIZE             | \
      VIRTIO_BLK_F_FLUSH)
 
      VIRTIO_BLK_F_BLK_SIZE             | \
      VIRTIO_BLK_F_FLUSH)
 
-#define VTBLK_MTX(_sc)         &(_sc)->vtblk_mtx
-#define VTBLK_LOCK_INIT(_sc)   spin_init(&(_sc)->vtblk_mtx)
-#define VTBLK_LOCK(_sc)                spin_lock(VTBLK_MTX((_sc)))
-#define VTBLK_TRYLOCK(_sc)     spin_trylock(VTBLK_MTX((_sc)))
-#define VTBLK_UNLOCK(_sc)      spin_unlock(VTBLK_MTX((_sc)))
-#define VTBLK_LOCK_DESTROY(_sc)        spin_uninit(VTBLK_MTX((_sc)))
-
-#define VTBLK_LOCK_ASSERT(_sc)
-#define VTBLK_LOCK_ASSERT_NOTOWNED(_sc)
-
 /*
  * Each block request uses at least two segments - one for the header
  * and one for the status.
 /*
  * Each block request uses at least two segments - one for the header
  * and one for the status.
@@ -267,7 +244,7 @@ vtblk_attach(device_t dev)
        sc->vtblk_dev = dev;
        sc->vtblk_unit = device_get_unit(dev);
 
        sc->vtblk_dev = dev;
        sc->vtblk_unit = device_get_unit(dev);
 
-       VTBLK_LOCK_INIT(sc);
+       lwkt_serialize_init(&sc->vtblk_slz);
 
        bioq_init(&sc->vtblk_bioq);
        TAILQ_INIT(&sc->vtblk_req_free);
 
        bioq_init(&sc->vtblk_bioq);
        TAILQ_INIT(&sc->vtblk_req_free);
@@ -331,9 +308,7 @@ vtblk_attach(device_t dev)
 
        vtblk_alloc_disk(sc, &blkcfg);
 
 
        vtblk_alloc_disk(sc, &blkcfg);
 
-       TASK_INIT(&sc->vtblk_intr_task, 0, vtblk_complete, sc);
-
-       error = virtio_setup_intr(dev);
+       error = virtio_setup_intr(dev, &sc->vtblk_slz);
        if (error) {
                device_printf(dev, "cannot setup virtqueue interrupt\n");
                goto fail;
        if (error) {
                device_printf(dev, "cannot setup virtqueue interrupt\n");
                goto fail;
@@ -355,13 +330,11 @@ vtblk_detach(device_t dev)
 
        sc = device_get_softc(dev);
 
 
        sc = device_get_softc(dev);
 
-       VTBLK_LOCK(sc);
+       lwkt_serialize_enter(&sc->vtblk_slz);
        sc->vtblk_flags |= VTBLK_FLAG_DETACH;
        if (device_is_attached(dev))
                vtblk_stop(sc);
        sc->vtblk_flags |= VTBLK_FLAG_DETACH;
        if (device_is_attached(dev))
                vtblk_stop(sc);
-       VTBLK_UNLOCK(sc);
-
-       taskqueue_drain(taskqueue_thread[mycpuid], &sc->vtblk_intr_task);
+       lwkt_serialize_exit(&sc->vtblk_slz);
 
        vtblk_drain(sc);
 
 
        vtblk_drain(sc);
 
@@ -370,8 +343,6 @@ vtblk_detach(device_t dev)
                sc->vtblk_sglist = NULL;
        }
 
                sc->vtblk_sglist = NULL;
        }
 
-       VTBLK_LOCK_DESTROY(sc);
-
        return (0);
 }
 
        return (0);
 }
 
@@ -382,10 +353,10 @@ vtblk_suspend(device_t dev)
 
        sc = device_get_softc(dev);
 
 
        sc = device_get_softc(dev);
 
-       VTBLK_LOCK(sc);
+       lwkt_serialize_enter(&sc->vtblk_slz);
        sc->vtblk_flags |= VTBLK_FLAG_SUSPEND;
        /* TODO Wait for any inflight IO to complete? */
        sc->vtblk_flags |= VTBLK_FLAG_SUSPEND;
        /* TODO Wait for any inflight IO to complete? */
-       VTBLK_UNLOCK(sc);
+       lwkt_serialize_exit(&sc->vtblk_slz);
 
        return (0);
 }
 
        return (0);
 }
@@ -397,10 +368,10 @@ vtblk_resume(device_t dev)
 
        sc = device_get_softc(dev);
 
 
        sc = device_get_softc(dev);
 
-       VTBLK_LOCK(sc);
+       lwkt_serialize_enter(&sc->vtblk_slz);
        sc->vtblk_flags &= ~VTBLK_FLAG_SUSPEND;
        /* TODO Resume IO? */
        sc->vtblk_flags &= ~VTBLK_FLAG_SUSPEND;
        /* TODO Resume IO? */
-       VTBLK_UNLOCK(sc);
+       lwkt_serialize_exit(&sc->vtblk_slz);
 
        return (0);
 }
 
        return (0);
 }
@@ -434,30 +405,7 @@ vtblk_dump(struct dev_dump_args *ap)
        cdev_t dev = ap->a_head.a_dev;
        sc = dev->si_drv1;
 
        cdev_t dev = ap->a_head.a_dev;
        sc = dev->si_drv1;
 
-       if (sc == NULL)
-               return (ENXIO);
-
-       if (VTBLK_TRYLOCK(sc) == 0) {
-               device_printf(sc->vtblk_dev,
-                   "softc already locked, cannot dump...\n");
-               return (EBUSY);
-       }
-
-       if ((sc->vtblk_flags & VTBLK_FLAG_DUMPING) == 0) {
-               vtblk_prepare_dump(sc);
-               sc->vtblk_flags |= VTBLK_FLAG_DUMPING;
-       }
-
-       if (ap->a_length > 0) {
-               error = vtblk_write_dump(sc, ap->a_virtual, ap->a_offset,
-                                        ap->a_length);
-       } else if (ap->a_virtual == NULL && ap->a_offset == 0) {
-               error = vtblk_flush_dump(sc);
-       }
-
-       VTBLK_UNLOCK(sc);
-
-       return (error);
+       return (ENXIO);
 }
 
 static int
 }
 
 static int
@@ -486,7 +434,7 @@ vtblk_strategy(struct dev_strategy_args *ap)
                return (EINVAL);
        }
 
                return (EINVAL);
        }
 
-       VTBLK_LOCK(sc);
+       lwkt_serialize_enter(&sc->vtblk_slz);
        if ((sc->vtblk_flags & VTBLK_FLAG_DETACH) == 0) {
                devstat_start_transaction(&sc->stats);
                bioqdisksort(&sc->vtblk_bioq, bio);
        if ((sc->vtblk_flags & VTBLK_FLAG_DETACH) == 0) {
                devstat_start_transaction(&sc->stats);
                bioqdisksort(&sc->vtblk_bioq, bio);
@@ -494,7 +442,7 @@ vtblk_strategy(struct dev_strategy_args *ap)
        } else {
                vtblk_bio_error(bio, ENXIO);
        }
        } else {
                vtblk_bio_error(bio, ENXIO);
        }
-       VTBLK_UNLOCK(sc);
+       lwkt_serialize_exit(&sc->vtblk_slz);
        return 0;
 }
 
        return 0;
 }
 
@@ -589,8 +537,8 @@ vtblk_startio(struct vtblk_softc *sc)
        vq = sc->vtblk_vq;
        enq = 0;
 
        vq = sc->vtblk_vq;
        enq = 0;
 
-       VTBLK_LOCK_ASSERT(sc);
-
+       ASSERT_SERIALIZED(&sc->vtblk_slz);
+       
        if (sc->vtblk_flags & VTBLK_FLAG_SUSPEND)
                return;
 
        if (sc->vtblk_flags & VTBLK_FLAG_SUSPEND)
                return;
 
@@ -609,7 +557,7 @@ vtblk_startio(struct vtblk_softc *sc)
        }
 
        if (enq > 0)
        }
 
        if (enq > 0)
-               virtqueue_notify(vq, &sc->vtblk_mtx);
+               virtqueue_notify(vq, &sc->vtblk_slz);
 }
 
 static struct vtblk_request *
 }
 
 static struct vtblk_request *
@@ -710,18 +658,13 @@ vtblk_execute_request(struct vtblk_softc *sc, struct vtblk_request *req)
 static int
 vtblk_vq_intr(void *xsc)
 {
 static int
 vtblk_vq_intr(void *xsc)
 {
-       struct vtblk_softc *sc;
-
-       sc = xsc;
-
-       virtqueue_disable_intr(sc->vtblk_vq);
-       taskqueue_enqueue(taskqueue_thread[mycpuid], &sc->vtblk_intr_task);
+       vtblk_complete(xsc);
 
        return (1);
 }
 
 static void
 
        return (1);
 }
 
 static void
-vtblk_complete(void *arg, int pending)
+vtblk_complete(void *arg)
 {
        struct vtblk_softc *sc;
        struct vtblk_request *req;
 {
        struct vtblk_softc *sc;
        struct vtblk_request *req;
@@ -732,12 +675,13 @@ vtblk_complete(void *arg, int pending)
        sc = arg;
        vq = sc->vtblk_vq;
 
        sc = arg;
        vq = sc->vtblk_vq;
 
+       lwkt_serialize_handler_disable(&sc->vtblk_slz);
+       virtqueue_disable_intr(sc->vtblk_vq);
+       ASSERT_SERIALIZED(&sc->vtblk_slz);
+
 retry:
 retry:
-       VTBLK_LOCK(sc);
-       if (sc->vtblk_flags & VTBLK_FLAG_DETACH) {
-               VTBLK_UNLOCK(sc);
+       if (sc->vtblk_flags & VTBLK_FLAG_DETACH)
                return;
                return;
-       }
 
        while ((req = virtqueue_dequeue(vq, NULL)) != NULL) {
                bio = req->vbr_bp;
 
        while ((req = virtqueue_dequeue(vq, NULL)) != NULL) {
                bio = req->vbr_bp;
@@ -756,15 +700,15 @@ retry:
 
                devstat_end_transaction_buf(&sc->stats, bio->bio_buf);
 
 
                devstat_end_transaction_buf(&sc->stats, bio->bio_buf);
 
-               VTBLK_UNLOCK(sc);
+               lwkt_serialize_exit(&sc->vtblk_slz);
                /*
                 * Unlocking the controller around biodone() does not allow
                 * processing further device interrupts; when we queued
                /*
                 * Unlocking the controller around biodone() does not allow
                 * processing further device interrupts; when we queued
-                * vtblk_intr_task, we disabled interrupts. It will allow
+                * vtblk_complete, we disabled interrupts. It will allow
                 * concurrent vtblk_strategy/_startio command dispatches.
                 */
                biodone(bio);
                 * concurrent vtblk_strategy/_startio command dispatches.
                 */
                biodone(bio);
-               VTBLK_LOCK(sc);
+               lwkt_serialize_enter(&sc->vtblk_slz);
 
                vtblk_enqueue_request(sc, req);
        }
 
                vtblk_enqueue_request(sc, req);
        }
@@ -779,11 +723,9 @@ retry:
                 * I/O dispatch for too long.
                 */
                virtqueue_disable_intr(vq);
                 * I/O dispatch for too long.
                 */
                virtqueue_disable_intr(vq);
-               VTBLK_UNLOCK(sc);
                goto retry;
        }
                goto retry;
        }
-
-       VTBLK_UNLOCK(sc);
+       lwkt_serialize_handler_enable(&sc->vtblk_slz);
 }
 
 static void
 }
 
 static void
@@ -794,112 +736,6 @@ vtblk_stop(struct vtblk_softc *sc)
 }
 
 static void
 }
 
 static void
-vtblk_prepare_dump(struct vtblk_softc *sc)
-{
-       device_t dev;
-       struct virtqueue *vq;
-
-       dev = sc->vtblk_dev;
-       vq = sc->vtblk_vq;
-
-       vtblk_stop(sc);
-
-       /*
-        * Drain all requests caught in-flight in the virtqueue,
-        * skipping biodone(). When dumping, only one request is
-        * outstanding at a time, and we just poll the virtqueue
-        * for the response.
-        */
-       vtblk_drain_vq(sc, 1);
-
-       if (virtio_reinit(dev, sc->vtblk_features) != 0)
-               panic("cannot reinit VirtIO block device during dump");
-
-       virtqueue_disable_intr(vq);
-       virtio_reinit_complete(dev);
-}
-
-static int
-vtblk_write_dump(struct vtblk_softc *sc, void *virtual, off_t offset,
-                size_t length)
-{
-       struct bio bio;
-       struct vtblk_request *req;
-       struct buf *bp;
-
-       req = &sc->vtblk_dump_request;
-       req->vbr_ack = -1;
-       req->vbr_hdr.type = VIRTIO_BLK_T_OUT;
-       req->vbr_hdr.ioprio = 1;
-       req->vbr_hdr.sector = offset / DEV_BSIZE;
-
-       req->vbr_bp = &bio;
-       bzero(&buf, sizeof(struct bio));
-       bp = bio.bio_buf;
-
-       bp->b_cmd = BUF_CMD_WRITE;
-       bp->b_data = virtual;
-       bp->b_bcount = length;
-
-       return (vtblk_poll_request(sc, req));
-}
-
-static int
-vtblk_flush_dump(struct vtblk_softc *sc)
-{
-       struct bio bio;
-       struct vtblk_request *req;
-       struct buf *bp;
-
-       req = &sc->vtblk_dump_request;
-       req->vbr_ack = -1;
-       req->vbr_hdr.type = VIRTIO_BLK_T_FLUSH;
-       req->vbr_hdr.ioprio = 1;
-       req->vbr_hdr.sector = 0;
-
-       req->vbr_bp = &bio;
-       bzero(&buf, sizeof(struct bio));
-       bp = bio.bio_buf;
-       
-       bp->b_cmd = BUF_CMD_FLUSH;
-
-       return (vtblk_poll_request(sc, req));
-}
-
-static int
-vtblk_poll_request(struct vtblk_softc *sc, struct vtblk_request *req)
-{
-       device_t dev;
-       struct virtqueue *vq;
-       struct vtblk_request *r __debugvar;
-       int error;
-
-       dev = sc->vtblk_dev;
-       vq = sc->vtblk_vq;
-
-       if (!virtqueue_empty(vq))
-               return (EBUSY);
-
-       error = vtblk_execute_request(sc, req);
-       if (error)
-               return (error);
-
-       virtqueue_notify(vq, &sc->vtblk_mtx);
-
-       r = virtqueue_poll(vq, NULL);
-       KASSERT(r == req, ("unexpected request response"));
-
-       if (req->vbr_ack != VIRTIO_BLK_S_OK) {
-               error = req->vbr_ack == VIRTIO_BLK_S_UNSUPP ? ENOTSUP : EIO;
-               if (bootverbose)
-                       device_printf(dev,
-                           "vtblk_poll_request: IO error: %d\n", error);
-       }
-
-       return (error);
-}
-
-static void
 vtblk_drain_vq(struct vtblk_softc *sc, int skip_done)
 {
        struct virtqueue *vq;
 vtblk_drain_vq(struct vtblk_softc *sc, int skip_done)
 {
        struct virtqueue *vq;
index ad33037..12963dc 100644 (file)
@@ -36,6 +36,7 @@
 #include <sys/kernel.h>
 #include <sys/module.h>
 #include <sys/malloc.h>
 #include <sys/kernel.h>
 #include <sys/module.h>
 #include <sys/malloc.h>
+#include <sys/serialize.h>
 
 #include <bus/pci/pcivar.h>
 #include <bus/pci/pcireg.h>
 
 #include <bus/pci/pcivar.h>
 #include <bus/pci/pcireg.h>
@@ -117,7 +118,7 @@ static uint64_t     vtpci_negotiate_features(device_t, uint64_t);
 static int     vtpci_with_feature(device_t, uint64_t);
 static int     vtpci_alloc_virtqueues(device_t, int, int,
                    struct vq_alloc_info *);
 static int     vtpci_with_feature(device_t, uint64_t);
 static int     vtpci_alloc_virtqueues(device_t, int, int,
                    struct vq_alloc_info *);
-static int     vtpci_setup_intr(device_t);
+static int     vtpci_setup_intr(device_t, lwkt_serialize_t);
 static void    vtpci_stop(device_t);
 static int     vtpci_reinit(device_t, uint64_t);
 static void    vtpci_reinit_complete(device_t);
 static void    vtpci_stop(device_t);
 static int     vtpci_reinit(device_t, uint64_t);
 static void    vtpci_reinit_complete(device_t);
@@ -498,7 +499,7 @@ vtpci_alloc_virtqueues(device_t dev, int flags, int nvqs,
 }
 
 static int
 }
 
 static int
-vtpci_setup_intr(device_t dev)
+vtpci_setup_intr(device_t dev, lwkt_serialize_t slz)
 {
        struct vtpci_softc *sc;
        struct vtpci_intr_resource *ires;
 {
        struct vtpci_softc *sc;
        struct vtpci_intr_resource *ires;
@@ -511,20 +512,22 @@ vtpci_setup_intr(device_t dev)
 
        if ((sc->vtpci_flags & VIRTIO_PCI_FLAG_MSIX) == 0) {
                error = bus_setup_intr(dev, ires->irq, flags,
 
        if ((sc->vtpci_flags & VIRTIO_PCI_FLAG_MSIX) == 0) {
                error = bus_setup_intr(dev, ires->irq, flags,
-               (driver_intr_t *)    vtpci_legacy_intr, sc, &ires->intrhand, NULL);
-
+                                      (driver_intr_t *) vtpci_legacy_intr,
+                                      sc, &ires->intrhand, slz);
                return (error);
        }
 
                return (error);
        }
 
-       error = bus_setup_intr(dev, ires->irq, flags,(driver_intr_t *) vtpci_config_intr,
-            sc, &ires->intrhand, NULL);
+       error = bus_setup_intr(dev, ires->irq, flags,
+                              (driver_intr_t *) vtpci_config_intr,
+                              sc, &ires->intrhand, slz);
        if (error)
                return (error);
 
        if (sc->vtpci_flags & VIRTIO_PCI_FLAG_SHARED_MSIX) {
                ires = &sc->vtpci_intr_res[1];
                error = bus_setup_intr(dev, ires->irq, flags,
        if (error)
                return (error);
 
        if (sc->vtpci_flags & VIRTIO_PCI_FLAG_SHARED_MSIX) {
                ires = &sc->vtpci_intr_res[1];
                error = bus_setup_intr(dev, ires->irq, flags,
-                (driver_intr_t *)   vtpci_vq_shared_intr, sc, &ires->intrhand, NULL);
+                                      (driver_intr_t *) vtpci_vq_shared_intr,
+                                      sc, &ires->intrhand, slz);
 
                return (error);
        }
 
                return (error);
        }
@@ -537,7 +540,8 @@ vtpci_setup_intr(device_t dev)
 
                ires = &sc->vtpci_intr_res[vqx->ires_idx];
                error = bus_setup_intr(dev, ires->irq, flags,
 
                ires = &sc->vtpci_intr_res[vqx->ires_idx];
                error = bus_setup_intr(dev, ires->irq, flags,
-                 (driver_intr_t *)  vtpci_vq_intr, vqx->vq, &ires->intrhand, NULL);
+                                      (driver_intr_t *) vtpci_vq_intr,
+                                      vqx->vq, &ires->intrhand, slz);
                if (error)
                        return (error);
        }
                if (error)
                        return (error);
        }
@@ -548,7 +552,6 @@ vtpci_setup_intr(device_t dev)
 static void
 vtpci_stop(device_t dev)
 {
 static void
 vtpci_stop(device_t dev)
 {
-
        vtpci_reset(device_get_softc(dev));
 }
 
        vtpci_reset(device_get_softc(dev));
 }
 
index ec8fcb3..b18e311 100644 (file)
@@ -35,6 +35,7 @@
 
 #include <machine/inttypes.h>
 #include <sys/bus.h>
 
 #include <machine/inttypes.h>
 #include <sys/bus.h>
+#include <sys/serialize.h>
 #include <sys/rman.h>
 
 #include "virtio.h"
 #include <sys/rman.h>
 
 #include "virtio.h"
@@ -154,12 +155,8 @@ virtio_describe(device_t dev, const char *msg,
        if (n > 0)
                sbuf_cat(&sb, ">");
 
        if (n > 0)
                sbuf_cat(&sb, ">");
 
-#if __FreeBSD_version < 900020
-       sbuf_finish(&sb);
-       if (sbuf_overflowed(&sb) == 0)
-#else
-       if (sbuf_finish(&sb) == 0)
-#endif
+       sbuf_finish(&sb);
+       if (sbuf_overflowed(&sb) == 0)
                device_printf(dev, "%s\n", sbuf_data(&sb));
 
        sbuf_delete(&sb);
                device_printf(dev, "%s\n", sbuf_data(&sb));
 
        sbuf_delete(&sb);
@@ -185,69 +182,60 @@ virtio_feature_name(uint64_t val, struct virtio_feature_desc *feature_desc)
 uint64_t
 virtio_negotiate_features(device_t dev, uint64_t child_features)
 {
 uint64_t
 virtio_negotiate_features(device_t dev, uint64_t child_features)
 {
-
        return (VIRTIO_BUS_NEGOTIATE_FEATURES(device_get_parent(dev),
        return (VIRTIO_BUS_NEGOTIATE_FEATURES(device_get_parent(dev),
-           child_features));
+               child_features));
 }
 
 int
 virtio_alloc_virtqueues(device_t dev, int flags, int nvqs,
     struct vq_alloc_info *info)
 {
 }
 
 int
 virtio_alloc_virtqueues(device_t dev, int flags, int nvqs,
     struct vq_alloc_info *info)
 {
-
        return (VIRTIO_BUS_ALLOC_VIRTQUEUES(device_get_parent(dev), flags,
        return (VIRTIO_BUS_ALLOC_VIRTQUEUES(device_get_parent(dev), flags,
-           nvqs, info));
+               nvqs, info));
 }
 
 int
 }
 
 int
-virtio_setup_intr(device_t dev)
+virtio_setup_intr(device_t dev, lwkt_serialize_t slz)
 {
 {
-
-       return (VIRTIO_BUS_SETUP_INTR(device_get_parent(dev)));
+       return (VIRTIO_BUS_SETUP_INTR(device_get_parent(dev), slz));
 }
 
 int
 virtio_with_feature(device_t dev, uint64_t feature)
 {
 }
 
 int
 virtio_with_feature(device_t dev, uint64_t feature)
 {
-
        return (VIRTIO_BUS_WITH_FEATURE(device_get_parent(dev), feature));
 }
 
 void
 virtio_stop(device_t dev)
 {
        return (VIRTIO_BUS_WITH_FEATURE(device_get_parent(dev), feature));
 }
 
 void
 virtio_stop(device_t dev)
 {
-
        VIRTIO_BUS_STOP(device_get_parent(dev));
 }
 
 int
 virtio_reinit(device_t dev, uint64_t features)
 {
        VIRTIO_BUS_STOP(device_get_parent(dev));
 }
 
 int
 virtio_reinit(device_t dev, uint64_t features)
 {
-
        return (VIRTIO_BUS_REINIT(device_get_parent(dev), features));
 }
 
 void
 virtio_reinit_complete(device_t dev)
 {
        return (VIRTIO_BUS_REINIT(device_get_parent(dev), features));
 }
 
 void
 virtio_reinit_complete(device_t dev)
 {
-
        VIRTIO_BUS_REINIT_COMPLETE(device_get_parent(dev));
 }
 
 void
 virtio_read_device_config(device_t dev, bus_size_t offset, void *dst, int len)
 {
        VIRTIO_BUS_REINIT_COMPLETE(device_get_parent(dev));
 }
 
 void
 virtio_read_device_config(device_t dev, bus_size_t offset, void *dst, int len)
 {
-
        VIRTIO_BUS_READ_DEVICE_CONFIG(device_get_parent(dev),
        VIRTIO_BUS_READ_DEVICE_CONFIG(device_get_parent(dev),
-           offset, dst, len);
+                                     offset, dst, len);
 }
 
 void
 virtio_write_device_config(device_t dev, bus_size_t offset, void *dst, int len)
 {
 }
 
 void
 virtio_write_device_config(device_t dev, bus_size_t offset, void *dst, int len)
 {
-
        VIRTIO_BUS_WRITE_DEVICE_CONFIG(device_get_parent(dev),
        VIRTIO_BUS_WRITE_DEVICE_CONFIG(device_get_parent(dev),
-           offset, dst, len);
+                                      offset, dst, len);
 }
 
 static int
 }
 
 static int
@@ -259,7 +247,6 @@ virtio_modevent(module_t mod, int type, void *unused)
 
        switch (type) {
        case MOD_LOAD:
 
        switch (type) {
        case MOD_LOAD:
-       //case MOD_QUIESCE:
        case MOD_UNLOAD:
        case MOD_SHUTDOWN:
                break;
        case MOD_UNLOAD:
        case MOD_SHUTDOWN:
                break;
index f859e19..58f2693 100644 (file)
@@ -32,6 +32,7 @@
 #define _VIRTIO_H_
 
 #include <sys/types.h>
 #define _VIRTIO_H_
 
 #include <sys/types.h>
+#include <sys/serialize.h>
 
 struct vq_alloc_info;
 
 
 struct vq_alloc_info;
 
@@ -100,7 +101,7 @@ void         virtio_describe(device_t dev, const char *msg,
 uint64_t virtio_negotiate_features(device_t dev, uint64_t child_features);
 int     virtio_alloc_virtqueues(device_t dev, int flags, int nvqs,
             struct vq_alloc_info *info);
 uint64_t virtio_negotiate_features(device_t dev, uint64_t child_features);
 int     virtio_alloc_virtqueues(device_t dev, int flags, int nvqs,
             struct vq_alloc_info *info);
-int     virtio_setup_intr(device_t dev);
+int     virtio_setup_intr(device_t dev, lwkt_serialize_t);
 int     virtio_with_feature(device_t dev, uint64_t feature);
 void    virtio_stop(device_t dev);
 int     virtio_reinit(device_t dev, uint64_t features);
 int     virtio_with_feature(device_t dev, uint64_t feature);
 void    virtio_stop(device_t dev);
 int     virtio_reinit(device_t dev, uint64_t features);
index b9a3872..657dd17 100644 (file)
@@ -54,37 +54,38 @@ HEADER {
 };
 
 METHOD int setup_intr {
 };
 
 METHOD int setup_intr {
-       device_t        dev;
+       device_t                dev;
+       lwkt_serialize_t        slz;
 };
 
 METHOD void stop {
 };
 
 METHOD void stop {
-       device_t        dev;
+       device_t                dev;
 };
 
 METHOD int reinit {
 };
 
 METHOD int reinit {
-       device_t        dev;
-       uint64_t        features;
+       device_t                dev;
+       uint64_t                features;
 };
 
 METHOD void reinit_complete {
 };
 
 METHOD void reinit_complete {
-       device_t        dev;
+       device_t                dev;
 };
 
 METHOD void notify_vq {
 };
 
 METHOD void notify_vq {
-       device_t        dev;
-       uint16_t        queue;
+       device_t                dev;
+       uint16_t                queue;
 };
 
 METHOD void read_device_config {
 };
 
 METHOD void read_device_config {
-       device_t        dev;
-       bus_size_t      offset;
-       void            *dst;
-       int             len;
+       device_t                dev;
+       bus_size_t              offset;
+       void                    *dst;
+       int                     len;
 };
 
 METHOD void write_device_config {
 };
 
 METHOD void write_device_config {
-       device_t        dev;
-       bus_size_t      offset;
-       void            *src;
-       int             len;
+       device_t                dev;
+       bus_size_t              offset;
+       void                    *src;
+       int                     len;
 };
 };
index 511efa3..b1f6f7e 100644 (file)
 #include <sys/kernel.h>
 #include <sys/malloc.h>
 #include <sys/sglist.h>
 #include <sys/kernel.h>
 #include <sys/malloc.h>
 #include <sys/sglist.h>
+#include <sys/serialize.h>
 #include <vm/vm.h>
 #include <vm/pmap.h>
 #include <vm/vm.h>
 #include <vm/pmap.h>
-#include <sys/spinlock.h>
-#include <sys/spinlock2.h>
 
 #include <machine/cpu.h>
 #include <machine/atomic.h>
 
 #include <machine/cpu.h>
 #include <machine/atomic.h>
@@ -279,15 +278,15 @@ virtqueue_full(struct virtqueue *vq)
 }
 
 void
 }
 
 void
-virtqueue_notify(struct virtqueue *vq, struct spinlock *interlock)
+virtqueue_notify(struct virtqueue *vq, lwkt_serialize_t interlock)
 {
        /* Ensure updated avail->idx is visible to host. */
        cpu_mfence();
 
        if (vq_ring_must_notify_host(vq)) {
 {
        /* Ensure updated avail->idx is visible to host. */
        cpu_mfence();
 
        if (vq_ring_must_notify_host(vq)) {
-               spin_unlock(interlock);
+               lwkt_serialize_exit(interlock);
                vq_ring_notify_host(vq);
                vq_ring_notify_host(vq);
-               spin_lock(interlock);
+               lwkt_serialize_enter(interlock);
        }
        vq->vq_queued_cnt = 0;
 }
        }
        vq->vq_queued_cnt = 0;
 }
index ceaa0e6..978ab7d 100644 (file)
 #define _VIRTIO_VIRTQUEUE_H
 
 #include <sys/types.h>
 #define _VIRTIO_VIRTQUEUE_H
 
 #include <sys/types.h>
+#include <sys/serialize.h>
 
 struct virtqueue;
 struct sglist;
 
 struct virtqueue;
 struct sglist;
-struct spinlock;
 
 /* The guest publishes the used index for which it expects an interrupt
  * at the end of the avail ring. Host should ignore the avail->flags field.
 
 /* The guest publishes the used index for which it expects an interrupt
  * at the end of the avail ring. Host should ignore the avail->flags field.
@@ -84,7 +84,7 @@ int    virtqueue_full(struct virtqueue *vq);
 int     virtqueue_empty(struct virtqueue *vq);
 int     virtqueue_size(struct virtqueue *vq);
 int     virtqueue_nused(struct virtqueue *vq);
 int     virtqueue_empty(struct virtqueue *vq);
 int     virtqueue_size(struct virtqueue *vq);
 int     virtqueue_nused(struct virtqueue *vq);
-void    virtqueue_notify(struct virtqueue *vq, struct spinlock *);
+void    virtqueue_notify(struct virtqueue *vq, lwkt_serialize_t);
 void    virtqueue_dump(struct virtqueue *vq);
 
 int     virtqueue_enqueue(struct virtqueue *vq, void *cookie,
 void    virtqueue_dump(struct virtqueue *vq);
 
 int     virtqueue_enqueue(struct virtqueue *vq, void *cookie,