qcacmn: Implement SWLM support for multi TX queue

Update SWLM data structures and API's to support
multi TX queue based traffic.

Change-Id: I67921a749b61b3c717f33f770095fbb4d3062e2f
CRs-Fixed: 3161165
Dieser Commit ist enthalten in:
Karthik Kantamneni
2022-03-07 14:48:39 +05:30
committet von Madan Koyyalamudi
Ursprung 73a570940f
Commit d98299184b
6 geänderte Dateien mit 99 neuen und 45 gelöschten Zeilen

Datei anzeigen

@@ -647,11 +647,12 @@ dp_tx_hw_enqueue_be(struct dp_soc *soc, struct dp_vdev *vdev,
/* Sync cached descriptor with HW */
hal_tx_desc_sync(hal_tx_desc_cached, hal_tx_desc);
coalesce = dp_tx_attempt_coalescing(soc, vdev, tx_desc, tid, msdu_info);
coalesce = dp_tx_attempt_coalescing(soc, vdev, tx_desc, tid,
msdu_info, ring_id);
DP_STATS_INC_PKT(vdev, tx_i.processed, 1, tx_desc->length);
DP_STATS_INC(soc, tx.tcl_enq[ring_id], 1);
dp_tx_update_stats(soc, tx_desc->nbuf);
dp_tx_update_stats(soc, tx_desc, ring_id);
status = QDF_STATUS_SUCCESS;
dp_tx_hw_desc_update_evt((uint8_t *)hal_tx_desc_cached,

Datei anzeigen

@@ -7983,7 +7983,7 @@ QDF_STATUS dp_txrx_get_soc_stats(struct cdp_soc_t *soc_hdl,
uint8_t cpus;
/* soc tx stats */
soc_stats->tx.egress = soc->stats.tx.egress;
soc_stats->tx.egress = soc->stats.tx.egress[0];
soc_stats->tx.tx_invalid_peer = soc->stats.tx.tx_invalid_peer;
for (inx = 0; inx < CDP_MAX_TX_DATA_RINGS; inx++) {
soc_stats->tx.tx_hw_enq[inx] = soc->stats.tx.tcl_enq[inx];

Datei anzeigen

@@ -1396,21 +1396,31 @@ void dp_vdev_peer_stats_update_protocol_cnt_tx(struct dp_vdev *vdev_hdl,
/**
* dp_tx_update_stats() - Update soc level tx stats
* @soc: DP soc handle
* @nbuf: packet being transmitted
* @tx_desc: TX descriptor reference
* @ring_id: TCL ring id
*
* Returns: none
*/
void dp_tx_update_stats(struct dp_soc *soc,
qdf_nbuf_t nbuf)
struct dp_tx_desc_s *tx_desc,
uint8_t ring_id)
{
DP_STATS_INC_PKT(soc, tx.egress, 1, qdf_nbuf_len(nbuf));
uint32_t stats_len = 0;
if (tx_desc->frm_type == dp_tx_frm_tso)
stats_len = tx_desc->msdu_ext_desc->tso_desc->seg.total_len;
else
stats_len = qdf_nbuf_len(tx_desc->nbuf);
DP_STATS_INC_PKT(soc, tx.egress[ring_id], 1, stats_len);
}
int
dp_tx_attempt_coalescing(struct dp_soc *soc, struct dp_vdev *vdev,
struct dp_tx_desc_s *tx_desc,
uint8_t tid,
struct dp_tx_msdu_info_s *msdu_info)
struct dp_tx_msdu_info_s *msdu_info,
uint8_t ring_id)
{
struct dp_swlm *swlm = &soc->swlm;
union swlm_data swlm_query_data;
@@ -1423,21 +1433,28 @@ dp_tx_attempt_coalescing(struct dp_soc *soc, struct dp_vdev *vdev,
tcl_data.nbuf = tx_desc->nbuf;
tcl_data.tid = tid;
tcl_data.ring_id = ring_id;
if (tx_desc->frm_type == dp_tx_frm_tso) {
tcl_data.pkt_len =
tx_desc->msdu_ext_desc->tso_desc->seg.total_len;
} else {
tcl_data.pkt_len = qdf_nbuf_len(tx_desc->nbuf);
}
tcl_data.num_ll_connections = vdev->num_latency_critical_conn;
swlm_query_data.tcl_data = &tcl_data;
status = dp_swlm_tcl_pre_check(soc, &tcl_data);
if (QDF_IS_STATUS_ERROR(status)) {
dp_swlm_tcl_reset_session_data(soc);
DP_STATS_INC(swlm, tcl.coalesce_fail, 1);
dp_swlm_tcl_reset_session_data(soc, ring_id);
DP_STATS_INC(swlm, tcl[ring_id].coalesce_fail, 1);
return 0;
}
ret = dp_swlm_query_policy(soc, TCL_DATA, swlm_query_data);
if (ret) {
DP_STATS_INC(swlm, tcl.coalesce_success, 1);
DP_STATS_INC(swlm, tcl[ring_id].coalesce_success, 1);
} else {
DP_STATS_INC(swlm, tcl.coalesce_fail, 1);
DP_STATS_INC(swlm, tcl[ring_id].coalesce_fail, 1);
}
return ret;

Datei anzeigen

@@ -771,12 +771,14 @@ dp_send_completion_to_pkt_capture(struct dp_soc *soc,
/**
* dp_tx_update_stats() - Update soc level tx stats
* @soc: DP soc handle
* @nbuf: packet being transmitted
* @tx_desc: TX descriptor reference
* @ring_id: TCL ring id
*
* Returns: none
*/
void dp_tx_update_stats(struct dp_soc *soc,
qdf_nbuf_t nbuf);
struct dp_tx_desc_s *tx_desc,
uint8_t ring_id);
/**
* dp_tx_attempt_coalescing() - Check and attempt TCL register write coalescing
@@ -784,6 +786,7 @@ void dp_tx_update_stats(struct dp_soc *soc,
* @tx_desc: tx packet descriptor
* @tid: TID for pkt transmission
* @msdu_info: MSDU info of tx packet
* @ring_id: TCL ring id
*
* Returns: 1, if coalescing is to be done
* 0, if coalescing is not to be done
@@ -791,7 +794,9 @@ void dp_tx_update_stats(struct dp_soc *soc,
int
dp_tx_attempt_coalescing(struct dp_soc *soc, struct dp_vdev *vdev,
struct dp_tx_desc_s *tx_desc,
uint8_t tid, struct dp_tx_msdu_info_s *msdu_info);
uint8_t tid,
struct dp_tx_msdu_info_s *msdu_info,
uint8_t ring_id);
/**
* dp_tx_ring_access_end() - HAL ring access end for data transmission
@@ -808,12 +813,15 @@ dp_tx_ring_access_end(struct dp_soc *soc, hal_ring_handle_t hal_ring_hdl,
/**
* dp_tx_update_stats() - Update soc level tx stats
* @soc: DP soc handle
* @nbuf: packet being transmitted
* @tx_desc: TX descriptor reference
* @ring_id: TCL ring id
*
* Returns: none
*/
static inline void dp_tx_update_stats(struct dp_soc *soc,
qdf_nbuf_t nbuf) { }
struct dp_tx_desc_s *tx_desc,
uint8_t ring_id){ }
static inline void
dp_tx_ring_access_end(struct dp_soc *soc, hal_ring_handle_t hal_ring_hdl,
int coalesce)
@@ -825,7 +833,8 @@ static inline int
dp_tx_attempt_coalescing(struct dp_soc *soc, struct dp_vdev *vdev,
struct dp_tx_desc_s *tx_desc,
uint8_t tid,
struct dp_tx_msdu_info_s *msdu_info)
struct dp_tx_msdu_info_s *msdu_info,
uint8_t ring_id)
{
return 0;
}

Datei anzeigen

@@ -1020,7 +1020,7 @@ struct dp_soc_stats {
/* SOC level TX stats */
struct {
/* Total packets transmitted */
struct cdp_pkt_info egress;
struct cdp_pkt_info egress[MAX_TCL_DATA_RINGS];
/* Enqueues per tcl ring */
uint32_t tcl_enq[MAX_TCL_DATA_RINGS];
/* packets dropped on tx because of no peer */
@@ -1489,6 +1489,8 @@ struct dp_last_op_info {
* @nbuf: TX packet
* @tid: tid for transmitting the current packet
* @num_ll_connections: Number of low latency connections on this vdev
* @ring_id: TCL ring id
* @pkt_len: Packet length
*
* This structure contains the information required by the software
* latency manager to decide on whether to coalesce the current TCL
@@ -1498,6 +1500,8 @@ struct dp_swlm_tcl_data {
qdf_nbuf_t nbuf;
uint8_t tid;
uint8_t num_ll_connections;
uint8_t ring_id;
uint32_t pkt_len;
};
/**
@@ -1549,43 +1553,65 @@ struct dp_swlm_stats {
uint32_t tput_criteria_fail;
uint32_t coalesce_success;
uint32_t coalesce_fail;
} tcl;
} tcl[MAX_TCL_DATA_RINGS];
};
/**
* struct dp_swlm_tcl_params: Parameters based on TCL for different modules
* in the Software latency manager.
* @soc: DP soc reference
* @ring_id: TCL ring id
* @flush_timer: Timer for flushing the coalesced TCL HP writes
* @sampling_session_tx_bytes: Num bytes transmitted in the sampling time
* @bytes_flush_thresh: Bytes threshold to flush the TCL HP register write
* @coalesce_end_time: End timestamp for current coalescing session
* @bytes_coalesced: Num bytes coalesced in the current session
* @prev_tx_packets: Previous TX packets accounted
* @prev_tx_bytes: Previous TX bytes accounted
* @prev_rx_bytes: Previous RX bytes accounted
* @expire_time: expiry time for sample
* @tput_pass_cnt: threshold throughput pass counter
*/
struct dp_swlm_tcl_params {
struct dp_soc *soc;
uint32_t ring_id;
qdf_timer_t flush_timer;
uint32_t sampling_session_tx_bytes;
uint32_t bytes_flush_thresh;
uint64_t coalesce_end_time;
uint32_t bytes_coalesced;
uint32_t prev_tx_packets;
uint32_t prev_tx_bytes;
uint32_t prev_rx_bytes;
uint64_t expire_time;
uint32_t tput_pass_cnt;
};
/**
* struct dp_swlm_params: Parameters for different modules in the
* Software latency manager.
* @tcl.flush_timer: Timer for flushing the coalesced TCL HP writes
* @tcl.rx_traffic_thresh: Threshold for RX traffic, to begin TCL register
* @rx_traffic_thresh: Threshold for RX traffic, to begin TCL register
* write coalescing
* @tcl.tx_traffic_thresh: Threshold for TX traffic, to begin TCL register
* @tx_traffic_thresh: Threshold for TX traffic, to begin TCL register
* write coalescing
* @tcl.sampling_time: Sampling time to test the throughput threshold
* @tcl.sampling_session_tx_bytes: Num bytes transmitted in the sampling time
* @tcl.bytes_flush_thresh: Bytes threshold to flush the TCL HP register write
* @tcl.time_flush_thresh: Time threshold to flush the TCL HP register write
* @tcl.tx_thresh_multiplier: Multiplier to deduce the bytes threshold after
* @sampling_time: Sampling time to test the throughput threshold
* @time_flush_thresh: Time threshold to flush the TCL HP register write
* @tx_thresh_multiplier: Multiplier to deduce the bytes threshold after
* which the TCL HP register is written, thereby
* ending the coalescing.
* @tcl.coalesce_end_time: End timestamp for current coalescing session
* @tcl.bytes_coalesced: Num bytes coalesced in the current session
* @tcl.tx_pkt_thresh: Threshold for TX packet count, to begin TCL register
* @tx_pkt_thresh: Threshold for TX packet count, to begin TCL register
* write coalescing
* @tcl: TCL ring specific params
*/
struct dp_swlm_params {
struct {
qdf_timer_t flush_timer;
uint32_t rx_traffic_thresh;
uint32_t tx_traffic_thresh;
uint32_t sampling_time;
uint32_t sampling_session_tx_bytes;
uint32_t bytes_flush_thresh;
uint32_t time_flush_thresh;
uint32_t tx_thresh_multiplier;
uint64_t coalesce_end_time;
uint32_t bytes_coalesced;
uint32_t tx_pkt_thresh;
} tcl;
uint32_t rx_traffic_thresh;
uint32_t tx_traffic_thresh;
uint32_t sampling_time;
uint32_t time_flush_thresh;
uint32_t tx_thresh_multiplier;
uint32_t tx_pkt_thresh;
struct dp_swlm_tcl_params tcl[MAX_TCL_DATA_RINGS];
};
/**

Datei anzeigen

@@ -498,10 +498,11 @@ dp_tx_hw_enqueue_li(struct dp_soc *soc, struct dp_vdev *vdev,
tx_desc->flags |= DP_TX_DESC_FLAG_QUEUED_TX;
dp_vdev_peer_stats_update_protocol_cnt_tx(vdev, tx_desc->nbuf);
hal_tx_desc_sync(hal_tx_desc_cached, hal_tx_desc);
coalesce = dp_tx_attempt_coalescing(soc, vdev, tx_desc, tid, msdu_info);
coalesce = dp_tx_attempt_coalescing(soc, vdev, tx_desc, tid,
msdu_info, ring_id);
DP_STATS_INC_PKT(vdev, tx_i.processed, 1, tx_desc->length);
DP_STATS_INC(soc, tx.tcl_enq[ring_id], 1);
dp_tx_update_stats(soc, tx_desc->nbuf);
dp_tx_update_stats(soc, tx_desc, ring_id);
status = QDF_STATUS_SUCCESS;
dp_tx_hw_desc_update_evt((uint8_t *)hal_tx_desc_cached,