@@ -1145,16 +1145,24 @@ nm_may_forward_up(struct netmap_kring *kring)
1145
1145
}
1146
1146
1147
1147
static inline int
1148
- nm_may_forward_down (struct netmap_kring * kring )
1148
+ nm_may_forward_down (struct netmap_kring * kring , int sync_flags )
1149
1149
{
1150
1150
return _nm_may_forward (kring ) &&
1151
+ (sync_flags & NAF_CAN_FORWARD_DOWN ) &&
1151
1152
kring -> ring_id == kring -> na -> num_rx_rings ;
1152
1153
}
1153
1154
1154
1155
/*
1155
1156
* 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.
1158
1166
*/
1159
1167
static u_int
1160
1168
netmap_sw_to_nic (struct netmap_adapter * na )
@@ -1168,8 +1176,6 @@ netmap_sw_to_nic(struct netmap_adapter *na)
1168
1176
1169
1177
/* scan rings to find space, then fill as much as possible */
1170
1178
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 */
1173
1179
struct netmap_kring * kdst = & na -> tx_rings [i ];
1174
1180
struct netmap_ring * rdst = kdst -> ring ;
1175
1181
u_int const dst_lim = kdst -> nkr_num_slots - 1 ;
@@ -1197,11 +1203,9 @@ netmap_sw_to_nic(struct netmap_adapter *na)
1197
1203
dst -> len = tmp .len ;
1198
1204
dst -> flags = NS_BUF_CHANGED ;
1199
1205
1200
- /* XXX is it safe to write head/cur concurrently to
1201
- * the userspace application? */
1202
1206
rdst -> head = rdst -> cur = nm_next (dst_head , dst_lim );
1203
1207
}
1204
- /* if (sent) XXX txsync ? */
1208
+ /* if (sent) XXX txsync ? it would be just an optimization */
1205
1209
}
1206
1210
return sent ;
1207
1211
}
@@ -1291,7 +1295,7 @@ netmap_rxsync_from_host(struct netmap_kring *kring, int flags)
1291
1295
*/
1292
1296
nm_i = kring -> nr_hwcur ;
1293
1297
if (nm_i != head ) { /* something was released */
1294
- if (nm_may_forward_down (kring )) {
1298
+ if (nm_may_forward_down (kring , flags )) {
1295
1299
ret = netmap_sw_to_nic (na );
1296
1300
if (ret > 0 ) {
1297
1301
kring -> nr_kflags |= NR_FORWARD ;
@@ -1806,6 +1810,13 @@ netmap_interp_ringid(struct netmap_priv_d *priv, uint16_t ringid, uint32_t flags
1806
1810
}
1807
1811
priv -> np_flags = (flags & ~NR_REG_MASK ) | reg ;
1808
1812
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
+
1809
1820
if (netmap_verbose ) {
1810
1821
D ("%s: tx [%d,%d) rx [%d,%d) id %d" ,
1811
1822
na -> name ,
@@ -2069,7 +2080,7 @@ netmap_do_regif(struct netmap_priv_d *priv, struct netmap_adapter *na,
2069
2080
goto err_rel_excl ;
2070
2081
2071
2082
/* in all cases, create a new netmap if */
2072
- nifp = netmap_mem_if_new (na );
2083
+ nifp = netmap_mem_if_new (na , priv );
2073
2084
if (nifp == NULL ) {
2074
2085
error = ENOMEM ;
2075
2086
goto err_del_rings ;
@@ -2177,6 +2188,7 @@ netmap_ioctl(struct netmap_priv_d *priv, u_long cmd, caddr_t data, struct thread
2177
2188
u_int i , qfirst , qlast ;
2178
2189
struct netmap_if * nifp ;
2179
2190
struct netmap_kring * krings ;
2191
+ int sync_flags ;
2180
2192
enum txrx t ;
2181
2193
2182
2194
if (cmd == NIOCGINFO || cmd == NIOCREGIF ) {
@@ -2387,6 +2399,7 @@ netmap_ioctl(struct netmap_priv_d *priv, u_long cmd, caddr_t data, struct thread
2387
2399
krings = NMR (na , t );
2388
2400
qfirst = priv -> np_qfirst [t ];
2389
2401
qlast = priv -> np_qlast [t ];
2402
+ sync_flags = priv -> np_sync_flags ;
2390
2403
2391
2404
for (i = qfirst ; i < qlast ; i ++ ) {
2392
2405
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
2404
2417
kring -> nr_hwcur );
2405
2418
if (nm_txsync_prologue (kring , ring ) >= kring -> nkr_num_slots ) {
2406
2419
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 ) {
2408
2421
nm_sync_finalize (kring );
2409
2422
}
2410
2423
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
2419
2432
/* transparent forwarding, see netmap_poll() */
2420
2433
netmap_grab_packets (kring , & q , netmap_fwd );
2421
2434
}
2422
- if (kring -> nm_sync (kring , NAF_FORCE_READ ) == 0 ) {
2435
+ if (kring -> nm_sync (kring , sync_flags | NAF_FORCE_READ ) == 0 ) {
2423
2436
nm_sync_finalize (kring );
2424
2437
}
2425
2438
ring_timestamp_set (ring );
@@ -2518,6 +2531,7 @@ netmap_poll(struct netmap_priv_d *priv, int events, NM_SELRECORD_T *sr)
2518
2531
* file descriptor.
2519
2532
*/
2520
2533
int send_down = 0 ;
2534
+ int sync_flags = priv -> np_sync_flags ;
2521
2535
2522
2536
mbq_init (& q );
2523
2537
@@ -2627,7 +2641,7 @@ netmap_poll(struct netmap_priv_d *priv, int events, NM_SELRECORD_T *sr)
2627
2641
netmap_ring_reinit (kring );
2628
2642
revents |= POLLERR ;
2629
2643
} else {
2630
- if (kring -> nm_sync (kring , 0 ))
2644
+ if (kring -> nm_sync (kring , sync_flags ))
2631
2645
revents |= POLLERR ;
2632
2646
else
2633
2647
nm_sync_finalize (kring );
@@ -2691,7 +2705,7 @@ netmap_poll(struct netmap_priv_d *priv, int events, NM_SELRECORD_T *sr)
2691
2705
* the nm_sync() below only on for the host RX ring (see
2692
2706
* netmap_rxsync_from_host()). */
2693
2707
kring -> nr_kflags &= ~NR_FORWARD ;
2694
- if (kring -> nm_sync (kring , 0 ))
2708
+ if (kring -> nm_sync (kring , sync_flags ))
2695
2709
revents |= POLLERR ;
2696
2710
else
2697
2711
nm_sync_finalize (kring );
0 commit comments