git: aceaccab659c - main - iflib: netmap: add support for NS_MOREFRAG
Vincenzo Maffione
vmaffione at FreeBSD.org
Sun Jan 24 21:21:45 UTC 2021
The branch main has been updated by vmaffione:
URL: https://cgit.FreeBSD.org/src/commit/?id=aceaccab659c9eb846fb21ff99be34434a9616c7
commit aceaccab659c9eb846fb21ff99be34434a9616c7
Author: Vincenzo Maffione <vmaffione at FreeBSD.org>
AuthorDate: 2021-01-24 21:12:41 +0000
Commit: Vincenzo Maffione <vmaffione at FreeBSD.org>
CommitDate: 2021-01-24 21:20:59 +0000
iflib: netmap: add support for NS_MOREFRAG
The NS_MOREFRAG flag can be set in a netmap slot to represent a
multi-fragment packet. Only the last fragment of a packet does
not have the flag set. On TX rings, the flag may be set by the
userspace application. The kernel will look at the flag and use it
to properly set up the NIC TX descriptors.
On RX rings, the kernel may set the flag if the packet received
was split across multiple netmap buffers. The userspace application
should look at the flag to know when the packet is complete.
Submitted by: rajesh1.kumar_amd.com
Reviewed by: vmaffione
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D27799
---
sys/net/iflib.c | 82 ++++++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 58 insertions(+), 24 deletions(-)
diff --git a/sys/net/iflib.c b/sys/net/iflib.c
index ea2c5789a7b5..0d4124599419 100644
--- a/sys/net/iflib.c
+++ b/sys/net/iflib.c
@@ -1005,6 +1005,8 @@ iflib_netmap_txsync(struct netmap_kring *kring, int flags)
nm_i = kring->nr_hwcur;
if (nm_i != head) { /* we have new packets to send */
+ uint32_t pkt_len = 0, seg_idx = 0;
+ int nic_i_start = -1, flags = 0;
pkt_info_zero(&pi);
pi.ipi_segs = txq->ift_segs;
pi.ipi_qsidx = kring->ring_id;
@@ -1019,22 +1021,40 @@ iflib_netmap_txsync(struct netmap_kring *kring, int flags)
u_int len = slot->len;
uint64_t paddr;
void *addr = PNMB(na, slot, &paddr);
- int flags = (slot->flags & NS_REPORT ||
+
+ flags |= (slot->flags & NS_REPORT ||
nic_i == 0 || nic_i == report_frequency) ?
IPI_TX_INTR : 0;
- /* device-specific */
- pi.ipi_len = len;
- pi.ipi_segs[0].ds_addr = paddr;
- pi.ipi_segs[0].ds_len = len;
- pi.ipi_nsegs = 1;
- pi.ipi_ndescs = 0;
- pi.ipi_pidx = nic_i;
- pi.ipi_flags = flags;
+ /*
+ * If this is the first packet fragment, save the
+ * index of the first NIC slot for later.
+ */
+ if (nic_i_start < 0)
+ nic_i_start = nic_i;
+
+ pi.ipi_segs[seg_idx].ds_addr = paddr;
+ pi.ipi_segs[seg_idx].ds_len = len;
+ if (len) {
+ pkt_len += len;
+ seg_idx++;
+ }
- /* Fill the slot in the NIC ring. */
- ctx->isc_txd_encap(ctx->ifc_softc, &pi);
- DBG_COUNTER_INC(tx_encap);
+ if (!(slot->flags & NS_MOREFRAG)) {
+ pi.ipi_len = pkt_len;
+ pi.ipi_nsegs = seg_idx;
+ pi.ipi_pidx = nic_i_start;
+ pi.ipi_ndescs = 0;
+ pi.ipi_flags = flags;
+
+ /* Prepare the NIC TX ring. */
+ ctx->isc_txd_encap(ctx->ifc_softc, &pi);
+ DBG_COUNTER_INC(tx_encap);
+
+ /* Reinit per-packet info for the next one. */
+ flags = seg_idx = pkt_len = 0;
+ nic_i_start = -1;
+ }
/* prefetch for next round */
__builtin_prefetch(&ring->slot[nm_i + 1]);
@@ -1053,7 +1073,7 @@ iflib_netmap_txsync(struct netmap_kring *kring, int flags)
txq->ift_sds.ifsd_map[nic_i],
BUS_DMASYNC_PREWRITE);
- slot->flags &= ~(NS_REPORT | NS_BUF_CHANGED);
+ slot->flags &= ~(NS_REPORT | NS_BUF_CHANGED | NS_MOREFRAG);
nm_i = nm_next(nm_i, lim);
nic_i = nm_next(nic_i, lim);
}
@@ -1116,6 +1136,7 @@ iflib_netmap_rxsync(struct netmap_kring *kring, int flags)
u_int n;
u_int const lim = kring->nkr_num_slots - 1;
int force_update = (flags & NAF_FORCE_READ) || kring->nr_kflags & NKR_PENDINTR;
+ int i = 0;
if_ctx_t ctx = ifp->if_softc;
if_shared_ctx_t sctx = ctx->ifc_sctx;
@@ -1177,17 +1198,30 @@ iflib_netmap_rxsync(struct netmap_kring *kring, int flags)
ri.iri_cidx = *cidxp;
error = ctx->isc_rxd_pkt_get(ctx->ifc_softc, &ri);
- ring->slot[nm_i].len = error ? 0 : ri.iri_len - crclen;
- ring->slot[nm_i].flags = 0;
- if (have_rxcq) {
- *cidxp = ri.iri_cidx;
- while (*cidxp >= scctx->isc_nrxd[0])
- *cidxp -= scctx->isc_nrxd[0];
+ for (i = 0; i < ri.iri_nfrags; i++) {
+ if (error) {
+ ring->slot[nm_i].len = 0;
+ ring->slot[nm_i].flags = 0;
+ } else {
+ ring->slot[nm_i].len = ri.iri_frags[i].irf_len;
+ if (i == (ri.iri_nfrags - 1)) {
+ ring->slot[nm_i].len -= crclen;
+ ring->slot[nm_i].flags = 0;
+ } else
+ ring->slot[nm_i].flags = NS_MOREFRAG;
+ }
+
+ if (have_rxcq) {
+ *cidxp = ri.iri_cidx;
+ while (*cidxp >= scctx->isc_nrxd[0])
+ *cidxp -= scctx->isc_nrxd[0];
+ }
+
+ bus_dmamap_sync(fl->ifl_buf_tag,
+ fl->ifl_sds.ifsd_map[nic_i], BUS_DMASYNC_POSTREAD);
+ nm_i = nm_next(nm_i, lim);
+ fl->ifl_cidx = nic_i = nm_next(nic_i, lim);
}
- bus_dmamap_sync(fl->ifl_buf_tag,
- fl->ifl_sds.ifsd_map[nic_i], BUS_DMASYNC_POSTREAD);
- nm_i = nm_next(nm_i, lim);
- fl->ifl_cidx = nic_i = nm_next(nic_i, lim);
}
if (n) { /* update the state variables */
if (netmap_no_pendintr && !force_update) {
@@ -1234,7 +1268,7 @@ iflib_netmap_attach(if_ctx_t ctx)
bzero(&na, sizeof(na));
na.ifp = ctx->ifc_ifp;
- na.na_flags = NAF_BDG_MAYSLEEP;
+ na.na_flags = NAF_BDG_MAYSLEEP | NAF_MOREFRAG;
MPASS(ctx->ifc_softc_ctx.isc_ntxqsets);
MPASS(ctx->ifc_softc_ctx.isc_nrxqsets);
More information about the dev-commits-src-main
mailing list