aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/netmap/netmap.c
diff options
context:
space:
mode:
authorVincenzo Maffione <vmaffione@FreeBSD.org>2021-08-22 09:31:05 +0000
committerVincenzo Maffione <vmaffione@FreeBSD.org>2021-08-22 09:31:05 +0000
commit98399ab06f6c6adbd795266bc8a45e3f804ac6f8 (patch)
tree3297037cce8aeddf30cc4f7ddc48be7c44ae845f /sys/dev/netmap/netmap.c
parentf8c1b1a9296696f70ac209612a00ae0722d07ed9 (diff)
Diffstat (limited to 'sys/dev/netmap/netmap.c')
-rw-r--r--sys/dev/netmap/netmap.c36
1 files changed, 31 insertions, 5 deletions
diff --git a/sys/dev/netmap/netmap.c b/sys/dev/netmap/netmap.c
index 9f1edb246cae..ed3154a524db 100644
--- a/sys/dev/netmap/netmap.c
+++ b/sys/dev/netmap/netmap.c
@@ -1002,6 +1002,22 @@ netmap_mem_drop(struct netmap_adapter *na)
}
}
+static void
+netmap_update_hostrings_mode(struct netmap_adapter *na)
+{
+ enum txrx t;
+ struct netmap_kring *kring;
+ int i;
+
+ for_rx_tx(t) {
+ for (i = nma_get_nrings(na, t);
+ i < netmap_real_rings(na, t); i++) {
+ kring = NMR(na, t)[i];
+ kring->nr_mode = kring->nr_pending_mode;
+ }
+ }
+}
+
/*
* Undo everything that was done in netmap_do_regif(). In particular,
* call nm_register(ifp,0) to stop netmap mode on the interface and
@@ -1032,7 +1048,9 @@ netmap_do_unregif(struct netmap_priv_d *priv)
#endif
if (na->active_fds <= 0 || nm_kring_pending(priv)) {
+ netmap_set_all_rings(na, NM_KR_LOCKED);
na->nm_register(na, 0);
+ netmap_set_all_rings(na, 0);
}
/* delete rings and buffers that are no longer needed */
@@ -2630,7 +2648,9 @@ netmap_do_regif(struct netmap_priv_d *priv, struct netmap_adapter *na,
if (nm_kring_pending(priv)) {
/* Some kring is switching mode, tell the adapter to
* react on this. */
+ netmap_set_all_rings(na, NM_KR_LOCKED);
error = na->nm_register(na, 1);
+ netmap_set_all_rings(na, 0);
if (error)
goto err_del_if;
}
@@ -2858,6 +2878,8 @@ netmap_ioctl(struct netmap_priv_d *priv, u_long cmd, caddr_t data,
&nifp->ni_bufs_head, req->nr_extra_bufs);
if (netmap_verbose)
nm_prinf("got %d extra buffers", req->nr_extra_bufs);
+ } else {
+ nifp->ni_bufs_head = 0;
}
req->nr_offset = netmap_mem_if_offset(na->nm_mem, nifp);
@@ -4178,12 +4200,16 @@ netmap_hw_krings_create(struct netmap_adapter *na)
void
netmap_detach(struct ifnet *ifp)
{
- struct netmap_adapter *na = NA(ifp);
+ struct netmap_adapter *na;
- if (!na)
+ NMG_LOCK();
+
+ if (!NM_NA_VALID(ifp)) {
+ NMG_UNLOCK();
return;
+ }
- NMG_LOCK();
+ na = NA(ifp);
netmap_set_all_rings(na, NM_KR_LOCKED);
/*
* if the netmap adapter is not native, somebody
@@ -4491,7 +4517,7 @@ nm_set_native_flags(struct netmap_adapter *na)
na->na_flags |= NAF_NETMAP_ON;
nm_os_onenter(ifp);
- nm_update_hostrings_mode(na);
+ netmap_update_hostrings_mode(na);
}
void
@@ -4505,7 +4531,7 @@ nm_clear_native_flags(struct netmap_adapter *na)
return;
}
- nm_update_hostrings_mode(na);
+ netmap_update_hostrings_mode(na);
nm_os_onexit(ifp);
na->na_flags &= ~NAF_NETMAP_ON;