Changeset View
Changeset View
Standalone View
Standalone View
sys/net/iflib.c
Show First 20 Lines • Show All 136 Lines • ▼ Show 20 Lines | |||||
typedef struct iflib_rxq *iflib_rxq_t; | typedef struct iflib_rxq *iflib_rxq_t; | ||||
struct iflib_fl; | struct iflib_fl; | ||||
typedef struct iflib_fl *iflib_fl_t; | typedef struct iflib_fl *iflib_fl_t; | ||||
struct iflib_ctx; | struct iflib_ctx; | ||||
static void iru_init(if_rxd_update_t iru, iflib_rxq_t rxq, uint8_t flid); | static void iru_init(if_rxd_update_t iru, iflib_rxq_t rxq, uint8_t flid); | ||||
static void iflib_timer(void *arg); | static void iflib_timer(void *arg); | ||||
static void iflib_tqg_detach(if_ctx_t ctx); | |||||
typedef struct iflib_filter_info { | typedef struct iflib_filter_info { | ||||
driver_filter_t *ifi_filter; | driver_filter_t *ifi_filter; | ||||
void *ifi_filter_arg; | void *ifi_filter_arg; | ||||
struct grouptask *ifi_task; | struct grouptask *ifi_task; | ||||
void *ifi_ctx; | void *ifi_ctx; | ||||
} *iflib_filter_info_t; | } *iflib_filter_info_t; | ||||
▲ Show 20 Lines • Show All 2,100 Lines • ▼ Show 20 Lines | for (i = 0; i < rxq->ifr_nfl; i++) { | ||||
} | } | ||||
bus_dma_tag_destroy(fl->ifl_buf_tag); | bus_dma_tag_destroy(fl->ifl_buf_tag); | ||||
fl->ifl_buf_tag = NULL; | fl->ifl_buf_tag = NULL; | ||||
} | } | ||||
free(fl->ifl_sds.ifsd_m, M_IFLIB); | free(fl->ifl_sds.ifsd_m, M_IFLIB); | ||||
free(fl->ifl_sds.ifsd_cl, M_IFLIB); | free(fl->ifl_sds.ifsd_cl, M_IFLIB); | ||||
free(fl->ifl_sds.ifsd_ba, M_IFLIB); | free(fl->ifl_sds.ifsd_ba, M_IFLIB); | ||||
free(fl->ifl_sds.ifsd_map, M_IFLIB); | free(fl->ifl_sds.ifsd_map, M_IFLIB); | ||||
free(fl->ifl_rx_bitmap, M_IFLIB); | |||||
fl->ifl_sds.ifsd_m = NULL; | fl->ifl_sds.ifsd_m = NULL; | ||||
fl->ifl_sds.ifsd_cl = NULL; | fl->ifl_sds.ifsd_cl = NULL; | ||||
fl->ifl_sds.ifsd_ba = NULL; | fl->ifl_sds.ifsd_ba = NULL; | ||||
fl->ifl_sds.ifsd_map = NULL; | fl->ifl_sds.ifsd_map = NULL; | ||||
fl->ifl_rx_bitmap = NULL; | |||||
} | } | ||||
free(rxq->ifr_fl, M_IFLIB); | free(rxq->ifr_fl, M_IFLIB); | ||||
rxq->ifr_fl = NULL; | rxq->ifr_fl = NULL; | ||||
free(rxq->ifr_ifdi, M_IFLIB); | free(rxq->ifr_ifdi, M_IFLIB); | ||||
rxq->ifr_ifdi = NULL; | rxq->ifr_ifdi = NULL; | ||||
rxq->ifr_cq_cidx = 0; | rxq->ifr_cq_cidx = 0; | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 2,564 Lines • ▼ Show 20 Lines | |||||
fail_detach: | fail_detach: | ||||
ether_ifdetach(ctx->ifc_ifp); | ether_ifdetach(ctx->ifc_ifp); | ||||
fail_intr_free: | fail_intr_free: | ||||
iflib_free_intr_mem(ctx); | iflib_free_intr_mem(ctx); | ||||
fail_queues: | fail_queues: | ||||
iflib_tx_structures_free(ctx); | iflib_tx_structures_free(ctx); | ||||
iflib_rx_structures_free(ctx); | iflib_rx_structures_free(ctx); | ||||
taskqgroup_detach(qgroup_if_config_tqg, &ctx->ifc_admin_task); | iflib_tqg_detach(ctx); | ||||
IFDI_DETACH(ctx); | IFDI_DETACH(ctx); | ||||
fail_unlock: | fail_unlock: | ||||
CTX_UNLOCK(ctx); | CTX_UNLOCK(ctx); | ||||
iflib_deregister(ctx); | iflib_deregister(ctx); | ||||
fail_ctx_free: | fail_ctx_free: | ||||
device_set_softc(ctx->ifc_dev, NULL); | device_set_softc(ctx->ifc_dev, NULL); | ||||
if (ctx->ifc_flags & IFC_SC_ALLOCATED) | if (ctx->ifc_flags & IFC_SC_ALLOCATED) | ||||
free(ctx->ifc_softc, M_IFLIB); | free(ctx->ifc_softc, M_IFLIB); | ||||
▲ Show 20 Lines • Show All 183 Lines • ▼ Show 20 Lines | #endif | ||||
CTX_UNLOCK(ctx); | CTX_UNLOCK(ctx); | ||||
return (0); | return (0); | ||||
fail_detach: | fail_detach: | ||||
ether_ifdetach(ctx->ifc_ifp); | ether_ifdetach(ctx->ifc_ifp); | ||||
fail_queues: | fail_queues: | ||||
iflib_tx_structures_free(ctx); | iflib_tx_structures_free(ctx); | ||||
iflib_rx_structures_free(ctx); | iflib_rx_structures_free(ctx); | ||||
iflib_tqg_detach(ctx); | |||||
fail_iflib_detach: | fail_iflib_detach: | ||||
IFDI_DETACH(ctx); | IFDI_DETACH(ctx); | ||||
fail_unlock: | fail_unlock: | ||||
CTX_UNLOCK(ctx); | CTX_UNLOCK(ctx); | ||||
iflib_deregister(ctx); | iflib_deregister(ctx); | ||||
fail_ctx_free: | fail_ctx_free: | ||||
free(ctx->ifc_softc, M_IFLIB); | free(ctx->ifc_softc, M_IFLIB); | ||||
free(ctx, M_IFLIB); | free(ctx, M_IFLIB); | ||||
return (err); | return (err); | ||||
} | } | ||||
int | int | ||||
iflib_pseudo_deregister(if_ctx_t ctx) | iflib_pseudo_deregister(if_ctx_t ctx) | ||||
{ | { | ||||
if_t ifp = ctx->ifc_ifp; | if_t ifp = ctx->ifc_ifp; | ||||
if_shared_ctx_t sctx = ctx->ifc_sctx; | if_shared_ctx_t sctx = ctx->ifc_sctx; | ||||
iflib_txq_t txq; | |||||
iflib_rxq_t rxq; | |||||
int i, j; | |||||
struct taskqgroup *tqg; | |||||
iflib_fl_t fl; | |||||
/* Unregister VLAN event handlers early */ | /* Unregister VLAN event handlers early */ | ||||
iflib_unregister_vlan_handlers(ctx); | iflib_unregister_vlan_handlers(ctx); | ||||
if ((sctx->isc_flags & IFLIB_PSEUDO) && | if ((sctx->isc_flags & IFLIB_PSEUDO) && | ||||
(sctx->isc_flags & IFLIB_PSEUDO_ETHER) == 0) { | (sctx->isc_flags & IFLIB_PSEUDO_ETHER) == 0) { | ||||
bpfdetach(ifp); | bpfdetach(ifp); | ||||
if_detach(ifp); | if_detach(ifp); | ||||
} else { | } else { | ||||
ether_ifdetach(ifp); | ether_ifdetach(ifp); | ||||
} | } | ||||
/* XXX drain any dependent tasks */ | |||||
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); | |||||
} | |||||
for (i = 0, rxq = ctx->ifc_rxqs; i < NRXQSETS(ctx); i++, rxq++) { | |||||
callout_drain(&rxq->ifr_watchdog); | |||||
if (rxq->ifr_task.gt_uniq != NULL) | |||||
taskqgroup_detach(tqg, &rxq->ifr_task); | |||||
for (j = 0, fl = rxq->ifr_fl; j < rxq->ifr_nfl; j++, fl++) | iflib_tqg_detach(ctx); | ||||
free(fl->ifl_rx_bitmap, M_IFLIB); | |||||
} | |||||
tqg = qgroup_if_config_tqg; | |||||
if (ctx->ifc_admin_task.gt_uniq != NULL) | |||||
taskqgroup_detach(tqg, &ctx->ifc_admin_task); | |||||
if (ctx->ifc_vflr_task.gt_uniq != NULL) | |||||
taskqgroup_detach(tqg, &ctx->ifc_vflr_task); | |||||
iflib_tx_structures_free(ctx); | iflib_tx_structures_free(ctx); | ||||
iflib_rx_structures_free(ctx); | iflib_rx_structures_free(ctx); | ||||
markj: This calls `iflib_rx_sds_free()` on each rxq, so why is it necessary to keep freeing the… | |||||
Not Done Inline ActionsThanks Mark for pointing this out. I agree. Above loop to free bitmap is not necessary. I will remove the loop and refresh the change. stallamr_netapp.com: Thanks Mark for pointing this out. I agree. Above loop to free bitmap is not necessary. I will… | |||||
iflib_deregister(ctx); | iflib_deregister(ctx); | ||||
if (ctx->ifc_flags & IFC_SC_ALLOCATED) | if (ctx->ifc_flags & IFC_SC_ALLOCATED) | ||||
free(ctx->ifc_softc, M_IFLIB); | free(ctx->ifc_softc, M_IFLIB); | ||||
free(ctx, M_IFLIB); | free(ctx, M_IFLIB); | ||||
return (0); | return (0); | ||||
} | } | ||||
Show All 11 Lines | iflib_device_attach(device_t dev) | ||||
return (iflib_device_register(dev, NULL, sctx, &ctx)); | return (iflib_device_register(dev, NULL, sctx, &ctx)); | ||||
} | } | ||||
int | int | ||||
iflib_device_deregister(if_ctx_t ctx) | iflib_device_deregister(if_ctx_t ctx) | ||||
{ | { | ||||
if_t ifp = ctx->ifc_ifp; | if_t ifp = ctx->ifc_ifp; | ||||
iflib_txq_t txq; | |||||
iflib_rxq_t rxq; | |||||
device_t dev = ctx->ifc_dev; | device_t dev = ctx->ifc_dev; | ||||
int i, j; | |||||
struct taskqgroup *tqg; | |||||
iflib_fl_t fl; | |||||
/* Make sure VLANS are not using driver */ | /* Make sure VLANS are not using driver */ | ||||
if (if_vlantrunkinuse(ifp)) { | if (if_vlantrunkinuse(ifp)) { | ||||
device_printf(dev, "Vlan in use, detach first\n"); | device_printf(dev, "Vlan in use, detach first\n"); | ||||
return (EBUSY); | return (EBUSY); | ||||
} | } | ||||
#ifdef PCI_IOV | #ifdef PCI_IOV | ||||
if (!CTX_IS_VF(ctx) && pci_iov_detach(dev) != 0) { | if (!CTX_IS_VF(ctx) && pci_iov_detach(dev) != 0) { | ||||
Show All 14 Lines | #endif | ||||
CTX_LOCK(ctx); | CTX_LOCK(ctx); | ||||
iflib_stop(ctx); | iflib_stop(ctx); | ||||
CTX_UNLOCK(ctx); | CTX_UNLOCK(ctx); | ||||
iflib_rem_pfil(ctx); | iflib_rem_pfil(ctx); | ||||
if (ctx->ifc_led_dev != NULL) | if (ctx->ifc_led_dev != NULL) | ||||
led_destroy(ctx->ifc_led_dev); | led_destroy(ctx->ifc_led_dev); | ||||
/* XXX drain any dependent tasks */ | |||||
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); | |||||
} | |||||
for (i = 0, rxq = ctx->ifc_rxqs; i < NRXQSETS(ctx); i++, rxq++) { | |||||
if (rxq->ifr_task.gt_uniq != NULL) | |||||
taskqgroup_detach(tqg, &rxq->ifr_task); | |||||
for (j = 0, fl = rxq->ifr_fl; j < rxq->ifr_nfl; j++, fl++) | iflib_tqg_detach(ctx); | ||||
free(fl->ifl_rx_bitmap, M_IFLIB); | |||||
} | |||||
tqg = qgroup_if_config_tqg; | |||||
if (ctx->ifc_admin_task.gt_uniq != NULL) | |||||
taskqgroup_detach(tqg, &ctx->ifc_admin_task); | |||||
if (ctx->ifc_vflr_task.gt_uniq != NULL) | |||||
taskqgroup_detach(tqg, &ctx->ifc_vflr_task); | |||||
CTX_LOCK(ctx); | CTX_LOCK(ctx); | ||||
IFDI_DETACH(ctx); | IFDI_DETACH(ctx); | ||||
CTX_UNLOCK(ctx); | CTX_UNLOCK(ctx); | ||||
/* ether_ifdetach calls if_qflush - lock must be destroy afterwards*/ | /* ether_ifdetach calls if_qflush - lock must be destroy afterwards*/ | ||||
iflib_free_intr_mem(ctx); | iflib_free_intr_mem(ctx); | ||||
bus_generic_detach(dev); | bus_generic_detach(dev); | ||||
iflib_tx_structures_free(ctx); | iflib_tx_structures_free(ctx); | ||||
iflib_rx_structures_free(ctx); | iflib_rx_structures_free(ctx); | ||||
Not Done Inline ActionsSame question as above. markj: Same question as above. | |||||
Not Done Inline ActionsAgree. Will remove the loop and refresh the review. stallamr_netapp.com: Agree. Will remove the loop and refresh the review. | |||||
iflib_deregister(ctx); | iflib_deregister(ctx); | ||||
device_set_softc(ctx->ifc_dev, NULL); | device_set_softc(ctx->ifc_dev, NULL); | ||||
if (ctx->ifc_flags & IFC_SC_ALLOCATED) | if (ctx->ifc_flags & IFC_SC_ALLOCATED) | ||||
free(ctx->ifc_softc, M_IFLIB); | free(ctx->ifc_softc, M_IFLIB); | ||||
unref_ctx_core_offset(ctx); | unref_ctx_core_offset(ctx); | ||||
free(ctx, M_IFLIB); | free(ctx, M_IFLIB); | ||||
return (0); | return (0); | ||||
} | |||||
static void | |||||
iflib_tqg_detach(if_ctx_t ctx) | |||||
{ | |||||
iflib_txq_t txq; | |||||
iflib_rxq_t rxq; | |||||
int i; | |||||
struct taskqgroup *tqg; | |||||
/* XXX drain any dependent tasks */ | |||||
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); | |||||
} | |||||
for (i = 0, rxq = ctx->ifc_rxqs; i < NRXQSETS(ctx); i++, rxq++) { | |||||
if (rxq->ifr_task.gt_uniq != NULL) | |||||
taskqgroup_detach(tqg, &rxq->ifr_task); | |||||
} | |||||
tqg = qgroup_if_config_tqg; | |||||
if (ctx->ifc_admin_task.gt_uniq != NULL) | |||||
taskqgroup_detach(tqg, &ctx->ifc_admin_task); | |||||
if (ctx->ifc_vflr_task.gt_uniq != NULL) | |||||
taskqgroup_detach(tqg, &ctx->ifc_vflr_task); | |||||
} | } | ||||
static void | static void | ||||
iflib_free_intr_mem(if_ctx_t ctx) | iflib_free_intr_mem(if_ctx_t ctx) | ||||
{ | { | ||||
if (ctx->ifc_softc_ctx.isc_intr != IFLIB_INTR_MSIX) { | if (ctx->ifc_softc_ctx.isc_intr != IFLIB_INTR_MSIX) { | ||||
iflib_irq_free(ctx, &ctx->ifc_legacy_irq); | iflib_irq_free(ctx, &ctx->ifc_legacy_irq); | ||||
▲ Show 20 Lines • Show All 1,697 Lines • Show Last 20 Lines |
This calls iflib_rx_sds_free() on each rxq, so why is it necessary to keep freeing the freelist bitmaps in the loop immediately above?