qcacmn: Ensure nbuf count is less than no of segs
While preparing raw packets for transmission, the count of nbuf belonging to one mpdu must be less than the number of segments.This makes sure the frags array inside seg_info does not go out of bounds. Change-Id: I7fffba7f64da274aa73c558cfc63d90f4419a04d
This commit is contained in:
@@ -1161,6 +1161,7 @@ struct cdp_rx_stats {
|
|||||||
* @bcast: Number of broadcast packets
|
* @bcast: Number of broadcast packets
|
||||||
* @raw_pkt: Total Raw packets
|
* @raw_pkt: Total Raw packets
|
||||||
* @dma_map_error: DMA map error
|
* @dma_map_error: DMA map error
|
||||||
|
* @num_frags_overflow_err: msdu's nbuf count exceeds num of segemnts
|
||||||
* @num_seg: No of segments in TSO packets
|
* @num_seg: No of segments in TSO packets
|
||||||
* @tso_pkt:total no of TSO packets
|
* @tso_pkt:total no of TSO packets
|
||||||
* @non_tso_pkts: non - TSO packets
|
* @non_tso_pkts: non - TSO packets
|
||||||
@@ -1206,6 +1207,7 @@ struct cdp_tx_ingress_stats {
|
|||||||
struct cdp_pkt_info raw_pkt;
|
struct cdp_pkt_info raw_pkt;
|
||||||
uint32_t dma_map_error;
|
uint32_t dma_map_error;
|
||||||
uint32_t invalid_raw_pkt_datatype;
|
uint32_t invalid_raw_pkt_datatype;
|
||||||
|
uint32_t num_frags_overflow_err;
|
||||||
} raw;
|
} raw;
|
||||||
|
|
||||||
/* Scatter Gather packet info */
|
/* Scatter Gather packet info */
|
||||||
|
@@ -714,6 +714,7 @@ static inline void dp_update_pdev_ingress_stats(struct dp_pdev *tgtobj,
|
|||||||
DP_STATS_AGGR_PKT(tgtobj, srcobj, tx_i.inspect_pkts);
|
DP_STATS_AGGR_PKT(tgtobj, srcobj, tx_i.inspect_pkts);
|
||||||
DP_STATS_AGGR_PKT(tgtobj, srcobj, tx_i.raw.raw_pkt);
|
DP_STATS_AGGR_PKT(tgtobj, srcobj, tx_i.raw.raw_pkt);
|
||||||
DP_STATS_AGGR(tgtobj, srcobj, tx_i.raw.dma_map_error);
|
DP_STATS_AGGR(tgtobj, srcobj, tx_i.raw.dma_map_error);
|
||||||
|
DP_STATS_AGGR(tgtobj, srcobj, tx_i.raw.num_frags_overflow_err);
|
||||||
DP_STATS_AGGR(tgtobj, srcobj, tx_i.sg.dropped_host.num);
|
DP_STATS_AGGR(tgtobj, srcobj, tx_i.sg.dropped_host.num);
|
||||||
DP_STATS_AGGR(tgtobj, srcobj, tx_i.sg.dropped_target);
|
DP_STATS_AGGR(tgtobj, srcobj, tx_i.sg.dropped_target);
|
||||||
DP_STATS_AGGR_PKT(tgtobj, srcobj, tx_i.sg.sg_pkt);
|
DP_STATS_AGGR_PKT(tgtobj, srcobj, tx_i.sg.sg_pkt);
|
||||||
|
@@ -6200,6 +6200,8 @@ dp_print_pdev_tx_stats(struct dp_pdev *pdev)
|
|||||||
pdev->stats.tx_i.raw.dma_map_error);
|
pdev->stats.tx_i.raw.dma_map_error);
|
||||||
DP_PRINT_STATS(" RAW pkt type[!data] error = %d",
|
DP_PRINT_STATS(" RAW pkt type[!data] error = %d",
|
||||||
pdev->stats.tx_i.raw.invalid_raw_pkt_datatype);
|
pdev->stats.tx_i.raw.invalid_raw_pkt_datatype);
|
||||||
|
DP_PRINT_STATS(" Frags count overflow error = %d",
|
||||||
|
pdev->stats.tx_i.raw.num_frags_overflow_err);
|
||||||
DP_PRINT_STATS("Reinjected:");
|
DP_PRINT_STATS("Reinjected:");
|
||||||
DP_PRINT_STATS(" Packets = %d",
|
DP_PRINT_STATS(" Packets = %d",
|
||||||
pdev->stats.tx_i.reinject_pkts.num);
|
pdev->stats.tx_i.reinject_pkts.num);
|
||||||
|
@@ -1036,7 +1036,15 @@ static qdf_nbuf_t dp_tx_prepare_raw(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
|
|||||||
|
|
||||||
for (curr_nbuf = nbuf, i = 0; curr_nbuf;
|
for (curr_nbuf = nbuf, i = 0; curr_nbuf;
|
||||||
curr_nbuf = qdf_nbuf_next(curr_nbuf), i++) {
|
curr_nbuf = qdf_nbuf_next(curr_nbuf), i++) {
|
||||||
|
/*
|
||||||
|
* Number of nbuf's must not exceed the size of the frags
|
||||||
|
* array in seg_info.
|
||||||
|
*/
|
||||||
|
if (i >= DP_TX_MAX_NUM_FRAGS) {
|
||||||
|
dp_err_rl("nbuf cnt exceeds the max number of segs");
|
||||||
|
DP_STATS_INC(vdev, tx_i.raw.num_frags_overflow_err, 1);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
if (QDF_STATUS_SUCCESS !=
|
if (QDF_STATUS_SUCCESS !=
|
||||||
qdf_nbuf_map_nbytes_single(vdev->osdev,
|
qdf_nbuf_map_nbytes_single(vdev->osdev,
|
||||||
curr_nbuf,
|
curr_nbuf,
|
||||||
@@ -1045,10 +1053,10 @@ static qdf_nbuf_t dp_tx_prepare_raw(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
|
|||||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||||
"%s dma map error ", __func__);
|
"%s dma map error ", __func__);
|
||||||
DP_STATS_INC(vdev, tx_i.raw.dma_map_error, 1);
|
DP_STATS_INC(vdev, tx_i.raw.dma_map_error, 1);
|
||||||
mapped_buf_num = i;
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
/* Update the count of mapped nbuf's */
|
||||||
|
mapped_buf_num++;
|
||||||
paddr = qdf_nbuf_get_frag_paddr(curr_nbuf, 0);
|
paddr = qdf_nbuf_get_frag_paddr(curr_nbuf, 0);
|
||||||
seg_info->frags[i].paddr_lo = paddr;
|
seg_info->frags[i].paddr_lo = paddr;
|
||||||
seg_info->frags[i].paddr_hi = ((uint64_t)paddr >> 32);
|
seg_info->frags[i].paddr_hi = ((uint64_t)paddr >> 32);
|
||||||
|
Reference in New Issue
Block a user