Page MenuHomeFreeBSD

D59712.id186813.diff
No OneTemporary

D59712.id186813.diff

diff --git a/sys/net/iflib.c b/sys/net/iflib.c
--- a/sys/net/iflib.c
+++ b/sys/net/iflib.c
@@ -193,6 +193,8 @@
static void iflib_timer(void *arg);
static void iflib_tqg_detach(if_ctx_t ctx);
static int iflib_simple_transmit(if_t ifp, struct mbuf *m);
+static int iflib_simple_transmit_txq_select(if_t ifp, struct mbuf *m);
+static int iflib_simple_transmit_txq_select_v2(if_t ifp, struct mbuf *m);
static void iflib_simple_if_start(if_t ifp);
static void iflib_simple_txq_drain(iflib_txq_t txq);
@@ -4708,7 +4710,6 @@
static int
iflib_altq_if_transmit(if_t ifp, struct mbuf *m)
{
- if_ctx_t ctx = if_getsoftc(ifp);
int err;
if (if_altq_is_enabled(ifp)) {
@@ -4717,12 +4718,7 @@
if_start(ifp);
return (err);
}
- if (ctx->ifc_sysctl_simple_tx)
- err = iflib_simple_transmit(ifp, m);
- else
- err = iflib_if_transmit(ifp, m);
-
- return (err);
+ return (iflib_if_transmit(ifp, m));
}
#endif /* ALTQ */
@@ -5545,9 +5541,7 @@
ifp = ctx->ifc_ifp;
if (ctx->ifc_sysctl_simple_tx) {
/* if_start drives the same drbr drain when ALTQ is active. */
-#ifndef ALTQ
if_settransmitfn(ifp, iflib_simple_transmit);
-#endif
if_setstartfn(ifp, iflib_simple_if_start);
device_printf(dev, "using simple transmit\n");
}
@@ -5564,6 +5558,19 @@
fail_cleanup);
_iflib_pre_assert(scctx);
ctx->ifc_txrx = *scctx->isc_txrx;
+ /*
+ * Bind optional queue selection to a transmit entry point once, rather
+ * than testing for optional methods for every packet. Prefer v2 when
+ * the driver provides both methods.
+ */
+ if (ctx->ifc_sysctl_simple_tx) {
+ if (ctx->isc_txq_select_v2 != NULL)
+ if_settransmitfn(ifp,
+ iflib_simple_transmit_txq_select_v2);
+ else if (ctx->isc_txq_select != NULL)
+ if_settransmitfn(ifp,
+ iflib_simple_transmit_txq_select);
+ }
MPASS(scctx->isc_dma_width <= flsll(BUS_SPACE_MAXADDR));
@@ -7976,23 +7983,6 @@
}
#endif /* DEBUGNET */
-static inline iflib_txq_t
-iflib_simple_select_queue(if_ctx_t ctx, struct mbuf *m)
-{
- int qidx;
-
-#ifdef ALTQ
- /* ALTQ-enabled interfaces always use queue 0. */
- if (if_altq_is_enabled(ctx->ifc_ifp))
- return (&ctx->ifc_txqs[0]);
-#endif
- if ((NTXQSETS(ctx) > 1) && M_HASHTYPE_GET(m))
- qidx = QIDX(ctx, m);
- else
- qidx = NTXQSETS(ctx) + FIRST_QSET(ctx) - 1;
- return (&ctx->ifc_txqs[qidx]);
-}
-
enum iflib_txq_producer_status {
IFLIB_TXQ_PRODUCER_ENTERED,
IFLIB_TXQ_PRODUCER_QUIESCING,
@@ -8254,23 +8244,32 @@
return (error);
}
-static int
-iflib_simple_transmit(if_t ifp, struct mbuf *m)
+/*
+ * Always inline the common transmit path so queue selection does not add a
+ * function call to the default simple transmit path.
+ */
+static __always_inline int
+iflib_simple_transmit_impl(if_ctx_t ctx, if_t ifp, struct mbuf *m,
+ iflib_txq_t txq)
{
- if_ctx_t ctx;
- iflib_txq_t txq;
struct mbuf **m_defer;
enum iflib_txq_producer_status producer_status;
bool pinned;
int error, i, reclaimable;
int bytes_sent = 0, pkt_sent = 0, mcast_sent = 0;
- ctx = if_getsoftc(ifp);
+#ifdef ALTQ
+ if (if_altq_is_enabled(ifp)) {
+ IFQ_ENQUEUE(&ifp->if_snd, m, error); /* XXX - DRVAPI */
+ if (error == 0)
+ if_start(ifp);
+ return (error);
+ }
+#endif
if (__predict_false((if_getdrvflags(ifp) & IFF_DRV_RUNNING) == 0
|| !LINK_ACTIVE(ctx)))
goto net_down;
- txq = iflib_simple_select_queue(ctx, m);
/*
* Avoid blocking behind another transmitter; the ring is drained by
* whoever holds ift_mtx, by tx completion, or by the watchdog timer.
@@ -8345,6 +8344,60 @@
return (ENETDOWN);
}
+static int
+iflib_simple_transmit(if_t ifp, struct mbuf *m)
+{
+ if_ctx_t ctx;
+ iflib_txq_t txq;
+ int qidx;
+
+ ctx = if_getsoftc(ifp);
+ if ((NTXQSETS(ctx) > 1) && M_HASHTYPE_GET(m))
+ qidx = QIDX(ctx, m);
+ else
+ qidx = NTXQSETS(ctx) + FIRST_QSET(ctx) - 1;
+ MPASS(qidx < NTXQSETS(ctx));
+ txq = &ctx->ifc_txqs[qidx];
+ return (iflib_simple_transmit_impl(ctx, ifp, m, txq));
+}
+
+static int
+iflib_simple_transmit_txq_select(if_t ifp, struct mbuf *m)
+{
+ if_ctx_t ctx;
+ int qidx;
+
+ ctx = if_getsoftc(ifp);
+ qidx = ctx->isc_txq_select(ctx->ifc_softc, m);
+ MPASS(qidx < NTXQSETS(ctx));
+ return (iflib_simple_transmit_impl(ctx, ifp, m,
+ &ctx->ifc_txqs[qidx]));
+}
+
+static int
+iflib_simple_transmit_txq_select_v2(if_t ifp, struct mbuf *m)
+{
+ struct if_pkt_info pi;
+ if_ctx_t ctx;
+ uint64_t early_pullups = 0;
+ int error, qidx;
+
+ ctx = if_getsoftc(ifp);
+ memset(&pi, 0, sizeof(pi));
+ error = iflib_parse_header_partial(&pi, &m, &early_pullups);
+ if (error != 0) {
+ /* Assign pullups for bad packets to the default queue. */
+ ctx->ifc_txqs[0].ift_pullups += early_pullups;
+ DBG_COUNTER_INC(encap_txd_encap_fail);
+ return (error);
+ }
+ qidx = ctx->isc_txq_select_v2(ctx->ifc_softc, m, &pi);
+ MPASS(qidx < NTXQSETS(ctx));
+ ctx->ifc_txqs[qidx].ift_pullups += early_pullups;
+ return (iflib_simple_transmit_impl(ctx, ifp, m,
+ &ctx->ifc_txqs[qidx]));
+}
+
/*
* ALTQ entry point. drbr_dequeue() pulls from ifp->if_snd when a discipline
* is attached, so the drain loop is shared with the if_transmit path. Only

File Metadata

Mime Type
text/plain
Expires
Mon, Sep 28, 9:33 AM (3 h, 18 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
39030500
Default Alt Text
D59712.id186813.diff (5 KB)

Event Timeline