diff options
author | luigi <luigi@FreeBSD.org> | 2015-07-10 05:51:36 +0000 |
---|---|---|
committer | luigi <luigi@FreeBSD.org> | 2015-07-10 05:51:36 +0000 |
commit | c354cad8fde9b680d7f14a49789fbb1063153772 (patch) | |
tree | 2a938ad28f8fa79c60e58c3430a4c2c93631db94 /sys/dev/netmap/netmap_freebsd.c | |
parent | 0f9bc3ce0cd3f89195d493ab53e62b96aed6a21a (diff) | |
download | FreeBSD-src-c354cad8fde9b680d7f14a49789fbb1063153772.zip FreeBSD-src-c354cad8fde9b680d7f14a49789fbb1063153772.tar.gz |
Sync netmap sources with the version in our private tree.
This commit contains large contributions from Giuseppe Lettieri and
Stefano Garzarella, is partly supported by grants from Verisign and Cisco,
and brings in the following:
- fix zerocopy monitor ports and introduce copying monitor ports
(the latter are lower performance but give access to all traffic
in parallel with the application)
- exclusive open mode, useful to implement solutions that recover
from crashes of the main netmap client (suggested by Patrick Kelsey)
- revised memory allocator in preparation for the 'passthrough mode'
(ptnetmap) recently presented at bsdcan. ptnetmap is described in
S. Garzarella, G. Lettieri, L. Rizzo;
Virtual device passthrough for high speed VM networking,
ACM/IEEE ANCS 2015, Oakland (CA) May 2015
http://info.iet.unipi.it/~luigi/research.html
- fix rx CRC handing on ixl
- add module dependencies for netmap when building drivers as modules
- minor simplifications to device-specific routines (*txsync, *rxsync)
- general code cleanup (remove unused variables, introduce macros
to access rings and remove duplicate code,
Applications do not need to be recompiled, unless of course
they want to use the new features (monitors and exclusive open).
Those willing to try this code on stable/10 can just update the
sys/dev/netmap/*, sys/net/netmap* with the version in HEAD
and apply the small patches to individual device drivers.
MFC after: 1 month
Sponsored by: (partly) Verisign, Cisco
Diffstat (limited to 'sys/dev/netmap/netmap_freebsd.c')
-rw-r--r-- | sys/dev/netmap/netmap_freebsd.c | 39 |
1 files changed, 26 insertions, 13 deletions
diff --git a/sys/dev/netmap/netmap_freebsd.c b/sys/dev/netmap/netmap_freebsd.c index 9687248..ebac6b0 100644 --- a/sys/dev/netmap/netmap_freebsd.c +++ b/sys/dev/netmap/netmap_freebsd.c @@ -24,6 +24,8 @@ */ /* $FreeBSD$ */ +#include "opt_inet.h" +#include "opt_inet6.h" #include <sys/types.h> #include <sys/module.h> @@ -148,9 +150,9 @@ nm_csum_tcpudp_ipv6(struct nm_ipv6hdr *ip6h, void *data, * Second argument is non-zero to intercept, 0 to restore */ int -netmap_catch_rx(struct netmap_adapter *na, int intercept) +netmap_catch_rx(struct netmap_generic_adapter *gna, int intercept) { - struct netmap_generic_adapter *gna = (struct netmap_generic_adapter *)na; + struct netmap_adapter *na = &gna->up.up; struct ifnet *ifp = na->ifp; if (intercept) { @@ -183,7 +185,7 @@ void netmap_catch_tx(struct netmap_generic_adapter *gna, int enable) { struct netmap_adapter *na = &gna->up.up; - struct ifnet *ifp = na->ifp; + struct ifnet *ifp = netmap_generic_getifp(gna); if (enable) { na->if_transmit = ifp->if_transmit; @@ -494,6 +496,7 @@ netmap_dev_pager_fault(vm_object_t object, vm_ooffset_t offset, { struct netmap_vm_handle_t *vmh = object->handle; struct netmap_priv_d *priv = vmh->priv; + struct netmap_adapter *na = priv->np_na; vm_paddr_t paddr; vm_page_t page; vm_memattr_t memattr; @@ -503,7 +506,7 @@ netmap_dev_pager_fault(vm_object_t object, vm_ooffset_t offset, object, (intmax_t)offset, prot, mres); memattr = object->memattr; pidx = OFF_TO_IDX(offset); - paddr = netmap_mem_ofstophys(priv->np_mref, offset); + paddr = netmap_mem_ofstophys(na->nm_mem, offset); if (paddr == 0) return VM_PAGER_FAIL; @@ -568,14 +571,14 @@ netmap_mmap_single(struct cdev *cdev, vm_ooffset_t *foff, error = devfs_get_cdevpriv((void**)&priv); if (error) goto err_unlock; + if (priv->np_nifp == NULL) { + error = EINVAL; + goto err_unlock; + } vmh->priv = priv; priv->np_refcount++; NMG_UNLOCK(); - error = netmap_get_memory(priv); - if (error) - goto err_deref; - obj = cdev_pager_allocate(vmh, OBJT_DEVICE, &netmap_cdev_pager_ops, objsize, prot, *foff, NULL); @@ -598,8 +601,18 @@ err_unlock: return error; } - -// XXX can we remove this ? +/* + * netmap_close() is called on every close(), but we do not need to do + * anything at that moment, since the process may have other open file + * descriptors for /dev/netmap. Instead, we pass netmap_dtor() to + * devfs_set_cdevpriv() on open(). The FreeBSD kernel will call the destructor + * when the last fd pointing to the device is closed. + * + * Unfortunately, FreeBSD does not automatically track active mmap()s on an fd, + * so we have to track them by ourselvesi (see above). The result is that + * netmap_dtor() is called when the process has no open fds and no active + * memory maps on /dev/netmap, as in linux. + */ static int netmap_close(struct cdev *dev, int fflag, int devtype, struct thread *td) { @@ -673,7 +686,7 @@ static void netmap_knrdetach(struct knote *kn) { struct netmap_priv_d *priv = (struct netmap_priv_d *)kn->kn_hook; - struct selinfo *si = &priv->np_rxsi->si; + struct selinfo *si = &priv->np_si[NR_RX]->si; D("remove selinfo %p", si); knlist_remove(&si->si_note, kn, 0); @@ -683,7 +696,7 @@ static void netmap_knwdetach(struct knote *kn) { struct netmap_priv_d *priv = (struct netmap_priv_d *)kn->kn_hook; - struct selinfo *si = &priv->np_txsi->si; + struct selinfo *si = &priv->np_si[NR_TX]->si; D("remove selinfo %p", si); knlist_remove(&si->si_note, kn, 0); @@ -773,7 +786,7 @@ netmap_kqfilter(struct cdev *dev, struct knote *kn) return 1; } /* the si is indicated in the priv */ - si = (ev == EVFILT_WRITE) ? priv->np_txsi : priv->np_rxsi; + si = priv->np_si[(ev == EVFILT_WRITE) ? NR_TX : NR_RX]; // XXX lock(priv) ? kn->kn_fop = (ev == EVFILT_WRITE) ? &netmap_wfiltops : &netmap_rfiltops; |