Merge "[qca-nss-drv] kmemleak-Fix false positives by adding references"
diff --git a/Makefile b/Makefile
index 9f0f072..08ce191 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
##########################################################################
-# Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+# Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
# Permission to use, copy, modify, and/or distribute this software for
# any purpose with or without fee is hereby granted, provided that the
# above copyright notice and this permission notice appear in all copies.
@@ -58,7 +58,7 @@
PM_SUPPORT := 0
-ccflags-y += -I$(obj)/nss_hal/include -I$(obj)/exports -DNSS_DEBUG_LEVEL=0 -DNSS_EMPTY_BUFFER_SIZE=1792 -DNSS_PKT_STATS_ENABLED=0
+ccflags-y += -I$(obj)/nss_hal/include -I$(obj)/exports -DNSS_DEBUG_LEVEL=0 -DNSS_EMPTY_BUFFER_SIZE=1792 -DNSS_PKT_STATS_ENABLED=1
ccflags-y += -DNSS_PM_DEBUG_LEVEL=0
ifneq ($(findstring 3.4, $(KERNELVERSION)),)
diff --git a/nss_core.c b/nss_core.c
index 44ff83b..b0cb03d 100755
--- a/nss_core.c
+++ b/nss_core.c
@@ -1,6 +1,6 @@
/*
**************************************************************************
- * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
@@ -49,6 +49,11 @@
static struct nss_rx_cb_list nss_rx_interface_handlers[NSS_MAX_NET_INTERFACES];
+#ifdef CONFIG_DEBUG_KMEMLEAK
+struct sk_buff_head nss_skb_list;
+#endif
+
+
/*
* nss_core_set_jumbo_mru()
* Set the jumbo_mru to the specified value
@@ -301,6 +306,18 @@
nss_phys_if_rx_callback_t cb;
struct nss_subsystem_dataplane_register *subsys_dp_reg = &nss_top->subsys_dp_register[interface_num];
+
+#ifdef CONFIG_DEBUG_KMEMLEAK
+ /*
+ * Tracking for kmemleak: Remove the skb from the nss_skb_list
+ */
+ spin_lock_bh(&nss_skb_list.lock);
+ __skb_unlink(nbuf, &nss_skb_list);
+ spin_unlock_bh(&nss_skb_list.lock);
+#endif
+
+ NSS_PKT_STATS_DECREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_NSS_SKB_COUNT]);
+
switch (buffer_type) {
case N2H_BUFFER_SHAPER_BOUNCED_INTERFACE:
{
@@ -879,7 +896,7 @@
opaque = desc->opaque;
bit_flags = desc->bit_flags;
if (unlikely((buffer_type == N2H_BUFFER_CRYPTO_RESP))) {
- NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_top->stats_drv[NSS_STATS_DRV_RX_CRYPTO_RESP]);
+ NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_RX_CRYPTO_RESP]);
/*
* This is a crypto buffer hence send it to crypto driver
*
@@ -900,7 +917,7 @@
* Invalid opaque pointer
*/
nss_dump_desc(nss_ctx, desc);
- NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_top->stats_drv[NSS_STATS_DRV_RX_BAD_DESCRIPTOR]);
+ NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_RX_BAD_DESCRIPTOR]);
goto next;
}
@@ -949,6 +966,17 @@
if (unlikely(head)) {
nss_warning("%p: we should not have an incomplete paged skb while"
" constructing a linear skb %p", nbuf, head);
+
+#ifdef CONFIG_DEBUG_KMEMLEAK
+ /*
+ * Tracking for kmemleak: Remove the skb from the nss_skb_list
+ */
+ spin_lock_bh(&nss_skb_list.lock);
+ __skb_unlink(head, &nss_skb_list);
+ spin_unlock_bh(&nss_skb_list.lock);
+#endif
+
+ NSS_PKT_STATS_DECREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_NSS_SKB_COUNT]);
dev_kfree_skb_any(head);
head = NULL;
goto next;
@@ -968,6 +996,17 @@
if (unlikely(jumbo_start)) {
nss_warning("%p: we should not have an incomplete linear skb while"
" constructing a paged skb %p", nbuf, jumbo_start);
+
+#ifdef CONFIG_DEBUG_KMEMLEAK
+ /*
+ * Tracking for kmemleak: Remove the skb from the nss_skb_list
+ */
+ spin_lock_bh(&nss_skb_list.lock);
+ __skb_unlink(jumbo_start, &nss_skb_list);
+ spin_unlock_bh(&nss_skb_list.lock);
+#endif
+
+ NSS_PKT_STATS_DECREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_NSS_SKB_COUNT]);
dev_kfree_skb_any(jumbo_start);
jumbo_start = NULL;
goto next;
@@ -1241,6 +1280,16 @@
break;
}
+#ifdef CONFIG_DEBUG_KMEMLEAK
+ /*
+ * Tracking for kmemleak because skbs dont have references.
+ */
+ spin_lock_bh(&nss_skb_list.lock);
+ __skb_queue_head(&nss_skb_list, nbuf);
+ spin_unlock_bh(&nss_skb_list.lock);
+#endif
+
+ NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_NSS_SKB_COUNT]);
desc->opaque = (uint32_t)nbuf;
desc->buffer = buffer;
desc->buffer_type = H2N_BUFFER_EMPTY;
@@ -1899,6 +1948,16 @@
h2n_desc_ring->hlos_index = hlos_index;
if_map->h2n_hlos_index[qid] = hlos_index;
+#ifdef CONFIG_DEBUG_KMEMLEAK
+ /*
+ * Tracking for kmemleak because skbs dont have references.
+ */
+ spin_lock_bh(&nss_skb_list.lock);
+ __skb_queue_head(&nss_skb_list, nbuf);
+ spin_unlock_bh(&nss_skb_list.lock);
+#endif
+
+ NSS_PKT_STATS_INCREMENT(nss_ctx, &nss_ctx->nss_top->stats_drv[NSS_STATS_DRV_NSS_SKB_COUNT]);
spin_unlock_bh(&h2n_desc_ring->lock);
return NSS_CORE_STATUS_SUCCESS;
}
diff --git a/nss_core.h b/nss_core.h
index 20f3628..d088084 100755
--- a/nss_core.h
+++ b/nss_core.h
@@ -88,6 +88,7 @@
#if (NSS_PKT_STATS_ENABLED == 1)
#define NSS_PKT_STATS_INCREMENT(nss_ctx, x) nss_pkt_stats_increment((nss_ctx), (x))
+#define NSS_PKT_STATS_DECREMENT(nss_ctx, x) nss_pkt_stats_decrement((nss_ctx), (x))
#else
#define NSS_PKT_STATS_INCREMENT(nss_ctx, x)
#endif
@@ -314,6 +315,7 @@
NSS_STATS_DRV_RX_NR_FRAGS, /* N2H NR Frags SKB Packets */
NSS_STATS_DRV_RX_SKB_FRAGLIST, /* N2H Fraglist SKB Packets */
NSS_STATS_DRV_RX_BAD_DESCRIPTOR, /* N2H Bad descriptor reads */
+ NSS_STATS_DRV_NSS_SKB_COUNT,
NSS_STATS_DRV_MAX,
};
@@ -702,6 +704,17 @@
*stat = *stat + 1;
spin_unlock_bh(&nss_ctx->nss_top->stats_lock);
}
+
+/*
+ * nss_pkt_stats_increment()
+ */
+static inline void nss_pkt_stats_decrement(struct nss_ctx_instance *nss_ctx, uint64_t *stat)
+{
+ spin_lock_bh(&nss_ctx->nss_top->stats_lock);
+ *stat = *stat - 1;
+ spin_unlock_bh(&nss_ctx->nss_top->stats_lock);
+}
+
#endif
/*
diff --git a/nss_init.c b/nss_init.c
index 29203b2..f9ca687 100755
--- a/nss_init.c
+++ b/nss_init.c
@@ -68,6 +68,10 @@
int nss_jumbo_mru __read_mostly = 0;
int nss_paged_mode __read_mostly = 0;
+#ifdef CONFIG_DEBUG_KMEMLEAK
+extern struct sk_buff_head nss_skb_list;
+#endif
+
/*
* PM client handle
*/
@@ -1376,6 +1380,15 @@
nss_ipv4_register_sysctl();
nss_ipv6_register_sysctl();
+#ifdef CONFIG_DEBUG_KMEMLEAK
+ /*
+ * If the system is under kmemleak debugging, track our
+ * skbs by putting them in a list.
+ */
+
+ skb_queue_head_init(&nss_skb_list);
+#endif
+
#if (NSS_PM_SUPPORT == 1)
/*
* Setup Runtime Sample values
diff --git a/nss_stats.c b/nss_stats.c
index 15a91af..2864c9e 100644
--- a/nss_stats.c
+++ b/nss_stats.c
@@ -1,6 +1,6 @@
/*
**************************************************************************
- * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
@@ -160,7 +160,8 @@
"rx_skb_simple",
"rx_skb_nr_frags",
"rx_skb_fraglist",
- "rx_bad_desciptor"
+ "rx_bad_desciptor",
+ "nss_skb_count"
};
/*