From 15d8bb5c6b584a9e4beca36dae8a963391565436 Mon Sep 17 00:00:00 2001 From: Shivani Soni Date: Fri, 24 Jul 2020 18:08:33 +0530 Subject: [PATCH] qcacmn: QDF API and SKB debug framework support for alloc_skb Implementation of QDF API to allocate skb to avoid recycler pool and extending skb debug framework support. QDF API: qdf_nbuf_alloc_no_recycler Change-Id: I32ccae7337000c899e8fba8127aa9fb3c8551783 CRs-Fixed: 2734717 --- qdf/inc/qdf_nbuf.h | 50 ++++++++++++++++++++++++++++++++++ qdf/linux/src/i_qdf_nbuf.h | 16 +++++++++++ qdf/linux/src/qdf_nbuf.c | 55 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 121 insertions(+) diff --git a/qdf/inc/qdf_nbuf.h b/qdf/inc/qdf_nbuf.h index ca2eefd009..3d66a6389e 100644 --- a/qdf/inc/qdf_nbuf.h +++ b/qdf/inc/qdf_nbuf.h @@ -1520,6 +1520,25 @@ qdf_nbuf_t qdf_nbuf_alloc_debug(qdf_device_t osdev, qdf_size_t size, int reserve, int align, int prio, const char *func, uint32_t line); +/** + * qdf_nbuf_alloc_no_recycler() - Allocates skb + * @size: Size to be allocated for skb + * @reserve: Reserved headroom size + * @align: Align + * @func: Function name of the call site + * @line: Line number of the callsite + * + * This API allocates skb of required size and aligns if needed and reserves + * some space in the front. This skb allocation is not from skb recycler pool. + * + * Return: Allocated nbuf pointer + */ +#define qdf_nbuf_alloc_no_recycler(s, r, a) \ + qdf_nbuf_alloc_no_recycler_debug(s, r, a, __func__, __LINE__) + +qdf_nbuf_t qdf_nbuf_alloc_no_recycler_debug(size_t size, int reserve, int align, + const char *func, uint32_t line); + #define qdf_nbuf_free(d) \ qdf_nbuf_free_debug(d, __func__, __LINE__) @@ -1616,6 +1635,10 @@ qdf_net_buf_debug_update_unmap_node(qdf_nbuf_t net_buf, #define qdf_nbuf_alloc(osdev, size, reserve, align, prio) \ qdf_nbuf_alloc_fl(osdev, size, reserve, align, prio, \ __func__, __LINE__) + +#define qdf_nbuf_alloc_no_recycler(size, reserve, align) \ + qdf_nbuf_alloc_no_recycler_fl(size, reserve, align, __func__, __LINE__) + static inline qdf_nbuf_t qdf_nbuf_alloc_fl(qdf_device_t osdev, qdf_size_t size, int reserve, int align, int prio, const char *func, uint32_t line) @@ -1628,6 +1651,33 @@ qdf_nbuf_alloc_fl(qdf_device_t osdev, qdf_size_t size, int reserve, int align, return nbuf; } +/** + * qdf_nbuf_alloc_no_recycler_fl() - Allocate SKB + * @size: Size to be allocated for skb + * @reserve: Reserved headroom size + * @align: Align + * @func: Function name of the call site + * @line: Line number of the callsite + * + * This API allocates skb of required size and aligns if needed and reserves + * some space in the front. This skb allocation is not from skb recycler pool. + * + * Return: Allocated nbuf pointer + */ +static inline qdf_nbuf_t +qdf_nbuf_alloc_no_recycler_fl(size_t size, int reserve, int align, + const char *func, uint32_t line) +{ + qdf_nbuf_t nbuf; + + nbuf = __qdf_nbuf_alloc_no_recycler(size, reserve, align, func, line); + + if (qdf_likely(nbuf)) + qdf_mem_skb_inc(nbuf->truesize); + + return nbuf; +} + static inline void qdf_nbuf_free(qdf_nbuf_t buf) { if (qdf_likely(buf)) diff --git a/qdf/linux/src/i_qdf_nbuf.h b/qdf/linux/src/i_qdf_nbuf.h index 2d864f8114..b73ad7af00 100644 --- a/qdf/linux/src/i_qdf_nbuf.h +++ b/qdf/linux/src/i_qdf_nbuf.h @@ -754,6 +754,22 @@ __qdf_nbuf_t __qdf_nbuf_alloc(__qdf_device_t osdev, size_t size, int reserve, int align, int prio, const char *func, uint32_t line); +/** + * __qdf_nbuf_alloc_no_recycler() - Allocates skb + * @size: Size to be allocated for skb + * @reserve: Reserve headroom size + * @align: Align data + * @func: Function name of the call site + * @line: Line number of the callsite + * + * This API allocates a nbuf and aligns it if needed and reserves some headroom + * space after the alignment where nbuf is not allocated from skb recycler pool. + * + * Return: Allocated nbuf pointer + */ +__qdf_nbuf_t __qdf_nbuf_alloc_no_recycler(size_t size, int reserve, int align, + const char *func, uint32_t line); + void __qdf_nbuf_free(struct sk_buff *skb); QDF_STATUS __qdf_nbuf_map(__qdf_device_t osdev, struct sk_buff *skb, qdf_dma_dir_t dir); diff --git a/qdf/linux/src/qdf_nbuf.c b/qdf/linux/src/qdf_nbuf.c index 35193beab9..90f053f917 100644 --- a/qdf/linux/src/qdf_nbuf.c +++ b/qdf/linux/src/qdf_nbuf.c @@ -538,6 +538,37 @@ skb_alloc: #endif qdf_export_symbol(__qdf_nbuf_alloc); +__qdf_nbuf_t __qdf_nbuf_alloc_no_recycler(size_t size, int reserve, int align, + const char *func, uint32_t line) +{ + qdf_nbuf_t nbuf; + unsigned long offset; + + if (align) + size += (align - 1); + + nbuf = alloc_skb(size, GFP_ATOMIC); + if (!nbuf) + goto ret_nbuf; + + memset(nbuf->cb, 0x0, sizeof(nbuf->cb)); + + skb_reserve(nbuf, reserve); + + if (align) { + offset = ((unsigned long)nbuf->data) % align; + if (offset) + skb_reserve(nbuf, align - offset); + } + + qdf_nbuf_count_inc(nbuf); + +ret_nbuf: + return nbuf; +} + +qdf_export_symbol(__qdf_nbuf_alloc_no_recycler); + /** * __qdf_nbuf_free() - free the nbuf its interrupt safe * @skb: Pointer to network buffer @@ -2753,6 +2784,30 @@ qdf_nbuf_t qdf_nbuf_alloc_debug(qdf_device_t osdev, qdf_size_t size, } qdf_export_symbol(qdf_nbuf_alloc_debug); +qdf_nbuf_t qdf_nbuf_alloc_no_recycler_debug(size_t size, int reserve, int align, + const char *func, uint32_t line) +{ + qdf_nbuf_t nbuf; + + if (is_initial_mem_debug_disabled) + return __qdf_nbuf_alloc_no_recycler(size, reserve, align, func, + line); + + nbuf = __qdf_nbuf_alloc_no_recycler(size, reserve, align, func, line); + + /* Store SKB in internal QDF tracking table */ + if (qdf_likely(nbuf)) { + qdf_net_buf_debug_add_node(nbuf, size, func, line); + qdf_nbuf_history_add(nbuf, func, line, QDF_NBUF_ALLOC); + } else { + qdf_nbuf_history_add(nbuf, func, line, QDF_NBUF_ALLOC_FAILURE); + } + + return nbuf; +} + +qdf_export_symbol(qdf_nbuf_alloc_no_recycler_debug); + void qdf_nbuf_free_debug(qdf_nbuf_t nbuf, const char *func, uint32_t line) { qdf_nbuf_t ext_list;