[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