Skip to content

Commit 6292c40

Browse files
committed
Merge branch 'master' into gh
2 parents 4cb0862 + 528c311 commit 6292c40

10 files changed

+67
-46
lines changed

sys/dev/netmap/netmap.c

+28-14
Original file line numberDiff line numberDiff line change
@@ -1145,16 +1145,24 @@ nm_may_forward_up(struct netmap_kring *kring)
11451145
}
11461146

11471147
static inline int
1148-
nm_may_forward_down(struct netmap_kring *kring)
1148+
nm_may_forward_down(struct netmap_kring *kring, int sync_flags)
11491149
{
11501150
return _nm_may_forward(kring) &&
1151+
(sync_flags & NAF_CAN_FORWARD_DOWN) &&
11511152
kring->ring_id == kring->na->num_rx_rings;
11521153
}
11531154

11541155
/*
11551156
* Send to the NIC rings packets marked NS_FORWARD between
1156-
* kring->nr_hwcur and kring->rhead
1157-
* Called under kring->rx_queue.lock on the sw rx ring,
1157+
* kring->nr_hwcur and kring->rhead.
1158+
* Called under kring->rx_queue.lock on the sw rx ring.
1159+
*
1160+
* It can only be called if the user opened all the TX hw rings,
1161+
* see NAF_CAN_FORWARD_DOWN flag.
1162+
* We can touch the TX netmap rings (slots, head and cur) since
1163+
* we are in poll/ioctl system call context, and the application
1164+
* is not supposed to touch the ring (using a different thread)
1165+
* during the execution of the system call.
11581166
*/
11591167
static u_int
11601168
netmap_sw_to_nic(struct netmap_adapter *na)
@@ -1168,8 +1176,6 @@ netmap_sw_to_nic(struct netmap_adapter *na)
11681176

11691177
/* scan rings to find space, then fill as much as possible */
11701178
for (i = 0; i < na->num_tx_rings; i++) {
1171-
/* XXX some krings may not be in netmap mode,
1172-
* buffers may not be there */
11731179
struct netmap_kring *kdst = &na->tx_rings[i];
11741180
struct netmap_ring *rdst = kdst->ring;
11751181
u_int const dst_lim = kdst->nkr_num_slots - 1;
@@ -1197,11 +1203,9 @@ netmap_sw_to_nic(struct netmap_adapter *na)
11971203
dst->len = tmp.len;
11981204
dst->flags = NS_BUF_CHANGED;
11991205

1200-
/* XXX is it safe to write head/cur concurrently to
1201-
* the userspace application? */
12021206
rdst->head = rdst->cur = nm_next(dst_head, dst_lim);
12031207
}
1204-
/* if (sent) XXX txsync ? */
1208+
/* if (sent) XXX txsync ? it would be just an optimization */
12051209
}
12061210
return sent;
12071211
}
@@ -1291,7 +1295,7 @@ netmap_rxsync_from_host(struct netmap_kring *kring, int flags)
12911295
*/
12921296
nm_i = kring->nr_hwcur;
12931297
if (nm_i != head) { /* something was released */
1294-
if (nm_may_forward_down(kring)) {
1298+
if (nm_may_forward_down(kring, flags)) {
12951299
ret = netmap_sw_to_nic(na);
12961300
if (ret > 0) {
12971301
kring->nr_kflags |= NR_FORWARD;
@@ -1806,6 +1810,13 @@ netmap_interp_ringid(struct netmap_priv_d *priv, uint16_t ringid, uint32_t flags
18061810
}
18071811
priv->np_flags = (flags & ~NR_REG_MASK) | reg;
18081812

1813+
/* Allow transparent forwarding mode in the host --> nic
1814+
* direction only if all the TX hw rings have been opened. */
1815+
if (priv->np_qfirst[NR_TX] == 0 &&
1816+
priv->np_qlast[NR_TX] >= na->num_tx_rings) {
1817+
priv->np_sync_flags |= NAF_CAN_FORWARD_DOWN;
1818+
}
1819+
18091820
if (netmap_verbose) {
18101821
D("%s: tx [%d,%d) rx [%d,%d) id %d",
18111822
na->name,
@@ -2069,7 +2080,7 @@ netmap_do_regif(struct netmap_priv_d *priv, struct netmap_adapter *na,
20692080
goto err_rel_excl;
20702081

20712082
/* in all cases, create a new netmap if */
2072-
nifp = netmap_mem_if_new(na);
2083+
nifp = netmap_mem_if_new(na, priv);
20732084
if (nifp == NULL) {
20742085
error = ENOMEM;
20752086
goto err_del_rings;
@@ -2177,6 +2188,7 @@ netmap_ioctl(struct netmap_priv_d *priv, u_long cmd, caddr_t data, struct thread
21772188
u_int i, qfirst, qlast;
21782189
struct netmap_if *nifp;
21792190
struct netmap_kring *krings;
2191+
int sync_flags;
21802192
enum txrx t;
21812193

21822194
if (cmd == NIOCGINFO || cmd == NIOCREGIF) {
@@ -2387,6 +2399,7 @@ netmap_ioctl(struct netmap_priv_d *priv, u_long cmd, caddr_t data, struct thread
23872399
krings = NMR(na, t);
23882400
qfirst = priv->np_qfirst[t];
23892401
qlast = priv->np_qlast[t];
2402+
sync_flags = priv->np_sync_flags;
23902403

23912404
for (i = qfirst; i < qlast; i++) {
23922405
struct netmap_kring *kring = krings + i;
@@ -2404,7 +2417,7 @@ netmap_ioctl(struct netmap_priv_d *priv, u_long cmd, caddr_t data, struct thread
24042417
kring->nr_hwcur);
24052418
if (nm_txsync_prologue(kring, ring) >= kring->nkr_num_slots) {
24062419
netmap_ring_reinit(kring);
2407-
} else if (kring->nm_sync(kring, NAF_FORCE_RECLAIM) == 0) {
2420+
} else if (kring->nm_sync(kring, sync_flags | NAF_FORCE_RECLAIM) == 0) {
24082421
nm_sync_finalize(kring);
24092422
}
24102423
if (netmap_verbose & NM_VERB_TXSYNC)
@@ -2419,7 +2432,7 @@ netmap_ioctl(struct netmap_priv_d *priv, u_long cmd, caddr_t data, struct thread
24192432
/* transparent forwarding, see netmap_poll() */
24202433
netmap_grab_packets(kring, &q, netmap_fwd);
24212434
}
2422-
if (kring->nm_sync(kring, NAF_FORCE_READ) == 0) {
2435+
if (kring->nm_sync(kring, sync_flags | NAF_FORCE_READ) == 0) {
24232436
nm_sync_finalize(kring);
24242437
}
24252438
ring_timestamp_set(ring);
@@ -2518,6 +2531,7 @@ netmap_poll(struct netmap_priv_d *priv, int events, NM_SELRECORD_T *sr)
25182531
* file descriptor.
25192532
*/
25202533
int send_down = 0;
2534+
int sync_flags = priv->np_sync_flags;
25212535

25222536
mbq_init(&q);
25232537

@@ -2627,7 +2641,7 @@ netmap_poll(struct netmap_priv_d *priv, int events, NM_SELRECORD_T *sr)
26272641
netmap_ring_reinit(kring);
26282642
revents |= POLLERR;
26292643
} else {
2630-
if (kring->nm_sync(kring, 0))
2644+
if (kring->nm_sync(kring, sync_flags))
26312645
revents |= POLLERR;
26322646
else
26332647
nm_sync_finalize(kring);
@@ -2691,7 +2705,7 @@ netmap_poll(struct netmap_priv_d *priv, int events, NM_SELRECORD_T *sr)
26912705
* the nm_sync() below only on for the host RX ring (see
26922706
* netmap_rxsync_from_host()). */
26932707
kring->nr_kflags &= ~NR_FORWARD;
2694-
if (kring->nm_sync(kring, 0))
2708+
if (kring->nm_sync(kring, sync_flags))
26952709
revents |= POLLERR;
26962710
else
26972711
nm_sync_finalize(kring);

sys/dev/netmap/netmap_generic.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -165,12 +165,12 @@ nm_os_get_mbuf(struct ifnet *ifp, int len)
165165
* has a KASSERT(), checking that the mbuf dtor function is not NULL.
166166
*/
167167

168+
static void void_mbuf_dtor(struct mbuf *m, void *arg1, void *arg2) { }
169+
168170
#define SET_MBUF_DESTRUCTOR(m, fn) do { \
169-
(m)->m_ext.ext_free = (void *)fn; \
171+
(m)->m_ext.ext_free = fn ? (void *)fn : (void *)void_mbuf_dtor; \
170172
} while (0)
171173

172-
static void void_mbuf_dtor(struct mbuf *m, void *arg1, void *arg2) { }
173-
174174
static inline struct mbuf *
175175
nm_os_get_mbuf(struct ifnet *ifp, int len)
176176
{

sys/dev/netmap/netmap_kern.h

+6-4
Original file line numberDiff line numberDiff line change
@@ -749,8 +749,9 @@ struct netmap_adapter {
749749
int (*nm_txsync)(struct netmap_kring *kring, int flags);
750750
int (*nm_rxsync)(struct netmap_kring *kring, int flags);
751751
int (*nm_notify)(struct netmap_kring *kring, int flags);
752-
#define NAF_FORCE_READ 1
753-
#define NAF_FORCE_RECLAIM 2
752+
#define NAF_FORCE_READ 1
753+
#define NAF_FORCE_RECLAIM 2
754+
#define NAF_CAN_FORWARD_DOWN 4
754755
/* return configuration information */
755756
int (*nm_config)(struct netmap_adapter *,
756757
u_int *txr, u_int *txd, u_int *rxr, u_int *rxd);
@@ -1405,7 +1406,7 @@ u_int nm_bound_var(u_int *v, u_int dflt, u_int lo, u_int hi, const char *msg);
14051406
int netmap_get_na(struct nmreq *nmr, struct netmap_adapter **na,
14061407
struct ifnet **ifp, struct netmap_mem_d *nmd, int create);
14071408
void netmap_unget_na(struct netmap_adapter *na, struct ifnet *ifp);
1408-
int netmap_get_hw_na(struct ifnet *ifp,
1409+
int netmap_get_hw_na(struct ifnet *ifp,
14091410
struct netmap_mem_d *nmd, struct netmap_adapter **na);
14101411

14111412

@@ -1808,6 +1809,7 @@ struct netmap_priv_d {
18081809
u_int np_qfirst[NR_TXRX],
18091810
np_qlast[NR_TXRX]; /* range of tx/rx rings to scan */
18101811
uint16_t np_txpoll; /* XXX and also np_rxpoll ? */
1812+
int np_sync_flags; /* to be passed to nm_sync */
18111813

18121814
int np_refs; /* use with NMG_LOCK held */
18131815

@@ -2069,7 +2071,7 @@ struct netmap_pt_host_adapter {
20692071
void *ptns;
20702072
};
20712073
/* ptnetmap HOST routines */
2072-
int netmap_get_pt_host_na(struct nmreq *nmr, struct netmap_adapter **na,
2074+
int netmap_get_pt_host_na(struct nmreq *nmr, struct netmap_adapter **na,
20732075
struct netmap_mem_d * nmd, int create);
20742076
int ptnetmap_ctl(struct nmreq *nmr, struct netmap_adapter *na);
20752077
static inline int

sys/dev/netmap/netmap_mem2.c

+23-18
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,8 @@ struct netmap_mem_ops {
142142
ssize_t (*nmd_if_offset)(struct netmap_mem_d *, const void *vaddr);
143143
void (*nmd_delete)(struct netmap_mem_d *);
144144

145-
struct netmap_if * (*nmd_if_new)(struct netmap_adapter *);
145+
struct netmap_if * (*nmd_if_new)(struct netmap_adapter *,
146+
struct netmap_priv_d *);
146147
void (*nmd_if_delete)(struct netmap_adapter *, struct netmap_if *);
147148
int (*nmd_rings_create)(struct netmap_adapter *);
148149
void (*nmd_rings_delete)(struct netmap_adapter *);
@@ -221,7 +222,7 @@ NMD_DEFCB(int, config);
221222
NMD_DEFCB1(ssize_t, if_offset, const void *);
222223
NMD_DEFCB(void, delete);
223224

224-
NMD_DEFNACB(struct netmap_if *, if_new);
225+
NMD_DEFNACB1(struct netmap_if *, if_new, struct netmap_priv_d *);
225226
NMD_DEFNACB1(void, if_delete, struct netmap_if *);
226227
NMD_DEFNACB(int, rings_create);
227228
NMD_DEFNACB(void, rings_delete);
@@ -1756,7 +1757,7 @@ netmap_mem2_rings_delete(struct netmap_adapter *na)
17561757
* the interface is in netmap mode.
17571758
*/
17581759
static struct netmap_if *
1759-
netmap_mem2_if_new(struct netmap_adapter *na)
1760+
netmap_mem2_if_new(struct netmap_adapter *na, struct netmap_priv_d *priv)
17601761
{
17611762
struct netmap_if *nifp;
17621763
ssize_t base; /* handy for relative offsets between rings and nifp */
@@ -1795,24 +1796,28 @@ netmap_mem2_if_new(struct netmap_adapter *na)
17951796
*/
17961797
base = netmap_if_offset(na->nm_mem, nifp);
17971798
for (i = 0; i < n[NR_TX]; i++) {
1798-
if (na->tx_rings[i].ring == NULL) {
1799-
// XXX maybe use the offset of an error ring,
1800-
// like we do for buffers?
1801-
*(ssize_t *)(uintptr_t)&nifp->ring_ofs[i] = 0;
1802-
continue;
1799+
/* XXX instead of ofs == 0 maybe use the offset of an error
1800+
* ring, like we do for buffers? */
1801+
ssize_t ofs = 0;
1802+
1803+
if (na->tx_rings[i].ring != NULL && i >= priv->np_qfirst[NR_TX]
1804+
&& i < priv->np_qlast[NR_TX]) {
1805+
ofs = netmap_ring_offset(na->nm_mem,
1806+
na->tx_rings[i].ring) - base;
18031807
}
1804-
*(ssize_t *)(uintptr_t)&nifp->ring_ofs[i] =
1805-
netmap_ring_offset(na->nm_mem, na->tx_rings[i].ring) - base;
1808+
*(ssize_t *)(uintptr_t)&nifp->ring_ofs[i] = ofs;
18061809
}
18071810
for (i = 0; i < n[NR_RX]; i++) {
1808-
if (na->rx_rings[i].ring == NULL) {
1809-
// XXX maybe use the offset of an error ring,
1810-
// like we do for buffers?
1811-
*(ssize_t *)(uintptr_t)&nifp->ring_ofs[i+n[NR_TX]] = 0;
1812-
continue;
1811+
/* XXX instead of ofs == 0 maybe use the offset of an error
1812+
* ring, like we do for buffers? */
1813+
ssize_t ofs = 0;
1814+
1815+
if (na->rx_rings[i].ring != NULL && i >= priv->np_qfirst[NR_RX]
1816+
&& i < priv->np_qlast[NR_RX]) {
1817+
ofs = netmap_ring_offset(na->nm_mem,
1818+
na->rx_rings[i].ring) - base;
18131819
}
1814-
*(ssize_t *)(uintptr_t)&nifp->ring_ofs[i+n[NR_TX]] =
1815-
netmap_ring_offset(na->nm_mem, na->rx_rings[i].ring) - base;
1820+
*(ssize_t *)(uintptr_t)&nifp->ring_ofs[i+n[NR_TX]] = ofs;
18161821
}
18171822

18181823
NMA_UNLOCK(na->nm_mem);
@@ -2171,7 +2176,7 @@ netmap_mem_pt_guest_delete(struct netmap_mem_d *nmd)
21712176
}
21722177

21732178
static struct netmap_if *
2174-
netmap_mem_pt_guest_if_new(struct netmap_adapter *na)
2179+
netmap_mem_pt_guest_if_new(struct netmap_adapter *na, struct netmap_priv_d *priv)
21752180
{
21762181
struct netmap_mem_ptg *ptnmd = (struct netmap_mem_ptg *)na->nm_mem;
21772182
struct mem_pt_if *ptif;

sys/dev/netmap/netmap_mem2.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ PMDL win32_build_user_vm_map(struct netmap_mem_d* nmd);
130130
int netmap_mem_finalize(struct netmap_mem_d *, struct netmap_adapter *);
131131
int netmap_mem_init(void);
132132
void netmap_mem_fini(void);
133-
struct netmap_if * netmap_mem_if_new(struct netmap_adapter *);
133+
struct netmap_if * netmap_mem_if_new(struct netmap_adapter *, struct netmap_priv_d *);
134134
void netmap_mem_if_delete(struct netmap_adapter *, struct netmap_if *);
135135
int netmap_mem_rings_create(struct netmap_adapter *);
136136
void netmap_mem_rings_delete(struct netmap_adapter *);

sys/dev/netmap/netmap_monitor.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ nm_monitor_alloc(struct netmap_kring *kring, u_int n)
198198
if (n <= kring->max_monitors)
199199
/* we already have more entries that requested */
200200
return 0;
201-
201+
202202
old_len = sizeof(struct netmap_kring *)*kring->max_monitors;
203203
len = sizeof(struct netmap_kring *) * n;
204204
nm = nm_os_realloc(kring->monitors, len, old_len);

sys/dev/netmap/netmap_pipe.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,7 @@ netmap_pipe_dtor(struct netmap_adapter *na)
525525
}
526526

527527
int
528-
netmap_get_pipe_na(struct nmreq *nmr, struct netmap_adapter **na,
528+
netmap_get_pipe_na(struct nmreq *nmr, struct netmap_adapter **na,
529529
struct netmap_mem_d *nmd, int create)
530530
{
531531
struct nmreq pnmr;

sys/dev/netmap/netmap_pt.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1146,7 +1146,7 @@ nm_pt_host_dtor(struct netmap_adapter *na)
11461146

11471147
/* check if nmr is a request for a ptnetmap adapter that we can satisfy */
11481148
int
1149-
netmap_get_pt_host_na(struct nmreq *nmr, struct netmap_adapter **na,
1149+
netmap_get_pt_host_na(struct nmreq *nmr, struct netmap_adapter **na,
11501150
struct netmap_mem_d *nmd, int create)
11511151
{
11521152
struct nmreq parent_nmr;

sys/dev/netmap/netmap_vale.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ SYSCTL_DECL(_dev_netmap);
161161
SYSCTL_INT(_dev_netmap, OID_AUTO, bridge_batch, CTLFLAG_RW, &bridge_batch, 0 , "");
162162
SYSEND;
163163

164-
static int netmap_vp_create(struct nmreq *, struct ifnet *,
164+
static int netmap_vp_create(struct nmreq *, struct ifnet *,
165165
struct netmap_mem_d *nmd, struct netmap_vp_adapter **);
166166
static int netmap_vp_reg(struct netmap_adapter *na, int onoff);
167167
static int netmap_bwrap_reg(struct netmap_adapter *, int onoff);

sys/net/netmap_user.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ typedef void (*nm_cb_t)(u_char *, const struct nm_pkthdr *, const u_char *d);
309309
* ifname (netmap:foo or vale:foo) is the port name
310310
* a suffix can indicate the follwing:
311311
* ^ bind the host (sw) ring pair
312-
* * bind host and NIC ring pairs (transparent)
312+
* * bind host and NIC ring pairs
313313
* -NN bind individual NIC ring pair
314314
* {NN bind master side of pipe NN
315315
* }NN bind slave side of pipe NN
@@ -870,7 +870,7 @@ nm_open(const char *ifname, const struct nmreq *req,
870870

871871
nr_reg = d->req.nr_flags & NR_REG_MASK;
872872

873-
if (nr_reg == NR_REG_SW) { /* host stack */
873+
if (nr_reg == NR_REG_SW) { /* host stack */
874874
d->first_tx_ring = d->last_tx_ring = d->req.nr_tx_rings;
875875
d->first_rx_ring = d->last_rx_ring = d->req.nr_rx_rings;
876876
} else if (nr_reg == NR_REG_ALL_NIC) { /* only nic */

0 commit comments

Comments
 (0)