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
这个提交包含在:
Mohit Khanna
2019-10-14 23:27:36 -07:00
提交者 nshrivas
父节点 45ecf4361c
当前提交 80002653b1
修改 4 个文件,包含 120 行新增13 行删除

查看文件

@@ -5068,6 +5068,8 @@ void dp_print_per_ring_stats(struct dp_soc *soc)
total_packets = 0;
DP_PRINT_STATS("Packets on ring %u:", ring);
for (core = 0; core < num_possible_cpus(); core++) {
if (!soc->stats.rx.ring_packets[core][ring])
continue;
DP_PRINT_STATS("Packets arriving on core %u: %llu",
core,
soc->stats.rx.ring_packets[core][ring]);
@@ -5154,11 +5156,14 @@ void dp_txrx_path_stats(struct dp_soc *soc)
DP_PRINT_STATS("delivered %u msdus ( %llu bytes),",
pdev->stats.rx.to_stack.num,
pdev->stats.rx.to_stack.bytes);
for (i = 0; i < CDP_MAX_RX_RINGS; i++)
for (i = 0; i < CDP_MAX_RX_RINGS; i++) {
if (!pdev->stats.rx.rcvd_reo[i].num)
continue;
DP_PRINT_STATS(
"received on reo[%d] %u msdus( %llu bytes),",
i, pdev->stats.rx.rcvd_reo[i].num,
pdev->stats.rx.rcvd_reo[i].bytes);
}
DP_PRINT_STATS("intra-bss packets %u msdus ( %llu bytes),",
pdev->stats.rx.intra_bss.pkts.num,
pdev->stats.rx.intra_bss.pkts.bytes);
@@ -5187,6 +5192,7 @@ void dp_txrx_path_stats(struct dp_soc *soc)
pdev->soc->stats.rx.err.pkt_delivered_no_peer);
DP_PRINT_STATS("Reo Statistics");
DP_PRINT_STATS("near_full: %u ", soc->stats.rx.near_full);
DP_PRINT_STATS("rbm error: %u msdus",
pdev->soc->stats.rx.err.invalid_rbm);
DP_PRINT_STATS("hal ring access fail: %u msdus",
@@ -5617,7 +5623,7 @@ void dp_print_soc_interrupt_stats(struct dp_soc *soc)
DP_PRINT_STATS("INT: Total |txComps|reo[0] |reo[1] |reo[2] |reo[3] |mon |rx_err | wbm |reo_sta|rxdm2hst|hst2rxdm|");
for (i = 0; i < WLAN_CFG_INT_NUM_CONTEXTS; i++) {
intr_stats = &soc->intr_ctx[i].intr_stats;
DP_PRINT_STATS("%3u[%d]: %7u %7u %7u %7u %7u %7u %7u %7u %7u %7u %8u %8u",
DP_PRINT_STATS("%3u[%3d]: %7u %7u %7u %7u %7u %7u %7u %7u %7u %7u %8u %8u",
i,
hif_get_int_ctx_irq_num(soc->hif_handle, i),
intr_stats->num_masks,
@@ -5676,6 +5682,8 @@ dp_print_soc_rx_stats(struct dp_soc *soc)
DP_PRINT_STATS("RX frag err: %d", soc->stats.rx.rx_frag_err);
DP_PRINT_STATS("RX HP out_of_sync: %d", soc->stats.rx.hp_oos2);
DP_PRINT_STATS("RX Ring Near Full: %d", soc->stats.rx.near_full);
DP_PRINT_STATS("RX Reap Loop Pkt Limit Hit: %d",
soc->stats.rx.reap_loop_pkt_limit_hit);
DP_PRINT_STATS("RX DESC invalid magic: %u",