qca-wifi: Drop msdu on queue exceed threshold
Add support
a. Drop msdu on queue exceed threshold of 4096
b. Add support to print consolidated peer tid queue.
Change-Id: I2b91b151531c839657716ac52987cf5e4a62e7cc
diff --git a/dp/wifi3.0/dp_tx_capture.c b/dp/wifi3.0/dp_tx_capture.c
index 7aaca86..6a31e01 100644
--- a/dp/wifi3.0/dp_tx_capture.c
+++ b/dp/wifi3.0/dp_tx_capture.c
@@ -282,12 +282,15 @@
*
* Return: void
*/
-void dp_print_tid_qlen_per_peer(void *pdev_hdl)
+void dp_print_tid_qlen_per_peer(void *pdev_hdl, uint8_t consolidated)
{
struct dp_pdev *pdev = (struct dp_pdev *)pdev_hdl;
struct dp_soc *soc = pdev->soc;
struct dp_vdev *vdev = NULL;
struct dp_peer *peer = NULL;
+ uint64_t c_defer_msdu_len = 0;
+ uint64_t c_tasklet_msdu_len = 0;
+ uint64_t c_pending_q_len = 0;
DP_PRINT_STATS("pending peer msdu and ppdu:");
qdf_spin_lock_bh(&soc->peer_ref_mutex);
@@ -308,6 +311,14 @@
qdf_nbuf_queue_len(&tx_tid->msdu_comp_q);
ppdu_len =
qdf_nbuf_queue_len(&tx_tid->pending_ppdu_q);
+
+ c_defer_msdu_len += msdu_len;
+ c_tasklet_msdu_len += tasklet_msdu_len;
+ c_pending_q_len += ppdu_len;
+
+ if (consolidated)
+ continue;
+
if (!msdu_len && !ppdu_len && !tasklet_msdu_len)
continue;
DP_PRINT_STATS(" peer_id[%d] tid[%d] msdu_comp_q[%d] defer_msdu_q[%d] pending_ppdu_q[%d]",
@@ -315,10 +326,16 @@
tasklet_msdu_len,
msdu_len, ppdu_len);
}
- dp_tx_capture_print_stats(peer);
+
+ if (!consolidated)
+ dp_tx_capture_print_stats(peer);
}
}
+ DP_PRINT_STATS("consolidated: msdu_comp_q[%d] defer_msdu_q[%d] pending_ppdu_q[%d]",
+ c_tasklet_msdu_len, c_defer_msdu_len,
+ c_pending_q_len);
+
qdf_spin_unlock_bh(&pdev->vdev_list_lock);
qdf_spin_unlock_bh(&soc->peer_ref_mutex);
}
@@ -408,7 +425,7 @@
i, ptr_tx_cap->htt_frame_type[i]);
}
- dp_print_tid_qlen_per_peer(pdev);
+ dp_print_tid_qlen_per_peer(pdev, 0);
}
/**
@@ -1012,20 +1029,21 @@
}
#define MAX_MSDU_THRESHOLD_TSF 100000
-#define MAX_MSDU_ENQUEUE_THRESHOLD 10000
+#define MAX_MSDU_ENQUEUE_THRESHOLD 4096
/**
* dp_drop_enq_msdu_on_thresh(): Function to drop msdu when exceed
* storing threshold limit
* @peer: dp_peer
+ * @tx_tid: tx tid
* @ptr_msdu_comp_q: pointer to skb queue, it can be either tasklet or WQ msdu q
* @tsf: current timestamp
*
- * this function must be called inside lock of corresponding msdu_q
* return: status
*/
QDF_STATUS
dp_drop_enq_msdu_on_thresh(struct dp_peer *peer,
+ struct dp_tx_tid *tx_tid,
qdf_nbuf_queue_t *ptr_msdu_comp_q,
uint32_t tsf)
{
@@ -1035,6 +1053,8 @@
uint32_t tsf_delta;
uint32_t qlen;
+ /* take lock here */
+ qdf_spin_lock_bh(&tx_tid->tasklet_tid_lock);
while ((head_msdu = qdf_nbuf_queue_first(ptr_msdu_comp_q))) {
ptr_msdu_info =
(struct msdu_completion_info *)qdf_nbuf_data(head_msdu);
@@ -1060,16 +1080,46 @@
/* get queue length */
qlen = qdf_nbuf_queue_len(ptr_msdu_comp_q);
+ /* release lock here */
+ qdf_spin_unlock_bh(&tx_tid->tasklet_tid_lock);
+
+ /* take lock here */
+ qdf_spin_lock_bh(&tx_tid->tid_lock);
+ qlen += qdf_nbuf_queue_len(&tx_tid->defer_msdu_q);
if (qlen > MAX_MSDU_ENQUEUE_THRESHOLD) {
- /* free head */
- nbuf = qdf_nbuf_queue_remove(ptr_msdu_comp_q);
- if (qdf_unlikely(!nbuf)) {
- qdf_assert_always(0);
- return QDF_STATUS_E_ABORTED;
+ qdf_nbuf_t nbuf = NULL;
+
+ /* free head, nbuf will be NULL if queue empty */
+ nbuf = qdf_nbuf_queue_remove(&tx_tid->defer_msdu_q);
+ /* release lock here */
+ qdf_spin_unlock_bh(&tx_tid->tid_lock);
+ if (qdf_likely(nbuf)) {
+ qdf_nbuf_free(nbuf);
+ dp_tx_cap_stats_msdu_update(peer, PEER_MSDU_DROP, 1);
+ return QDF_STATUS_SUCCESS;
}
- qdf_nbuf_free(nbuf);
- dp_tx_cap_stats_msdu_update(peer, PEER_MSDU_DROP, 1);
+ /* take lock here */
+ qdf_spin_lock_bh(&tx_tid->tasklet_tid_lock);
+ if (!qdf_nbuf_is_queue_empty(ptr_msdu_comp_q)) {
+ /* free head, nbuf will be NULL if queue empty */
+ nbuf = qdf_nbuf_queue_remove(ptr_msdu_comp_q);
+ /* release lock here */
+ qdf_spin_unlock_bh(&tx_tid->tasklet_tid_lock);
+ if (qdf_unlikely(!nbuf)) {
+ qdf_assert_always(0);
+ return QDF_STATUS_E_ABORTED;
+ }
+
+ qdf_nbuf_free(nbuf);
+ dp_tx_cap_stats_msdu_update(peer, PEER_MSDU_DROP, 1);
+ } else {
+ /* release lock here */
+ qdf_spin_unlock_bh(&tx_tid->tasklet_tid_lock);
+ }
+ } else {
+ /* release lock here */
+ qdf_spin_unlock_bh(&tx_tid->tid_lock);
}
return QDF_STATUS_SUCCESS;
@@ -1137,12 +1187,12 @@
msdu_comp_info->tsf = ts->tsf;
msdu_comp_info->status = ts->status;
- /* lock here */
- qdf_spin_lock_bh(&tx_tid->tasklet_tid_lock);
if (tx_tid->max_ppdu_id != ts->ppdu_id)
- dp_drop_enq_msdu_on_thresh(peer, &tx_tid->msdu_comp_q,
+ dp_drop_enq_msdu_on_thresh(peer, tx_tid, &tx_tid->msdu_comp_q,
ts->tsf);
+ /* lock here */
+ qdf_spin_lock_bh(&tx_tid->tasklet_tid_lock);
/* add nbuf to tail queue per peer tid */
qdf_nbuf_queue_add(&tx_tid->msdu_comp_q, netbuf);
dp_tx_cap_stats_msdu_update(peer, PEER_MSDU_ENQ, 1);
@@ -2064,10 +2114,10 @@
qdf_spin_unlock_bh(&tx_tid->tasklet_tid_lock);
/* lock here */
- qdf_spin_lock(&tx_tid->tid_lock);
+ qdf_spin_lock_bh(&tx_tid->tid_lock);
if (qdf_nbuf_is_queue_empty(&tx_tid->defer_msdu_q)) {
- qdf_spin_unlock(&tx_tid->tid_lock);
+ qdf_spin_unlock_bh(&tx_tid->tid_lock);
return 0;
}
@@ -2137,7 +2187,7 @@
}
- qdf_spin_unlock(&tx_tid->tid_lock);
+ qdf_spin_unlock_bh(&tx_tid->tid_lock);
return matched;
}
diff --git a/dp/wifi3.0/dp_tx_capture.h b/dp/wifi3.0/dp_tx_capture.h
index dc298e4..f0d6897 100644
--- a/dp/wifi3.0/dp_tx_capture.h
+++ b/dp/wifi3.0/dp_tx_capture.h
@@ -319,6 +319,15 @@
*/
void dp_print_pdev_tx_capture_stats(struct dp_pdev *pdev);
+/*
+ * dp_iterate_print_tid_qlen_per_peer()- API to print peer tid msdu queue
+ * @pdev_handle: DP_PDEV handle
+ * @consolidated: consolidated flag
+ *
+ * Return: void
+ */
+void dp_print_tid_qlen_per_peer(void *pdev_hdl, uint8_t consolidated);
+
/**
* dp_send_ack_frame_to_stack(): Function to generate BA or ACK frame and
* send to upper layer on received unicast frame