Page MenuHomeFreeBSD

D20703.id58810.diff
No OneTemporary

D20703.id58810.diff

Index: sys/dev/virtio/mmio/virtio_mmio.c
===================================================================
--- sys/dev/virtio/mmio/virtio_mmio.c
+++ sys/dev/virtio/mmio/virtio_mmio.c
@@ -161,6 +161,7 @@
DEVMETHOD(virtio_bus_notify_vq, vtmmio_notify_virtqueue),
DEVMETHOD(virtio_bus_read_device_config, vtmmio_read_dev_config),
DEVMETHOD(virtio_bus_write_device_config, vtmmio_write_dev_config),
+ DEVMETHOD(virtio_bus_virtqueue_size, vtmmio_virtqueue_size),
DEVMETHOD_END
};
@@ -404,6 +405,19 @@
return ((sc->vtmmio_features & feature) != 0);
}
+static uint32_t
+vtmmio_virtqueue_size(device_t dev, int idx)
+{
+ struct vtmmio_softc *sc;
+ uint32_t size;
+
+ sc = device_get_softc(dev);
+ vtmmio_select_virtqueue(sc, idx);
+ size = vtmmio_read_config_4(sc, VIRTIO_MMIO_QUEUE_NUM_MAX);
+
+ return (size);
+}
+
static int
vtmmio_alloc_virtqueues(device_t dev, int flags, int nvqs,
struct vq_alloc_info *vq_info)
Index: sys/dev/virtio/pci/virtio_pci.c
===================================================================
--- sys/dev/virtio/pci/virtio_pci.c
+++ sys/dev/virtio/pci/virtio_pci.c
@@ -113,6 +113,7 @@
static uint64_t vtpci_negotiate_features(device_t, uint64_t);
static int vtpci_with_feature(device_t, uint64_t);
+static uint32_t vtpci_virtqueue_size(device_t dev, int idx);
static int vtpci_alloc_virtqueues(device_t, int, int,
struct vq_alloc_info *);
static int vtpci_setup_intr(device_t, enum intr_type);
@@ -215,6 +216,7 @@
DEVMETHOD(virtio_bus_notify_vq, vtpci_notify_virtqueue),
DEVMETHOD(virtio_bus_read_device_config, vtpci_read_dev_config),
DEVMETHOD(virtio_bus_write_device_config, vtpci_write_dev_config),
+ DEVMETHOD(virtio_bus_virtqueue_size, vtpci_virtqueue_size),
DEVMETHOD_END
};
@@ -474,6 +476,19 @@
return ((sc->vtpci_features & feature) != 0);
}
+static uint32_t
+vtpci_virtqueue_size(device_t dev, int idx)
+{
+ struct vtpci_softc *sc;
+ uint32_t size;
+
+ sc = device_get_softc(dev);
+ vtpci_select_virtqueue(sc, idx);
+ size = vtpci_read_config_2(sc, VIRTIO_PCI_QUEUE_NUM);
+
+ return (size);
+}
+
static int
vtpci_alloc_virtqueues(device_t dev, int flags, int nvqs,
struct vq_alloc_info *vq_info)
Index: sys/dev/virtio/scsi/virtio_scsi.c
===================================================================
--- sys/dev/virtio/scsi/virtio_scsi.c
+++ sys/dev/virtio/scsi/virtio_scsi.c
@@ -68,6 +68,8 @@
#include "virtio_if.h"
+#define VTSCSI_FIRST_REQUEST_QUEUE 2
+
static int vtscsi_modevent(module_t, int, void *);
static int vtscsi_probe(device_t);
@@ -79,7 +81,8 @@
static void vtscsi_negotiate_features(struct vtscsi_softc *);
static void vtscsi_read_config(struct vtscsi_softc *,
struct virtio_scsi_config *);
-static int vtscsi_maximum_segments(struct vtscsi_softc *, int);
+static uint32_t vtscsi_minimum_request_queue_size(struct vtscsi_softc *, int);
+static int vtscsi_maximum_segments(struct vtscsi_softc *, int, int);
static int vtscsi_alloc_virtqueues(struct vtscsi_softc *);
static void vtscsi_write_device_config(struct vtscsi_softc *);
static int vtscsi_reinit(struct vtscsi_softc *);
@@ -297,7 +300,8 @@
vtscsi_write_device_config(sc);
- sc->vtscsi_max_nsegs = vtscsi_maximum_segments(sc, scsicfg.seg_max);
+ sc->vtscsi_max_nsegs = vtscsi_maximum_segments(sc, scsicfg.seg_max,
+ scsicfg.num_queues);
sc->vtscsi_sglist = sglist_alloc(sc->vtscsi_max_nsegs, M_NOWAIT);
if (sc->vtscsi_sglist == NULL) {
error = ENOMEM;
@@ -437,8 +441,27 @@
#undef VTSCSI_GET_CONFIG
+static uint32_t
+vtscsi_minimum_request_queue_size(struct vtscsi_softc *sc, int num_queues)
+{
+ device_t dev;
+ uint32_t size, s;
+ int i;
+
+ dev = sc->vtscsi_dev;
+ size = 0;
+ for (i = 0; i < num_queues; ++i) {
+ s = virtio_virtqueue_size(dev, i + VTSCSI_FIRST_REQUEST_QUEUE);
+ if (s != 0 && (size == 0 || s < size)) {
+ size = s;
+ }
+ }
+
+ return (size);
+}
+
static int
-vtscsi_maximum_segments(struct vtscsi_softc *sc, int seg_max)
+vtscsi_maximum_segments(struct vtscsi_softc *sc, int seg_max, int num_queues)
{
int nsegs;
@@ -448,6 +471,12 @@
nsegs += MIN(seg_max, MAXPHYS / PAGE_SIZE + 1);
if (sc->vtscsi_flags & VTSCSI_FLAG_INDIRECT)
nsegs = MIN(nsegs, VIRTIO_MAX_INDIRECT);
+ /*
+ * Ensure the assertions in virtqueue_enqueue(),
+ * even if the hypervisor reports a bad seg_max.
+ */
+ nsegs = MIN(nsegs,
+ vtscsi_minimum_request_queue_size(sc, num_queues));
} else
nsegs += 1;
Index: sys/dev/virtio/virtio.h
===================================================================
--- sys/dev/virtio/virtio.h
+++ sys/dev/virtio/virtio.h
@@ -96,6 +96,7 @@
int virtio_config_generation(device_t dev);
int virtio_reinit(device_t dev, uint64_t features);
void virtio_reinit_complete(device_t dev);
+uint32_t virtio_virtqueue_size(device_t dev, int idx);
int virtio_child_pnpinfo_str(device_t busdev, device_t child, char *buf,
size_t buflen);
Index: sys/dev/virtio/virtio.c
===================================================================
--- sys/dev/virtio/virtio.c
+++ sys/dev/virtio/virtio.c
@@ -287,6 +287,13 @@
return (0);
}
+uint32_t
+virtio_virtqueue_size(device_t dev, int idx)
+{
+
+ return (VIRTIO_BUS_VIRTQUEUE_SIZE(device_get_parent(dev), idx));
+}
+
static int
virtio_modevent(module_t mod, int type, void *unused)
{
Index: sys/dev/virtio/virtio_bus_if.m
===================================================================
--- sys/dev/virtio/virtio_bus_if.m
+++ sys/dev/virtio/virtio_bus_if.m
@@ -104,3 +104,7 @@
device_t dev;
};
+METHOD uint32_t virtqueue_size {
+ device_t dev;
+ int idx;
+};

File Metadata

Mime Type
text/plain
Expires
Thu, Jun 11, 4:14 PM (17 h, 7 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33884168
Default Alt Text
D20703.id58810.diff (5 KB)

Event Timeline