qcacmn: Add option to enable or disable accounting of Tx in NAPI budget
Add a division factor for number of tx completions to be accounted for in NAPI budget. Fix the data type of budget to int to account for negative values. Change-Id: I620af5537c5c1cdf3161da3a3c053a2c8bf777e8 CRs-Fixed: 2092526
This commit is contained in:

committed by
snandini

parent
6bcbdd5a27
commit
9e34025ada
@@ -733,60 +733,70 @@ static uint32_t dp_service_srngs(void *dp_ctx, uint32_t dp_budget)
|
|||||||
struct dp_soc *soc = int_ctx->soc;
|
struct dp_soc *soc = int_ctx->soc;
|
||||||
int ring = 0;
|
int ring = 0;
|
||||||
uint32_t work_done = 0;
|
uint32_t work_done = 0;
|
||||||
uint32_t budget = dp_budget;
|
int budget = dp_budget;
|
||||||
uint8_t tx_mask = int_ctx->tx_ring_mask;
|
uint8_t tx_mask = int_ctx->tx_ring_mask;
|
||||||
uint8_t rx_mask = int_ctx->rx_ring_mask;
|
uint8_t rx_mask = int_ctx->rx_ring_mask;
|
||||||
uint8_t rx_err_mask = int_ctx->rx_err_ring_mask;
|
uint8_t rx_err_mask = int_ctx->rx_err_ring_mask;
|
||||||
uint8_t rx_wbm_rel_mask = int_ctx->rx_wbm_rel_ring_mask;
|
uint8_t rx_wbm_rel_mask = int_ctx->rx_wbm_rel_ring_mask;
|
||||||
uint8_t reo_status_mask = int_ctx->reo_status_ring_mask;
|
uint8_t reo_status_mask = int_ctx->reo_status_ring_mask;
|
||||||
|
uint32_t remaining_quota = dp_budget;
|
||||||
|
|
||||||
/* Process Tx completion interrupts first to return back buffers */
|
/* Process Tx completion interrupts first to return back buffers */
|
||||||
if (tx_mask) {
|
while (tx_mask) {
|
||||||
for (ring = 0; ring < soc->num_tcl_data_rings; ring++) {
|
if (tx_mask & 0x1) {
|
||||||
if (tx_mask & (1 << ring)) {
|
work_done =
|
||||||
work_done =
|
dp_tx_comp_handler(soc,
|
||||||
dp_tx_comp_handler(soc, ring, budget);
|
soc->tx_comp_ring[ring].hal_srng,
|
||||||
budget -= work_done;
|
remaining_quota);
|
||||||
if (work_done)
|
|
||||||
QDF_TRACE(QDF_MODULE_ID_DP,
|
QDF_TRACE(QDF_MODULE_ID_DP,
|
||||||
QDF_TRACE_LEVEL_INFO,
|
QDF_TRACE_LEVEL_INFO,
|
||||||
"tx mask 0x%x ring %d,"
|
"tx mask 0x%x ring %d,"
|
||||||
"budget %d",
|
"budget %d, work_done %d",
|
||||||
tx_mask, ring, budget);
|
tx_mask, ring, budget, work_done);
|
||||||
if (budget <= 0)
|
|
||||||
goto budget_done;
|
budget -= work_done;
|
||||||
}
|
if (budget <= 0)
|
||||||
|
goto budget_done;
|
||||||
|
|
||||||
|
remaining_quota = budget;
|
||||||
}
|
}
|
||||||
|
tx_mask = tx_mask >> 1;
|
||||||
|
ring++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Process REO Exception ring interrupt */
|
/* Process REO Exception ring interrupt */
|
||||||
if (rx_err_mask) {
|
if (rx_err_mask) {
|
||||||
work_done = dp_rx_err_process(soc,
|
work_done = dp_rx_err_process(soc,
|
||||||
soc->reo_exception_ring.hal_srng, budget);
|
soc->reo_exception_ring.hal_srng,
|
||||||
budget -= work_done;
|
remaining_quota);
|
||||||
|
|
||||||
if (work_done)
|
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO,
|
||||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO,
|
|
||||||
"REO Exception Ring: work_done %d budget %d",
|
"REO Exception Ring: work_done %d budget %d",
|
||||||
work_done, budget);
|
work_done, budget);
|
||||||
|
|
||||||
|
budget -= work_done;
|
||||||
if (budget <= 0) {
|
if (budget <= 0) {
|
||||||
goto budget_done;
|
goto budget_done;
|
||||||
}
|
}
|
||||||
|
remaining_quota = budget;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process Rx WBM release ring interrupt */
|
/* Process Rx WBM release ring interrupt */
|
||||||
if (rx_wbm_rel_mask) {
|
if (rx_wbm_rel_mask) {
|
||||||
work_done = dp_rx_wbm_err_process(soc,
|
work_done = dp_rx_wbm_err_process(soc,
|
||||||
soc->rx_rel_ring.hal_srng, budget);
|
soc->rx_rel_ring.hal_srng, remaining_quota);
|
||||||
budget -= work_done;
|
|
||||||
|
|
||||||
if (work_done)
|
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO,
|
||||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO,
|
|
||||||
"WBM Release Ring: work_done %d budget %d",
|
"WBM Release Ring: work_done %d budget %d",
|
||||||
work_done, budget);
|
work_done, budget);
|
||||||
|
|
||||||
|
budget -= work_done;
|
||||||
if (budget <= 0) {
|
if (budget <= 0) {
|
||||||
goto budget_done;
|
goto budget_done;
|
||||||
}
|
}
|
||||||
|
remaining_quota = budget;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process Rx interrupts */
|
/* Process Rx interrupts */
|
||||||
@@ -796,16 +806,19 @@ static uint32_t dp_service_srngs(void *dp_ctx, uint32_t dp_budget)
|
|||||||
work_done =
|
work_done =
|
||||||
dp_rx_process(int_ctx,
|
dp_rx_process(int_ctx,
|
||||||
soc->reo_dest_ring[ring].hal_srng,
|
soc->reo_dest_ring[ring].hal_srng,
|
||||||
budget);
|
remaining_quota);
|
||||||
budget -= work_done;
|
|
||||||
if (work_done)
|
QDF_TRACE(QDF_MODULE_ID_DP,
|
||||||
QDF_TRACE(QDF_MODULE_ID_DP,
|
|
||||||
QDF_TRACE_LEVEL_INFO,
|
QDF_TRACE_LEVEL_INFO,
|
||||||
"rx mask 0x%x ring %d,"
|
"rx mask 0x%x ring %d,"
|
||||||
"budget %d",
|
"work_done %d budget %d",
|
||||||
tx_mask, ring, budget);
|
rx_mask, ring, work_done,
|
||||||
|
budget);
|
||||||
|
|
||||||
|
budget -= work_done;
|
||||||
if (budget <= 0)
|
if (budget <= 0)
|
||||||
goto budget_done;
|
goto budget_done;
|
||||||
|
remaining_quota = budget;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -819,16 +832,17 @@ static uint32_t dp_service_srngs(void *dp_ctx, uint32_t dp_budget)
|
|||||||
continue;
|
continue;
|
||||||
if (int_ctx->rx_mon_ring_mask & (1 << ring)) {
|
if (int_ctx->rx_mon_ring_mask & (1 << ring)) {
|
||||||
work_done =
|
work_done =
|
||||||
dp_mon_process(soc, ring, budget);
|
dp_mon_process(soc, ring, remaining_quota);
|
||||||
budget -= work_done;
|
budget -= work_done;
|
||||||
|
remaining_quota = budget;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (int_ctx->rxdma2host_ring_mask & (1 << ring)) {
|
if (int_ctx->rxdma2host_ring_mask & (1 << ring)) {
|
||||||
work_done =
|
work_done =
|
||||||
dp_rxdma_err_process(soc, ring, budget);
|
dp_rxdma_err_process(soc, ring,
|
||||||
|
remaining_quota);
|
||||||
budget -= work_done;
|
budget -= work_done;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
qdf_lro_flush(int_ctx->lro_ctx);
|
qdf_lro_flush(int_ctx->lro_ctx);
|
||||||
|
@@ -38,7 +38,6 @@
|
|||||||
void dp_rx_mon_dest_process(struct dp_soc *soc, uint32_t mac_id,
|
void dp_rx_mon_dest_process(struct dp_soc *soc, uint32_t mac_id,
|
||||||
uint32_t quota);
|
uint32_t quota);
|
||||||
|
|
||||||
|
|
||||||
QDF_STATUS dp_rx_pdev_mon_attach(struct dp_pdev *pdev);
|
QDF_STATUS dp_rx_pdev_mon_attach(struct dp_pdev *pdev);
|
||||||
QDF_STATUS dp_rx_pdev_mon_detach(struct dp_pdev *pdev);
|
QDF_STATUS dp_rx_pdev_mon_detach(struct dp_pdev *pdev);
|
||||||
|
|
||||||
|
@@ -2063,7 +2063,7 @@ static void dp_tx_comp_process_desc(struct dp_soc *soc,
|
|||||||
* dp_tx_comp_handler() - Tx completion handler
|
* dp_tx_comp_handler() - Tx completion handler
|
||||||
* @soc: core txrx main context
|
* @soc: core txrx main context
|
||||||
* @ring_id: completion ring id
|
* @ring_id: completion ring id
|
||||||
* @budget: No. of packets/descriptors that can be serviced in one loop
|
* @quota: No. of packets/descriptors that can be serviced in one loop
|
||||||
*
|
*
|
||||||
* This function will collect hardware release ring element contents and
|
* This function will collect hardware release ring element contents and
|
||||||
* handle descriptor contents. Based on contents, free packet or handle error
|
* handle descriptor contents. Based on contents, free packet or handle error
|
||||||
@@ -2071,8 +2071,7 @@ static void dp_tx_comp_process_desc(struct dp_soc *soc,
|
|||||||
*
|
*
|
||||||
* Return: none
|
* Return: none
|
||||||
*/
|
*/
|
||||||
uint32_t dp_tx_comp_handler(struct dp_soc *soc, uint32_t ring_id,
|
uint32_t dp_tx_comp_handler(struct dp_soc *soc, void *hal_srng, uint32_t quota)
|
||||||
uint32_t budget)
|
|
||||||
{
|
{
|
||||||
void *tx_comp_hal_desc;
|
void *tx_comp_hal_desc;
|
||||||
uint8_t buffer_src;
|
uint8_t buffer_src;
|
||||||
@@ -2082,7 +2081,7 @@ uint32_t dp_tx_comp_handler(struct dp_soc *soc, uint32_t ring_id,
|
|||||||
struct dp_tx_desc_s *head_desc = NULL;
|
struct dp_tx_desc_s *head_desc = NULL;
|
||||||
struct dp_tx_desc_s *tail_desc = NULL;
|
struct dp_tx_desc_s *tail_desc = NULL;
|
||||||
uint32_t num_processed;
|
uint32_t num_processed;
|
||||||
void *hal_srng = soc->tx_comp_ring[ring_id].hal_srng;
|
uint32_t count;
|
||||||
|
|
||||||
if (qdf_unlikely(hal_srng_access_start(soc->hal_soc, hal_srng))) {
|
if (qdf_unlikely(hal_srng_access_start(soc->hal_soc, hal_srng))) {
|
||||||
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
|
||||||
@@ -2092,6 +2091,7 @@ uint32_t dp_tx_comp_handler(struct dp_soc *soc, uint32_t ring_id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
num_processed = 0;
|
num_processed = 0;
|
||||||
|
count = 0;
|
||||||
|
|
||||||
/* Find head descriptor from completion ring */
|
/* Find head descriptor from completion ring */
|
||||||
while (qdf_likely(tx_comp_hal_desc =
|
while (qdf_likely(tx_comp_hal_desc =
|
||||||
@@ -2100,16 +2100,15 @@ uint32_t dp_tx_comp_handler(struct dp_soc *soc, uint32_t ring_id,
|
|||||||
buffer_src = hal_tx_comp_get_buffer_source(tx_comp_hal_desc);
|
buffer_src = hal_tx_comp_get_buffer_source(tx_comp_hal_desc);
|
||||||
|
|
||||||
/* If this buffer was not released by TQM or FW, then it is not
|
/* If this buffer was not released by TQM or FW, then it is not
|
||||||
* Tx completion indication, skip to next descriptor */
|
* Tx completion indication, assert */
|
||||||
if ((buffer_src != HAL_TX_COMP_RELEASE_SOURCE_TQM) &&
|
if ((buffer_src != HAL_TX_COMP_RELEASE_SOURCE_TQM) &&
|
||||||
(buffer_src != HAL_TX_COMP_RELEASE_SOURCE_FW)) {
|
(buffer_src != HAL_TX_COMP_RELEASE_SOURCE_FW)) {
|
||||||
|
|
||||||
QDF_TRACE(QDF_MODULE_ID_DP,
|
QDF_TRACE(QDF_MODULE_ID_DP,
|
||||||
QDF_TRACE_LEVEL_ERROR,
|
QDF_TRACE_LEVEL_FATAL,
|
||||||
"Tx comp release_src != TQM | FW");
|
"Tx comp release_src != TQM | FW");
|
||||||
|
|
||||||
/* TODO Handle Freeing of the buffer in descriptor */
|
qdf_assert_always(0);
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get descriptor id */
|
/* Get descriptor id */
|
||||||
@@ -2122,12 +2121,10 @@ uint32_t dp_tx_comp_handler(struct dp_soc *soc, uint32_t ring_id,
|
|||||||
soc->wlan_cfg_ctx)) {
|
soc->wlan_cfg_ctx)) {
|
||||||
QDF_TRACE(QDF_MODULE_ID_DP,
|
QDF_TRACE(QDF_MODULE_ID_DP,
|
||||||
QDF_TRACE_LEVEL_FATAL,
|
QDF_TRACE_LEVEL_FATAL,
|
||||||
"TX COMP pool id %d not valid",
|
"Tx Comp pool id %d not valid",
|
||||||
pool_id);
|
pool_id);
|
||||||
|
|
||||||
/* Check if assert aborts execution, if not handle
|
qdf_assert_always(0);
|
||||||
* return here */
|
|
||||||
QDF_ASSERT(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find Tx descriptor */
|
/* Find Tx descriptor */
|
||||||
@@ -2144,9 +2141,7 @@ uint32_t dp_tx_comp_handler(struct dp_soc *soc, uint32_t ring_id,
|
|||||||
"Tx Comp pool id %d not matched %d",
|
"Tx Comp pool id %d not matched %d",
|
||||||
pool_id, tx_desc->pool_id);
|
pool_id, tx_desc->pool_id);
|
||||||
|
|
||||||
/* Check if assert aborts execution, if not handle
|
qdf_assert_always(0);
|
||||||
* return here */
|
|
||||||
QDF_ASSERT(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(tx_desc->flags & DP_TX_DESC_FLAG_ALLOCATED) ||
|
if (!(tx_desc->flags & DP_TX_DESC_FLAG_ALLOCATED) ||
|
||||||
@@ -2160,8 +2155,7 @@ uint32_t dp_tx_comp_handler(struct dp_soc *soc, uint32_t ring_id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the release source is FW, process the HTT
|
* If the release source is FW, process the HTT status
|
||||||
* status
|
|
||||||
*/
|
*/
|
||||||
if (qdf_unlikely(buffer_src ==
|
if (qdf_unlikely(buffer_src ==
|
||||||
HAL_TX_COMP_RELEASE_SOURCE_FW)) {
|
HAL_TX_COMP_RELEASE_SOURCE_FW)) {
|
||||||
@@ -2171,15 +2165,15 @@ uint32_t dp_tx_comp_handler(struct dp_soc *soc, uint32_t ring_id,
|
|||||||
dp_tx_process_htt_completion(tx_desc,
|
dp_tx_process_htt_completion(tx_desc,
|
||||||
htt_tx_status);
|
htt_tx_status);
|
||||||
} else {
|
} else {
|
||||||
tx_desc->next = NULL;
|
|
||||||
|
|
||||||
/* First ring descriptor on the cycle */
|
/* First ring descriptor on the cycle */
|
||||||
if (!head_desc) {
|
if (!head_desc) {
|
||||||
head_desc = tx_desc;
|
head_desc = tx_desc;
|
||||||
} else {
|
tail_desc = tx_desc;
|
||||||
tail_desc->next = tx_desc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tail_desc->next = tx_desc;
|
||||||
|
tx_desc->next = NULL;
|
||||||
tail_desc = tx_desc;
|
tail_desc = tx_desc;
|
||||||
|
|
||||||
/* Collect hw completion contents */
|
/* Collect hw completion contents */
|
||||||
@@ -2188,15 +2182,16 @@ uint32_t dp_tx_comp_handler(struct dp_soc *soc, uint32_t ring_id,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
num_processed++;
|
num_processed += !(count & DP_TX_NAPI_BUDGET_DIV_MASK);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Processed packet count is more than given quota
|
* Processed packet count is more than given quota
|
||||||
* stop to processing
|
* stop to processing
|
||||||
*/
|
*/
|
||||||
if (num_processed >= budget)
|
if ((num_processed >= quota))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
hal_srng_access_end(soc->hal_soc, hal_srng);
|
hal_srng_access_end(soc->hal_soc, hal_srng);
|
||||||
|
@@ -143,8 +143,7 @@ QDF_STATUS dp_tx_pdev_attach(struct dp_pdev *pdev);
|
|||||||
|
|
||||||
qdf_nbuf_t dp_tx_send(void *data_vdev, qdf_nbuf_t nbuf);
|
qdf_nbuf_t dp_tx_send(void *data_vdev, qdf_nbuf_t nbuf);
|
||||||
|
|
||||||
uint32_t dp_tx_comp_handler(struct dp_soc *soc, uint32_t ring_id,
|
uint32_t dp_tx_comp_handler(struct dp_soc *soc, void *hal_srng, uint32_t quota);
|
||||||
uint32_t budget);
|
|
||||||
|
|
||||||
int32_t
|
int32_t
|
||||||
dp_tx_prepare_send_me(struct dp_vdev *vdev, qdf_nbuf_t nbuf);
|
dp_tx_prepare_send_me(struct dp_vdev *vdev, qdf_nbuf_t nbuf);
|
||||||
|
@@ -26,9 +26,19 @@
|
|||||||
#if defined(CONFIG_MCL)
|
#if defined(CONFIG_MCL)
|
||||||
#define MAX_PDEV_CNT 1
|
#define MAX_PDEV_CNT 1
|
||||||
#define WLAN_CFG_INT_NUM_CONTEXTS 7
|
#define WLAN_CFG_INT_NUM_CONTEXTS 7
|
||||||
|
/*
|
||||||
|
* This mask defines how many transmit frames account for 1 NAPI work unit
|
||||||
|
* 0 means each tx completion is 1 unit
|
||||||
|
*/
|
||||||
|
#define DP_TX_NAPI_BUDGET_DIV_MASK 0
|
||||||
#else
|
#else
|
||||||
#define MAX_PDEV_CNT 3
|
#define MAX_PDEV_CNT 3
|
||||||
#define WLAN_CFG_INT_NUM_CONTEXTS 4
|
#define WLAN_CFG_INT_NUM_CONTEXTS 4
|
||||||
|
/*
|
||||||
|
* This mask defines how many transmit frames account for 1 NAPI work unit
|
||||||
|
* 0xFFFF means each 64K tx frame completions account for 1 unit of NAPI budget
|
||||||
|
*/
|
||||||
|
#define DP_TX_NAPI_BUDGET_DIV_MASK 0xFFFF
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Tx configuration */
|
/* Tx configuration */
|
||||||
|
Reference in New Issue
Block a user