Changeset View
Changeset View
Standalone View
Standalone View
sys/net/iflib.c
Show First 20 Lines • Show All 1,404 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
int i; | int i; | ||||
iflib_dma_info_t *dmaiter = dmalist; | iflib_dma_info_t *dmaiter = dmalist; | ||||
for (i = 0; i < count; i++, dmaiter++) | for (i = 0; i < count; i++, dmaiter++) | ||||
iflib_dma_free(*dmaiter); | iflib_dma_free(*dmaiter); | ||||
} | } | ||||
#ifdef EARLY_AP_STARTUP | |||||
static const int iflib_started = 1; | |||||
#else | |||||
/* | |||||
* We used to abuse the smp_started flag to decide if the queues have been | |||||
* fully initialized (by late taskqgroup_adjust() calls in a SYSINIT()). | |||||
* That gave bad races, since the SYSINIT() runs strictly after smp_started | |||||
* is set. Run a SYSINIT() strictly after that to just set a usable | |||||
* completion flag. | |||||
*/ | |||||
static int iflib_started; | |||||
static void | |||||
iflib_record_started(void *arg) | |||||
{ | |||||
iflib_started = 1; | |||||
} | |||||
SYSINIT(iflib_record_started, SI_SUB_SMP + 1, SI_ORDER_FIRST, | |||||
iflib_record_started, NULL); | |||||
#endif | |||||
static int | static int | ||||
iflib_fast_intr(void *arg) | iflib_fast_intr(void *arg) | ||||
{ | { | ||||
iflib_filter_info_t info = arg; | iflib_filter_info_t info = arg; | ||||
struct grouptask *gtask = info->ifi_task; | struct grouptask *gtask = info->ifi_task; | ||||
int result; | int result; | ||||
if (!iflib_started) | |||||
return (FILTER_STRAY); | |||||
DBG_COUNTER_INC(fast_intrs); | DBG_COUNTER_INC(fast_intrs); | ||||
if (info->ifi_filter != NULL) { | if (info->ifi_filter != NULL) { | ||||
result = info->ifi_filter(info->ifi_filter_arg); | result = info->ifi_filter(info->ifi_filter_arg); | ||||
if ((result & FILTER_SCHEDULE_THREAD) == 0) | if ((result & FILTER_SCHEDULE_THREAD) == 0) | ||||
return (result); | return (result); | ||||
} | } | ||||
GROUPTASK_ENQUEUE(gtask); | GROUPTASK_ENQUEUE(gtask); | ||||
return (FILTER_HANDLED); | return (FILTER_HANDLED); | ||||
} | } | ||||
static int | static int | ||||
iflib_fast_intr_rxtx(void *arg) | iflib_fast_intr_rxtx(void *arg) | ||||
{ | { | ||||
iflib_filter_info_t info = arg; | iflib_filter_info_t info = arg; | ||||
struct grouptask *gtask = info->ifi_task; | struct grouptask *gtask = info->ifi_task; | ||||
if_ctx_t ctx; | if_ctx_t ctx; | ||||
iflib_rxq_t rxq = (iflib_rxq_t)info->ifi_ctx; | iflib_rxq_t rxq = (iflib_rxq_t)info->ifi_ctx; | ||||
iflib_txq_t txq; | iflib_txq_t txq; | ||||
void *sc; | void *sc; | ||||
int i, cidx, result; | int i, cidx, result; | ||||
qidx_t txqid; | qidx_t txqid; | ||||
bool intr_enable, intr_legacy; | bool intr_enable, intr_legacy; | ||||
if (!iflib_started) | |||||
return (FILTER_STRAY); | |||||
DBG_COUNTER_INC(fast_intrs); | DBG_COUNTER_INC(fast_intrs); | ||||
if (info->ifi_filter != NULL) { | if (info->ifi_filter != NULL) { | ||||
result = info->ifi_filter(info->ifi_filter_arg); | result = info->ifi_filter(info->ifi_filter_arg); | ||||
if ((result & FILTER_SCHEDULE_THREAD) == 0) | if ((result & FILTER_SCHEDULE_THREAD) == 0) | ||||
return (result); | return (result); | ||||
} | } | ||||
ctx = rxq->ifr_ctx; | ctx = rxq->ifr_ctx; | ||||
Show All 36 Lines | |||||
static int | static int | ||||
iflib_fast_intr_ctx(void *arg) | iflib_fast_intr_ctx(void *arg) | ||||
{ | { | ||||
iflib_filter_info_t info = arg; | iflib_filter_info_t info = arg; | ||||
struct grouptask *gtask = info->ifi_task; | struct grouptask *gtask = info->ifi_task; | ||||
int result; | int result; | ||||
if (!iflib_started) | |||||
return (FILTER_STRAY); | |||||
DBG_COUNTER_INC(fast_intrs); | DBG_COUNTER_INC(fast_intrs); | ||||
if (info->ifi_filter != NULL) { | if (info->ifi_filter != NULL) { | ||||
result = info->ifi_filter(info->ifi_filter_arg); | result = info->ifi_filter(info->ifi_filter_arg); | ||||
if ((result & FILTER_SCHEDULE_THREAD) == 0) | if ((result & FILTER_SCHEDULE_THREAD) == 0) | ||||
return (result); | return (result); | ||||
} | } | ||||
GROUPTASK_ENQUEUE(gtask); | GROUPTASK_ENQUEUE(gtask); | ||||
▲ Show 20 Lines • Show All 3,204 Lines • ▼ Show 20 Lines | #endif | ||||
if ((err = iflib_qset_structures_setup(ctx))) | if ((err = iflib_qset_structures_setup(ctx))) | ||||
goto fail_queues; | goto fail_queues; | ||||
/* | /* | ||||
* Now that we know how many queues there are, get the core offset. | * Now that we know how many queues there are, get the core offset. | ||||
*/ | */ | ||||
ctx->ifc_sysctl_core_offset = get_ctx_core_offset(ctx); | ctx->ifc_sysctl_core_offset = get_ctx_core_offset(ctx); | ||||
/* | |||||
* Group taskqueues aren't properly set up until SMP is started, | |||||
* so we disable interrupts until we can handle them post | |||||
* SI_SUB_SMP. | |||||
* | |||||
* XXX: disabling interrupts doesn't actually work, at least for | |||||
* the non-MSI case. When they occur before SI_SUB_SMP completes, | |||||
* we do null handling and depend on this not causing too large an | |||||
* interrupt storm. | |||||
*/ | |||||
IFDI_INTR_DISABLE(ctx); | |||||
if (msix > 1) { | if (msix > 1) { | ||||
/* | /* | ||||
* When using MSI-X, ensure that ifdi_{r,t}x_queue_intr_enable | * When using MSI-X, ensure that ifdi_{r,t}x_queue_intr_enable | ||||
* aren't the default NULL implementation. | * aren't the default NULL implementation. | ||||
*/ | */ | ||||
kobj_desc = &ifdi_rx_queue_intr_enable_desc; | kobj_desc = &ifdi_rx_queue_intr_enable_desc; | ||||
kobj_method = kobj_lookup_method(((kobj_t)ctx)->ops->cls, NULL, | kobj_method = kobj_lookup_method(((kobj_t)ctx)->ops->cls, NULL, | ||||
▲ Show 20 Lines • Show All 2,117 Lines • Show Last 20 Lines |