svn commit: r361696 - head/sys/dev/netmap
Vincenzo Maffione
vmaffione at FreeBSD.org
Mon Jun 1 16:10:45 UTC 2020
Author: vmaffione
Date: Mon Jun 1 16:10:44 2020
New Revision: 361696
URL: https://svnweb.freebsd.org/changeset/base/361696
Log:
netmap: vtnet: fix RX virtqueue initialization bug
The vtnet_netmap_rxq_populate() function erroneously assumed
that kring->nr_hwcur = 0, i.e. the kring was in the initial
state. However, this is not always the case: for example,
when a vtnet reinit is triggered by some changes in the
interface flags or capenable.
This patch changes the behaviour of vtnet_netmap_kring_refill()
so that it always starts publishing the netmap buffers starting
from the current value of kring->nr_hwcur.
MFC after: 1 week
Modified:
head/sys/dev/netmap/if_vtnet_netmap.h
Modified: head/sys/dev/netmap/if_vtnet_netmap.h
==============================================================================
--- head/sys/dev/netmap/if_vtnet_netmap.h Mon Jun 1 15:58:22 2020 (r361695)
+++ head/sys/dev/netmap/if_vtnet_netmap.h Mon Jun 1 16:10:44 2020 (r361696)
@@ -232,14 +232,20 @@ vtnet_netmap_txsync(struct netmap_kring *kring, int fl
return 0;
}
+/*
+ * Publish (up to) num netmap receive buffers to the host,
+ * starting from the first one that the user made available
+ * (kring->nr_hwcur).
+ */
static int
-vtnet_netmap_kring_refill(struct netmap_kring *kring, u_int nm_i, u_int head)
+vtnet_netmap_kring_refill(struct netmap_kring *kring, u_int num)
{
struct netmap_adapter *na = kring->na;
struct ifnet *ifp = na->ifp;
struct netmap_ring *ring = kring->ring;
u_int ring_nr = kring->ring_id;
u_int const lim = kring->nkr_num_slots - 1;
+ u_int nm_i = kring->nr_hwcur;
/* device-specific */
struct vtnet_softc *sc = ifp->if_softc;
@@ -250,7 +256,7 @@ vtnet_netmap_kring_refill(struct netmap_kring *kring,
struct sglist_seg ss[2];
struct sglist sg = { ss, 0, 0, 2 };
- for (; nm_i != head; nm_i = nm_next(nm_i, lim)) {
+ for (; num > 0; nm_i = nm_next(nm_i, lim), num--) {
struct netmap_slot *slot = &ring->slot[nm_i];
uint64_t paddr;
void *addr = PNMB(na, slot, &paddr);
@@ -302,10 +308,11 @@ vtnet_netmap_rxq_populate(struct vtnet_rxq *rxq)
kring->nr_pending_mode == NKR_NETMAP_ON))
return -1;
- /* Expose all the RX netmap buffers. Note that the number of
- * netmap slots in the RX ring matches the maximum number of
- * 2-elements sglist that the RX virtqueue can accommodate. */
- error = vtnet_netmap_kring_refill(kring, 0, na->num_rx_desc);
+ /* Expose all the RX netmap buffers we can. In case of no indirect
+ * buffers, the number of netmap slots in the RX ring matches the
+ * maximum number of 2-elements sglist that the RX virtqueue can
+ * accommodate. */
+ error = vtnet_netmap_kring_refill(kring, na->num_rx_desc);
virtqueue_notify(rxq->vtnrx_vq);
return error < 0 ? ENXIO : 0;
@@ -381,7 +388,12 @@ vtnet_netmap_rxsync(struct netmap_kring *kring, int fl
*/
nm_i = kring->nr_hwcur; /* netmap ring index */
if (nm_i != head) {
- int nm_j = vtnet_netmap_kring_refill(kring, nm_i, head);
+ int howmany = head - nm_i;
+ int nm_j;
+
+ if (howmany < 0)
+ howmany += kring->nkr_num_slots;
+ nm_j = vtnet_netmap_kring_refill(kring, howmany);
if (nm_j < 0)
return nm_j;
kring->nr_hwcur = nm_j;
More information about the svn-src-all
mailing list