Date: Thu, 27 Oct 2011 05:48:21 +0000 (UTC) From: Peter Grehan <grehan@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r226826 - in projects/virtio/sys/dev/virtio: block network pci Message-ID: <201110270548.p9R5mLxV086674@svn.freebsd.org>
index | next in thread | raw e-mail
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;help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201110270548.p9R5mLxV086674>
