Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F177358485
D61313.1794191496.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
4 KB
Referenced Files
None
Subscribers
None
D61313.1794191496.diff
View Options
diff --git a/FreeBSD/sys/net/iflib.c b/FreeBSD/sys/net/iflib.c
--- a/FreeBSD/sys/net/iflib.c
+++ b/FreeBSD/sys/net/iflib.c
@@ -197,6 +197,7 @@
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);
+static void iflib_tx_drain_schedule(iflib_txq_t txq);
typedef struct iflib_filter_info {
driver_filter_t *ifi_filter;
@@ -459,6 +460,7 @@
qidx_t ift_pad;
uint16_t ift_id;
struct callout ift_timer;
+ struct callout ift_drain_timer;
#ifdef DEV_NETMAP
struct callout ift_netmap_timer;
#endif /* DEV_NETMAP */
@@ -704,6 +706,10 @@
SYSCTL_UINT(_net_iflib, OID_AUTO, simple_drain_quota_thread, CTLFLAG_RWTUN,
&iflib_simple_drain_quota_thread, 0,
"maximum packets sent per simple tx deferral ring drain from another thread");
+static u_int iflib_tx_drain_min_us = 1;
+SYSCTL_UINT(_net_iflib, OID_AUTO, tx_drain_min_us, CTLFLAG_RWTUN,
+ &iflib_tx_drain_min_us, 0,
+ "Minimum time to wait to run tx drain callout");
static u_int iflib_max_producers = 8;
static bool iflib_single_llc __read_mostly;
static bool iflib_producer_gate __read_mostly;
@@ -2701,6 +2707,8 @@
STATE_LOCK(ctx);
iflib_set_running(ctx, false);
STATE_UNLOCK(ctx);
+ for (i = 0; i < scctx->isc_ntxqsets; i++)
+ callout_drain(&ctx->ifc_txqs[i].ift_drain_timer);
IFDI_INTR_DISABLE(ctx);
/*
@@ -2872,6 +2880,8 @@
STATE_LOCK(ctx);
iflib_set_running(ctx, false);
STATE_UNLOCK(ctx);
+ for (i = 0; i < scctx->isc_ntxqsets; i++)
+ callout_drain(&txq[i].ift_drain_timer);
if (stop_hardware) {
ctx->ifc_datapath_state = IFLIB_DP_STOPPING;
@@ -3930,8 +3940,9 @@
m_freem(*m_headp);
DBG_COUNTER_INC(tx_frees);
*m_headp = NULL;
- }
- if ((txq->ift_task.gt_task.ta_flags & TASK_ENQUEUED) == 0)
+ iflib_tx_drain_schedule(txq);
+ } else if ((txq->ift_task.gt_task.ta_flags &
+ TASK_ENQUEUED) == 0)
GROUPTASK_ENQUEUE(&txq->ift_task);
return (ENOBUFS);
}
@@ -5980,6 +5991,7 @@
tqg = qgroup_if_io_tqg;
for (txq = ctx->ifc_txqs, i = 0; i < NTXQSETS(ctx); i++, txq++) {
callout_drain(&txq->ift_timer);
+ callout_drain(&txq->ift_drain_timer);
#ifdef DEV_NETMAP
callout_drain(&txq->ift_netmap_timer);
#endif /* DEV_NETMAP */
@@ -6557,6 +6569,7 @@
device_get_nameunit(dev), txq->ift_id);
mtx_init(&txq->ift_mtx, txq->ift_mtx_name, NULL, MTX_DEF);
callout_init_mtx(&txq->ift_timer, &txq->ift_mtx, 0);
+ callout_init(&txq->ift_drain_timer, 1);
txq->ift_timer.c_cpu = cpu;
#ifdef DEV_NETMAP
callout_init_mtx(&txq->ift_netmap_timer, &txq->ift_mtx, 0);
@@ -8083,6 +8096,43 @@
sched_unpin();
}
+static void
+iflib_tx_drain_timer(void *arg)
+{
+ iflib_txq_t txq = arg;
+
+ if (iflib_is_running(txq->ift_ctx))
+ iflib_simple_txq_drain(txq);
+}
+
+static void
+iflib_tx_drain_schedule(iflib_txq_t txq)
+{
+ uint64_t baudrate, usec;
+ if_t ifp;
+
+ mtx_assert(&txq->ift_mtx, MA_OWNED);
+ if (!iflib_is_running(txq->ift_ctx) ||
+ callout_pending(&txq->ift_drain_timer))
+ return;
+
+ /*
+ * Leave time for half a full ring to drain: one MTU per
+ * descriptor. Assume worst case of 1 ring handling all
+ * traffic. Cap at 1/2 of the iflib timer period.
+ */
+ ifp = txq->ift_ctx->ifc_ifp;
+ baudrate = MAX(1, if_getbaudrate(ifp));
+ usec = (uint64_t)txq->ift_size * if_getmtu(ifp) *
+ 8 * sbttous(SBT_1S) / baudrate / 2;
+ usec = MIN(usec, TICKS_2_USEC(iflib_timer_default / 2));
+ usec = MAX(usec, 1);
+ callout_reset_sbt_on(&txq->ift_drain_timer,
+ ustosbt(MAX(usec, iflib_tx_drain_min_us)), 0,
+ iflib_tx_drain_timer, txq,
+ txq->ift_task.gt_cpu, C_PREL(2));
+}
+
/* Consumes the mbuf in all cases */
static int
iflib_simple_encap(iflib_txq_t txq, struct mbuf *m, int *bytes, int *pkts,
@@ -8141,9 +8191,7 @@
}
if (!drbr_empty(ifp, txq->ift_drbr)) {
txq->ift_drbr_stall++;
- if (quota != iflib_simple_drain_quota &&
- (txq->ift_task.gt_task.ta_flags & TASK_ENQUEUED) == 0)
- GROUPTASK_ENQUEUE(&txq->ift_task);
+ iflib_tx_drain_schedule(txq);
}
}
@@ -8392,7 +8440,6 @@
{
if_ctx_t ctx;
iflib_txq_t txq;
- bool retry;
int bytes_sent = 0, pkt_sent = 0, mcast_sent = 0;
ctx = if_getsoftc(ifp);
@@ -8404,12 +8451,8 @@
&mcast_sent);
if (txq->ift_db_pending != 0)
(void)iflib_txd_db_check(txq, true);
- retry = !drbr_empty(ifp, txq->ift_drbr);
mtx_unlock(&txq->ift_mtx);
- if (retry)
- GROUPTASK_ENQUEUE(&txq->ift_task);
-
if_inc_counter(ifp, IFCOUNTER_OBYTES, bytes_sent);
if_inc_counter(ifp, IFCOUNTER_OPACKETS, pkt_sent);
if (mcast_sent)
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Nov 9, 2:31 AM (10 h, 53 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41602742
Default Alt Text
D61313.1794191496.diff (4 KB)
Attached To
Mode
D61313: iflib: rate limit deferred tx ring drain
Attached
Detach File
Event Timeline