MCPcopy Create free account
hub / github.com/F-Stack/f-stack / iflib_netmap_txsync

Function iflib_netmap_txsync

freebsd/net/iflib.c:959–1113  ·  view source on GitHub ↗

* Reconcile kernel and user view of the transmit ring. * * All information is in the kring. * Userspace wants to send packets up to the one before kring->rhead, * kernel knows kring->nr_hwcur is the first unsent packet. * * Here we push packets out (as many as possible), and possibly * reclaim buffers from previously completed transmission. * * The caller (netmap) guarantees that there is

Source from the content-addressed store, hash-verified

957 * methods should be handled by the individual drivers.
958 */
959static int
960iflib_netmap_txsync(struct netmap_kring *kring, int flags)
961{
962 struct netmap_adapter *na = kring->na;
963 if_t ifp = na->ifp;
964 struct netmap_ring *ring = kring->ring;
965 u_int nm_i; /* index into the netmap kring */
966 u_int nic_i; /* index into the NIC ring */
967 u_int n;
968 u_int const lim = kring->nkr_num_slots - 1;
969 u_int const head = kring->rhead;
970 struct if_pkt_info pi;
971
972 /*
973 * interrupts on every tx packet are expensive so request
974 * them every half ring, or where NS_REPORT is set
975 */
976 u_int report_frequency = kring->nkr_num_slots >> 1;
977 /* device-specific */
978 if_ctx_t ctx = ifp->if_softc;
979 iflib_txq_t txq = &ctx->ifc_txqs[kring->ring_id];
980
981 bus_dmamap_sync(txq->ift_ifdi->idi_tag, txq->ift_ifdi->idi_map,
982 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
983
984 /*
985 * First part: process new packets to send.
986 * nm_i is the current index in the netmap kring,
987 * nic_i is the corresponding index in the NIC ring.
988 *
989 * If we have packets to send (nm_i != head)
990 * iterate over the netmap ring, fetch length and update
991 * the corresponding slot in the NIC ring. Some drivers also
992 * need to update the buffer's physical address in the NIC slot
993 * even NS_BUF_CHANGED is not set (PNMB computes the addresses).
994 *
995 * The netmap_reload_map() calls is especially expensive,
996 * even when (as in this case) the tag is 0, so do only
997 * when the buffer has actually changed.
998 *
999 * If possible do not set the report/intr bit on all slots,
1000 * but only a few times per ring or when NS_REPORT is set.
1001 *
1002 * Finally, on 10G and faster drivers, it might be useful
1003 * to prefetch the next slot and txr entry.
1004 */
1005
1006 nm_i = kring->nr_hwcur;
1007 if (nm_i != head) { /* we have new packets to send */
1008 uint32_t pkt_len = 0, seg_idx = 0;
1009 int nic_i_start = -1, flags = 0;
1010 pkt_info_zero(&pi);
1011 pi.ipi_segs = txq->ift_segs;
1012 pi.ipi_qsidx = kring->ring_id;
1013 nic_i = netmap_idx_k2n(kring, nm_i);
1014
1015 __builtin_prefetch(&ring->slot[nm_i]);
1016 __builtin_prefetch(&txq->ift_sds.ifsd_m[nic_i]);

Callers

nothing calls this directly

Calls 4

pkt_info_zeroFunction · 0.85
iflib_tx_credits_updateFunction · 0.85
callout_reset_sbt_onFunction · 0.85
bus_dmamap_syncFunction · 0.50

Tested by

no test coverage detected