svn commit: r226826 - in projects/virtio/sys/dev/virtio: block
network pci
Peter Grehan
grehan at FreeBSD.org
Thu Oct 27 05:48:21 UTC 2011
Author: grehan
Date: Thu Oct 27 05:48:21 2011
New Revision: 226826
URL: http://svn.freebsd.org/changeset/base/226826
Log:
Sync to change #162500 in Bryan Venteicher's hg repo
Modified:
projects/virtio/sys/dev/virtio/block/virtio_blk.c
projects/virtio/sys/dev/virtio/network/if_vtnet.c
projects/virtio/sys/dev/virtio/pci/virtio_pci.c
Modified: projects/virtio/sys/dev/virtio/block/virtio_blk.c
==============================================================================
--- projects/virtio/sys/dev/virtio/block/virtio_blk.c Thu Oct 27 04:56:53 2011 (r226825)
+++ projects/virtio/sys/dev/virtio/block/virtio_blk.c Thu Oct 27 05:48:21 2011 (r226826)
@@ -124,6 +124,7 @@ static int vtblk_maximum_segments(struct
static int vtblk_alloc_virtqueue(struct vtblk_softc *);
static void vtblk_alloc_disk(struct vtblk_softc *,
struct virtio_blk_config *);
+static void vtblk_create_disk(struct vtblk_softc *);
static int vtblk_open(struct disk *);
static int vtblk_close(struct disk *);
@@ -365,8 +366,7 @@ vtblk_attach(device_t dev)
goto fail;
}
- if (vtblk_no_ident == 0)
- vtblk_get_ident(sc);
+ vtblk_create_disk(sc);
virtqueue_enable_intr(sc->vtblk_vq);
@@ -541,7 +541,8 @@ vtblk_strategy(struct bio *bp)
/*
* Prevent read/write buffers spanning too many segments from
- * getting into the queue.
+ * getting into the queue. This should only trip if d_maxsize
+ * was incorrectly set.
*/
if (bp->bio_cmd == BIO_READ || bp->bio_cmd == BIO_WRITE) {
KASSERT(VTBLK_BIO_SEGMENTS(bp) <= sc->vtblk_max_nsegs -
@@ -642,7 +643,7 @@ vtblk_alloc_disk(struct vtblk_softc *sc,
* by physically contiguous pages. Therefore, we have to assume
* no pages are contiguous. This may impose an artificially low
* maximum I/O size. But in practice, since QEMU advertises 128
- * segments, this gives us a maxinum IO size of 125 * PAGE_SIZE,
+ * segments, this gives us a maximum IO size of 125 * PAGE_SIZE,
* which is typically greater than MAXPHYS. Eventually we should
* just advertise MAXPHYS and split buffers that are too big.
*
@@ -661,6 +662,25 @@ vtblk_alloc_disk(struct vtblk_softc *sc,
if (virtio_with_feature(dev, VIRTIO_BLK_F_FLUSH))
dp->d_flags |= DISKFLAG_CANFLUSHCACHE;
+}
+
+static void
+vtblk_create_disk(struct vtblk_softc *sc)
+{
+ struct disk *dp;
+
+ dp = sc->vtblk_disk;
+
+ /*
+ * Retrieving the identification string must be done after
+ * the virtqueue interrupt is setup otherwise it will hang.
+ */
+ vtblk_get_ident(sc);
+
+ device_printf(sc->vtblk_dev, "%juMB (%ju %u byte sectors)\n",
+ (uintmax_t) dp->d_mediasize >> 20,
+ (uintmax_t) dp->d_mediasize / dp->d_sectorsize,
+ dp->d_sectorsize);
disk_create(dp, DISK_VERSION);
}
@@ -864,6 +884,9 @@ vtblk_get_ident(struct vtblk_softc *sc)
dp = sc->vtblk_disk;
len = MIN(VIRTIO_BLK_ID_BYTES, DISK_IDENT_SIZE);
+ if (vtblk_no_ident != 0)
+ return;
+
req = vtblk_dequeue_request(sc);
if (req == NULL)
return;
Modified: projects/virtio/sys/dev/virtio/network/if_vtnet.c
==============================================================================
--- projects/virtio/sys/dev/virtio/network/if_vtnet.c Thu Oct 27 04:56:53 2011 (r226825)
+++ projects/virtio/sys/dev/virtio/network/if_vtnet.c Thu Oct 27 05:48:21 2011 (r226826)
@@ -94,6 +94,7 @@ static void vtnet_negotiate_features(str
static int vtnet_alloc_virtqueues(struct vtnet_softc *);
static void vtnet_get_hwaddr(struct vtnet_softc *);
static void vtnet_set_hwaddr(struct vtnet_softc *);
+static int vtnet_is_link_up(struct vtnet_softc *);
static void vtnet_update_link_status(struct vtnet_softc *);
static void vtnet_watchdog(struct vtnet_softc *);
static void vtnet_config_change_task(void *, int);
@@ -611,29 +612,24 @@ vtnet_negotiate_features(struct vtnet_so
if (virtio_with_feature(dev, VIRTIO_NET_F_MRG_RXBUF) == 0 &&
virtio_with_feature(dev, VTNET_LRO_FEATURES)) {
/*
- * LRO without mergeable buffers requires special handling.
- * Unfortunately, this configuration is less than ideal since
- * each receive buffer must be large enough to maximum TCP
- * packet along with the Ethernet header and vtnet_rx_header.
- * This requires 34 descriptors when using MCLBYTES clusters.
- *
- * The QEMU and vhost receive virtqueue are 256 descriptors
- * big. This means that unless indirect descriptors are
- * negotiated, the receive queue can only hold seven buffers.
- * Therefore LRO is disabled unless indirect descriptors are
- * available.
+ * LRO without mergeable buffers requires special care. This
+ * is not ideal because every receive buffer must be large
+ * enough to hold the maximum TCP packet, the Ethernet header,
+ * and the vtnet_rx_header. This requires up to 34 descriptors
+ * when using MCLBYTES clusters. If we do not have indirect
+ * descriptors, LRO is disabled since the virtqueue will not
+ * be able to contain very many receive buffers.
*/
+ if (virtio_with_feature(dev,
+ VIRTIO_RING_F_INDIRECT_DESC) == 0) {
+ device_printf(dev,
+ "LRO disabled due to lack of both mergeable "
+ "buffers and indirect descriptors\n");
- if (virtio_with_feature(dev, VIRTIO_RING_F_INDIRECT_DESC))
- sc->vtnet_flags |= VTNET_FLAG_LRO_NOMRG;
- else {
sc->vtnet_features = virtio_negotiate_features(dev,
features & ~VTNET_LRO_FEATURES);
-
- device_printf(dev, "LRO disbled because mergeable "
- "buffers and indirect descriptors were not "
- "negotiated\n");
- }
+ } else
+ sc->vtnet_flags |= VTNET_FLAG_LRO_NOMRG;
}
}
@@ -711,12 +707,11 @@ vtnet_set_hwaddr(struct vtnet_softc *sc)
sc->vtnet_hwaddr, ETHER_ADDR_LEN);
}
-static void
-vtnet_update_link_status(struct vtnet_softc *sc)
+static int
+vtnet_is_link_up(struct vtnet_softc *sc)
{
device_t dev;
struct ifnet *ifp;
- int link;
uint16_t status;
dev = sc->vtnet_dev;
@@ -724,15 +719,26 @@ vtnet_update_link_status(struct vtnet_so
VTNET_LOCK_ASSERT(sc);
- if (ifp->if_capenable & IFCAP_LINKSTATE) {
- status = virtio_read_dev_config_2(dev,
- offsetof(struct virtio_net_config, status));
- if (status & VIRTIO_NET_S_LINK_UP)
- link = 1;
- else
- link = 0;
- } else
- link = 1;
+ if ((ifp->if_capenable & IFCAP_LINKSTATE) == 0)
+ return (1);
+
+ status = virtio_read_dev_config_2(dev,
+ offsetof(struct virtio_net_config, status));
+
+ return ((status & VIRTIO_NET_S_LINK_UP) != 0);
+}
+
+static void
+vtnet_update_link_status(struct vtnet_softc *sc)
+{
+ device_t dev;
+ struct ifnet *ifp;
+ int link;
+
+ dev = sc->vtnet_dev;
+ ifp = sc->vtnet_ifp;
+
+ link = vtnet_is_link_up(sc);
if (link && ((sc->vtnet_flags & VTNET_FLAG_LINK) == 0)) {
sc->vtnet_flags |= VTNET_FLAG_LINK;
@@ -2630,7 +2636,7 @@ vtnet_ifmedia_sts(struct ifnet *ifp, str
ifmr->ifm_active = IFM_ETHER;
VTNET_LOCK(sc);
- if (sc->vtnet_flags & VTNET_FLAG_LINK) {
+ if (vtnet_is_link_up(sc) != 0) {
ifmr->ifm_status |= IFM_ACTIVE;
ifmr->ifm_active |= VTNET_MEDIATYPE;
} else
@@ -2692,6 +2698,9 @@ vtnet_add_statistics(struct vtnet_softc
SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "tx_csum_offloaded",
CTLFLAG_RD, &stats->tx_csum_offloaded,
"Offloaded checksum of transmitted buffer");
+ SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "tx_tso_offloaded",
+ CTLFLAG_RD, &stats->tx_tso_offloaded,
+ "Segmentation offload of transmitted buffer");
SYSCTL_ADD_ULONG(ctx, child, OID_AUTO, "tx_csum_bad_ethtype",
CTLFLAG_RD, &stats->tx_csum_bad_ethtype,
"Aborted transmit of checksum offloaded buffer with unknown "
Modified: projects/virtio/sys/dev/virtio/pci/virtio_pci.c
==============================================================================
--- projects/virtio/sys/dev/virtio/pci/virtio_pci.c Thu Oct 27 04:56:53 2011 (r226825)
+++ projects/virtio/sys/dev/virtio/pci/virtio_pci.c Thu Oct 27 05:48:21 2011 (r226826)
@@ -126,6 +126,8 @@ static void vtpci_set_status(device_t, u
static void vtpci_read_dev_config(device_t, bus_size_t, void *, int);
static void vtpci_write_dev_config(device_t, bus_size_t, void *, int);
+static void vtpci_describe_features(struct vtpci_softc *, const char *,
+ uint64_t);
static void vtpci_probe_and_attach_child(struct vtpci_softc *);
static int vtpci_alloc_interrupts(struct vtpci_softc *, int, int,
@@ -409,22 +411,18 @@ vtpci_negotiate_features(device_t dev, u
sc = device_get_softc(dev);
host_features = vtpci_read_config_4(sc, VIRTIO_PCI_HOST_FEATURES);
- if (bootverbose)
- virtio_describe(dev, "available", host_features,
- sc->vtpci_child_feat_desc);
+ vtpci_describe_features(sc, "host", host_features);
/*
- * Limit negotiated features to what the host, guest, and
- * virtqueue all support.
+ * Limit negotiated features to what the driver, virtqueue, and
+ * host all support.
*/
features = host_features & child_features;
features = virtqueue_filter_features(features);
sc->vtpci_features = features;
- vtpci_write_config_4(sc, VIRTIO_PCI_GUEST_FEATURES, features);
- if (bootverbose)
- virtio_describe(dev, "negotiated", features,
- sc->vtpci_child_feat_desc);
+ vtpci_describe_features(sc, "negotiated", features);
+ vtpci_write_config_4(sc, VIRTIO_PCI_GUEST_FEATURES, features);
return (features);
}
@@ -710,6 +708,21 @@ vtpci_write_dev_config(device_t dev, bus
}
static void
+vtpci_describe_features(struct vtpci_softc *sc, const char *msg,
+ uint64_t features)
+{
+ device_t dev, child;
+
+ dev = sc->vtpci_dev;
+ child = sc->vtpci_child_dev;
+
+ if (device_is_attached(child) && bootverbose == 0)
+ return;
+
+ virtio_describe(dev, msg, features, sc->vtpci_child_feat_desc);
+}
+
+static void
vtpci_probe_and_attach_child(struct vtpci_softc *sc)
{
device_t dev, child;
More information about the svn-src-projects
mailing list