Changeset View
Standalone View
sys/net/iflib.c
Show First 20 Lines • Show All 203 Lines • ▼ Show 20 Lines | |||||
#define isc_txd_encap ifc_txrx.ift_txd_encap | #define isc_txd_encap ifc_txrx.ift_txd_encap | ||||
#define isc_txd_flush ifc_txrx.ift_txd_flush | #define isc_txd_flush ifc_txrx.ift_txd_flush | ||||
#define isc_txd_credits_update ifc_txrx.ift_txd_credits_update | #define isc_txd_credits_update ifc_txrx.ift_txd_credits_update | ||||
#define isc_rxd_available ifc_txrx.ift_rxd_available | #define isc_rxd_available ifc_txrx.ift_rxd_available | ||||
#define isc_rxd_pkt_get ifc_txrx.ift_rxd_pkt_get | #define isc_rxd_pkt_get ifc_txrx.ift_rxd_pkt_get | ||||
#define isc_rxd_refill ifc_txrx.ift_rxd_refill | #define isc_rxd_refill ifc_txrx.ift_rxd_refill | ||||
#define isc_rxd_flush ifc_txrx.ift_rxd_flush | #define isc_rxd_flush ifc_txrx.ift_rxd_flush | ||||
#define isc_legacy_intr ifc_txrx.ift_legacy_intr | #define isc_legacy_intr ifc_txrx.ift_legacy_intr | ||||
#define isc_txq_select ifc_txrx.ift_txq_select | |||||
eventhandler_tag ifc_vlan_attach_event; | eventhandler_tag ifc_vlan_attach_event; | ||||
eventhandler_tag ifc_vlan_detach_event; | eventhandler_tag ifc_vlan_detach_event; | ||||
struct ether_addr ifc_mac; | struct ether_addr ifc_mac; | ||||
}; | }; | ||||
void * | void * | ||||
iflib_get_softc(if_ctx_t ctx) | iflib_get_softc(if_ctx_t ctx) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 3,928 Lines • ▼ Show 20 Lines | if (__predict_false((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || !LINK_ACTIVE(ctx))) { | ||||
DBG_COUNTER_INC(tx_frees); | DBG_COUNTER_INC(tx_frees); | ||||
m_freem(m); | m_freem(m); | ||||
return (ENETDOWN); | return (ENETDOWN); | ||||
} | } | ||||
MPASS(m->m_nextpkt == NULL); | MPASS(m->m_nextpkt == NULL); | ||||
/* ALTQ-enabled interfaces always use queue 0. */ | /* ALTQ-enabled interfaces always use queue 0. */ | ||||
qidx = 0; | qidx = 0; | ||||
if ((NTXQSETS(ctx) > 1) && M_HASHTYPE_GET(m) && !ALTQ_IS_ENABLED(&ifp->if_snd)) | /* Use driver-supplied queue selection method if it exists */ | ||||
if (ctx->isc_txq_select) | |||||
gallatin: What's the cost these days on common platforms of following a function pointer vs an… | |||||
Done Inline ActionsI hope someone else can answer your question. I considered using just a function pointer, but my gut feeling was that an if-else statement was probably faster and less disruptive. I wish someone would benchmark the difference, but I'd also believe the performance difference is small enough that people wouldn't notice the difference between the two approaches. I don't really know how to approach a benchmark for that either -- something like netmap's pkt-gen, but one that goes through this function? (Does it do that already? I didn't think it did) erj: I hope someone else can answer your question. I considered using just a function pointer, but… | |||||
Not Done Inline Actions@olivier still has his benchmarking setup, and has volunteered to test this. If there is a measurable regression, do you mind implementing the alternate patch based on just function pointers for him to test as well? gallatin: @olivier still has his benchmarking setup, and has volunteered to test this. If there is a… | |||||
Done Inline ActionsNope, I don't mind. erj: Nope, I don't mind. | |||||
qidx = ctx->isc_txq_select(ctx->ifc_softc, m); | |||||
/* If not, use iflib's standard method */ | |||||
else if ((NTXQSETS(ctx) > 1) && M_HASHTYPE_GET(m) && !ALTQ_IS_ENABLED(&ifp->if_snd)) | |||||
qidx = QIDX(ctx, m); | qidx = QIDX(ctx, m); | ||||
/* | |||||
* XXX calculate buf_ring based on flowid (divvy up bits?) | /* Set TX queue */ | ||||
*/ | |||||
txq = &ctx->ifc_txqs[qidx]; | txq = &ctx->ifc_txqs[qidx]; | ||||
#ifdef DRIVER_BACKPRESSURE | #ifdef DRIVER_BACKPRESSURE | ||||
if (txq->ift_closed) { | if (txq->ift_closed) { | ||||
while (m != NULL) { | while (m != NULL) { | ||||
next = m->m_nextpkt; | next = m->m_nextpkt; | ||||
m->m_nextpkt = NULL; | m->m_nextpkt = NULL; | ||||
m_freem(m); | m_freem(m); | ||||
▲ Show 20 Lines • Show All 3,021 Lines • Show Last 20 Lines |
What's the cost these days on common platforms of following a function pointer vs an if/then/else check? I'm wondering if it might be just as fast to put the default iflib queue selection into a a default function for isc_txq_select()