qcacmn: Account for Tx nbuf memory in mapped unmapped TSO segs

During TCP Tx traffic account for the Tx nbuf memory mapped
and unmapped in the driver.

Change-Id: I40df92f124eec94f2fa3ddc8bcd910615f4539bf
CRs-Fixed: 2831015
This commit is contained in:
Nisha Menon
2020-12-02 18:16:47 -08:00
committed by Gerrit - the friendly Code Review server
parent 8f049e633b
commit af829916ee
3 changed files with 136 additions and 39 deletions

View File

@@ -3816,6 +3816,19 @@ static inline qdf_size_t qdf_nbuf_get_data_len(qdf_nbuf_t nbuf)
return __qdf_nbuf_get_data_len(nbuf);
}
/**
* qdf_nbuf_get_end_offset() - Return the size of the nbuf from
* head pointer to end pointer
* @nbuf: qdf_nbuf_t
*
* Return: size of network buffer from head pointer to end
* pointer
*/
static inline qdf_size_t qdf_nbuf_get_end_offset(qdf_nbuf_t nbuf)
{
return __qdf_nbuf_get_end_offset(nbuf);
}
#ifdef NBUF_FRAG_MEMORY_DEBUG
#define qdf_nbuf_move_frag_page_offset(f, i, o) \
@@ -4002,6 +4015,26 @@ void qdf_nbuf_release_track_lock(uint32_t index,
QDF_NBUF_TRACK *qdf_nbuf_get_track_tbl(uint32_t index);
#endif /* MEMORY_DEBUG */
#ifdef CONFIG_WLAN_SYSFS_MEM_STATS
/**
* qdf_record_nbuf_nbytes() - add or subtract the size of the nbuf
* from the total skb mem and DP tx/rx skb mem
* @nbytes: number of bytes
* @dir: direction
* @is_mapped: is mapped or unmapped memory
*
* Return: none
*/
void qdf_record_nbuf_nbytes(
uint32_t nbytes, qdf_dma_dir_t dir, bool is_mapped);
#else /* CONFIG_WLAN_SYSFS_MEM_STATS */
static inline void qdf_record_nbuf_nbytes(
int nbytes, qdf_dma_dir_t dir, bool is_mapped)
{
}
#endif /* CONFIG_WLAN_SYSFS_MEM_STATS */
#ifdef CONFIG_NBUF_AP_PLATFORM
#include <i_qdf_nbuf_api_w.h>
#else

View File

@@ -2236,6 +2236,19 @@ static inline void __qdf_nbuf_orphan(struct sk_buff *skb)
return skb_orphan(skb);
}
/**
* __qdf_nbuf_get_end_offset() - Return the size of the nbuf from
* head pointer to end pointer
* @nbuf: qdf_nbuf_t
*
* Return: size of network buffer from head pointer to end
* pointer
*/
static inline unsigned int __qdf_nbuf_get_end_offset(__qdf_nbuf_t nbuf)
{
return skb_end_offset(nbuf);
}
#ifdef CONFIG_WLAN_SYSFS_MEM_STATS
/**
* __qdf_record_nbuf_nbytes() - add or subtract the size of the nbuf
@@ -2311,7 +2324,8 @@ static inline QDF_STATUS __qdf_nbuf_map_nbytes_single(
ret = dma_mapping_error(osdev->dev, paddr) ?
QDF_STATUS_E_FAULT : QDF_STATUS_SUCCESS;
if (QDF_IS_STATUS_SUCCESS(ret))
__qdf_record_nbuf_nbytes(nbytes, dir, true);
__qdf_record_nbuf_nbytes(__qdf_nbuf_get_end_offset(buf),
dir, true);
return ret;
}
#endif
@@ -2339,7 +2353,8 @@ __qdf_nbuf_unmap_nbytes_single(qdf_device_t osdev, struct sk_buff *buf,
qdf_dma_addr_t paddr = QDF_NBUF_CB_PADDR(buf);
if (qdf_likely(paddr)) {
__qdf_record_nbuf_nbytes(nbytes, dir, false);
__qdf_record_nbuf_nbytes(
__qdf_nbuf_get_end_offset(buf), dir, false);
dma_unmap_single(osdev->dev, paddr, nbytes,
__qdf_dma_dir_to_os(dir));
return;

View File

@@ -1088,7 +1088,7 @@ __qdf_nbuf_map_single(qdf_device_t osdev, qdf_nbuf_t buf, qdf_dma_dir_t dir)
skb_end_pointer(buf) - buf->data,
__qdf_dma_dir_to_os(dir));
__qdf_record_nbuf_nbytes(
__qdf_nbuf_get_data_len(buf), dir, true);
__qdf_nbuf_get_end_offset(buf), dir, true);
return dma_mapping_error(osdev->dev, paddr)
? QDF_STATUS_E_FAILURE
: QDF_STATUS_SUCCESS;
@@ -1114,7 +1114,7 @@ void __qdf_nbuf_unmap_single(qdf_device_t osdev, qdf_nbuf_t buf,
{
if (QDF_NBUF_CB_PADDR(buf)) {
__qdf_record_nbuf_nbytes(
__qdf_nbuf_get_data_len(buf), dir, false);
__qdf_nbuf_get_end_offset(buf), dir, false);
dma_unmap_single(osdev->dev, QDF_NBUF_CB_PADDR(buf),
skb_end_pointer(buf) - buf->data,
__qdf_dma_dir_to_os(dir));
@@ -3211,6 +3211,66 @@ static uint8_t qdf_nbuf_adj_tso_frag(struct sk_buff *skb)
}
#endif
#ifdef CONFIG_WLAN_SYSFS_MEM_STATS
void qdf_record_nbuf_nbytes(
uint32_t nbytes, qdf_dma_dir_t dir, bool is_mapped)
{
__qdf_record_nbuf_nbytes(nbytes, dir, is_mapped);
}
qdf_export_symbol(qdf_record_nbuf_nbytes);
#endif /* CONFIG_WLAN_SYSFS_MEM_STATS */
/**
* qdf_nbuf_tso_map_frag() - Map TSO segment
* @osdev: qdf device handle
* @tso_frag_vaddr: addr of tso fragment
* @nbytes: number of bytes
* @dir: direction
*
* Map TSO segment and for MCL record the amount of memory mapped
*
* Return: DMA address of mapped TSO fragment in success and
* NULL in case of DMA mapping failure
*/
static inline qdf_dma_addr_t qdf_nbuf_tso_map_frag(
qdf_device_t osdev, void *tso_frag_vaddr,
uint32_t nbytes, qdf_dma_dir_t dir)
{
qdf_dma_addr_t tso_frag_paddr = 0;
tso_frag_paddr = dma_map_single(osdev->dev, tso_frag_vaddr,
nbytes, __qdf_dma_dir_to_os(dir));
if (unlikely(dma_mapping_error(osdev->dev, tso_frag_paddr))) {
qdf_err("DMA mapping error!");
qdf_assert_always(0);
return 0;
}
qdf_record_nbuf_nbytes(nbytes, dir, true);
return tso_frag_paddr;
}
/**
* qdf_nbuf_tso_unmap_frag() - Unmap TSO segment
* @osdev: qdf device handle
* @tso_frag_paddr: DMA addr of tso fragment
* @dir: direction
* @nbytes: number of bytes
*
* Unmap TSO segment and for MCL record the amount of memory mapped
*
* Return: None
*/
static inline void qdf_nbuf_tso_unmap_frag(
qdf_device_t osdev, qdf_dma_addr_t tso_frag_paddr,
uint32_t nbytes, qdf_dma_dir_t dir)
{
qdf_record_nbuf_nbytes(nbytes, dir, false);
dma_unmap_single(osdev->dev, tso_frag_paddr,
nbytes, __qdf_dma_dir_to_os(dir));
}
/**
* __qdf_nbuf_get_tso_cmn_seg_info() - get TSO common
* information
@@ -3258,16 +3318,12 @@ static uint8_t __qdf_nbuf_get_tso_cmn_seg_info(qdf_device_t osdev,
tso_info->eit_hdr = skb->data;
tso_info->eit_hdr_len = (skb_transport_header(skb)
- skb_mac_header(skb)) + tcp_hdrlen(skb);
tso_info->eit_hdr_dma_map_addr = dma_map_single(osdev->dev,
tso_info->eit_hdr,
tso_info->eit_hdr_len,
DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(osdev->dev,
tso_info->eit_hdr_dma_map_addr))) {
qdf_err("DMA mapping error!");
qdf_assert(0);
tso_info->eit_hdr_dma_map_addr = qdf_nbuf_tso_map_frag(
osdev, tso_info->eit_hdr,
tso_info->eit_hdr_len,
QDF_DMA_TO_DEVICE);
if (qdf_unlikely(!tso_info->eit_hdr_dma_map_addr))
return 1;
}
if (tso_info->ethproto == htons(ETH_P_IP)) {
/* inlcude IPv4 header length for IPV4 (total length) */
@@ -3411,16 +3467,13 @@ uint32_t __qdf_nbuf_get_tso_info(qdf_device_t osdev, struct sk_buff *skb,
tso_frag_len = min(skb_frag_len, tso_seg_size);
if (tso_frag_len != 0) {
tso_frag_paddr = dma_map_single(osdev->dev,
tso_frag_vaddr, tso_frag_len, DMA_TO_DEVICE);
tso_frag_paddr = qdf_nbuf_tso_map_frag(
osdev, tso_frag_vaddr, tso_frag_len,
QDF_DMA_TO_DEVICE);
if (qdf_unlikely(!tso_frag_paddr))
return 0;
}
if (unlikely(dma_mapping_error(osdev->dev,
tso_frag_paddr))) {
qdf_err("DMA mapping error!");
qdf_assert_always(0);
return 0;
}
TSO_DEBUG("%s[%d] skb frag len %d tso frag len %d\n", __func__,
__LINE__, skb_frag_len, tso_frag_len);
num_seg = tso_info->num_segs;
@@ -3545,17 +3598,12 @@ uint32_t __qdf_nbuf_get_tso_info(qdf_device_t osdev, struct sk_buff *skb,
return 0;
}
tso_frag_paddr =
dma_map_single(osdev->dev,
tso_frag_vaddr,
tso_frag_len,
DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(osdev->dev,
tso_frag_paddr))) {
qdf_err("DMA mapping error!");
qdf_assert_always(0);
tso_frag_paddr = qdf_nbuf_tso_map_frag(
osdev, tso_frag_vaddr,
tso_frag_len,
QDF_DMA_TO_DEVICE);
if (qdf_unlikely(!tso_frag_paddr))
return 0;
}
}
TSO_DEBUG("%s tcp_seq_num: %u", __func__,
curr_seg->seg.tso_flags.tcp_seq_num);
@@ -3613,10 +3661,11 @@ void __qdf_nbuf_unmap_tso_segment(qdf_device_t osdev,
qdf_assert(0);
return;
}
dma_unmap_single(osdev->dev,
tso_seg->seg.tso_frags[num_frags].paddr,
tso_seg->seg.tso_frags[num_frags].length,
__qdf_dma_dir_to_os(QDF_DMA_TO_DEVICE));
qdf_nbuf_tso_unmap_frag(
osdev,
tso_seg->seg.tso_frags[num_frags].paddr,
tso_seg->seg.tso_frags[num_frags].length,
QDF_DMA_TO_DEVICE);
tso_seg->seg.tso_frags[num_frags].paddr = 0;
num_frags--;
qdf_tso_seg_dbg_record(tso_seg, TSOSEG_LOC_UNMAPTSO);
@@ -3630,10 +3679,10 @@ last_seg_free_first_frag:
qdf_assert(0);
return;
}
dma_unmap_single(osdev->dev,
tso_seg->seg.tso_frags[0].paddr,
tso_seg->seg.tso_frags[0].length,
__qdf_dma_dir_to_os(QDF_DMA_TO_DEVICE));
qdf_nbuf_tso_unmap_frag(osdev,
tso_seg->seg.tso_frags[0].paddr,
tso_seg->seg.tso_frags[0].length,
QDF_DMA_TO_DEVICE);
tso_seg->seg.tso_frags[0].paddr = 0;
qdf_tso_seg_dbg_record(tso_seg, TSOSEG_LOC_UNMAPLAST);
}