netmap.c
NIOCTXSYNC和NIOCRXSYNC
这两个使用相同的代码,同步ring
case NIOCTXSYNC:
case NIOCRXSYNC:
nifp = priv->np_nifp;
if (nifp == NULL) {
error = ENXIO;
break;
}
mb(); /* make sure following reads are not from cache */
na = priv->np_na; /* we have a reference */
if (na == NULL) {
D("Internal error: nifp != NULL && na == NULL");
error = ENXIO;
break;
}
t = (cmd == NIOCTXSYNC ? NR_TX : NR_RX);
//得到tx/rx ring地址
krings = NMR(na, t);
qfirst = priv->np_qfirst[t];
qlast = priv->np_qlast[t];
for (i = qfirst; i < qlast; i++) {
struct netmap_kring *kring = krings + i;
struct netmap_ring *ring = kring->ring;
if (unlikely(nm_kr_tryget(kring, 1, &error))) {
error = (error ? EIO : 0);
continue;
}
if (cmd == NIOCTXSYNC) {
if (netmap_verbose & NM_VERB_TXSYNC)
D("pre txsync ring %d cur %d hwcur %d",
i, ring->cur,
kring->nr_hwcur);
if (nm_txsync_prologue(kring, ring) >= kring->nkr_num_slots) {
netmap_ring_reinit(kring);
} else if (kring->nm_sync(kring, NAF_FORCE_RECLAIM) == 0) {
nm_sync_finalize(kring);
}
if (netmap_verbose & NM_VERB_TXSYNC)
D("post txsync ring %d cur %d hwcur %d",
i, ring->cur,
kring->nr_hwcur);
} else {
if (nm_rxsync_prologue(kring, ring) >= kring->nkr_num_slots) {
netmap_ring_reinit(kring);
} else if (kring->nm_sync(kring, NAF_FORCE_READ) == 0) {
nm_sync_finalize(kring);
}
microtime(&ring->ts);
}
nm_kr_put(kring);
}
break;