qcacmn: Check for ring approaching full during RX

Check if REO ring is near full at the end of dp_rx_process. In case the
ring is near full, reap the packets in the ring (and replenish, send to
upper layer) until the quota allows. Ignore the HIF yield time
limit in such cases.

This change is needed to prevent back pressure from the REO ring(in case
it gets full). Backpressure from REO ring (to LMAC) may lead to a
watchdog and eventually a FW crash. Hence, avoid such a scenario by
reaping as many packets as the 'quota' allows when the REO ring is in
aforementioned condition.

A sid-effect of this change would be that at times the RX softirq may run
longer (till the quota limit) than the configured HIF yield time.
However, this logic is not expected to kick-in in perf builds. The issue
is reported for a defconfig build where lots debug options are enabled
in the kernel which can slow the processing down.

Change-Id: I2eb6544c159ec5957d10386b1750fd96473fe13a
CRs-Fixed: 2540964
This commit is contained in:
Mohit Khanna
2019-10-14 23:27:36 -07:00
committed by nshrivas
parent 45ecf4361c
commit 80002653b1
4 changed files with 120 additions and 13 deletions

View File

@@ -789,9 +789,10 @@ void *hal_srng_dst_peek_sync_locked(hal_soc_handle_t hal_soc_hdl,
* @sync_hw_ptr: Sync cached head pointer with HW
*
*/
static inline uint32_t hal_srng_dst_num_valid(void *hal_soc,
hal_ring_handle_t hal_ring_hdl,
int sync_hw_ptr)
static inline
uint32_t hal_srng_dst_num_valid(void *hal_soc,
hal_ring_handle_t hal_ring_hdl,
int sync_hw_ptr)
{
struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl;
uint32_t hp;
@@ -810,6 +811,33 @@ static inline uint32_t hal_srng_dst_num_valid(void *hal_soc,
return (srng->ring_size - tp + hp) / srng->entry_size;
}
/**
* hal_srng_dst_num_valid_locked - Returns num valid entries to be processed
*
* @hal_soc: Opaque HAL SOC handle
* @hal_ring_hdl: Destination ring pointer
* @sync_hw_ptr: Sync cached head pointer with HW
*
* Returns number of valid entries to be processed by the host driver. The
* function takes up SRNG lock.
*
* Return: Number of valid destination entries
*/
static inline uint32_t
hal_srng_dst_num_valid_locked(hal_soc_handle_t hal_soc,
hal_ring_handle_t hal_ring_hdl,
int sync_hw_ptr)
{
uint32_t num_valid;
struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl;
SRNG_LOCK(&srng->lock);
num_valid = hal_srng_dst_num_valid(hal_soc, hal_ring_hdl, sync_hw_ptr);
SRNG_UNLOCK(&srng->lock);
return num_valid;
}
/**
* hal_srng_src_reap_next - Reap next entry from a source ring and move reap
* pointer. This can be used to release any buffers associated with completed
@@ -1384,6 +1412,23 @@ hal_srng_get_tp_addr(void *hal_soc, hal_ring_handle_t hal_ring_hdl)
}
}
/**
* hal_srng_get_num_entries - Get total entries in the HAL Srng
*
* @hal_soc: Opaque HAL SOC handle
* @hal_ring_hdl: Ring pointer (Source or Destination ring)
*
* Return: total number of entries in hal ring
*/
static inline
uint32_t hal_srng_get_num_entries(hal_soc_handle_t hal_soc_hdl,
hal_ring_handle_t hal_ring_hdl)
{
struct hal_srng *srng = (struct hal_srng *)hal_ring_hdl;
return srng->num_entries;
}
/**
* hal_get_srng_params - Retrieve SRNG parameters for a given ring from HAL
*