Browse Source

qcacmn: Add API to remove frag from skb

Add API to remove frag from skb

CRs-Fixed: 3172668
Change-Id: I0b392366760036c6fda545f558f72a64138d2b11
Amir Patel 3 years ago
parent
commit
6b69543b79
3 changed files with 113 additions and 0 deletions
  1. 37 0
      qdf/inc/qdf_nbuf.h
  2. 9 0
      qdf/linux/src/i_qdf_nbuf.h
  3. 67 0
      qdf/linux/src/qdf_nbuf.c

+ 37 - 0
qdf/inc/qdf_nbuf.h

@@ -4319,6 +4319,27 @@ QDF_STATUS qdf_nbuf_move_frag_page_offset_debug(qdf_nbuf_t nbuf, uint8_t idx,
 						int offset, const char *func,
 						uint32_t line);
 
+#define qdf_nbuf_remove_frag(n, i, t) \
+	qdf_nbuf_remove_frag_debug(n, i, t, __func__, __LINE__)
+
+/**
+ * qdf_nbuf_remove_frag_debug - Remove frag from nbuf
+ * @nbuf: nbuf where frag will be removed
+ * @idx: frag index
+ * @truesize: truesize of frag
+ * @func: Caller function name
+ * @line:  Caller function line no.
+ *
+ * Return: QDF_STATUS
+ *
+ */
+QDF_STATUS
+qdf_nbuf_remove_frag_debug(qdf_nbuf_t nbuf,
+			   uint16_t idx,
+			   uint16_t truesize,
+			   const char *func,
+			   uint32_t line);
+
 #define qdf_nbuf_add_rx_frag(f, b, o, l, s, r) \
 	qdf_nbuf_add_rx_frag_debug(f, b, o, l, s, r, __func__, __LINE__)
 
@@ -4416,6 +4437,22 @@ static inline QDF_STATUS qdf_nbuf_move_frag_page_offset(qdf_nbuf_t nbuf,
 	return __qdf_nbuf_move_frag_page_offset(nbuf, idx, offset);
 }
 
+/**
+ * qdf_nbuf_remove_frag() - Remove frag from nbuf
+ *
+ * @nbuf: nbuf pointer
+ * @idx: idx at which frag need to be removed
+ * @truesize: truesize of frag
+ *
+ * Return: void
+ */
+static inline void qdf_nbuf_remove_frag(qdf_nbuf_t nbuf,
+					uint16_t idx,
+					uint16_t truesize)
+{
+	return __qdf_nbuf_remove_frag(nbuf, idx, truesize);
+}
+
 /**
  * qdf_nbuf_add_rx_frag() - Add frag to nbuf at index frag_idx
  * @buf: Frag pointer needs to be added in nbuf frag

+ 9 - 0
qdf/linux/src/i_qdf_nbuf.h

@@ -2561,6 +2561,15 @@ static inline void __qdf_nbuf_trim_add_frag_size(__qdf_nbuf_t nbuf, uint8_t idx,
 QDF_STATUS __qdf_nbuf_move_frag_page_offset(__qdf_nbuf_t nbuf, uint8_t idx,
 					    int offset);
 
+/**
+ * __qdf_nbuf_remove_frag() - Remove frag from nbuf
+ * @nbuf: nbuf pointer
+ * @idx: frag idx need to be removed
+ * @truesize: truesize of frag
+ *
+ * Return : void
+ */
+void __qdf_nbuf_remove_frag(__qdf_nbuf_t nbuf, uint16_t idx, uint16_t truesize);
 /**
  * __qdf_nbuf_add_rx_frag() - Add frag to nbuf at nr_frag index
  * @buf: Frag pointer needs to be added in nbuf frag

+ 67 - 0
qdf/linux/src/qdf_nbuf.c

@@ -5504,6 +5504,28 @@ QDF_STATUS __qdf_nbuf_move_frag_page_offset(__qdf_nbuf_t nbuf, uint8_t idx,
 
 qdf_export_symbol(__qdf_nbuf_move_frag_page_offset);
 
+void __qdf_nbuf_remove_frag(__qdf_nbuf_t nbuf,
+			    uint16_t idx,
+			    uint16_t truesize)
+{
+	struct page *page;
+	uint16_t frag_len;
+
+	page = skb_frag_page(&skb_shinfo(nbuf)->frags[idx]);
+
+	if (qdf_unlikely(!page))
+		return;
+
+	frag_len = qdf_nbuf_get_frag_size_by_idx(nbuf, idx);
+	put_page(page);
+	nbuf->len -= frag_len;
+	nbuf->data_len -= frag_len;
+	nbuf->truesize -= truesize;
+	skb_shinfo(nbuf)->nr_frags--;
+}
+
+qdf_export_symbol(__qdf_nbuf_remove_frag);
+
 void __qdf_nbuf_add_rx_frag(__qdf_frag_t buf, __qdf_nbuf_t nbuf,
 			    int offset, int frag_len,
 			    unsigned int truesize, bool take_frag_ref)
@@ -5730,6 +5752,51 @@ void qdf_net_buf_debug_release_frag(qdf_nbuf_t buf, const char *func,
 }
 
 qdf_export_symbol(qdf_net_buf_debug_release_frag);
+
+/**
+ * qdf_nbuf_remove_frag_debug - Remove frag from nbuf
+ * @nbuf: nbuf  where frag will be removed
+ * @idx: frag index
+ * @truesize: truesize of frag
+ * @func: Caller function name
+ * @line:  Caller function line no.
+ *
+ * Return: QDF_STATUS
+ *
+ */
+QDF_STATUS
+qdf_nbuf_remove_frag_debug(qdf_nbuf_t nbuf,
+			   uint16_t idx,
+			   uint16_t truesize,
+			   const char *func,
+			   uint32_t line)
+{
+	uint16_t num_frags;
+	qdf_frag_t frag;
+
+	if (qdf_unlikely(!nbuf))
+		return QDF_STATUS_E_INVAL;
+
+	num_frags = qdf_nbuf_get_nr_frags(nbuf);
+	if (idx >= num_frags)
+		return QDF_STATUS_E_INVAL;
+
+	if (qdf_likely(is_initial_mem_debug_disabled)) {
+		__qdf_nbuf_remove_frag(nbuf, idx, truesize);
+		return QDF_STATUS_SUCCESS;
+	}
+
+	frag = qdf_nbuf_get_frag_addr(nbuf, idx);
+	if (qdf_likely(frag))
+		qdf_frag_debug_refcount_dec(frag, func, line);
+
+	__qdf_nbuf_remove_frag(nbuf, idx, truesize);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+qdf_export_symbol(qdf_nbuf_remove_frag_debug);
+
 #endif /* NBUF_FRAG_MEMORY_DEBUG */
 
 /**