qcacmn: Add support to add memory tracking in tx path
Add support to add memory tracking in tx path in WLAN driver using already present infrastructure for memory tracking. Change-Id: I6a2c9890e0af1fd51c4e2dfcded68f0075a3a4ef CRs-Fixed: 2025670
Этот коммит содержится в:

коммит произвёл
Sandeep Puligilla

родитель
a47828dd20
Коммит
33d0d707bd
@@ -630,12 +630,66 @@ qdf_nbuf_dma_map_info(qdf_dma_map_t bmap, qdf_dmamap_info_t *sg)
|
||||
__qdf_nbuf_dma_map_info(bmap, sg);
|
||||
}
|
||||
|
||||
/**
|
||||
* qdf_nbuf_is_tso() - is the network buffer a jumbo packet?
|
||||
* @buf: Network buffer
|
||||
*
|
||||
* Return: 1 - this is a jumbo packet 0 - not a jumbo packet
|
||||
*/
|
||||
static inline uint8_t qdf_nbuf_is_tso(qdf_nbuf_t nbuf)
|
||||
{
|
||||
return __qdf_nbuf_is_tso(nbuf);
|
||||
}
|
||||
|
||||
/**
|
||||
* qdf_nbuf_get_users() - function to get the number of users referencing this
|
||||
* network buffer
|
||||
*
|
||||
* @nbuf: network buffer
|
||||
*
|
||||
* Return: number of user references to nbuf.
|
||||
*/
|
||||
static inline int qdf_nbuf_get_users(qdf_nbuf_t nbuf)
|
||||
{
|
||||
return __qdf_nbuf_get_users(nbuf);
|
||||
}
|
||||
|
||||
/**
|
||||
* qdf_nbuf_next() - get the next packet in the linked list
|
||||
* @buf: Network buffer
|
||||
*
|
||||
* This function can be used when nbufs are directly linked into a list,
|
||||
* rather than using a separate network buffer queue object.
|
||||
*
|
||||
* Return: next network buffer in the linked list
|
||||
*/
|
||||
static inline qdf_nbuf_t qdf_nbuf_next(qdf_nbuf_t buf)
|
||||
{
|
||||
return __qdf_nbuf_next(buf);
|
||||
}
|
||||
|
||||
#ifdef MEMORY_DEBUG
|
||||
void qdf_net_buf_debug_init(void);
|
||||
void qdf_net_buf_debug_exit(void);
|
||||
void qdf_net_buf_debug_clean(void);
|
||||
void qdf_net_buf_debug_add_node(qdf_nbuf_t net_buf, size_t size,
|
||||
uint8_t *file_name, uint32_t line_num);
|
||||
void qdf_net_buf_debug_delete_node(qdf_nbuf_t net_buf);
|
||||
|
||||
/**
|
||||
* qdf_net_buf_debug_acquire_skb() - acquire skb to avoid memory leak
|
||||
* @net_buf: Network buf holding head segment (single)
|
||||
* @file_name: pointer to file name
|
||||
* @line_num: line number
|
||||
*
|
||||
* WLAN driver module's SKB which are allocated by network stack are
|
||||
* suppose to call this API before freeing it such that the SKB
|
||||
* is not reported as memory leak.
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void qdf_net_buf_debug_acquire_skb(qdf_nbuf_t net_buf,
|
||||
uint8_t *file_name, uint32_t line_num);
|
||||
void qdf_net_buf_debug_release_skb(qdf_nbuf_t net_buf);
|
||||
|
||||
/* nbuf allocation rouines */
|
||||
@@ -659,10 +713,15 @@ qdf_nbuf_alloc_debug(qdf_device_t osdev, qdf_size_t size, int reserve,
|
||||
|
||||
static inline void qdf_nbuf_free(qdf_nbuf_t net_buf)
|
||||
{
|
||||
if (qdf_nbuf_is_tso(net_buf) &&
|
||||
qdf_nbuf_get_users(net_buf) > 1)
|
||||
goto free_buf;
|
||||
|
||||
/* Remove SKB from internal QDF tracking table */
|
||||
if (qdf_likely(net_buf))
|
||||
qdf_net_buf_debug_delete_node(net_buf);
|
||||
|
||||
free_buf:
|
||||
__qdf_nbuf_free(net_buf);
|
||||
}
|
||||
|
||||
@@ -727,6 +786,11 @@ qdf_nbuf_copy_debug(qdf_nbuf_t buf, uint8_t *file_name,
|
||||
|
||||
#else
|
||||
|
||||
static inline void qdf_net_buf_debug_acquire_skb(qdf_nbuf_t net_buf,
|
||||
uint8_t *file_name, uint32_t line_num)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void qdf_net_buf_debug_release_skb(qdf_nbuf_t net_buf)
|
||||
{
|
||||
return;
|
||||
@@ -795,7 +859,12 @@ static inline void qdf_nbuf_init_fast(qdf_nbuf_t nbuf)
|
||||
|
||||
static inline void qdf_nbuf_tx_free(qdf_nbuf_t buf_list, int tx_err)
|
||||
{
|
||||
__qdf_nbuf_tx_free(buf_list, tx_err);
|
||||
while (buf_list) {
|
||||
qdf_nbuf_t next = qdf_nbuf_next(buf_list);
|
||||
|
||||
qdf_nbuf_free(buf_list);
|
||||
buf_list = next;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void qdf_nbuf_ref(qdf_nbuf_t buf)
|
||||
@@ -1087,20 +1156,6 @@ qdf_nbuf_queue_first(qdf_nbuf_queue_t *head)
|
||||
return __qdf_nbuf_queue_first(head);
|
||||
}
|
||||
|
||||
/**
|
||||
* qdf_nbuf_next() - get the next packet in the linked list
|
||||
* @buf: Network buffer
|
||||
*
|
||||
* This function can be used when nbufs are directly linked into a list,
|
||||
* rather than using a separate network buffer queue object.
|
||||
*
|
||||
* Return: next network buffer in the linked list
|
||||
*/
|
||||
static inline qdf_nbuf_t qdf_nbuf_next(qdf_nbuf_t buf)
|
||||
{
|
||||
return __qdf_nbuf_next(buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* qdf_nbuf_get_protocol() - return the protocol value of the skb
|
||||
* @skb: Pointer to network buffer
|
||||
@@ -1929,17 +1984,6 @@ static inline void qdf_dmaaddr_to_32s(qdf_dma_addr_t dmaaddr,
|
||||
return __qdf_dmaaddr_to_32s(dmaaddr, lo, hi);
|
||||
}
|
||||
|
||||
/**
|
||||
* qdf_nbuf_is_tso() - is the network buffer a jumbo packet?
|
||||
* @buf: Network buffer
|
||||
*
|
||||
* Return: 1 - this is a jumbo packet 0 - not a jumbo packet
|
||||
*/
|
||||
static inline uint8_t qdf_nbuf_is_tso(qdf_nbuf_t nbuf)
|
||||
{
|
||||
return __qdf_nbuf_is_tso(nbuf);
|
||||
}
|
||||
|
||||
/**
|
||||
* qdf_nbuf_get_tso_info() - function to divide a jumbo TSO
|
||||
* network buffer into segments
|
||||
@@ -2006,19 +2050,6 @@ static inline qdf_nbuf_t qdf_nbuf_inc_users(qdf_nbuf_t nbuf)
|
||||
return __qdf_nbuf_inc_users(nbuf);
|
||||
}
|
||||
|
||||
/**
|
||||
* qdf_nbuf_get_users() - function to get the number of users referencing this
|
||||
* network buffer
|
||||
*
|
||||
* @nbuf: network buffer
|
||||
*
|
||||
* Return: number of user references to nbuf.
|
||||
*/
|
||||
static inline int qdf_nbuf_get_users(qdf_nbuf_t nbuf)
|
||||
{
|
||||
return __qdf_nbuf_get_users(nbuf);
|
||||
}
|
||||
|
||||
/**
|
||||
* qdf_nbuf_data_attr_get() - Get data_attr field from cvg_nbuf_cb
|
||||
*
|
||||
|
@@ -116,7 +116,6 @@ typedef union {
|
||||
* @tx.trace : combined structure for DP and protocol trace
|
||||
* @tx.trace.packet_state: {NBUF_TX_PKT_[(HDD)|(TXRX_ENQUEUE)|(TXRX_DEQUEUE)|
|
||||
* + (TXRX)|(HTT)|(HTC)|(HIF)|(CE)|(FREE)]
|
||||
* @tx.trace.is_packet_priv: flag, pkt generated internally or come from NS
|
||||
* @tx.trace.packet_track: {NBUF_TX_PKT_[(DATA)|(MGMT)]_TRACK}
|
||||
* @tx.trace.proto_type : bitmap of NBUF_PKT_TRAC_TYPE[(EAPOL)|(DHCP)|
|
||||
* + (MGMT_ACTION)] - 4 bits
|
||||
@@ -186,8 +185,7 @@ struct qdf_nbuf_cb {
|
||||
struct {
|
||||
uint32_t data_attr; /* 4 bytes */
|
||||
struct{
|
||||
uint8_t packet_state:7,
|
||||
is_packet_priv:1;
|
||||
uint8_t packet_state;
|
||||
uint8_t packet_track:4,
|
||||
proto_type:4;
|
||||
uint8_t dp_trace:1,
|
||||
@@ -286,9 +284,6 @@ struct qdf_nbuf_cb {
|
||||
#define QDF_NBUF_CB_TX_PACKET_STATE(skb) \
|
||||
(((struct qdf_nbuf_cb *) \
|
||||
((skb)->cb))->u.tx.dev.mcl.trace.packet_state)
|
||||
#define QDF_NBUF_CB_TX_IS_PACKET_PRIV(skb) \
|
||||
(((struct qdf_nbuf_cb *) \
|
||||
((skb)->cb))->u.tx.dev.mcl.trace.is_packet_priv)
|
||||
#define QDF_NBUF_CB_TX_PACKET_TRACK(skb) \
|
||||
(((struct qdf_nbuf_cb *) \
|
||||
((skb)->cb))->u.tx.dev.mcl.trace.packet_track)
|
||||
@@ -540,7 +535,6 @@ void __qdf_nbuf_unmap_nbytes_single(
|
||||
void __qdf_nbuf_dma_map_info(__qdf_dma_map_t bmap, qdf_dmamap_info_t *sg);
|
||||
uint32_t __qdf_nbuf_get_frag_size(__qdf_nbuf_t nbuf, uint32_t cur_frag);
|
||||
void __qdf_nbuf_frag_info(struct sk_buff *skb, qdf_sglist_t *sg);
|
||||
void qdf_net_buf_debug_delete_node(struct sk_buff *net_buf);
|
||||
QDF_STATUS __qdf_nbuf_frag_map(
|
||||
qdf_device_t osdev, __qdf_nbuf_t nbuf,
|
||||
int offset, qdf_dma_dir_t dir, int cur_frag);
|
||||
@@ -966,27 +960,6 @@ static inline struct sk_buff *__qdf_nbuf_get_ext_list(struct sk_buff *head_buf)
|
||||
return (skb_shinfo(head_buf)->frag_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* __qdf_nbuf_tx_free() - free skb list
|
||||
* @skb: Pointer to network buffer
|
||||
* @tx_err: TX error
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
static inline void __qdf_nbuf_tx_free(struct sk_buff *bufs, int tx_err)
|
||||
{
|
||||
while (bufs) {
|
||||
struct sk_buff *next = __qdf_nbuf_next(bufs);
|
||||
|
||||
if (QDF_NBUF_CB_TX_IS_PACKET_PRIV(bufs)) {
|
||||
if (qdf_likely(bufs))
|
||||
qdf_net_buf_debug_delete_node(bufs);
|
||||
}
|
||||
__qdf_nbuf_free(bufs);
|
||||
bufs = next;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* __qdf_nbuf_get_age() - return the checksum value of the skb
|
||||
* @skb: Pointer to network buffer
|
||||
|
@@ -1477,6 +1477,7 @@ void qdf_net_buf_debug_add_node(qdf_nbuf_t net_buf, size_t size,
|
||||
"Mem alloc failed ! Could not track skb from %s %d of size %zu",
|
||||
file_name, line_num, size);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&g_qdf_net_buf_track_lock[i], irq_flag);
|
||||
|
||||
return;
|
||||
@@ -1540,6 +1541,26 @@ done:
|
||||
}
|
||||
EXPORT_SYMBOL(qdf_net_buf_debug_delete_node);
|
||||
|
||||
void qdf_net_buf_debug_acquire_skb(qdf_nbuf_t net_buf,
|
||||
uint8_t *file_name, uint32_t line_num)
|
||||
{
|
||||
qdf_nbuf_t ext_list = qdf_nbuf_get_ext_list(net_buf);
|
||||
|
||||
while (ext_list) {
|
||||
/*
|
||||
* Take care to add if it is Jumbo packet connected using
|
||||
* frag_list
|
||||
*/
|
||||
qdf_nbuf_t next;
|
||||
|
||||
next = qdf_nbuf_queue_next(ext_list);
|
||||
qdf_net_buf_debug_add_node(ext_list, 0, file_name, line_num);
|
||||
ext_list = next;
|
||||
}
|
||||
qdf_net_buf_debug_add_node(net_buf, 0, file_name, line_num);
|
||||
}
|
||||
EXPORT_SYMBOL(qdf_net_buf_debug_acquire_skb);
|
||||
|
||||
/**
|
||||
* qdf_net_buf_debug_release_skb() - release skb to avoid memory leak
|
||||
* @net_buf: Network buf holding head segment (single)
|
||||
@@ -1569,13 +1590,7 @@ void qdf_net_buf_debug_release_skb(qdf_nbuf_t net_buf)
|
||||
}
|
||||
EXPORT_SYMBOL(qdf_net_buf_debug_release_skb);
|
||||
|
||||
#else
|
||||
void qdf_net_buf_debug_delete_node(qdf_nbuf_t net_buf)
|
||||
{
|
||||
}
|
||||
EXPORT_SYMBOL(qdf_net_buf_debug_delete_node);
|
||||
#endif /*MEMORY_DEBUG */
|
||||
|
||||
#if defined(FEATURE_TSO)
|
||||
|
||||
/**
|
||||
|
Ссылка в новой задаче
Block a user