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
Этот коммит содержится в:
Himanshu Agarwal
2017-04-04 19:15:30 +05:30
коммит произвёл Sandeep Puligilla
родитель a47828dd20
Коммит 33d0d707bd
3 изменённых файлов: 92 добавлений и 73 удалений

Просмотреть файл

@@ -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)
/**