From 6b69543b7988e347cc4a45d3bdc2722721d1ab7c Mon Sep 17 00:00:00 2001 From: Amir Patel Date: Mon, 11 Apr 2022 16:12:25 +0530 Subject: [PATCH] qcacmn: Add API to remove frag from skb Add API to remove frag from skb CRs-Fixed: 3172668 Change-Id: I0b392366760036c6fda545f558f72a64138d2b11 --- qdf/inc/qdf_nbuf.h | 37 +++++++++++++++++++++ qdf/linux/src/i_qdf_nbuf.h | 9 +++++ qdf/linux/src/qdf_nbuf.c | 67 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+) diff --git a/qdf/inc/qdf_nbuf.h b/qdf/inc/qdf_nbuf.h index 2ba038e2ed..afe957fdf6 100644 --- a/qdf/inc/qdf_nbuf.h +++ b/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 diff --git a/qdf/linux/src/i_qdf_nbuf.h b/qdf/linux/src/i_qdf_nbuf.h index 1821757307..2ca33bcbba 100644 --- a/qdf/linux/src/i_qdf_nbuf.h +++ b/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 diff --git a/qdf/linux/src/qdf_nbuf.c b/qdf/linux/src/qdf_nbuf.c index 61fdbd811c..319fac542b 100644 --- a/qdf/linux/src/qdf_nbuf.c +++ b/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 */ /**