diff options
| author | Manjunathappa Prakash <prakashpm@codeaurora.org> | 2017-10-05 18:26:38 -0700 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-10-17 21:07:14 -0700 |
| commit | 5acd0f17abc7a6606131e94fc13257c8ff2a6869 (patch) | |
| tree | 09be451844930b29c2226cd7fb6857d3863acb19 | |
| parent | 541bae0e32b3605585395264fb8f50815ba65afb (diff) | |
qcacmn: Add GRO support to NAPI+Rx_thread processing model
GRO aggregations are hanging out of NAPI instance and We cannot use the
hif NAPI instance in Rx thread as gro_list inside NAPI is flushed out
at the start and end of NAPI poll, this will corrupt the gro_list on
which rx_thread is working. Address this concern by creating dummy
NAPI instances mapping to each hif NAPI and not scheduling them.
Change-Id: I517c4c6158ed3ac073f5f617afde46c7ed07ff3e
CRs-Fixed: 2128457
| -rw-r--r-- | dp/inc/cdp_txrx_cmn.h | 2 | ||||
| -rw-r--r-- | dp/inc/cdp_txrx_lro.h | 6 | ||||
| -rw-r--r-- | hif/inc/hif.h | 15 | ||||
| -rw-r--r-- | hif/inc/hif_napi.h | 4 | ||||
| -rw-r--r-- | hif/src/ce/ce_api.h | 2 | ||||
| -rw-r--r-- | hif/src/ce/ce_main.c | 2 | ||||
| -rw-r--r-- | hif/src/hif_main.c | 37 | ||||
| -rw-r--r-- | hif/src/hif_napi.c | 51 |
8 files changed, 62 insertions, 57 deletions
diff --git a/dp/inc/cdp_txrx_cmn.h b/dp/inc/cdp_txrx_cmn.h index f84578e447bc..8593921b45f9 100644 --- a/dp/inc/cdp_txrx_cmn.h +++ b/dp/inc/cdp_txrx_cmn.h @@ -344,6 +344,8 @@ void ol_txrx_vdev_register(ol_txrx_vdev_handle vdev, void *osif_vdev, struct ol_txrx_ops *txrx_ops); +void ol_register_offld_flush_cb(void (gro_flush_cb)(void *), + void *(gro_init_cb)(void)); int ol_txrx_mgmt_send( ol_txrx_vdev_handle vdev, diff --git a/dp/inc/cdp_txrx_lro.h b/dp/inc/cdp_txrx_lro.h index 8a35d147682e..19e8b111dd29 100644 --- a/dp/inc/cdp_txrx_lro.h +++ b/dp/inc/cdp_txrx_lro.h @@ -32,8 +32,8 @@ #ifndef _CDP_TXRX_LRO_H_ #define _CDP_TXRX_LRO_H_ -void ol_register_lro_flush_cb(void (*lro_flush_cb)(void *data), - void *(lro_init_cb)(void)); -void ol_deregister_lro_flush_cb(void (*lro_deinit_cb)(void *data)); +void ol_register_offld_flush_cb(void (*offld_flush_cb)(void *data), + void *(offld_init_cb)(void)); +void ol_deregister_offld_flush_cb(void (*offld_deinit_cb)(void *data)); #endif /* _CDP_TXRX_LRO_H_ */ diff --git a/hif/inc/hif.h b/hif/inc/hif.h index 86c16bd3ffc1..b0c2fd385da3 100644 --- a/hif/inc/hif.h +++ b/hif/inc/hif.h @@ -147,8 +147,8 @@ struct qca_napi_info { int irq; struct qca_napi_stat stats[NR_CPUS]; /* will only be present for data rx CE's */ - void (*lro_flush_cb)(void *arg); - void *lro_ctx; + void (*offld_flush_cb)(void *arg); + void *offld_ctx; }; /** @@ -709,11 +709,12 @@ int ol_copy_ramdump(struct hif_opaque_softc *hif_ctx); void hif_crash_shutdown(struct hif_opaque_softc *hif_ctx); void hif_get_hw_info(struct hif_opaque_softc *hif_ctx, u32 *version, u32 *revision, const char **target_name); -void hif_lro_flush_cb_register(struct hif_opaque_softc *hif_ctx, - void (lro_flush_handler)(void *arg), - void *(lro_init_handler)(void)); -void hif_lro_flush_cb_deregister(struct hif_opaque_softc *hif_ctx, - void (lro_deinit_cb)(void *arg)); + +void hif_offld_flush_cb_register(struct hif_opaque_softc *scn, + void (offld_flush_handler)(void *), + void *(offld_init_handler)(void)); +void hif_offld_flush_cb_deregister(struct hif_opaque_softc *hif_ctx, + void (offld_deinit_cb)(void *arg)); bool hif_needs_bmi(struct hif_opaque_softc *hif_ctx); enum qdf_bus_type hif_get_bus_type(struct hif_opaque_softc *hif_hdl); struct hif_target_info *hif_get_target_info_handle(struct hif_opaque_softc * diff --git a/hif/inc/hif_napi.h b/hif/inc/hif_napi.h index 865f156d27dd..dab7876932b2 100644 --- a/hif/inc/hif_napi.h +++ b/hif/inc/hif_napi.h @@ -96,7 +96,7 @@ enum qca_napi_event { #define NAPI_ID2PIPE(i) ((i)-1) #define NAPI_PIPE2ID(p) ((p)+1) -int hif_napi_lro_flush_cb_register(struct hif_opaque_softc *hif_hdl, +int hif_napi_offld_flush_cb_register(struct hif_opaque_softc *hif_hdl, void (lro_flush_handler)(void *arg), void *(lro_init_handler)(void)); @@ -123,7 +123,7 @@ int hif_napi_destroy(struct hif_opaque_softc *hif, int force); struct qca_napi_data *hif_napi_get_all(struct hif_opaque_softc *hif); -struct napi_struct *hif_get_napi(int napi_id, void *napi_d); +struct qca_napi_info *hif_get_napi(int napi_id, void *napi_d); int hif_napi_event(struct hif_opaque_softc *hif, enum qca_napi_event event, diff --git a/hif/src/ce/ce_api.h b/hif/src/ce/ce_api.h index 836853d12d58..68ef7963c638 100644 --- a/hif/src/ce/ce_api.h +++ b/hif/src/ce/ce_api.h @@ -485,13 +485,11 @@ static inline void ce_pkt_error_count_incr( bool ce_check_rx_pending(struct CE_state *CE_state); void *hif_ce_get_lro_ctx(struct hif_opaque_softc *hif_hdl, int ctx_id); -#if defined(FEATURE_LRO) int ce_lro_flush_cb_register(struct hif_opaque_softc *scn, void (handler)(void *arg), void *(lro_init_handler)(void)); int ce_lro_flush_cb_deregister(struct hif_opaque_softc *hif_hdl, void (lro_deinit_cb)(void *arg)); -#endif int hif_ce_bus_early_suspend(struct hif_softc *scn); int hif_ce_bus_late_resume(struct hif_softc *scn); diff --git a/hif/src/ce/ce_main.c b/hif/src/ce/ce_main.c index 783b515c1148..e72a4547b614 100644 --- a/hif/src/ce/ce_main.c +++ b/hif/src/ce/ce_main.c @@ -2696,6 +2696,7 @@ void *hif_ce_get_lro_ctx(struct hif_opaque_softc *hif_hdl, int ctx_id) return ce_state->lro_data; } +#endif /** * ce_lro_flush_cb_register() - register the LRO flush @@ -2774,7 +2775,6 @@ int ce_lro_flush_cb_deregister(struct hif_opaque_softc *hif_hdl, } return rc; } -#endif /** * hif_map_service_to_pipe() - returns the ce ids pertaining to diff --git a/hif/src/hif_main.c b/hif/src/hif_main.c index 6cd21f42f771..ba553465c840 100644 --- a/hif/src/hif_main.c +++ b/hif/src/hif_main.c @@ -802,27 +802,27 @@ int hif_get_rx_ctx_id(int ctx_id, struct hif_opaque_softc *hif_hdl) return ctx_id; } -#if defined(FEATURE_LRO) /** - * hif_lro_flush_cb_register - API to register for LRO Flush Callback + * hif_offld_flush_cb_register - API to register for LRO Flush Callback * @scn: HIF Context - * @handler: Function pointer to be called by HIF - * @data: Private data to be used by the module registering to HIF + * @offld_flush_handler: Flush handler + * @offld_init_handler: Init handler of Rx offload * * Return: void */ -void hif_lro_flush_cb_register(struct hif_opaque_softc *scn, - void (lro_flush_handler)(void *), - void *(lro_init_handler)(void)) +void hif_offld_flush_cb_register(struct hif_opaque_softc *scn, + void (offld_flush_handler)(void *), + void *(offld_init_handler)(void)) { if (hif_napi_enabled(scn, -1)) - hif_napi_lro_flush_cb_register(scn, lro_flush_handler, - lro_init_handler); + hif_napi_offld_flush_cb_register(scn, offld_flush_handler, + offld_init_handler); else - ce_lro_flush_cb_register(scn, lro_flush_handler, - lro_init_handler); + ce_lro_flush_cb_register(scn, offld_flush_handler, + offld_init_handler); } +#if defined(FEATURE_LRO) /** * hif_get_lro_info - Returns LRO instance for instance ID * @ctx_id: LRO instance ID @@ -842,20 +842,21 @@ void *hif_get_lro_info(int ctx_id, struct hif_opaque_softc *hif_hdl) return data; } + +#endif /** - * hif_lro_flush_cb_deregister - API to deregister for LRO Flush Callbacks + * hif_offld_flush_cb_deregister - API to deregister offload Flush Callbacks * @hif_hdl: HIF Context - * @lro_deinit_cb: LRO deinit callback + * @offld_deinit_cb: Rx offload deinit callback * * Return: void */ -void hif_lro_flush_cb_deregister(struct hif_opaque_softc *hif_hdl, - void (lro_deinit_cb)(void *)) +void hif_offld_flush_cb_deregister(struct hif_opaque_softc *hif_hdl, + void (offld_deinit_cb)(void *)) { - hif_napi_lro_flush_cb_deregister(hif_hdl, lro_deinit_cb); - ce_lro_flush_cb_deregister(hif_hdl, lro_deinit_cb); + hif_napi_lro_flush_cb_deregister(hif_hdl, offld_deinit_cb); + ce_lro_flush_cb_deregister(hif_hdl, offld_deinit_cb); } -#endif /** * hif_get_target_status - API to get target status diff --git a/hif/src/hif_napi.c b/hif/src/hif_napi.c index 8d98eb842c1c..a587049f84fc 100644 --- a/hif/src/hif_napi.c +++ b/hif/src/hif_napi.c @@ -184,6 +184,7 @@ int hif_napi_create(struct hif_opaque_softc *hif_ctx, NAPI_DEBUG("adding napi=%pK to netdev=%pK (poll=%pK, bdgt=%d)", &(napii->napi), &(napii->netdev), poll, budget); netif_napi_add(&(napii->netdev), &(napii->napi), poll, budget); + napii->offld_ctx = &(napii->napi); NAPI_DEBUG("after napi_add"); NAPI_DEBUG("napi=0x%pK, netdev=0x%pK", @@ -323,16 +324,18 @@ int hif_napi_destroy(struct hif_opaque_softc *hif_ctx, } /** - * hif_napi_lro_flush_cb_register() - init and register flush callback for LRO + * hif_napi_offld_flush_cb_register() - init and register flush callback * @hif_hdl: pointer to hif context - * @lro_flush_handler: register LRO flush callback - * @lro_init_handler: Callback for initializing LRO + * @offld_flush_handler: register Rx offload flush callback + * @offld_init_handler: Callback for initializing Rx offfload + * + * Init and register flush callback for LRO or GRO Rx offload features * * Return: positive value on success and 0 on failure */ -int hif_napi_lro_flush_cb_register(struct hif_opaque_softc *hif_hdl, - void (lro_flush_handler)(void *), - void *(lro_init_handler)(void)) +int hif_napi_offld_flush_cb_register(struct hif_opaque_softc *hif_hdl, + void (offld_flush_handler)(void *), + void *(offld_init_handler)(void)) { int rc = 0; int i; @@ -348,17 +351,17 @@ int hif_napi_lro_flush_cb_register(struct hif_opaque_softc *hif_hdl, for (i = 0; i < scn->ce_count; i++) { napii = napid->napis[i]; if (napii) { - data = lro_init_handler(); + data = offld_init_handler(); if (data == NULL) { - HIF_ERROR("%s: Failed to init LRO for CE %d", + HIF_ERROR("%s: Failed to init offld for CE %d", __func__, i); continue; } - napii->lro_flush_cb = lro_flush_handler; - napii->lro_ctx = data; - HIF_DBG("Registering LRO for ce_id %d NAPI callback for %d flush_cb %pK, lro_data %pK\n", - i, napii->id, napii->lro_flush_cb, - napii->lro_ctx); + napii->offld_flush_cb = offld_flush_handler; + napii->offld_ctx = data; + HIF_DBG("Registering offld for ce_id %d NAPI callback for %d flush_cb %pK, offld_data %pK\n", + i, napii->id, napii->offld_flush_cb, + napii->offld_ctx); rc++; } } @@ -368,12 +371,12 @@ int hif_napi_lro_flush_cb_register(struct hif_opaque_softc *hif_hdl, return rc; } -struct napi_struct *hif_get_napi(int napi_id, void *napi_d) +struct qca_napi_info *hif_get_napi(int napi_id, void *napi_d) { struct qca_napi_data *napid = napi_d; int id = NAPI_ID2PIPE(napi_id); - return &(napid->napis[id]->napi); + return napid->napis[id]; } /** @@ -399,11 +402,11 @@ void hif_napi_lro_flush_cb_deregister(struct hif_opaque_softc *hif_hdl, napii = napid->napis[i]; if (napii) { HIF_DBG("deRegistering LRO for ce_id %d NAPI callback for %d flush_cb %pK, lro_data %pK\n", - i, napii->id, napii->lro_flush_cb, - napii->lro_ctx); - napii->lro_flush_cb = NULL; - lro_deinit_cb(napii->lro_ctx); - napii->lro_ctx = NULL; + i, napii->id, napii->offld_flush_cb, + napii->offld_ctx); + napii->offld_flush_cb = NULL; + lro_deinit_cb(napii->offld_ctx); + napii->offld_ctx = NULL; } } } else { @@ -432,7 +435,7 @@ void *hif_napi_get_lro_info(struct hif_opaque_softc *hif_hdl, int napi_id) napii = napid->napis[NAPI_ID2PIPE(napi_id)]; if (napii) - return napii->lro_ctx; + return napii->offld_ctx; return 0; } @@ -867,8 +870,8 @@ int hif_napi_poll(struct hif_opaque_softc *hif_ctx, NAPI_DEBUG("%s: ce_per_engine_service processed %d msgs", __func__, rc); - if (napi_info->lro_flush_cb) - napi_info->lro_flush_cb(napi_info->lro_ctx); + if (napi_info->offld_flush_cb) + napi_info->offld_flush_cb(napi_info->offld_ctx); /* do not return 0, if there was some work done, * even if it is below the scale @@ -910,8 +913,8 @@ int hif_napi_poll(struct hif_opaque_softc *hif_ctx, if (normalized >= budget) normalized = budget - 1; - /* enable interrupts */ napi_complete(napi); + /* enable interrupts */ hif_napi_enable_irq(hif_ctx, napi_info->id); /* support suspend/resume */ qdf_atomic_dec(&(hif->active_tasklet_cnt)); |
