qcacmn: Add QDF wrapper for frag ops
Introduce qdf wrapper API 1. frag is added to nbuf fragment array. If frag can't be fit in that nbuf a new nbuf is allocated and frag is added to the new nbuf. Once added nbuf is added as a fraglist to head nbuf. On a subsequent call, frag is added to the last nbuf in a fraglist. 2. get reference for fragment. Change-Id: Ia4ccbc48e54b08d6b9d4f0cf5089fbf43ee8b496
This commit is contained in:

committed by
Madan Koyyalamudi

parent
a9948f7e23
commit
85dca44878
@@ -4071,6 +4071,19 @@ void qdf_nbuf_add_rx_frag_debug(qdf_frag_t buf, qdf_nbuf_t nbuf,
|
|||||||
unsigned int truesize, bool take_frag_ref,
|
unsigned int truesize, bool take_frag_ref,
|
||||||
const char *func, uint32_t line);
|
const char *func, uint32_t line);
|
||||||
|
|
||||||
|
#define qdf_nbuf_ref_frag(f) \
|
||||||
|
qdf_nbuf_ref_frag_debug(f, __func__, __LINE__)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qdf_nbuf_ref_frag_debug() - get frag reference
|
||||||
|
* @buf: Frag pointer needs to be taken reference.
|
||||||
|
* @func: Caller function name
|
||||||
|
* @line: Caller function line no.
|
||||||
|
*
|
||||||
|
* Return: none
|
||||||
|
*/
|
||||||
|
void qdf_nbuf_ref_frag_debug(qdf_frag_t buf, const char *func, uint32_t line);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* qdf_net_buf_debug_acquire_frag() - Add frag nodes to frag debug tracker
|
* qdf_net_buf_debug_acquire_frag() - Add frag nodes to frag debug tracker
|
||||||
* when nbuf is received from network stack
|
* when nbuf is received from network stack
|
||||||
@@ -4154,6 +4167,17 @@ static inline void qdf_nbuf_add_rx_frag(qdf_frag_t buf, qdf_nbuf_t nbuf,
|
|||||||
frag_len, truesize, take_frag_ref);
|
frag_len, truesize, take_frag_ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qdf_nbuf_ref_frag() - get frag reference
|
||||||
|
* @buf: Frag pointer needs to be taken reference.
|
||||||
|
*
|
||||||
|
* Return: void
|
||||||
|
*/
|
||||||
|
static inline void qdf_nbuf_ref_frag(qdf_frag_t buf)
|
||||||
|
{
|
||||||
|
__qdf_nbuf_ref_frag(buf);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void qdf_net_buf_debug_acquire_frag(qdf_nbuf_t buf,
|
static inline void qdf_net_buf_debug_acquire_frag(qdf_nbuf_t buf,
|
||||||
const char *func,
|
const char *func,
|
||||||
uint32_t line)
|
uint32_t line)
|
||||||
@@ -4176,6 +4200,41 @@ static inline void qdf_nbuf_frag_count_dec(qdf_nbuf_t buf)
|
|||||||
|
|
||||||
#endif /* NBUF_FRAG_MEMORY_DEBUG */
|
#endif /* NBUF_FRAG_MEMORY_DEBUG */
|
||||||
|
|
||||||
|
#define qdf_nbuf_add_frag(dev, f, n, o, f_l, t_sz, f_r, sz) \
|
||||||
|
qdf_nbuf_add_frag_debug(dev, f, n, o, f_l, t_sz, \
|
||||||
|
f_r, sz, __func__, __LINE__)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qdf_nbuf_add_frag_debug() - Add frag to nbuf
|
||||||
|
* @osdev: Device handle
|
||||||
|
* @buf: Frag pointer needs to be added in nbuf frag
|
||||||
|
* @nbuf: qdf_nbuf_t where frag will be added
|
||||||
|
* @offset: Offset in frag to be added to nbuf_frags
|
||||||
|
* @frag_len: Frag length
|
||||||
|
* @truesize: truesize
|
||||||
|
* @take_frag_ref: Whether to take ref for frag or not
|
||||||
|
* This bool must be set as per below comdition:
|
||||||
|
* 1. False: If this frag is being added in any nbuf
|
||||||
|
* for the first time after allocation
|
||||||
|
* 2. True: If frag is already attached part of any
|
||||||
|
* nbuf
|
||||||
|
* @minsize: Minimum size to allocate
|
||||||
|
* @func: Caller function name
|
||||||
|
* @line: Caller function line no.
|
||||||
|
*
|
||||||
|
* if number of frag exceed maximum frag array. A new nbuf is allocated
|
||||||
|
* with minimum headroom and frag it added to that nbuf.
|
||||||
|
* new nbuf is added as frag_list to the master nbuf.
|
||||||
|
*
|
||||||
|
* Return: QDF_STATUS
|
||||||
|
*/
|
||||||
|
QDF_STATUS
|
||||||
|
qdf_nbuf_add_frag_debug(qdf_device_t osdev, qdf_frag_t buf,
|
||||||
|
qdf_nbuf_t nbuf, int offset,
|
||||||
|
int frag_len, unsigned int truesize,
|
||||||
|
bool take_frag_ref, unsigned int minsize,
|
||||||
|
const char *func, uint32_t line);
|
||||||
|
|
||||||
#ifdef MEMORY_DEBUG
|
#ifdef MEMORY_DEBUG
|
||||||
/**
|
/**
|
||||||
* qdf_nbuf_acquire_track_lock - acquire the nbuf spinlock at the
|
* qdf_nbuf_acquire_track_lock - acquire the nbuf spinlock at the
|
||||||
|
@@ -1985,6 +1985,38 @@ __qdf_nbuf_copy_expand(struct sk_buff *buf, int headroom, int tailroom)
|
|||||||
return skb_copy_expand(buf, headroom, tailroom, GFP_ATOMIC);
|
return skb_copy_expand(buf, headroom, tailroom, GFP_ATOMIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __qdf_nbuf_has_fraglist() - check buf has fraglist
|
||||||
|
* @buf: Network buf instance
|
||||||
|
*
|
||||||
|
* Return: True, if buf has frag_list else return False
|
||||||
|
*/
|
||||||
|
static inline bool
|
||||||
|
__qdf_nbuf_has_fraglist(struct sk_buff *buf)
|
||||||
|
{
|
||||||
|
return skb_has_frag_list(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __qdf_nbuf_get_last_frag_list_nbuf() - Get last frag_list nbuf
|
||||||
|
* @buf: Network buf instance
|
||||||
|
*
|
||||||
|
* Return: Network buf instance
|
||||||
|
*/
|
||||||
|
static inline struct sk_buff *
|
||||||
|
__qdf_nbuf_get_last_frag_list_nbuf(struct sk_buff *buf)
|
||||||
|
{
|
||||||
|
struct sk_buff *list;
|
||||||
|
|
||||||
|
if (!__qdf_nbuf_has_fraglist(buf))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (list = skb_shinfo(buf)->frag_list; list->next; list = list->next)
|
||||||
|
;
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* __qdf_nbuf_get_ref_fraglist() - get reference to fragments
|
* __qdf_nbuf_get_ref_fraglist() - get reference to fragments
|
||||||
* @buf: Network buf instance
|
* @buf: Network buf instance
|
||||||
@@ -2542,6 +2574,13 @@ void __qdf_nbuf_add_rx_frag(__qdf_frag_t buf, __qdf_nbuf_t nbuf,
|
|||||||
int offset, int frag_len,
|
int offset, int frag_len,
|
||||||
unsigned int truesize, bool take_frag_ref);
|
unsigned int truesize, bool take_frag_ref);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __qdf_nbuf_ref_frag() - get frag reference
|
||||||
|
*
|
||||||
|
* Return: void
|
||||||
|
*/
|
||||||
|
void __qdf_nbuf_ref_frag(qdf_frag_t buf);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* __qdf_nbuf_set_mark() - Set nbuf mark
|
* __qdf_nbuf_set_mark() - Set nbuf mark
|
||||||
* @buf: Pointer to nbuf
|
* @buf: Pointer to nbuf
|
||||||
|
@@ -5181,6 +5181,24 @@ void __qdf_nbuf_add_rx_frag(__qdf_frag_t buf, __qdf_nbuf_t nbuf,
|
|||||||
|
|
||||||
qdf_export_symbol(__qdf_nbuf_add_rx_frag);
|
qdf_export_symbol(__qdf_nbuf_add_rx_frag);
|
||||||
|
|
||||||
|
void __qdf_nbuf_ref_frag(__qdf_frag_t buf)
|
||||||
|
{
|
||||||
|
struct page *page;
|
||||||
|
skb_frag_t frag = {0};
|
||||||
|
|
||||||
|
page = virt_to_head_page(buf);
|
||||||
|
__skb_frag_set_page(&frag, page);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* since __skb_frag_ref() just use page to increase ref
|
||||||
|
* we just decode page alone
|
||||||
|
*/
|
||||||
|
qdf_frag_count_inc(QDF_NBUF_FRAG_DEBUG_COUNT_ONE);
|
||||||
|
__skb_frag_ref(&frag);
|
||||||
|
}
|
||||||
|
|
||||||
|
qdf_export_symbol(__qdf_nbuf_ref_frag);
|
||||||
|
|
||||||
#ifdef NBUF_FRAG_MEMORY_DEBUG
|
#ifdef NBUF_FRAG_MEMORY_DEBUG
|
||||||
|
|
||||||
QDF_STATUS qdf_nbuf_move_frag_page_offset_debug(qdf_nbuf_t nbuf, uint8_t idx,
|
QDF_STATUS qdf_nbuf_move_frag_page_offset_debug(qdf_nbuf_t nbuf, uint8_t idx,
|
||||||
@@ -5240,6 +5258,25 @@ void qdf_nbuf_add_rx_frag_debug(qdf_frag_t buf, qdf_nbuf_t nbuf,
|
|||||||
|
|
||||||
qdf_export_symbol(qdf_nbuf_add_rx_frag_debug);
|
qdf_export_symbol(qdf_nbuf_add_rx_frag_debug);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qdf_nbuf_ref_frag_debug() - get frag reference
|
||||||
|
* @buf: Frag pointer needs to be taken reference.
|
||||||
|
*
|
||||||
|
* return: void
|
||||||
|
*/
|
||||||
|
void qdf_nbuf_ref_frag_debug(qdf_frag_t buf, const char *func, uint32_t line)
|
||||||
|
{
|
||||||
|
__qdf_nbuf_ref_frag(buf);
|
||||||
|
|
||||||
|
if (qdf_likely(is_initial_mem_debug_disabled))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Update frag refcount in frag debug tracking table */
|
||||||
|
qdf_frag_debug_refcount_inc(buf, func, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
qdf_export_symbol(qdf_nbuf_ref_frag_debug);
|
||||||
|
|
||||||
void qdf_net_buf_debug_acquire_frag(qdf_nbuf_t buf, const char *func,
|
void qdf_net_buf_debug_acquire_frag(qdf_nbuf_t buf, const char *func,
|
||||||
uint32_t line)
|
uint32_t line)
|
||||||
{
|
{
|
||||||
@@ -5346,6 +5383,112 @@ void qdf_net_buf_debug_release_frag(qdf_nbuf_t buf, const char *func,
|
|||||||
qdf_export_symbol(qdf_net_buf_debug_release_frag);
|
qdf_export_symbol(qdf_net_buf_debug_release_frag);
|
||||||
#endif /* NBUF_FRAG_MEMORY_DEBUG */
|
#endif /* NBUF_FRAG_MEMORY_DEBUG */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qdf_get_nbuf_valid_frag() - Get nbuf to store frag
|
||||||
|
* @nbuf: qdf_nbuf_t master nbuf
|
||||||
|
*
|
||||||
|
* Return: qdf_nbuf_t
|
||||||
|
*/
|
||||||
|
static inline qdf_nbuf_t qdf_get_nbuf_valid_frag(qdf_nbuf_t nbuf)
|
||||||
|
{
|
||||||
|
qdf_nbuf_t last_nbuf;
|
||||||
|
uint32_t num_frags;
|
||||||
|
|
||||||
|
if (qdf_unlikely(!nbuf))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
num_frags = qdf_nbuf_get_nr_frags(nbuf);
|
||||||
|
|
||||||
|
/* Check nbuf has enough memory to store frag memory */
|
||||||
|
if (num_frags <= QDF_NBUF_MAX_FRAGS)
|
||||||
|
return nbuf;
|
||||||
|
|
||||||
|
if (num_frags > QDF_NBUF_MAX_FRAGS && !__qdf_nbuf_has_fraglist(nbuf))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
last_nbuf = __qdf_nbuf_get_last_frag_list_nbuf(nbuf);
|
||||||
|
if (qdf_unlikely(!last_nbuf))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
num_frags = qdf_nbuf_get_nr_frags(last_nbuf);
|
||||||
|
if (num_frags < QDF_NBUF_MAX_FRAGS)
|
||||||
|
return last_nbuf;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qdf_nbuf_add_frag_debug() - Add frag to nbuf
|
||||||
|
* @osdev: Device handle
|
||||||
|
* @buf: Frag pointer needs to be added in nbuf frag
|
||||||
|
* @nbuf: qdf_nbuf_t where frag will be added
|
||||||
|
* @offset: Offset in frag to be added to nbuf_frags
|
||||||
|
* @frag_len: Frag length
|
||||||
|
* @truesize: truesize
|
||||||
|
* @take_frag_ref: Whether to take ref for frag or not
|
||||||
|
* This bool must be set as per below comdition:
|
||||||
|
* 1. False: If this frag is being added in any nbuf
|
||||||
|
* for the first time after allocation
|
||||||
|
* 2. True: If frag is already attached part of any
|
||||||
|
* nbuf
|
||||||
|
* @minsize: Minimum size to allocate
|
||||||
|
* @func: Caller function name
|
||||||
|
* @line: Caller function line no.
|
||||||
|
*
|
||||||
|
* if number of frag exceed maximum frag array. A new nbuf is allocated
|
||||||
|
* with minimum headroom and frag it added to that nbuf.
|
||||||
|
* new nbuf is added as frag_list to the master nbuf.
|
||||||
|
*
|
||||||
|
* Return: QDF_STATUS
|
||||||
|
*/
|
||||||
|
QDF_STATUS
|
||||||
|
qdf_nbuf_add_frag_debug(qdf_device_t osdev, qdf_frag_t buf,
|
||||||
|
qdf_nbuf_t nbuf, int offset,
|
||||||
|
int frag_len, unsigned int truesize,
|
||||||
|
bool take_frag_ref, unsigned int minsize,
|
||||||
|
const char *func, uint32_t line)
|
||||||
|
{
|
||||||
|
qdf_nbuf_t cur_nbuf;
|
||||||
|
qdf_nbuf_t this_nbuf;
|
||||||
|
|
||||||
|
cur_nbuf = nbuf;
|
||||||
|
this_nbuf = nbuf;
|
||||||
|
|
||||||
|
if (qdf_unlikely(!frag_len || !buf)) {
|
||||||
|
qdf_nofl_err("%s : %d frag[ buf[%pK] len[%d]] not valid\n",
|
||||||
|
func, line,
|
||||||
|
buf, frag_len);
|
||||||
|
return QDF_STATUS_E_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
this_nbuf = qdf_get_nbuf_valid_frag(this_nbuf);
|
||||||
|
|
||||||
|
if (this_nbuf) {
|
||||||
|
cur_nbuf = this_nbuf;
|
||||||
|
} else {
|
||||||
|
/* allocate a dummy mpdu buffer of 64 bytes headroom */
|
||||||
|
this_nbuf = qdf_nbuf_alloc(osdev, minsize, minsize, 4, false);
|
||||||
|
if (qdf_unlikely(!this_nbuf)) {
|
||||||
|
qdf_nofl_err("%s : %d no memory to allocate\n",
|
||||||
|
func, line);
|
||||||
|
return QDF_STATUS_E_NOMEM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qdf_nbuf_add_rx_frag(buf, this_nbuf, offset, frag_len, truesize,
|
||||||
|
take_frag_ref);
|
||||||
|
|
||||||
|
if (this_nbuf != cur_nbuf) {
|
||||||
|
/* add new skb to frag list */
|
||||||
|
qdf_nbuf_append_ext_list(nbuf, this_nbuf,
|
||||||
|
qdf_nbuf_len(this_nbuf));
|
||||||
|
}
|
||||||
|
|
||||||
|
return QDF_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
qdf_export_symbol(qdf_nbuf_add_frag_debug);
|
||||||
|
|
||||||
#ifdef MEMORY_DEBUG
|
#ifdef MEMORY_DEBUG
|
||||||
void qdf_nbuf_acquire_track_lock(uint32_t index,
|
void qdf_nbuf_acquire_track_lock(uint32_t index,
|
||||||
unsigned long irq_flag)
|
unsigned long irq_flag)
|
||||||
|
Reference in New Issue
Block a user