diff --git a/dp/wifi3.0/dp_tx_capture.c b/dp/wifi3.0/dp_tx_capture.c index 1be6848ee6..2e196a79b0 100644 --- a/dp/wifi3.0/dp_tx_capture.c +++ b/dp/wifi3.0/dp_tx_capture.c @@ -280,12 +280,15 @@ void dp_tx_capture_htt_frame_counter(struct dp_pdev *pdev, * * 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); @@ -306,6 +309,14 @@ void dp_print_tid_qlen_per_peer(void *pdev_hdl) 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]", @@ -313,10 +324,16 @@ void dp_print_tid_qlen_per_peer(void *pdev_hdl) 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); } @@ -406,7 +423,7 @@ void dp_print_pdev_tx_capture_stats(struct dp_pdev *pdev) i, ptr_tx_cap->htt_frame_type[i]); } - dp_print_tid_qlen_per_peer(pdev); + dp_print_tid_qlen_per_peer(pdev, 0); } /** @@ -1010,20 +1027,21 @@ void dp_tx_ppdu_stats_detach(struct dp_pdev *pdev) } #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) { @@ -1033,6 +1051,8 @@ dp_drop_enq_msdu_on_thresh(struct dp_peer *peer, 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); @@ -1058,16 +1078,46 @@ dp_drop_enq_msdu_on_thresh(struct dp_peer *peer, /* 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; @@ -1135,12 +1185,12 @@ dp_update_msdu_to_list(struct dp_soc *soc, 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); @@ -2062,10 +2112,10 @@ uint32_t dp_tx_msdu_dequeue(struct dp_peer *peer, uint32_t ppdu_id, 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; } @@ -2135,7 +2185,7 @@ uint32_t dp_tx_msdu_dequeue(struct dp_peer *peer, uint32_t ppdu_id, } - 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 dc298e4517..f0d68974ae 100644 --- a/dp/wifi3.0/dp_tx_capture.h +++ b/dp/wifi3.0/dp_tx_capture.h @@ -319,6 +319,15 @@ void dp_tx_capture_htt_frame_counter(struct dp_pdev *pdev, */ 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