qcacmn: Add a set of nbuf fragment allocation APIs

It adds a set of frag way allocation APIs explicitly.
IPA Tx nbufs change to frag way allocation API, which saves memory.

Current __qdf_nbuf_alloc changes to non-frag way allocation by
default if SKB RECYLCER not defined.

Change-Id: I5f87ffac54c49f9af920775c13b6dfdd147476dd
CRs-Fixed: 3534452
This commit is contained in:
Sijun Wu
2023-03-31 14:53:55 +05:30
committed by Rahul Choudhary
parent e6b159369e
commit 27f8cfff08
5 changed files with 164 additions and 8 deletions

View File

@@ -555,6 +555,16 @@ skb_alloc:
}
#else
#ifdef QCA_DP_NBUF_FAST_RECYCLE_CHECK
struct sk_buff *__qdf_nbuf_alloc(qdf_device_t osdev, size_t size, int reserve,
int align, int prio, const char *func,
uint32_t line)
{
return __qdf_nbuf_frag_alloc(osdev, size, reserve, align, prio, func,
line);
}
#else
struct sk_buff *__qdf_nbuf_alloc(qdf_device_t osdev, size_t size, int reserve,
int align, int prio, const char *func,
uint32_t line)
@@ -579,6 +589,81 @@ struct sk_buff *__qdf_nbuf_alloc(qdf_device_t osdev, size_t size, int reserve,
#endif
}
skb = alloc_skb(size, flags);
if (skb)
goto skb_alloc;
skb = pld_nbuf_pre_alloc(size);
if (!skb) {
qdf_rl_nofl_err("NBUF alloc failed %zuB @ %s:%d",
size, func, line);
__qdf_nbuf_start_replenish_timer();
return NULL;
}
__qdf_nbuf_stop_replenish_timer();
skb_alloc:
memset(skb->cb, 0x0, sizeof(skb->cb));
skb->dev = NULL;
/*
* The default is for netbuf fragments to be interpreted
* as wordstreams rather than bytestreams.
*/
QDF_NBUF_CB_TX_EXTRA_FRAG_WORDSTR_EFRAG(skb) = 1;
QDF_NBUF_CB_TX_EXTRA_FRAG_WORDSTR_NBUF(skb) = 1;
/*
* XXX:how about we reserve first then align
* Align & make sure that the tail & data are adjusted properly
*/
if (align) {
offset = ((unsigned long)skb->data) % align;
if (offset)
skb_reserve(skb, align - offset);
}
/*
* NOTE:alloc doesn't take responsibility if reserve unaligns the data
* pointer
*/
skb_reserve(skb, reserve);
qdf_nbuf_count_inc(skb);
return skb;
}
#endif
#endif
qdf_export_symbol(__qdf_nbuf_alloc);
struct sk_buff *__qdf_nbuf_frag_alloc(qdf_device_t osdev, size_t size,
int reserve, int align, int prio,
const char *func, uint32_t line)
{
struct sk_buff *skb;
unsigned long offset;
int flags = GFP_KERNEL & ~__GFP_DIRECT_RECLAIM;
if (align)
size += (align - 1);
if (in_interrupt() || irqs_disabled() || in_atomic()) {
flags = GFP_ATOMIC;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
/*
* Observed that kcompactd burns out CPU to make order-3 page.
*__netdev_alloc_skb has 4k page fallback option just in case of
* failing high order page allocation so we don't need to be
* hard. Make kcompactd rest in piece.
*/
flags = flags & ~__GFP_KSWAPD_RECLAIM;
#endif
}
skb = __netdev_alloc_skb(NULL, size, flags);
if (skb)
@@ -591,13 +676,12 @@ struct sk_buff *__qdf_nbuf_alloc(qdf_device_t osdev, size_t size, int reserve,
size, func, line);
__qdf_nbuf_start_replenish_timer();
return NULL;
} else {
__qdf_nbuf_stop_replenish_timer();
}
__qdf_nbuf_stop_replenish_timer();
skb_alloc:
memset(skb->cb, 0x0, sizeof(skb->cb));
/*
* The default is for netbuf fragments to be interpreted
* as wordstreams rather than bytestreams.
@@ -625,8 +709,8 @@ skb_alloc:
return skb;
}
#endif
qdf_export_symbol(__qdf_nbuf_alloc);
qdf_export_symbol(__qdf_nbuf_frag_alloc);
__qdf_nbuf_t __qdf_nbuf_alloc_no_recycler(size_t size, int reserve, int align,
const char *func, uint32_t line)
@@ -3377,6 +3461,33 @@ 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_frag_alloc_debug(qdf_device_t osdev, qdf_size_t size,
int reserve, int align, int prio,
const char *func, uint32_t line)
{
qdf_nbuf_t nbuf;
if (is_initial_mem_debug_disabled)
return __qdf_nbuf_frag_alloc(osdev, size,
reserve, align,
prio, func, line);
nbuf = __qdf_nbuf_frag_alloc(osdev, size, reserve, align, prio,
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_frag_alloc_debug);
qdf_nbuf_t qdf_nbuf_alloc_no_recycler_debug(size_t size, int reserve, int align,
const char *func, uint32_t line)
{