[Midnightbsd-cvs] src [9348] trunk/sys/dev/netmap: sync the version of netmap with the one in FreeBSD HEAD (around releng 10 2013), including device

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sat Mar 4 11:51:12 EST 2017


Revision: 9348
          http://svnweb.midnightbsd.org/src/?rev=9348
Author:   laffer1
Date:     2017-03-04 11:51:12 -0500 (Sat, 04 Mar 2017)
Log Message:
-----------
sync the version of netmap with the one in FreeBSD HEAD (around releng 10 2013), including device
drivers (mostly simplifying the code in the interrupt handlers).

Modified Paths:
--------------
    trunk/sys/dev/netmap/if_em_netmap.h
    trunk/sys/dev/netmap/if_re_netmap.h
    trunk/sys/dev/netmap/ixgbe_netmap.h
    trunk/sys/dev/netmap/netmap.c
    trunk/sys/dev/netmap/netmap_kern.h
    trunk/sys/dev/netmap/netmap_mem2.c

Modified: trunk/sys/dev/netmap/if_em_netmap.h
===================================================================
--- trunk/sys/dev/netmap/if_em_netmap.h	2017-03-04 16:46:41 UTC (rev 9347)
+++ trunk/sys/dev/netmap/if_em_netmap.h	2017-03-04 16:51:12 UTC (rev 9348)
@@ -277,7 +277,7 @@
 	k = ring->cur;
 	if (k > lim)
 		return netmap_ring_reinit(kring);
- 
+
 	if (do_lock)
 		EM_RX_LOCK(rxr);
 

Modified: trunk/sys/dev/netmap/if_re_netmap.h
===================================================================
--- trunk/sys/dev/netmap/if_re_netmap.h	2017-03-04 16:46:41 UTC (rev 9347)
+++ trunk/sys/dev/netmap/if_re_netmap.h	2017-03-04 16:51:12 UTC (rev 9348)
@@ -151,7 +151,7 @@
 
 	/* update avail to what the kernel knows */
 	ring->avail = kring->nr_hwavail;
-	
+
 	j = kring->nr_hwcur;
 	if (j != k) {	/* we have new packets to send */
 		l = sc->rl_ldata.rl_tx_prodidx;
@@ -170,7 +170,7 @@
 				// XXX what about prodidx ?
 				return netmap_ring_reinit(kring);
 			}
-			
+
 			if (l == lim)	/* mark end of ring */
 				cmd |= RL_TDESC_CMD_EOR;
 
@@ -335,7 +335,7 @@
  */
 static void
 re_netmap_tx_init(struct rl_softc *sc)
-{   
+{
 	struct rl_txdesc *txd;
 	struct rl_desc *desc;
 	int i, n;

Modified: trunk/sys/dev/netmap/ixgbe_netmap.h
===================================================================
--- trunk/sys/dev/netmap/ixgbe_netmap.h	2017-03-04 16:46:41 UTC (rev 9347)
+++ trunk/sys/dev/netmap/ixgbe_netmap.h	2017-03-04 16:51:12 UTC (rev 9348)
@@ -226,7 +226,8 @@
 	struct netmap_adapter *na = NA(adapter->ifp);
 	struct netmap_kring *kring = &na->tx_rings[ring_nr];
 	struct netmap_ring *ring = kring->ring;
-	u_int j, k = ring->cur, l, n = 0, lim = kring->nkr_num_slots - 1;
+	u_int j, l, n = 0;
+	u_int const k = ring->cur, lim = kring->nkr_num_slots - 1;
 
 	/*
 	 * ixgbe can generate an interrupt on every tx packet, but it
@@ -393,11 +394,10 @@
 	    if (ix_use_dd) {
 		struct ixgbe_legacy_tx_desc *txd =
 		    (struct ixgbe_legacy_tx_desc *)txr->tx_base;
-
+		u_int k1 = netmap_idx_k2n(kring, kring->nr_hwcur);
 		l = txr->next_to_clean;
-		k = netmap_idx_k2n(kring, kring->nr_hwcur);
 		delta = 0;
-		while (l != k &&
+		while (l != k1 &&
 		    txd[l].upper.fields.status & IXGBE_TXD_STAT_DD) {
 		    delta++;
 		    l = (l == lim) ? 0 : l + 1;

Modified: trunk/sys/dev/netmap/netmap.c
===================================================================
--- trunk/sys/dev/netmap/netmap.c	2017-03-04 16:46:41 UTC (rev 9347)
+++ trunk/sys/dev/netmap/netmap.c	2017-03-04 16:51:12 UTC (rev 9348)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2012 Matteo Landi, Luigi Rizzo. All rights reserved.
+ * Copyright (C) 2011-2013 Matteo Landi, Luigi Rizzo. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -81,6 +81,7 @@
 #include <sys/mman.h>	/* PROT_EXEC */
 #include <sys/poll.h>
 #include <sys/proc.h>
+#include <sys/rwlock.h>
 #include <vm/vm.h>	/* vtophys */
 #include <vm/pmap.h>	/* vtophys */
 #include <sys/socket.h> /* sockaddrs */
@@ -98,6 +99,7 @@
 #include <net/netmap.h>
 #include <dev/netmap/netmap_kern.h>
 
+/* XXX the following variables must be deprecated and included in nm_mem */
 u_int netmap_total_buffers;
 u_int netmap_buf_size;
 char *netmap_buffer_base;	/* address of an invalid buffer */
@@ -121,12 +123,10 @@
 int netmap_drop = 0;	/* debugging */
 int netmap_flags = 0;	/* debug flags */
 int netmap_fwd = 0;	/* force transparent mode */
-int netmap_copy = 0;	/* debugging, copy content */
 
 SYSCTL_INT(_dev_netmap, OID_AUTO, drop, CTLFLAG_RW, &netmap_drop, 0 , "");
 SYSCTL_INT(_dev_netmap, OID_AUTO, flags, CTLFLAG_RW, &netmap_flags, 0 , "");
 SYSCTL_INT(_dev_netmap, OID_AUTO, fwd, CTLFLAG_RW, &netmap_fwd, 0 , "");
-SYSCTL_INT(_dev_netmap, OID_AUTO, copy, CTLFLAG_RW, &netmap_copy, 0 , "");
 
 #ifdef NM_BRIDGE /* support for netmap bridge */
 
@@ -147,22 +147,33 @@
 #define NM_BDG_HASH		1024	/* forwarding table entries */
 #define NM_BDG_BATCH		1024	/* entries in the forwarding buffer */
 #define	NM_BRIDGES		4	/* number of bridges */
+
+
 int netmap_bridge = NM_BDG_BATCH; /* bridge batch size */
 SYSCTL_INT(_dev_netmap, OID_AUTO, bridge, CTLFLAG_RW, &netmap_bridge, 0 , "");
 
 #ifdef linux
-#define	ADD_BDG_REF(ifp)	(NA(ifp)->if_refcount++)
-#define	DROP_BDG_REF(ifp)	(NA(ifp)->if_refcount-- <= 1)
+
+#define	refcount_acquire(_a)	atomic_add(1, (atomic_t *)_a)
+#define	refcount_release(_a)	atomic_dec_and_test((atomic_t *)_a)
+
 #else /* !linux */
-#define	ADD_BDG_REF(ifp)	(ifp)->if_refcount++
-#define	DROP_BDG_REF(ifp)	refcount_release(&(ifp)->if_refcount)
+
 #ifdef __FreeBSD__
 #include <sys/endian.h>
 #include <sys/refcount.h>
 #endif /* __FreeBSD__ */
+
 #define prefetch(x)	__builtin_prefetch(x)
+
 #endif /* !linux */
 
+/*
+ * These are used to handle reference counters for bridge ports.
+ */
+#define	ADD_BDG_REF(ifp)	refcount_acquire(&NA(ifp)->na_bdg_refcount)
+#define	DROP_BDG_REF(ifp)	refcount_release(&NA(ifp)->na_bdg_refcount)
+
 static void bdg_netmap_attach(struct ifnet *ifp);
 static int bdg_netmap_reg(struct ifnet *ifp, int onoff);
 /* per-tx-queue entry */
@@ -179,9 +190,14 @@
 };
 
 /*
- * Interfaces for a bridge are all in ports[].
+ * Interfaces for a bridge are all in bdg_ports[].
  * The array has fixed size, an empty entry does not terminate
- * the search.
+ * the search. But lookups only occur on attach/detach so we
+ * don't mind if they are slow.
+ *
+ * The bridge is non blocking on the transmit ports.
+ *
+ * bdg_lock protects accesses to the bdg_ports array.
  */
 struct nm_bridge {
 	struct ifnet *bdg_ports[NM_BDG_MAXPORTS];
@@ -297,7 +313,7 @@
 		txd = na->num_tx_desc;
 		rxr = na->num_rx_rings;
 		rxd = na->num_rx_desc;
-	}	
+	}
 
 	if (na->num_tx_rings == txr && na->num_tx_desc == txd &&
 	    na->num_rx_rings == rxr && na->num_rx_desc == rxd)
@@ -323,11 +339,7 @@
 }
 
 /*------------- memory allocator -----------------*/
-#ifdef NETMAP_MEM2
 #include "netmap_mem2.c"
-#else /* !NETMAP_MEM2 */
-#include "netmap_mem1.c"
-#endif /* !NETMAP_MEM2 */
 /*------------ end of memory allocator ----------*/
 
 
@@ -497,16 +509,16 @@
 {
 	struct netmap_priv_d *priv = data;
 	struct ifnet *ifp = priv->np_ifp;
-	struct netmap_adapter *na;
 
 	NMA_LOCK();
 	if (ifp) {
-		na = NA(ifp);
+		struct netmap_adapter *na = NA(ifp);
+
 		na->nm_lock(ifp, NETMAP_REG_LOCK, 0);
 		netmap_dtor_locked(data);
 		na->nm_lock(ifp, NETMAP_REG_UNLOCK, 0);
 
-		nm_if_rele(ifp);
+		nm_if_rele(ifp); /* might also destroy *na */
 	}
 	if (priv->ref_done) {
 		netmap_memory_deref();
@@ -1668,19 +1680,25 @@
 		ND("using default locks for %s", ifp->if_xname);
 		na->nm_lock = netmap_lock_wrapper;
 	}
+
 #ifdef linux
-	if (ifp->netdev_ops) {
-		ND("netdev_ops %p", ifp->netdev_ops);
-		/* prepare a clone of the netdev ops */
-		na->nm_ndo = *ifp->netdev_ops;
+	if (!ifp->netdev_ops) {
+		D("ouch, we cannot override netdev_ops");
+		goto fail;
 	}
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
+	/* if needed, prepare a clone of the entire netdev ops */
+	na->nm_ndo = *ifp->netdev_ops;
+#endif /* 2.6.28 and above */
 	na->nm_ndo.ndo_start_xmit = linux_netmap_start;
-#endif
+#endif /* linux */
+
 	D("success for %s", ifp->if_xname);
 	return 0;
 
 fail:
 	D("fail, arg %p ifp %p na %p", arg, ifp, na);
+	netmap_detach(ifp);
 	return (na ? EINVAL : ENOMEM);
 }
 
@@ -1726,6 +1744,12 @@
 	if (netmap_verbose & NM_VERB_HOST)
 		D("%s packet %d len %d from the stack", ifp->if_xname,
 			kring->nr_hwcur + kring->nr_hwavail, len);
+	if (len > NETMAP_BUF_SIZE) { /* too long for us */
+		D("%s from_host, drop packet size %d > %d", ifp->if_xname,
+			len, NETMAP_BUF_SIZE);
+		m_freem(m);
+		return EINVAL;
+	}
 	na->nm_lock(ifp, NETMAP_CORE_LOCK, 0);
 	if (kring->nr_hwavail >= lim) {
 		if (netmap_verbose)
@@ -1732,11 +1756,6 @@
 			D("stack ring %s full\n", ifp->if_xname);
 		goto done;	/* no space */
 	}
-	if (len > NETMAP_BUF_SIZE) {
-		D("%s from_host, drop packet size %d > %d", ifp->if_xname,
-			len, NETMAP_BUF_SIZE);
-		goto done;	/* too long for us */
-	}
 
 	/* compute the insert position */
 	i = kring->nr_hwcur + kring->nr_hwavail;
@@ -1837,6 +1856,10 @@
  * N rings, separate locks:
  *	lock(i); wake(i); unlock(i); lock(core) wake(N+1) unlock(core)
  * work_done is non-null on the RX path.
+ *
+ * The 'q' argument also includes flag to tell whether the queue is
+ * already locked on enter, and whether it should remain locked on exit.
+ * This helps adapting to different defaults in drivers and OSes.
  */
 int
 netmap_rx_irq(struct ifnet *ifp, int q, int *work_done)
@@ -1844,9 +1867,14 @@
 	struct netmap_adapter *na;
 	struct netmap_kring *r;
 	NM_SELINFO_T *main_wq;
+	int locktype, unlocktype, lock;
 
 	if (!(ifp->if_capenable & IFCAP_NETMAP))
 		return 0;
+
+	lock = q & (NETMAP_LOCKED_ENTER | NETMAP_LOCKED_EXIT);
+	q = q & NETMAP_RING_MASK;
+
 	ND(5, "received %s queue %d", work_done ? "RX" : "TX" , q);
 	na = NA(ifp);
 	if (na->na_flags & NAF_SKIP_INTR) {
@@ -1856,32 +1884,42 @@
 
 	if (work_done) { /* RX path */
 		if (q >= na->num_rx_rings)
-			return 0;	// regular queue
+			return 0;	// not a physical queue
 		r = na->rx_rings + q;
 		r->nr_kflags |= NKR_PENDINTR;
 		main_wq = (na->num_rx_rings > 1) ? &na->rx_si : NULL;
-	} else { /* tx path */
+		locktype = NETMAP_RX_LOCK;
+		unlocktype = NETMAP_RX_UNLOCK;
+	} else { /* TX path */
 		if (q >= na->num_tx_rings)
-			return 0;	// regular queue
+			return 0;	// not a physical queue
 		r = na->tx_rings + q;
 		main_wq = (na->num_tx_rings > 1) ? &na->tx_si : NULL;
 		work_done = &q; /* dummy */
+		locktype = NETMAP_TX_LOCK;
+		unlocktype = NETMAP_TX_UNLOCK;
 	}
 	if (na->separate_locks) {
-		mtx_lock(&r->q_lock);
+		if (!(lock & NETMAP_LOCKED_ENTER))
+			na->nm_lock(ifp, locktype, q);
 		selwakeuppri(&r->si, PI_NET);
-		mtx_unlock(&r->q_lock);
+		na->nm_lock(ifp, unlocktype, q);
 		if (main_wq) {
-			mtx_lock(&na->core_lock);
+			na->nm_lock(ifp, NETMAP_CORE_LOCK, 0);
 			selwakeuppri(main_wq, PI_NET);
-			mtx_unlock(&na->core_lock);
+			na->nm_lock(ifp, NETMAP_CORE_UNLOCK, 0);
 		}
+		/* lock the queue again if requested */
+		if (lock & NETMAP_LOCKED_EXIT)
+			na->nm_lock(ifp, locktype, q);
 	} else {
-		mtx_lock(&na->core_lock);
+		if (!(lock & NETMAP_LOCKED_ENTER))
+			na->nm_lock(ifp, NETMAP_CORE_LOCK, 0);
 		selwakeuppri(&r->si, PI_NET);
 		if (main_wq)
 			selwakeuppri(main_wq, PI_NET);
-		mtx_unlock(&na->core_lock);
+		if (!(lock & NETMAP_LOCKED_EXIT))
+			na->nm_lock(ifp, NETMAP_CORE_UNLOCK, 0);
 	}
 	*work_done = 1; /* do not fire napi again */
 	return 1;
@@ -1902,7 +1940,9 @@
 static u_int
 linux_netmap_poll(struct file * file, struct poll_table_struct *pwait)
 {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
+	int events = POLLIN | POLLOUT; /* XXX maybe... */
+#elif LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)
 	int events = pwait ? pwait->key : POLLIN | POLLOUT;
 #else /* in 3.4.0 field 'key' was renamed to '_key' */
 	int events = pwait ? pwait->_key : POLLIN | POLLOUT;
@@ -1942,7 +1982,7 @@
 		 * vtophys mapping in lut[k] so we use that, scanning
 		 * the lut[] array in steps of clustentries,
 		 * and we map each cluster (not individual pages,
-		 * it would be overkill).
+		 * it would be overkill -- XXX slow ? 20130415).
 		 */
 
 		/*

Modified: trunk/sys/dev/netmap/netmap_kern.h
===================================================================
--- trunk/sys/dev/netmap/netmap_kern.h	2017-03-04 16:46:41 UTC (rev 9347)
+++ trunk/sys/dev/netmap/netmap_kern.h	2017-03-04 16:51:12 UTC (rev 9348)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2012 Matteo Landi, Luigi Rizzo. All rights reserved.
+ * Copyright (C) 2011-2013 Matteo Landi, Luigi Rizzo. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -34,9 +34,8 @@
 #ifndef _NET_NETMAP_KERN_H_
 #define _NET_NETMAP_KERN_H_
 
-#define NETMAP_MEM2    // use the new memory allocator
+#if defined(__FreeBSD__)
 
-#if defined(__FreeBSD__)
 #define likely(x)	__builtin_expect(!!(x), 1)
 #define unlikely(x)	__builtin_expect(!!(x), 0)
 
@@ -44,8 +43,10 @@
 #define	NM_SELINFO_T	struct selinfo
 #define	MBUF_LEN(m)	((m)->m_pkthdr.len)
 #define	NM_SEND_UP(ifp, m)	((ifp)->if_input)(ifp, m)
+
 #elif defined (linux)
-#define	NM_LOCK_T	spinlock_t
+
+#define	NM_LOCK_T	safe_spinlock_t	// see bsd_glue.h
 #define	NM_SELINFO_T	wait_queue_head_t
 #define	MBUF_LEN(m)	((m)->len)
 #define	NM_SEND_UP(ifp, m)	netif_rx(m)
@@ -67,6 +68,7 @@
 #endif
 
 #elif defined (__APPLE__)
+
 #warning apple support is incomplete.
 #define likely(x)	__builtin_expect(!!(x), 1)
 #define unlikely(x)	__builtin_expect(!!(x), 0)
@@ -76,9 +78,11 @@
 #define	NM_SEND_UP(ifp, m)	((ifp)->if_input)(ifp, m)
 
 #else
+
 #error unsupported platform
-#endif
 
+#endif /* end - platform-specific code */
+
 #define ND(format, ...)
 #define D(format, ...)						\
 	do {							\
@@ -207,10 +211,20 @@
 	int (*nm_config)(struct ifnet *, u_int *txr, u_int *txd,
 					u_int *rxr, u_int *rxd);
 
+	/*
+	 * Bridge support:
+	 *
+	 * bdg_port is the port number used in the bridge;
+	 * na_bdg_refcount is a refcount used for bridge ports,
+	 *	when it goes to 0 we can detach+free this port
+	 *	(a bridge port is always attached if it exists;
+	 *	it is not always registered)
+	 */
 	int bdg_port;
+	int na_bdg_refcount;
+
 #ifdef linux
 	struct net_device_ops nm_ndo;
-	int if_refcount;	// XXX additions for bridge
 #endif /* linux */
 };
 
@@ -245,6 +259,10 @@
 #endif
 };
 
+/* How to handle locking support in netmap_rx_irq/netmap_tx_irq */
+#define	NETMAP_LOCKED_ENTER	0x10000000	/* already locked on enter */
+#define	NETMAP_LOCKED_EXIT	0x20000000	/* keep locked on exit */
+
 /*
  * The following are support routines used by individual drivers to
  * support netmap operation.
@@ -272,7 +290,7 @@
 int netmap_ring_reinit(struct netmap_kring *);
 
 extern u_int netmap_buf_size;
-#define NETMAP_BUF_SIZE	netmap_buf_size
+#define NETMAP_BUF_SIZE	netmap_buf_size	// XXX remove
 extern int netmap_mitigate;
 extern int netmap_no_pendintr;
 extern u_int netmap_total_buffers;
@@ -431,11 +449,10 @@
 }
 
 
-#ifdef NETMAP_MEM2
 /* Entries of the look-up table. */
 struct lut_entry {
 	void *vaddr;		/* virtual address. */
-	vm_paddr_t paddr;	/* phisical address. */
+	vm_paddr_t paddr;	/* physical address. */
 };
 
 struct netmap_obj_pool;
@@ -442,9 +459,6 @@
 extern struct lut_entry *netmap_buffer_lut;
 #define NMB_VA(i)	(netmap_buffer_lut[i].vaddr)
 #define NMB_PA(i)	(netmap_buffer_lut[i].paddr)
-#else /* NETMAP_MEM1 */
-#define NMB_VA(i)	(netmap_buffer_base + (i * NETMAP_BUF_SIZE) )
-#endif /* NETMAP_MEM2 */
 
 /*
  * NMB return the virtual address of a buffer (buffer 0 on bad index)
@@ -462,11 +476,8 @@
 {
 	uint32_t i = slot->buf_idx;
 	void *ret = (i >= netmap_total_buffers) ? NMB_VA(0) : NMB_VA(i);
-#ifdef NETMAP_MEM2
+
 	*pp = (i >= netmap_total_buffers) ? NMB_PA(0) : NMB_PA(i);
-#else
-	*pp = vtophys(ret);
-#endif
 	return ret;
 }
 
@@ -474,5 +485,4 @@
 int netmap_rx_irq(struct ifnet *, int, int *);
 #define netmap_tx_irq(_n, _q) netmap_rx_irq(_n, _q, NULL)
 
-extern int netmap_copy;
 #endif /* _NET_NETMAP_KERN_H_ */

Modified: trunk/sys/dev/netmap/netmap_mem2.c
===================================================================
--- trunk/sys/dev/netmap/netmap_mem2.c	2017-03-04 16:46:41 UTC (rev 9347)
+++ trunk/sys/dev/netmap/netmap_mem2.c	2017-03-04 16:51:12 UTC (rev 9348)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Matteo Landi, Luigi Rizzo, Giuseppe Lettieri. All rights reserved.
+ * Copyright (C) 2012-2013 Matteo Landi, Luigi Rizzo, Giuseppe Lettieri. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -56,7 +56,7 @@
  * The pool is split into smaller clusters, whose size is a
  * multiple of the page size. The cluster size is chosen
  * to minimize the waste for a given max cluster size
- * (we do it by brute force, as we have relatively few object
+ * (we do it by brute force, as we have relatively few objects
  * per cluster).
  *
  * Objects are aligned to the cache line (64 bytes) rounding up object
@@ -80,7 +80,7 @@
  *	In the worst case we have one netmap_if per ring in the system.
  *
  * struct netmap_ring
- *	variable too, 8 byte per slot plus some fixed amount.
+ *	variable size, 8 byte per slot plus some fixed amount.
  *	Rings can be large (e.g. 4k slots, or >32Kbytes).
  *	We default to 36 KB (9 pages), and a few hundred rings.
  *
@@ -93,16 +93,14 @@
  *	the size to multiple of 1K or so. Default to 2K
  */
 
-#ifndef CONSERVATIVE
 #define NETMAP_BUF_MAX_NUM	20*4096*2	/* large machine */
-#else /* CONSERVATIVE */
-#define NETMAP_BUF_MAX_NUM      20000   /* 40MB */
-#endif
 
 #ifdef linux
+// XXX a mtx would suffice here 20130415 lr
+// #define NMA_LOCK_T		safe_spinlock_t
 #define NMA_LOCK_T		struct semaphore
 #define NMA_LOCK_INIT()		sema_init(&nm_mem.nm_mtx, 1)
-#define NMA_LOCK_DESTROY()	
+#define NMA_LOCK_DESTROY()
 #define NMA_LOCK()		down(&nm_mem.nm_mtx)
 #define NMA_UNLOCK()		up(&nm_mem.nm_mtx)
 #else /* !linux */
@@ -178,7 +176,11 @@
 	struct netmap_obj_pool pools[NETMAP_POOLS_NR];
 };
 
-
+/*
+ * nm_mem is the memory allocator used for all physical interfaces
+ * running in netmap mode.
+ * Virtual (VALE) ports will have each its own allocator.
+ */
 static struct netmap_mem_d nm_mem = {	/* Our memory allocator. */
 	.pools = {
 		[NETMAP_IF_POOL] = {
@@ -205,6 +207,7 @@
 	},
 };
 
+// XXX logically belongs to nm_mem
 struct lut_entry *netmap_buffer_lut;	/* exported */
 
 /* memory allocator related sysctls */
@@ -212,12 +215,10 @@
 #define STRINGIFY(x) #x
 
 #define DECLARE_SYSCTLS(id, name) \
-	/* TUNABLE_INT("hw.netmap." STRINGIFY(name) "_size", &netmap_params[id].size); */ \
 	SYSCTL_INT(_dev_netmap, OID_AUTO, name##_size, \
 	    CTLFLAG_RW, &netmap_params[id].size, 0, "Requested size of netmap " STRINGIFY(name) "s"); \
         SYSCTL_INT(_dev_netmap, OID_AUTO, name##_curr_size, \
             CTLFLAG_RD, &nm_mem.pools[id]._objsize, 0, "Current size of netmap " STRINGIFY(name) "s"); \
-	/* TUNABLE_INT("hw.netmap." STRINGIFY(name) "_num", &netmap_params[id].num); */ \
         SYSCTL_INT(_dev_netmap, OID_AUTO, name##_num, \
             CTLFLAG_RW, &netmap_params[id].num, 0, "Requested number of netmap " STRINGIFY(name) "s"); \
         SYSCTL_INT(_dev_netmap, OID_AUTO, name##_curr_num, \
@@ -228,14 +229,12 @@
 DECLARE_SYSCTLS(NETMAP_BUF_POOL, buf);
 
 /*
- * Convert a userspace offset to a phisical address.
- * XXX re-do in a simpler way.
+ * Convert a userspace offset to a physical address.
+ * XXX only called in the FreeBSD's netmap_mmap()
+ * because in linux we map everything at once.
  *
- * The idea here is to hide userspace applications the fact that pre-allocated
- * memory is not contiguous, but fragmented across different clusters and
- * smaller memory allocators. Consequently, first of all we need to find which
- * allocator is owning provided offset, then we need to find out the physical
- * address associated to target page (this is done using the look-up table.
+ * First, find the allocator that contains the requested offset,
+ * then locate the cluster through a lookup table.
  */
 static inline vm_paddr_t
 netmap_ofstophys(vm_offset_t offset)
@@ -247,7 +246,7 @@
 	for (i = 0; i < NETMAP_POOLS_NR; offset -= p[i]._memtotal, i++) {
 		if (offset >= p[i]._memtotal)
 			continue;
-		// XXX now scan the clusters
+		// now lookup the cluster's address
 		return p[i].lut[offset / p[i]._objsize].paddr +
 			offset % p[i]._objsize;
 	}
@@ -278,7 +277,7 @@
 		const char *base = p->lut[i].vaddr;
 		ssize_t relofs = (const char *) vaddr - base;
 
-		if (relofs < 0 || relofs > p->_clustsize)
+		if (relofs < 0 || relofs >= p->_clustsize)
 			continue;
 
 		ofs = ofs + relofs;
@@ -296,12 +295,12 @@
 	netmap_obj_offset(&nm_mem.pools[NETMAP_IF_POOL], (v))
 
 #define netmap_ring_offset(v)					\
-    (nm_mem.pools[NETMAP_IF_POOL]._memtotal + 				\
+    (nm_mem.pools[NETMAP_IF_POOL]._memtotal + 			\
 	netmap_obj_offset(&nm_mem.pools[NETMAP_RING_POOL], (v)))
 
 #define netmap_buf_offset(v)					\
-    (nm_mem.pools[NETMAP_IF_POOL]._memtotal +				\
-	nm_mem.pools[NETMAP_RING_POOL]._memtotal +			\
+    (nm_mem.pools[NETMAP_IF_POOL]._memtotal +			\
+	nm_mem.pools[NETMAP_RING_POOL]._memtotal +		\
 	netmap_obj_offset(&nm_mem.pools[NETMAP_BUF_POOL], (v)))
 
 
@@ -356,7 +355,8 @@
 
 
 /*
- * free by index, not by address
+ * free by index, not by address. This is slow, but is only used
+ * for a small number of objects (rings, nifp)
  */
 static void
 netmap_obj_free(struct netmap_obj_pool *p, uint32_t j)
@@ -380,7 +380,7 @@
 		ssize_t relofs = (ssize_t) vaddr - (ssize_t) base;
 
 		/* Given address, is out of the scope of the current cluster.*/
-		if (vaddr < base || relofs > p->_clustsize)
+		if (vaddr < base || relofs >= p->_clustsize)
 			continue;
 
 		j = j + relofs / p->_objsize;
@@ -428,7 +428,7 @@
 		 * in the NIC ring. This is a hack that hides missing
 		 * initializations in the drivers, and should go away.
 		 */
-		slot[i].flags = NS_BUF_CHANGED;
+		// slot[i].flags = NS_BUF_CHANGED;
 	}
 
 	ND("allocated %d buffers, %d available, first at %d", n, p->objfree, pos);
@@ -526,12 +526,12 @@
 		objsize += LINE_ROUND - i;
 	}
 	if (objsize < p->objminsize || objsize > p->objmaxsize) {
-		D("requested objsize %d out of range [%d, %d]", 
+		D("requested objsize %d out of range [%d, %d]",
 			objsize, p->objminsize, p->objmaxsize);
 		goto error;
 	}
 	if (objtotal < p->nummin || objtotal > p->nummax) {
-		D("requested objtotal %d out of range [%d, %d]", 
+		D("requested objtotal %d out of range [%d, %d]",
 			objtotal, p->nummin, p->nummax);
 		goto error;
 	}
@@ -683,7 +683,6 @@
 {
 	int i;
 
-
 	if (!netmap_memory_config_changed())
 		goto out;
 
@@ -693,7 +692,7 @@
 		/* reset previous allocation */
 		for (i = 0; i < NETMAP_POOLS_NR; i++) {
 			netmap_reset_obj_allocator(&nm_mem.pools[i]);
-		}    
+		}
 		nm_mem.finalized = 0;
         }
 



More information about the Midnightbsd-cvs mailing list