diff --git a/sys/dev/ixl/ixl_txrx.c b/sys/dev/ixl/ixl_txrx.c index e589bb839..61963848d 100644 --- a/sys/dev/ixl/ixl_txrx.c +++ b/sys/dev/ixl/ixl_txrx.c @@ -333,7 +333,6 @@ ixl_tso_setup(struct tx_ring *txr, if_pkt_info_t pi) * - return 0 on success, positive on failure * **********************************************************************/ -#define IXL_TXD_CMD (I40E_TX_DESC_CMD_EOP | I40E_TX_DESC_CMD_RS) static int ixl_isc_txd_encap(void *arg, if_pkt_info_t pi) @@ -398,7 +397,10 @@ ixl_isc_txd_encap(void *arg, if_pkt_info_t pi) } /* Set the last descriptor for report */ txd->cmd_type_offset_bsz |= - htole64(((u64)IXL_TXD_CMD << I40E_TXD_QW1_CMD_SHIFT)); + htole64(((u64)I40E_TX_DESC_CMD_EOP << I40E_TXD_QW1_CMD_SHIFT)); + if (tx_intr) + txd->cmd_type_offset_bsz |= + htole64(((u64)I40E_TX_DESC_CMD_RS << I40E_TXD_QW1_CMD_SHIFT)); /* Add to report status array (if using TX interrupts) */ if (!vsi->enable_head_writeback && tx_intr) { txr->tx_rsq[txr->tx_rs_pidx] = pidx_last; diff --git a/sys/net/iflib.c b/sys/net/iflib.c index 85c29f850..2fd5cb182 100644 --- a/sys/net/iflib.c +++ b/sys/net/iflib.c @@ -190,6 +190,7 @@ struct iflib_ctx { uint16_t ifc_sysctl_nrxqs; uint16_t ifc_sysctl_qs_eq_override; uint16_t ifc_sysctl_rx_budget; + uint16_t ifc_sysctl_nm_tx_tmr_us; uint16_t ifc_sysctl_tx_abdicate; uint16_t ifc_sysctl_core_offset; #define CORE_OFFSET_UNSPECIFIED 0xffff @@ -346,6 +347,9 @@ struct iflib_txq { qidx_t ift_size; uint16_t ift_id; struct callout ift_timer; +#ifdef DEV_NETMAP + struct callout ift_netmap_timer; +#endif /* DEV_NETMAP */ if_txsd_vec_t ift_sds; uint8_t ift_qstatus; @@ -753,6 +757,7 @@ iflib_num_tx_descs(if_ctx_t ctx) MODULE_DEPEND(iflib, netmap, 1, 1, 1); static int netmap_fl_refill(iflib_rxq_t rxq, struct netmap_kring *kring, bool init); +static void iflib_netmap_timer(void *arg); /* * device-specific sysctl variables: @@ -1058,11 +1063,17 @@ iflib_netmap_txsync(struct netmap_kring *kring, int flags) kring->nr_hwtail = nm_prev(netmap_idx_n2k(kring, nic_i), lim); } } + if (!(ctx->ifc_flags & IFC_NETMAP_TX_IRQ)) if (kring->nr_hwtail != nm_prev(kring->nr_hwcur, lim)) { - callout_reset_on(&txq->ift_timer, hz < 2000 ? 1 : hz / 1000, - iflib_timer, txq, txq->ift_timer.c_cpu); - } + uint16_t timer_us = ctx->ifc_sysctl_nm_tx_tmr_us; + + if (timer_us == 0) + timer_us = 500; + callout_reset_sbt(&txq->ift_netmap_timer, + timer_us * SBT_1US, SBT_1US, iflib_netmap_timer, + txq, 0); + } return (0); } @@ -1263,28 +1274,12 @@ iflib_netmap_rxq_init(if_ctx_t ctx, iflib_rxq_t rxq) } static void -iflib_netmap_timer_adjust(if_ctx_t ctx, iflib_txq_t txq, uint32_t *reset_on) +iflib_netmap_timer(void *arg) { - struct netmap_kring *kring; - uint16_t txqid; - - txqid = txq->ift_id; - kring = netmap_kring_on(NA(ctx->ifc_ifp), txqid, NR_TX); - if (kring == NULL) - return; + iflib_txq_t txq = arg; + if_ctx_t ctx = txq->ift_ctx; - if (kring->nr_hwcur != nm_next(kring->nr_hwtail, kring->nkr_num_slots - 1)) { - bus_dmamap_sync(txq->ift_ifdi->idi_tag, txq->ift_ifdi->idi_map, - BUS_DMASYNC_POSTREAD); - if (ctx->isc_txd_credits_update(ctx->ifc_softc, txqid, false)) - netmap_tx_irq(ctx->ifc_ifp, txqid); - if (!(ctx->ifc_flags & IFC_NETMAP_TX_IRQ)) { - if (hz < 2000) - *reset_on = 1; - else - *reset_on = hz / 1000; - } - } + netmap_tx_irq(ctx->ifc_ifp, txq->ift_id); } #define iflib_netmap_detach(ifp) netmap_detach(ifp) @@ -1296,8 +1291,6 @@ iflib_netmap_timer_adjust(if_ctx_t ctx, iflib_txq_t txq, uint32_t *reset_on) #define iflib_netmap_attach(ctx) (0) #define netmap_rx_irq(ifp, qid, budget) (0) -#define netmap_tx_irq(ifp, qid) do {} while (0) -#define iflib_netmap_timer_adjust(ctx, txq, reset_on) #endif #if defined(__i386__) || defined(__amd64__) @@ -2287,7 +2280,6 @@ iflib_timer(void *arg) if_ctx_t ctx = txq->ift_ctx; if_softc_ctx_t sctx = &ctx->ifc_softc_ctx; uint64_t this_tick = ticks; - uint32_t reset_on = hz / 2; if (!(if_getdrvflags(ctx->ifc_ifp) & IFF_DRV_RUNNING)) return; @@ -2312,17 +2304,13 @@ iflib_timer(void *arg) } txq->ift_cleaned_prev = txq->ift_cleaned; } -#ifdef DEV_NETMAP - if (if_getcapenable(ctx->ifc_ifp) & IFCAP_NETMAP) - iflib_netmap_timer_adjust(ctx, txq, &reset_on); -#endif /* handle any laggards */ if (txq->ift_db_pending) GROUPTASK_ENQUEUE(&txq->ift_task); sctx->isc_pause_frames = 0; if (if_getdrvflags(ctx->ifc_ifp) & IFF_DRV_RUNNING) - callout_reset_on(&txq->ift_timer, reset_on, iflib_timer, txq, txq->ift_timer.c_cpu); + callout_reset_on(&txq->ift_timer, hz / 2, iflib_timer, txq, txq->ift_timer.c_cpu); return; hung: @@ -2396,6 +2384,9 @@ iflib_init_locked(if_ctx_t ctx) for (i = 0, txq = ctx->ifc_txqs; i < sctx->isc_ntxqsets; i++, txq++) { CALLOUT_LOCK(txq); callout_stop(&txq->ift_timer); +#ifdef DEV_NETMAP + callout_stop(&txq->ift_netmap_timer); +#endif /* DEV_NETMAP */ CALLOUT_UNLOCK(txq); iflib_netmap_txq_init(ctx, txq); } @@ -2485,6 +2476,9 @@ iflib_stop(if_ctx_t ctx) CALLOUT_LOCK(txq); callout_stop(&txq->ift_timer); +#ifdef DEV_NETMAP + callout_stop(&txq->ift_netmap_timer); +#endif /* DEV_NETMAP */ CALLOUT_UNLOCK(txq); /* clean any enqueued buffers */ @@ -3882,7 +3876,6 @@ _task_fn_admin(void *context) iflib_txq_t txq; int i; bool oactive, running, do_reset, do_watchdog, in_detach; - uint32_t reset_on = hz / 2; STATE_LOCK(ctx); running = (if_getdrvflags(ctx->ifc_ifp) & IFF_DRV_RUNNING); @@ -3910,12 +3903,7 @@ _task_fn_admin(void *context) } IFDI_UPDATE_ADMIN_STATUS(ctx); for (txq = ctx->ifc_txqs, i = 0; i < sctx->isc_ntxqsets; i++, txq++) { -#ifdef DEV_NETMAP - reset_on = hz / 2; - if (if_getcapenable(ctx->ifc_ifp) & IFCAP_NETMAP) - iflib_netmap_timer_adjust(ctx, txq, &reset_on); -#endif - callout_reset_on(&txq->ift_timer, reset_on, iflib_timer, txq, txq->ift_timer.c_cpu); + callout_reset_on(&txq->ift_timer, hz / 2, iflib_timer, txq, txq->ift_timer.c_cpu); } IFDI_LINK_INTR_ENABLE(ctx); if (do_reset) @@ -5088,6 +5076,9 @@ iflib_pseudo_deregister(if_ctx_t ctx) tqg = qgroup_if_io_tqg; for (txq = ctx->ifc_txqs, i = 0; i < NTXQSETS(ctx); i++, txq++) { callout_drain(&txq->ift_timer); +#ifdef DEV_NETMAP + callout_drain(&txq->ift_netmap_timer); +#endif /* DEV_NETMAP */ if (txq->ift_task.gt_uniq != NULL) taskqgroup_detach(tqg, &txq->ift_task); } @@ -5174,6 +5165,9 @@ iflib_device_deregister(if_ctx_t ctx) tqg = qgroup_if_io_tqg; for (txq = ctx->ifc_txqs, i = 0; i < NTXQSETS(ctx); i++, txq++) { callout_drain(&txq->ift_timer); +#ifdef DEV_NETMAP + callout_drain(&txq->ift_netmap_timer); +#endif /* DEV_NETMAP */ if (txq->ift_task.gt_uniq != NULL) taskqgroup_detach(tqg, &txq->ift_task); } @@ -5583,8 +5577,6 @@ iflib_queues_alloc(if_ctx_t ctx) } else { txq->ift_br_offset = 0; } - /* XXX fix this */ - txq->ift_timer.c_cpu = cpu; if (iflib_txsd_alloc(txq)) { device_printf(dev, "Critical Failure setting up TX buffers\n"); @@ -5597,6 +5589,9 @@ iflib_queues_alloc(if_ctx_t ctx) 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); +#ifdef DEV_NETMAP + callout_init_mtx(&txq->ift_netmap_timer, &txq->ift_mtx, 0); +#endif /* DEV_NETMAP */ err = ifmp_ring_alloc(&txq->ift_br, 2048, txq, iflib_txq_drain, iflib_txq_can_drain, M_IFLIB, M_WAITOK); @@ -6610,6 +6605,9 @@ iflib_add_device_sysctl_pre(if_ctx_t ctx) SYSCTL_ADD_U16(ctx_list, oid_list, OID_AUTO, "rx_budget", CTLFLAG_RWTUN, &ctx->ifc_sysctl_rx_budget, 0, "set the RX budget"); + SYSCTL_ADD_U16(ctx_list, oid_list, OID_AUTO, "nm_tx_tmr_us", + CTLFLAG_RWTUN, &ctx->ifc_sysctl_nm_tx_tmr_us, 0, + "set the TX netmap timer period"); SYSCTL_ADD_U16(ctx_list, oid_list, OID_AUTO, "tx_abdicate", CTLFLAG_RWTUN, &ctx->ifc_sysctl_tx_abdicate, 0, "cause TX to abdicate instead of running to completion");