Changeset View
Changeset View
Standalone View
Standalone View
sys/net/iflib.c
Show First 20 Lines • Show All 987 Lines • ▼ Show 20 Lines | iflib_netmap_txsync(struct netmap_kring *kring, int flags) | ||||
if_t ifp = na->ifp; | if_t ifp = na->ifp; | ||||
struct netmap_ring *ring = kring->ring; | struct netmap_ring *ring = kring->ring; | ||||
u_int nm_i; /* index into the netmap kring */ | u_int nm_i; /* index into the netmap kring */ | ||||
u_int nic_i; /* index into the NIC ring */ | u_int nic_i; /* index into the NIC ring */ | ||||
u_int n; | u_int n; | ||||
u_int const lim = kring->nkr_num_slots - 1; | u_int const lim = kring->nkr_num_slots - 1; | ||||
u_int const head = kring->rhead; | u_int const head = kring->rhead; | ||||
struct if_pkt_info pi; | struct if_pkt_info pi; | ||||
int tx_pkts = 0, tx_bytes = 0; | |||||
/* | /* | ||||
* interrupts on every tx packet are expensive so request | * interrupts on every tx packet are expensive so request | ||||
* them every half ring, or where NS_REPORT is set | * them every half ring, or where NS_REPORT is set | ||||
*/ | */ | ||||
u_int report_frequency = kring->nkr_num_slots >> 1; | u_int report_frequency = kring->nkr_num_slots >> 1; | ||||
/* device-specific */ | /* device-specific */ | ||||
if_ctx_t ctx = ifp->if_softc; | if_ctx_t ctx = ifp->if_softc; | ||||
▲ Show 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | for (n = 0; nm_i != head; n++) { | ||||
pi.ipi_pidx = nic_i_start; | pi.ipi_pidx = nic_i_start; | ||||
pi.ipi_ndescs = 0; | pi.ipi_ndescs = 0; | ||||
pi.ipi_flags = flags; | pi.ipi_flags = flags; | ||||
/* Prepare the NIC TX ring. */ | /* Prepare the NIC TX ring. */ | ||||
ctx->isc_txd_encap(ctx->ifc_softc, &pi); | ctx->isc_txd_encap(ctx->ifc_softc, &pi); | ||||
DBG_COUNTER_INC(tx_encap); | DBG_COUNTER_INC(tx_encap); | ||||
/* Update transmit counters */ | |||||
tx_bytes += pi.ipi_len; | |||||
vmaffione: I think this should be `pkt_len`, which is the cumulative size of a multi-descriptor packet… | |||||
Done Inline ActionsNice catch, thanks! I changed it to pi.ipi_len where pkg_len is stored to avoid the dependency on an internal variable. franco_opnsense.org: Nice catch, thanks! I changed it to pi.ipi_len where pkg_len is stored to avoid the dependency… | |||||
tx_pkts++; | |||||
/* Reinit per-packet info for the next one. */ | /* Reinit per-packet info for the next one. */ | ||||
flags = seg_idx = pkt_len = 0; | flags = seg_idx = pkt_len = 0; | ||||
nic_i_start = -1; | nic_i_start = -1; | ||||
} | } | ||||
/* prefetch for next round */ | /* prefetch for next round */ | ||||
__builtin_prefetch(&ring->slot[nm_i + 1]); | __builtin_prefetch(&ring->slot[nm_i + 1]); | ||||
__builtin_prefetch(&txq->ift_sds.ifsd_m[nic_i + 1]); | __builtin_prefetch(&txq->ift_sds.ifsd_m[nic_i + 1]); | ||||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | iflib_netmap_txsync(struct netmap_kring *kring, int flags) | ||||
if (!(ctx->ifc_flags & IFC_NETMAP_TX_IRQ)) | if (!(ctx->ifc_flags & IFC_NETMAP_TX_IRQ)) | ||||
if (kring->nr_hwtail != nm_prev(kring->nr_hwcur, lim)) { | if (kring->nr_hwtail != nm_prev(kring->nr_hwcur, lim)) { | ||||
callout_reset_sbt_on(&txq->ift_netmap_timer, | callout_reset_sbt_on(&txq->ift_netmap_timer, | ||||
NETMAP_TX_TIMER_US * SBT_1US, SBT_1US, | NETMAP_TX_TIMER_US * SBT_1US, SBT_1US, | ||||
iflib_netmap_timer, txq, | iflib_netmap_timer, txq, | ||||
txq->ift_netmap_timer.c_cpu, 0); | txq->ift_netmap_timer.c_cpu, 0); | ||||
} | } | ||||
if_inc_counter(ifp, IFCOUNTER_OBYTES, tx_bytes); | |||||
if_inc_counter(ifp, IFCOUNTER_OPACKETS, tx_pkts); | |||||
return (0); | return (0); | ||||
} | } | ||||
/* | /* | ||||
* Reconcile kernel and user view of the receive ring. | * Reconcile kernel and user view of the receive ring. | ||||
* Same as for the txsync, this routine must be efficient. | * Same as for the txsync, this routine must be efficient. | ||||
* The caller guarantees a single invocations, but races against | * The caller guarantees a single invocations, but races against | ||||
* the rest of the driver should be handled here. | * the rest of the driver should be handled here. | ||||
Show All 11 Lines | iflib_netmap_rxsync(struct netmap_kring *kring, int flags) | ||||
struct netmap_adapter *na = kring->na; | struct netmap_adapter *na = kring->na; | ||||
struct netmap_ring *ring = kring->ring; | struct netmap_ring *ring = kring->ring; | ||||
if_t ifp = na->ifp; | if_t ifp = na->ifp; | ||||
uint32_t nm_i; /* index into the netmap ring */ | uint32_t nm_i; /* index into the netmap ring */ | ||||
uint32_t nic_i; /* index into the NIC ring */ | uint32_t nic_i; /* index into the NIC ring */ | ||||
u_int n; | u_int n; | ||||
u_int const lim = kring->nkr_num_slots - 1; | u_int const lim = kring->nkr_num_slots - 1; | ||||
int force_update = (flags & NAF_FORCE_READ) || kring->nr_kflags & NKR_PENDINTR; | int force_update = (flags & NAF_FORCE_READ) || kring->nr_kflags & NKR_PENDINTR; | ||||
int i = 0; | int i = 0, rx_bytes = 0, rx_pkts = 0; | ||||
if_ctx_t ctx = ifp->if_softc; | if_ctx_t ctx = ifp->if_softc; | ||||
if_shared_ctx_t sctx = ctx->ifc_sctx; | if_shared_ctx_t sctx = ctx->ifc_sctx; | ||||
if_softc_ctx_t scctx = &ctx->ifc_softc_ctx; | if_softc_ctx_t scctx = &ctx->ifc_softc_ctx; | ||||
iflib_rxq_t rxq = &ctx->ifc_rxqs[kring->ring_id]; | iflib_rxq_t rxq = &ctx->ifc_rxqs[kring->ring_id]; | ||||
iflib_fl_t fl = &rxq->ifr_fl[0]; | iflib_fl_t fl = &rxq->ifr_fl[0]; | ||||
struct if_rxd_info ri; | struct if_rxd_info ri; | ||||
qidx_t *cidxp; | qidx_t *cidxp; | ||||
▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | for (n = 0; avail > 0 && nm_i != hwtail_lim; n++, avail--) { | ||||
if (error) { | if (error) { | ||||
ring->slot[nm_i].len = 0; | ring->slot[nm_i].len = 0; | ||||
ring->slot[nm_i].flags = 0; | ring->slot[nm_i].flags = 0; | ||||
} else { | } else { | ||||
ring->slot[nm_i].len = ri.iri_frags[i].irf_len; | ring->slot[nm_i].len = ri.iri_frags[i].irf_len; | ||||
if (i == (ri.iri_nfrags - 1)) { | if (i == (ri.iri_nfrags - 1)) { | ||||
ring->slot[nm_i].len -= crclen; | ring->slot[nm_i].len -= crclen; | ||||
ring->slot[nm_i].flags = 0; | ring->slot[nm_i].flags = 0; | ||||
/* Update receive counters */ | |||||
rx_bytes += ri.iri_len; | |||||
rx_pkts++; | |||||
} else | } else | ||||
ring->slot[nm_i].flags = NS_MOREFRAG; | ring->slot[nm_i].flags = NS_MOREFRAG; | ||||
} | } | ||||
bus_dmamap_sync(fl->ifl_buf_tag, | bus_dmamap_sync(fl->ifl_buf_tag, | ||||
fl->ifl_sds.ifsd_map[nic_i], BUS_DMASYNC_POSTREAD); | fl->ifl_sds.ifsd_map[nic_i], BUS_DMASYNC_POSTREAD); | ||||
nm_i = nm_next(nm_i, lim); | nm_i = nm_next(nm_i, lim); | ||||
fl->ifl_cidx = nic_i = nm_next(nic_i, lim); | fl->ifl_cidx = nic_i = nm_next(nic_i, lim); | ||||
Show All 20 Lines | iflib_netmap_rxsync(struct netmap_kring *kring, int flags) | ||||
* Second part: skip past packets that userspace has released. | * Second part: skip past packets that userspace has released. | ||||
* (kring->nr_hwcur to head excluded), | * (kring->nr_hwcur to head excluded), | ||||
* and make the buffers available for reception. | * and make the buffers available for reception. | ||||
* As usual nm_i is the index in the netmap ring, | * As usual nm_i is the index in the netmap ring, | ||||
* nic_i is the index in the NIC ring, and | * nic_i is the index in the NIC ring, and | ||||
* nm_i == (nic_i + kring->nkr_hwofs) % ring_size | * nm_i == (nic_i + kring->nkr_hwofs) % ring_size | ||||
*/ | */ | ||||
netmap_fl_refill(rxq, kring, false); | netmap_fl_refill(rxq, kring, false); | ||||
if_inc_counter(ifp, IFCOUNTER_IBYTES, rx_bytes); | |||||
if_inc_counter(ifp, IFCOUNTER_IPACKETS, rx_pkts); | |||||
return (0); | return (0); | ||||
} | } | ||||
static void | static void | ||||
iflib_netmap_intr(struct netmap_adapter *na, int onoff) | iflib_netmap_intr(struct netmap_adapter *na, int onoff) | ||||
{ | { | ||||
if_ctx_t ctx = na->ifp->if_softc; | if_ctx_t ctx = na->ifp->if_softc; | ||||
▲ Show 20 Lines • Show All 5,889 Lines • Show Last 20 Lines |
I think this should be pkt_len, which is the cumulative size of a multi-descriptor packet, whereas len is the size of the last descriptor only.