Deleted Added
full compact
netmap.c (246355) netmap.c (250458)
1/*
1/*
2 * Copyright (C) 2011-2012 Matteo Landi, Luigi Rizzo. All rights reserved.
2 * Copyright (C) 2011-2013 Matteo Landi, Luigi Rizzo. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the

--- 49 unchanged lines hidden (view full) ---

60#endif /* linux */
61
62#ifdef __APPLE__
63#include "osx_glue.h"
64#endif /* __APPLE__ */
65
66#ifdef __FreeBSD__
67#include <sys/cdefs.h> /* prerequisite */
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the

--- 49 unchanged lines hidden (view full) ---

60#endif /* linux */
61
62#ifdef __APPLE__
63#include "osx_glue.h"
64#endif /* __APPLE__ */
65
66#ifdef __FreeBSD__
67#include <sys/cdefs.h> /* prerequisite */
68__FBSDID("$FreeBSD: stable/9/sys/dev/netmap/netmap.c 246355 2013-02-05 09:40:31Z luigi $");
68__FBSDID("$FreeBSD: stable/9/sys/dev/netmap/netmap.c 250458 2013-05-10 16:16:33Z luigi $");
69
70#include <sys/types.h>
71#include <sys/module.h>
72#include <sys/errno.h>
73#include <sys/param.h> /* defines used in kernel.h */
74#include <sys/jail.h>
75#include <sys/kernel.h> /* types used in module initialization */
76#include <sys/conf.h> /* cdevsw struct */
77#include <sys/uio.h> /* uio struct */
78#include <sys/sockio.h>
79#include <sys/socketvar.h> /* struct socket */
80#include <sys/malloc.h>
81#include <sys/mman.h> /* PROT_EXEC */
82#include <sys/poll.h>
83#include <sys/proc.h>
69
70#include <sys/types.h>
71#include <sys/module.h>
72#include <sys/errno.h>
73#include <sys/param.h> /* defines used in kernel.h */
74#include <sys/jail.h>
75#include <sys/kernel.h> /* types used in module initialization */
76#include <sys/conf.h> /* cdevsw struct */
77#include <sys/uio.h> /* uio struct */
78#include <sys/sockio.h>
79#include <sys/socketvar.h> /* struct socket */
80#include <sys/malloc.h>
81#include <sys/mman.h> /* PROT_EXEC */
82#include <sys/poll.h>
83#include <sys/proc.h>
84#include <sys/rwlock.h>
84#include <vm/vm.h> /* vtophys */
85#include <vm/pmap.h> /* vtophys */
86#include <sys/socket.h> /* sockaddrs */
87#include <machine/bus.h>
88#include <sys/selinfo.h>
89#include <sys/sysctl.h>
90#include <net/if.h>
91#include <net/bpf.h> /* BIOCIMMEDIATE */
92#include <net/vnet.h>
93#include <machine/bus.h> /* bus_dmamap_* */
94
95MALLOC_DEFINE(M_NETMAP, "netmap", "Network memory map");
96#endif /* __FreeBSD__ */
97
98#include <net/netmap.h>
99#include <dev/netmap/netmap_kern.h>
100
85#include <vm/vm.h> /* vtophys */
86#include <vm/pmap.h> /* vtophys */
87#include <sys/socket.h> /* sockaddrs */
88#include <machine/bus.h>
89#include <sys/selinfo.h>
90#include <sys/sysctl.h>
91#include <net/if.h>
92#include <net/bpf.h> /* BIOCIMMEDIATE */
93#include <net/vnet.h>
94#include <machine/bus.h> /* bus_dmamap_* */
95
96MALLOC_DEFINE(M_NETMAP, "netmap", "Network memory map");
97#endif /* __FreeBSD__ */
98
99#include <net/netmap.h>
100#include <dev/netmap/netmap_kern.h>
101
102/* XXX the following variables must be deprecated and included in nm_mem */
101u_int netmap_total_buffers;
102u_int netmap_buf_size;
103char *netmap_buffer_base; /* address of an invalid buffer */
104
105/* user-controlled variables */
106int netmap_verbose;
107
108static int netmap_no_timestamp; /* don't timestamp on rxsync */

--- 7 unchanged lines hidden (view full) ---

116SYSCTL_INT(_dev_netmap, OID_AUTO, mitigate, CTLFLAG_RW, &netmap_mitigate, 0, "");
117int netmap_no_pendintr = 1;
118SYSCTL_INT(_dev_netmap, OID_AUTO, no_pendintr,
119 CTLFLAG_RW, &netmap_no_pendintr, 0, "Always look for new received packets.");
120
121int netmap_drop = 0; /* debugging */
122int netmap_flags = 0; /* debug flags */
123int netmap_fwd = 0; /* force transparent mode */
103u_int netmap_total_buffers;
104u_int netmap_buf_size;
105char *netmap_buffer_base; /* address of an invalid buffer */
106
107/* user-controlled variables */
108int netmap_verbose;
109
110static int netmap_no_timestamp; /* don't timestamp on rxsync */

--- 7 unchanged lines hidden (view full) ---

118SYSCTL_INT(_dev_netmap, OID_AUTO, mitigate, CTLFLAG_RW, &netmap_mitigate, 0, "");
119int netmap_no_pendintr = 1;
120SYSCTL_INT(_dev_netmap, OID_AUTO, no_pendintr,
121 CTLFLAG_RW, &netmap_no_pendintr, 0, "Always look for new received packets.");
122
123int netmap_drop = 0; /* debugging */
124int netmap_flags = 0; /* debug flags */
125int netmap_fwd = 0; /* force transparent mode */
124int netmap_copy = 0; /* debugging, copy content */
125
126SYSCTL_INT(_dev_netmap, OID_AUTO, drop, CTLFLAG_RW, &netmap_drop, 0 , "");
127SYSCTL_INT(_dev_netmap, OID_AUTO, flags, CTLFLAG_RW, &netmap_flags, 0 , "");
128SYSCTL_INT(_dev_netmap, OID_AUTO, fwd, CTLFLAG_RW, &netmap_fwd, 0 , "");
126
127SYSCTL_INT(_dev_netmap, OID_AUTO, drop, CTLFLAG_RW, &netmap_drop, 0 , "");
128SYSCTL_INT(_dev_netmap, OID_AUTO, flags, CTLFLAG_RW, &netmap_flags, 0 , "");
129SYSCTL_INT(_dev_netmap, OID_AUTO, fwd, CTLFLAG_RW, &netmap_fwd, 0 , "");
129SYSCTL_INT(_dev_netmap, OID_AUTO, copy, CTLFLAG_RW, &netmap_copy, 0 , "");
130
131#ifdef NM_BRIDGE /* support for netmap bridge */
132
133/*
134 * system parameters.
135 *
136 * All switched ports have prefix NM_NAME.
137 * The switch has a max of NM_BDG_MAXPORTS ports (often stored in a bitmap,

--- 4 unchanged lines hidden (view full) ---

142 * faster. The batch size is NM_BDG_BATCH
143 */
144#define NM_NAME "vale" /* prefix for the interface */
145#define NM_BDG_MAXPORTS 16 /* up to 64 ? */
146#define NM_BRIDGE_RINGSIZE 1024 /* in the device */
147#define NM_BDG_HASH 1024 /* forwarding table entries */
148#define NM_BDG_BATCH 1024 /* entries in the forwarding buffer */
149#define NM_BRIDGES 4 /* number of bridges */
130
131#ifdef NM_BRIDGE /* support for netmap bridge */
132
133/*
134 * system parameters.
135 *
136 * All switched ports have prefix NM_NAME.
137 * The switch has a max of NM_BDG_MAXPORTS ports (often stored in a bitmap,

--- 4 unchanged lines hidden (view full) ---

142 * faster. The batch size is NM_BDG_BATCH
143 */
144#define NM_NAME "vale" /* prefix for the interface */
145#define NM_BDG_MAXPORTS 16 /* up to 64 ? */
146#define NM_BRIDGE_RINGSIZE 1024 /* in the device */
147#define NM_BDG_HASH 1024 /* forwarding table entries */
148#define NM_BDG_BATCH 1024 /* entries in the forwarding buffer */
149#define NM_BRIDGES 4 /* number of bridges */
150
151
150int netmap_bridge = NM_BDG_BATCH; /* bridge batch size */
151SYSCTL_INT(_dev_netmap, OID_AUTO, bridge, CTLFLAG_RW, &netmap_bridge, 0 , "");
152
153#ifdef linux
152int netmap_bridge = NM_BDG_BATCH; /* bridge batch size */
153SYSCTL_INT(_dev_netmap, OID_AUTO, bridge, CTLFLAG_RW, &netmap_bridge, 0 , "");
154
155#ifdef linux
154#define ADD_BDG_REF(ifp) (NA(ifp)->if_refcount++)
155#define DROP_BDG_REF(ifp) (NA(ifp)->if_refcount-- <= 1)
156
157#define refcount_acquire(_a) atomic_add(1, (atomic_t *)_a)
158#define refcount_release(_a) atomic_dec_and_test((atomic_t *)_a)
159
156#else /* !linux */
160#else /* !linux */
157#define ADD_BDG_REF(ifp) (ifp)->if_refcount++
158#define DROP_BDG_REF(ifp) refcount_release(&(ifp)->if_refcount)
161
159#ifdef __FreeBSD__
160#include <sys/endian.h>
161#include <sys/refcount.h>
162#endif /* __FreeBSD__ */
162#ifdef __FreeBSD__
163#include <sys/endian.h>
164#include <sys/refcount.h>
165#endif /* __FreeBSD__ */
166
163#define prefetch(x) __builtin_prefetch(x)
167#define prefetch(x) __builtin_prefetch(x)
168
164#endif /* !linux */
165
169#endif /* !linux */
170
171/*
172 * These are used to handle reference counters for bridge ports.
173 */
174#define ADD_BDG_REF(ifp) refcount_acquire(&NA(ifp)->na_bdg_refcount)
175#define DROP_BDG_REF(ifp) refcount_release(&NA(ifp)->na_bdg_refcount)
176
166static void bdg_netmap_attach(struct ifnet *ifp);
167static int bdg_netmap_reg(struct ifnet *ifp, int onoff);
168/* per-tx-queue entry */
169struct nm_bdg_fwd { /* forwarding entry for a bridge */
170 void *buf;
171 uint64_t dst; /* dst mask */
172 uint32_t src; /* src index ? */
173 uint16_t len; /* src len */
174};
175
176struct nm_hash_ent {
177 uint64_t mac; /* the top 2 bytes are the epoch */
178 uint64_t ports;
179};
180
181/*
177static void bdg_netmap_attach(struct ifnet *ifp);
178static int bdg_netmap_reg(struct ifnet *ifp, int onoff);
179/* per-tx-queue entry */
180struct nm_bdg_fwd { /* forwarding entry for a bridge */
181 void *buf;
182 uint64_t dst; /* dst mask */
183 uint32_t src; /* src index ? */
184 uint16_t len; /* src len */
185};
186
187struct nm_hash_ent {
188 uint64_t mac; /* the top 2 bytes are the epoch */
189 uint64_t ports;
190};
191
192/*
182 * Interfaces for a bridge are all in ports[].
193 * Interfaces for a bridge are all in bdg_ports[].
183 * The array has fixed size, an empty entry does not terminate
194 * The array has fixed size, an empty entry does not terminate
184 * the search.
195 * the search. But lookups only occur on attach/detach so we
196 * don't mind if they are slow.
197 *
198 * The bridge is non blocking on the transmit ports.
199 *
200 * bdg_lock protects accesses to the bdg_ports array.
185 */
186struct nm_bridge {
187 struct ifnet *bdg_ports[NM_BDG_MAXPORTS];
188 int n_ports;
189 uint64_t act_ports;
190 int freelist; /* first buffer index */
191 NM_SELINFO_T si; /* poll/select wait queue */
192 NM_LOCK_T bdg_lock; /* protect the selinfo ? */

--- 99 unchanged lines hidden (view full) ---

292 if (na->nm_config) {
293 na->nm_config(ifp, &txr, &txd, &rxr, &rxd);
294 } else {
295 /* take whatever we had at init time */
296 txr = na->num_tx_rings;
297 txd = na->num_tx_desc;
298 rxr = na->num_rx_rings;
299 rxd = na->num_rx_desc;
201 */
202struct nm_bridge {
203 struct ifnet *bdg_ports[NM_BDG_MAXPORTS];
204 int n_ports;
205 uint64_t act_ports;
206 int freelist; /* first buffer index */
207 NM_SELINFO_T si; /* poll/select wait queue */
208 NM_LOCK_T bdg_lock; /* protect the selinfo ? */

--- 99 unchanged lines hidden (view full) ---

308 if (na->nm_config) {
309 na->nm_config(ifp, &txr, &txd, &rxr, &rxd);
310 } else {
311 /* take whatever we had at init time */
312 txr = na->num_tx_rings;
313 txd = na->num_tx_desc;
314 rxr = na->num_rx_rings;
315 rxd = na->num_rx_desc;
300 }
316 }
301
302 if (na->num_tx_rings == txr && na->num_tx_desc == txd &&
303 na->num_rx_rings == rxr && na->num_rx_desc == rxd)
304 return 0; /* nothing changed */
305 if (netmap_verbose || na->refcount > 0) {
306 D("stored config %s: txring %d x %d, rxring %d x %d",
307 ifp->if_xname,
308 na->num_tx_rings, na->num_tx_desc,

--- 9 unchanged lines hidden (view full) ---

318 na->num_rx_desc = rxd;
319 return 0;
320 }
321 D("configuration changed while active, this is bad...");
322 return 1;
323}
324
325/*------------- memory allocator -----------------*/
317
318 if (na->num_tx_rings == txr && na->num_tx_desc == txd &&
319 na->num_rx_rings == rxr && na->num_rx_desc == rxd)
320 return 0; /* nothing changed */
321 if (netmap_verbose || na->refcount > 0) {
322 D("stored config %s: txring %d x %d, rxring %d x %d",
323 ifp->if_xname,
324 na->num_tx_rings, na->num_tx_desc,

--- 9 unchanged lines hidden (view full) ---

334 na->num_rx_desc = rxd;
335 return 0;
336 }
337 D("configuration changed while active, this is bad...");
338 return 1;
339}
340
341/*------------- memory allocator -----------------*/
326#ifdef NETMAP_MEM2
327#include "netmap_mem2.c"
342#include "netmap_mem2.c"
328#else /* !NETMAP_MEM2 */
329#include "netmap_mem1.c"
330#endif /* !NETMAP_MEM2 */
331/*------------ end of memory allocator ----------*/
332
333
334/* Structure associated to each thread which registered an interface.
335 *
336 * The first 4 fields of this structure are written by NIOCREGIF and
337 * read by poll() and NIOC?XSYNC.
338 * There is low contention among writers (actually, a correct user program

--- 153 unchanged lines hidden (view full) ---

492#endif /* NM_BRIDGE */
493}
494
495static void
496netmap_dtor(void *data)
497{
498 struct netmap_priv_d *priv = data;
499 struct ifnet *ifp = priv->np_ifp;
343/*------------ end of memory allocator ----------*/
344
345
346/* Structure associated to each thread which registered an interface.
347 *
348 * The first 4 fields of this structure are written by NIOCREGIF and
349 * read by poll() and NIOC?XSYNC.
350 * There is low contention among writers (actually, a correct user program

--- 153 unchanged lines hidden (view full) ---

504#endif /* NM_BRIDGE */
505}
506
507static void
508netmap_dtor(void *data)
509{
510 struct netmap_priv_d *priv = data;
511 struct ifnet *ifp = priv->np_ifp;
500 struct netmap_adapter *na;
501
502 NMA_LOCK();
503 if (ifp) {
512
513 NMA_LOCK();
514 if (ifp) {
504 na = NA(ifp);
515 struct netmap_adapter *na = NA(ifp);
516
505 na->nm_lock(ifp, NETMAP_REG_LOCK, 0);
506 netmap_dtor_locked(data);
507 na->nm_lock(ifp, NETMAP_REG_UNLOCK, 0);
508
517 na->nm_lock(ifp, NETMAP_REG_LOCK, 0);
518 netmap_dtor_locked(data);
519 na->nm_lock(ifp, NETMAP_REG_UNLOCK, 0);
520
509 nm_if_rele(ifp);
521 nm_if_rele(ifp); /* might also destroy *na */
510 }
511 if (priv->ref_done) {
512 netmap_memory_deref();
513 }
514 NMA_UNLOCK();
515 bzero(priv, sizeof(*priv)); /* XXX for safety */
516 free(priv, M_DEVBUF);
517}

--- 1145 unchanged lines hidden (view full) ---

1663 na->num_rx_rings = num_queues;
1664 na->refcount = na->na_single = na->na_multi = 0;
1665 /* Core lock initialized here, others after netmap_if_new. */
1666 mtx_init(&na->core_lock, "netmap core lock", MTX_NETWORK_LOCK, MTX_DEF);
1667 if (na->nm_lock == NULL) {
1668 ND("using default locks for %s", ifp->if_xname);
1669 na->nm_lock = netmap_lock_wrapper;
1670 }
522 }
523 if (priv->ref_done) {
524 netmap_memory_deref();
525 }
526 NMA_UNLOCK();
527 bzero(priv, sizeof(*priv)); /* XXX for safety */
528 free(priv, M_DEVBUF);
529}

--- 1145 unchanged lines hidden (view full) ---

1675 na->num_rx_rings = num_queues;
1676 na->refcount = na->na_single = na->na_multi = 0;
1677 /* Core lock initialized here, others after netmap_if_new. */
1678 mtx_init(&na->core_lock, "netmap core lock", MTX_NETWORK_LOCK, MTX_DEF);
1679 if (na->nm_lock == NULL) {
1680 ND("using default locks for %s", ifp->if_xname);
1681 na->nm_lock = netmap_lock_wrapper;
1682 }
1683
1671#ifdef linux
1684#ifdef linux
1672 if (ifp->netdev_ops) {
1673 ND("netdev_ops %p", ifp->netdev_ops);
1674 /* prepare a clone of the netdev ops */
1675 na->nm_ndo = *ifp->netdev_ops;
1685 if (!ifp->netdev_ops) {
1686 D("ouch, we cannot override netdev_ops");
1687 goto fail;
1676 }
1688 }
1689#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
1690 /* if needed, prepare a clone of the entire netdev ops */
1691 na->nm_ndo = *ifp->netdev_ops;
1692#endif /* 2.6.28 and above */
1677 na->nm_ndo.ndo_start_xmit = linux_netmap_start;
1693 na->nm_ndo.ndo_start_xmit = linux_netmap_start;
1678#endif
1694#endif /* linux */
1695
1679 D("success for %s", ifp->if_xname);
1680 return 0;
1681
1682fail:
1683 D("fail, arg %p ifp %p na %p", arg, ifp, na);
1696 D("success for %s", ifp->if_xname);
1697 return 0;
1698
1699fail:
1700 D("fail, arg %p ifp %p na %p", arg, ifp, na);
1701 netmap_detach(ifp);
1684 return (na ? EINVAL : ENOMEM);
1685}
1686
1687
1688/*
1689 * Free the allocated memory linked to the given ``netmap_adapter``
1690 * object.
1691 */

--- 29 unchanged lines hidden (view full) ---

1721 struct netmap_kring *kring = &na->rx_rings[na->num_rx_rings];
1722 u_int i, len = MBUF_LEN(m);
1723 u_int error = EBUSY, lim = kring->nkr_num_slots - 1;
1724 struct netmap_slot *slot;
1725
1726 if (netmap_verbose & NM_VERB_HOST)
1727 D("%s packet %d len %d from the stack", ifp->if_xname,
1728 kring->nr_hwcur + kring->nr_hwavail, len);
1702 return (na ? EINVAL : ENOMEM);
1703}
1704
1705
1706/*
1707 * Free the allocated memory linked to the given ``netmap_adapter``
1708 * object.
1709 */

--- 29 unchanged lines hidden (view full) ---

1739 struct netmap_kring *kring = &na->rx_rings[na->num_rx_rings];
1740 u_int i, len = MBUF_LEN(m);
1741 u_int error = EBUSY, lim = kring->nkr_num_slots - 1;
1742 struct netmap_slot *slot;
1743
1744 if (netmap_verbose & NM_VERB_HOST)
1745 D("%s packet %d len %d from the stack", ifp->if_xname,
1746 kring->nr_hwcur + kring->nr_hwavail, len);
1747 if (len > NETMAP_BUF_SIZE) { /* too long for us */
1748 D("%s from_host, drop packet size %d > %d", ifp->if_xname,
1749 len, NETMAP_BUF_SIZE);
1750 m_freem(m);
1751 return EINVAL;
1752 }
1729 na->nm_lock(ifp, NETMAP_CORE_LOCK, 0);
1730 if (kring->nr_hwavail >= lim) {
1731 if (netmap_verbose)
1732 D("stack ring %s full\n", ifp->if_xname);
1733 goto done; /* no space */
1734 }
1753 na->nm_lock(ifp, NETMAP_CORE_LOCK, 0);
1754 if (kring->nr_hwavail >= lim) {
1755 if (netmap_verbose)
1756 D("stack ring %s full\n", ifp->if_xname);
1757 goto done; /* no space */
1758 }
1735 if (len > NETMAP_BUF_SIZE) {
1736 D("%s from_host, drop packet size %d > %d", ifp->if_xname,
1737 len, NETMAP_BUF_SIZE);
1738 goto done; /* too long for us */
1739 }
1740
1741 /* compute the insert position */
1742 i = kring->nr_hwcur + kring->nr_hwavail;
1743 if (i > lim)
1744 i -= lim + 1;
1745 slot = &kring->ring->slot[i];
1746 m_copydata(m, 0, len, NMB(slot));
1747 slot->len = len;

--- 84 unchanged lines hidden (view full) ---

1832 * lock(core); wake(i=0); unlock(core)
1833 * N rings, single lock:
1834 * lock(core); wake(i); wake(N+1) unlock(core)
1835 * 1 ring, separate locks: (i=0)
1836 * lock(i); wake(i); unlock(i)
1837 * N rings, separate locks:
1838 * lock(i); wake(i); unlock(i); lock(core) wake(N+1) unlock(core)
1839 * work_done is non-null on the RX path.
1759
1760 /* compute the insert position */
1761 i = kring->nr_hwcur + kring->nr_hwavail;
1762 if (i > lim)
1763 i -= lim + 1;
1764 slot = &kring->ring->slot[i];
1765 m_copydata(m, 0, len, NMB(slot));
1766 slot->len = len;

--- 84 unchanged lines hidden (view full) ---

1851 * lock(core); wake(i=0); unlock(core)
1852 * N rings, single lock:
1853 * lock(core); wake(i); wake(N+1) unlock(core)
1854 * 1 ring, separate locks: (i=0)
1855 * lock(i); wake(i); unlock(i)
1856 * N rings, separate locks:
1857 * lock(i); wake(i); unlock(i); lock(core) wake(N+1) unlock(core)
1858 * work_done is non-null on the RX path.
1859 *
1860 * The 'q' argument also includes flag to tell whether the queue is
1861 * already locked on enter, and whether it should remain locked on exit.
1862 * This helps adapting to different defaults in drivers and OSes.
1840 */
1841int
1842netmap_rx_irq(struct ifnet *ifp, int q, int *work_done)
1843{
1844 struct netmap_adapter *na;
1845 struct netmap_kring *r;
1846 NM_SELINFO_T *main_wq;
1863 */
1864int
1865netmap_rx_irq(struct ifnet *ifp, int q, int *work_done)
1866{
1867 struct netmap_adapter *na;
1868 struct netmap_kring *r;
1869 NM_SELINFO_T *main_wq;
1870 int locktype, unlocktype, lock;
1847
1848 if (!(ifp->if_capenable & IFCAP_NETMAP))
1849 return 0;
1871
1872 if (!(ifp->if_capenable & IFCAP_NETMAP))
1873 return 0;
1874
1875 lock = q & (NETMAP_LOCKED_ENTER | NETMAP_LOCKED_EXIT);
1876 q = q & NETMAP_RING_MASK;
1877
1850 ND(5, "received %s queue %d", work_done ? "RX" : "TX" , q);
1851 na = NA(ifp);
1852 if (na->na_flags & NAF_SKIP_INTR) {
1853 ND("use regular interrupt");
1854 return 0;
1855 }
1856
1857 if (work_done) { /* RX path */
1858 if (q >= na->num_rx_rings)
1878 ND(5, "received %s queue %d", work_done ? "RX" : "TX" , q);
1879 na = NA(ifp);
1880 if (na->na_flags & NAF_SKIP_INTR) {
1881 ND("use regular interrupt");
1882 return 0;
1883 }
1884
1885 if (work_done) { /* RX path */
1886 if (q >= na->num_rx_rings)
1859 return 0; // regular queue
1887 return 0; // not a physical queue
1860 r = na->rx_rings + q;
1861 r->nr_kflags |= NKR_PENDINTR;
1862 main_wq = (na->num_rx_rings > 1) ? &na->rx_si : NULL;
1888 r = na->rx_rings + q;
1889 r->nr_kflags |= NKR_PENDINTR;
1890 main_wq = (na->num_rx_rings > 1) ? &na->rx_si : NULL;
1863 } else { /* tx path */
1891 locktype = NETMAP_RX_LOCK;
1892 unlocktype = NETMAP_RX_UNLOCK;
1893 } else { /* TX path */
1864 if (q >= na->num_tx_rings)
1894 if (q >= na->num_tx_rings)
1865 return 0; // regular queue
1895 return 0; // not a physical queue
1866 r = na->tx_rings + q;
1867 main_wq = (na->num_tx_rings > 1) ? &na->tx_si : NULL;
1868 work_done = &q; /* dummy */
1896 r = na->tx_rings + q;
1897 main_wq = (na->num_tx_rings > 1) ? &na->tx_si : NULL;
1898 work_done = &q; /* dummy */
1899 locktype = NETMAP_TX_LOCK;
1900 unlocktype = NETMAP_TX_UNLOCK;
1869 }
1870 if (na->separate_locks) {
1901 }
1902 if (na->separate_locks) {
1871 mtx_lock(&r->q_lock);
1903 if (!(lock & NETMAP_LOCKED_ENTER))
1904 na->nm_lock(ifp, locktype, q);
1872 selwakeuppri(&r->si, PI_NET);
1905 selwakeuppri(&r->si, PI_NET);
1873 mtx_unlock(&r->q_lock);
1906 na->nm_lock(ifp, unlocktype, q);
1874 if (main_wq) {
1907 if (main_wq) {
1875 mtx_lock(&na->core_lock);
1908 na->nm_lock(ifp, NETMAP_CORE_LOCK, 0);
1876 selwakeuppri(main_wq, PI_NET);
1909 selwakeuppri(main_wq, PI_NET);
1877 mtx_unlock(&na->core_lock);
1910 na->nm_lock(ifp, NETMAP_CORE_UNLOCK, 0);
1878 }
1911 }
1912 /* lock the queue again if requested */
1913 if (lock & NETMAP_LOCKED_EXIT)
1914 na->nm_lock(ifp, locktype, q);
1879 } else {
1915 } else {
1880 mtx_lock(&na->core_lock);
1916 if (!(lock & NETMAP_LOCKED_ENTER))
1917 na->nm_lock(ifp, NETMAP_CORE_LOCK, 0);
1881 selwakeuppri(&r->si, PI_NET);
1882 if (main_wq)
1883 selwakeuppri(main_wq, PI_NET);
1918 selwakeuppri(&r->si, PI_NET);
1919 if (main_wq)
1920 selwakeuppri(main_wq, PI_NET);
1884 mtx_unlock(&na->core_lock);
1921 if (!(lock & NETMAP_LOCKED_EXIT))
1922 na->nm_lock(ifp, NETMAP_CORE_UNLOCK, 0);
1885 }
1886 *work_done = 1; /* do not fire napi again */
1887 return 1;
1888}
1889
1890
1891#ifdef linux /* linux-specific routines */
1892

--- 4 unchanged lines hidden (view full) ---

1897 * events but they are filtered upstream.
1898 * If pwait != NULL, then pwait->key contains the list of events.
1899 * - events is computed from pwait as above.
1900 * - file is passed as 'td';
1901 */
1902static u_int
1903linux_netmap_poll(struct file * file, struct poll_table_struct *pwait)
1904{
1923 }
1924 *work_done = 1; /* do not fire napi again */
1925 return 1;
1926}
1927
1928
1929#ifdef linux /* linux-specific routines */
1930

--- 4 unchanged lines hidden (view full) ---

1935 * events but they are filtered upstream.
1936 * If pwait != NULL, then pwait->key contains the list of events.
1937 * - events is computed from pwait as above.
1938 * - file is passed as 'td';
1939 */
1940static u_int
1941linux_netmap_poll(struct file * file, struct poll_table_struct *pwait)
1942{
1905#if LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)
1943#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
1944 int events = POLLIN | POLLOUT; /* XXX maybe... */
1945#elif LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)
1906 int events = pwait ? pwait->key : POLLIN | POLLOUT;
1907#else /* in 3.4.0 field 'key' was renamed to '_key' */
1908 int events = pwait ? pwait->_key : POLLIN | POLLOUT;
1909#endif
1910 return netmap_poll((void *)pwait, events, (void *)file);
1911}
1912
1913static int

--- 23 unchanged lines hidden (view full) ---

1937 const struct netmap_obj_pool *p = &nm_mem.pools[i];
1938 /*
1939 * In each pool memory is allocated in clusters
1940 * of size _clustsize, each containing clustentries
1941 * entries. For each object k we already store the
1942 * vtophys mapping in lut[k] so we use that, scanning
1943 * the lut[] array in steps of clustentries,
1944 * and we map each cluster (not individual pages,
1946 int events = pwait ? pwait->key : POLLIN | POLLOUT;
1947#else /* in 3.4.0 field 'key' was renamed to '_key' */
1948 int events = pwait ? pwait->_key : POLLIN | POLLOUT;
1949#endif
1950 return netmap_poll((void *)pwait, events, (void *)file);
1951}
1952
1953static int

--- 23 unchanged lines hidden (view full) ---

1977 const struct netmap_obj_pool *p = &nm_mem.pools[i];
1978 /*
1979 * In each pool memory is allocated in clusters
1980 * of size _clustsize, each containing clustentries
1981 * entries. For each object k we already store the
1982 * vtophys mapping in lut[k] so we use that, scanning
1983 * the lut[] array in steps of clustentries,
1984 * and we map each cluster (not individual pages,
1945 * it would be overkill).
1985 * it would be overkill -- XXX slow ? 20130415).
1946 */
1947
1948 /*
1949 * We interpret vm_pgoff as an offset into the whole
1950 * netmap memory, as if all clusters where contiguous.
1951 */
1952 for (lut_skip = 0, j = 0; j < p->_numclusters; j++, lut_skip += p->clustentries) {
1953 unsigned long paddr, mapsize;

--- 561 unchanged lines hidden ---
1986 */
1987
1988 /*
1989 * We interpret vm_pgoff as an offset into the whole
1990 * netmap memory, as if all clusters where contiguous.
1991 */
1992 for (lut_skip = 0, j = 0; j < p->_numclusters; j++, lut_skip += p->clustentries) {
1993 unsigned long paddr, mapsize;

--- 561 unchanged lines hidden ---