Selaa lähdekoodia

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
Nisha Menon 4 vuotta sitten
vanhempi
sitoutus
af829916ee
3 muutettua tiedostoa jossa 136 lisäystä ja 39 poistoa
  1. 33 0
      qdf/inc/qdf_nbuf.h
  2. 17 2
      qdf/linux/src/i_qdf_nbuf.h
  3. 86 37
      qdf/linux/src/qdf_nbuf.c

+ 33 - 0
qdf/inc/qdf_nbuf.h

@@ -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

+ 17 - 2
qdf/linux/src/i_qdf_nbuf.h

@@ -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;

+ 86 - 37
qdf/linux/src/qdf_nbuf.c

@@ -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);
 	}