[PATCH 8/9] staging: ozwpan: Added debug support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Added tracing facilities and also memory allocation and URB tracking.
This is for debugging purposes and is all optional and can be switched
out at compile time.

Signed-off-by: Chris Kelly <ckelly@xxxxxxxxxxxxxxx>
---
 drivers/staging/ozwpan/ozalloc.c       |  107 ++++++++++++++++++++++++++++++++
 drivers/staging/ozwpan/ozalloc.h       |   28 ++++++++
 drivers/staging/ozwpan/oztrace.c       |   36 +++++++++++
 drivers/staging/ozwpan/oztrace.h       |   35 ++++++++++
 drivers/staging/ozwpan/ozurbparanoia.c |   53 ++++++++++++++++
 drivers/staging/ozwpan/ozurbparanoia.h |   19 ++++++
 6 files changed, 278 insertions(+), 0 deletions(-)
 create mode 100644 drivers/staging/ozwpan/ozalloc.c
 create mode 100644 drivers/staging/ozwpan/ozalloc.h
 create mode 100644 drivers/staging/ozwpan/oztrace.c
 create mode 100644 drivers/staging/ozwpan/oztrace.h
 create mode 100644 drivers/staging/ozwpan/ozurbparanoia.c
 create mode 100644 drivers/staging/ozwpan/ozurbparanoia.h

diff --git a/drivers/staging/ozwpan/ozalloc.c b/drivers/staging/ozwpan/ozalloc.c
new file mode 100644
index 0000000..fe3cd40
--- /dev/null
+++ b/drivers/staging/ozwpan/ozalloc.c
@@ -0,0 +1,107 @@
+/* -----------------------------------------------------------------------------
+ * Copyright (c) 2011 Ozmo Inc
+ * Released under the GNU General Public License Version 2 (GPLv2).
+ * This file contains debug allocation and free functions. These are turned on
+ * by the configuration switch WANT_DEBUG_KMALLOC. This flags should be turned
+ * off in the release version but facilitate memory leak and corruption during
+ * development.
+ * -----------------------------------------------------------------------------
+ */
+#include <linux/module.h>
+#include "ozconfig.h"
+#include "ozalloc.h"
+#include "oztrace.h"
+#ifdef WANT_DEBUG_KMALLOC
+/*------------------------------------------------------------------------------
+ */
+#define MAGIC_1	0x12848796
+#define MAGIC_2	0x87465920
+#define MAGIC_3	0x80288264
+/*------------------------------------------------------------------------------
+ */
+struct oz_alloc_hdr {
+	int size;
+	int line;
+	unsigned magic;
+	struct list_head link;
+};
+/*------------------------------------------------------------------------------
+ */
+static unsigned long g_total_alloc_size;
+static int g_alloc_count;
+static DEFINE_SPINLOCK(g_alloc_lock);
+static LIST_HEAD(g_alloc_list);
+/*------------------------------------------------------------------------------
+ * Context: any
+ */
+void *oz_alloc_debug(size_t size, gfp_t flags, int line)
+{
+	struct oz_alloc_hdr *hdr = (struct oz_alloc_hdr *)
+		kmalloc(size + sizeof(struct oz_alloc_hdr) +
+			sizeof(unsigned), flags);
+	if (hdr) {
+		unsigned long irq_state;
+		hdr->size = size;
+		hdr->line = line;
+		hdr->magic = MAGIC_1;
+		*(unsigned *)(((u8 *)(hdr + 1)) + size) = MAGIC_2;
+		spin_lock_irqsave(&g_alloc_lock, irq_state);
+		g_total_alloc_size += size;
+		g_alloc_count++;
+		list_add_tail(&hdr->link, &g_alloc_list);
+		spin_unlock_irqrestore(&g_alloc_lock, irq_state);
+		return hdr + 1;
+	}
+	return 0;
+}
+/*------------------------------------------------------------------------------
+ * Context: any
+ */
+void oz_free_debug(void *p)
+{
+	if (p) {
+		struct oz_alloc_hdr *hdr = (struct oz_alloc_hdr *)
+			(((unsigned char *)p) - sizeof(struct oz_alloc_hdr));
+		if (hdr->magic == MAGIC_1) {
+			unsigned long irq_state;
+			if (*(unsigned *)(((u8 *)(hdr + 1)) + hdr->size)
+				!= MAGIC_2) {
+				oz_trace("oz_free_debug: Corrupted beyond"
+					" %p size %d\n", hdr+1, hdr->size);
+				return;
+			}
+			spin_lock_irqsave(&g_alloc_lock, irq_state);
+			g_total_alloc_size -= hdr->size;
+			g_alloc_count--;
+			list_del(&hdr->link);
+			spin_unlock_irqrestore(&g_alloc_lock, irq_state);
+			hdr->magic = MAGIC_3;
+			kfree(hdr);
+		} else {
+			oz_trace("oz_free_debug: Invalid magic number %u\n",
+				hdr->magic);
+		}
+	}
+}
+/*------------------------------------------------------------------------------
+ * Context: process
+ */
+void oz_trace_leaks(void)
+{
+#ifdef WANT_TRACE
+	struct list_head *e;
+	oz_trace("Total alloc size:%ld  Alloc count:%d\n",
+			g_total_alloc_size, g_alloc_count);
+	if (g_alloc_count)
+		oz_trace("Trace of leaks.\n");
+	else
+		oz_trace("No memory leaks.\n");
+	list_for_each(e, &g_alloc_list) {
+		struct oz_alloc_hdr *hdr =
+			container_of(e, struct oz_alloc_hdr, link);
+		oz_trace("LEAK size %d line %d\n", hdr->size, hdr->line);
+	}
+#endif /* #ifdef WANT_TRACE */
+}
+#endif /* #ifdef WANT_DEBUG_KMALLOC */
+
diff --git a/drivers/staging/ozwpan/ozalloc.h b/drivers/staging/ozwpan/ozalloc.h
new file mode 100644
index 0000000..11a7a16
--- /dev/null
+++ b/drivers/staging/ozwpan/ozalloc.h
@@ -0,0 +1,28 @@
+/* -----------------------------------------------------------------------------
+ * Copyright (c) 2011 Ozmo Inc
+ * Released under the GNU General Public License Version 2 (GPLv2).
+ * -----------------------------------------------------------------------------
+ */
+#ifndef _OZALLOC_H
+#define _OZALLOC_H
+
+#include <linux/slab.h>
+
+#ifdef WANT_DEBUG_KMALLOC
+
+void *oz_alloc_debug(size_t size, gfp_t flags, int line);
+void oz_free_debug(void *p);
+void oz_trace_leaks(void);
+#define oz_alloc(__s, __f)	oz_alloc_debug(__s, __f, __LINE__)
+#define oz_free			oz_free_debug
+
+#else
+
+
+#define oz_alloc	kmalloc
+#define oz_free		kfree
+#define oz_trace_leaks()
+
+#endif /* #ifdef WANT_DEBUG_KMALLOC */
+
+#endif /* _OZALLOC_H */
diff --git a/drivers/staging/ozwpan/oztrace.c b/drivers/staging/ozwpan/oztrace.c
new file mode 100644
index 0000000..353ead2
--- /dev/null
+++ b/drivers/staging/ozwpan/oztrace.c
@@ -0,0 +1,36 @@
+/* -----------------------------------------------------------------------------
+ * Copyright (c) 2011 Ozmo Inc
+ * Released under the GNU General Public License Version 2 (GPLv2).
+ * -----------------------------------------------------------------------------
+ */
+#include "ozconfig.h"
+#include "oztrace.h"
+
+#ifdef WANT_VERBOSE_TRACE
+unsigned long trace_flags =
+	0
+#ifdef WANT_TRACE_STREAM
+	| OZ_TRACE_STREAM
+#endif /* WANT_TRACE_STREAM */
+#ifdef WANT_TRACE_URB
+	| OZ_TRACE_URB
+#endif /* WANT_TRACE_URB */
+
+#ifdef WANT_TRACE_CTRL_DETAIL
+	| OZ_TRACE_CTRL_DETAIL
+#endif /* WANT_TRACE_CTRL_DETAIL */
+
+#ifdef WANT_TRACE_HUB
+	| OZ_TRACE_HUB
+#endif /* WANT_TRACE_HUB */
+
+#ifdef WANT_TRACE_RX_FRAMES
+	| OZ_TRACE_RX_FRAMES
+#endif /* WANT_TRACE_RX_FRAMES */
+
+#ifdef WANT_TRACE_TX_FRAMES
+	| OZ_TRACE_TX_FRAMES
+#endif /* WANT_TRACE_TX_FRAMES */
+	;
+#endif /* WANT_VERBOSE_TRACE */
+
diff --git a/drivers/staging/ozwpan/oztrace.h b/drivers/staging/ozwpan/oztrace.h
new file mode 100644
index 0000000..8293b24
--- /dev/null
+++ b/drivers/staging/ozwpan/oztrace.h
@@ -0,0 +1,35 @@
+/* -----------------------------------------------------------------------------
+ * Copyright (c) 2011 Ozmo Inc
+ * Released under the GNU General Public License Version 2 (GPLv2).
+ * -----------------------------------------------------------------------------
+ */
+#ifndef _OZTRACE_H_
+#define _OZTRACE_H_
+#include "ozconfig.h"
+
+#define TRACE_PREFIX	KERN_ALERT "OZWPAN: "
+
+#ifdef WANT_TRACE
+#define oz_trace(...) printk(TRACE_PREFIX __VA_ARGS__)
+#ifdef WANT_VERBOSE_TRACE
+extern unsigned long trace_flags;
+#define oz_trace2(_flag, ...) \
+	do { if (trace_flags & _flag) printk(TRACE_PREFIX __VA_ARGS__); \
+	} while (0)
+#else
+#define oz_trace2(...)
+#endif /* #ifdef WANT_VERBOSE_TRACE */
+#else
+#define oz_trace(...)
+#define oz_trace2(...)
+#endif /* #ifdef WANT_TRACE */
+
+#define OZ_TRACE_STREAM		0x1
+#define OZ_TRACE_URB		0x2
+#define OZ_TRACE_CTRL_DETAIL	0x4
+#define OZ_TRACE_HUB		0x8
+#define OZ_TRACE_RX_FRAMES	0x10
+#define OZ_TRACE_TX_FRAMES	0x20
+
+#endif /* Sentry */
+
diff --git a/drivers/staging/ozwpan/ozurbparanoia.c b/drivers/staging/ozwpan/ozurbparanoia.c
new file mode 100644
index 0000000..55b9afb
--- /dev/null
+++ b/drivers/staging/ozwpan/ozurbparanoia.c
@@ -0,0 +1,53 @@
+/* -----------------------------------------------------------------------------
+ * Copyright (c) 2011 Ozmo Inc
+ * Released under the GNU General Public License Version 2 (GPLv2).
+ * -----------------------------------------------------------------------------
+ */
+#include <linux/usb.h>
+#include "ozconfig.h"
+#ifdef WANT_URB_PARANOIA
+#include "ozurbparanoia.h"
+#include "oztrace.h"
+/*-----------------------------------------------------------------------------
+ */
+#define OZ_MAX_URBS	1000
+struct urb *g_urb_memory[OZ_MAX_URBS];
+int g_nb_urbs;
+DEFINE_SPINLOCK(g_urb_mem_lock);
+/*-----------------------------------------------------------------------------
+ */
+void oz_remember_urb(struct urb *urb)
+{
+	unsigned long irq_state;
+	spin_lock_irqsave(&g_urb_mem_lock, irq_state);
+	if (g_nb_urbs < OZ_MAX_URBS) {
+		g_urb_memory[g_nb_urbs++] = urb;
+		oz_trace("%lu: urb up = %d %p\n", jiffies, g_nb_urbs, urb);
+	} else {
+		oz_trace("ERROR urb buffer full\n");
+	}
+	spin_unlock_irqrestore(&g_urb_mem_lock, irq_state);
+}
+/*------------------------------------------------------------------------------
+ */
+int oz_forget_urb(struct urb *urb)
+{
+	unsigned long irq_state;
+	int i;
+	int rc = -1;
+	spin_lock_irqsave(&g_urb_mem_lock, irq_state);
+	for (i = 0; i < g_nb_urbs; i++) {
+		if (g_urb_memory[i] == urb) {
+			rc = 0;
+			if (--g_nb_urbs > i)
+				memcpy(&g_urb_memory[i], &g_urb_memory[i+1],
+					(g_nb_urbs - i) * sizeof(struct urb *));
+			oz_trace("%lu: urb down = %d %p\n",
+				jiffies, g_nb_urbs, urb);
+		}
+	}
+	spin_unlock_irqrestore(&g_urb_mem_lock, irq_state);
+	return rc;
+}
+#endif /* #ifdef WANT_URB_PARANOIA */
+
diff --git a/drivers/staging/ozwpan/ozurbparanoia.h b/drivers/staging/ozwpan/ozurbparanoia.h
new file mode 100644
index 0000000..00f5a3a
--- /dev/null
+++ b/drivers/staging/ozwpan/ozurbparanoia.h
@@ -0,0 +1,19 @@
+#ifndef _OZURBPARANOIA_H
+#define _OZURBPARANOIA_H
+/* -----------------------------------------------------------------------------
+ * Released under the GNU General Public License Version 2 (GPLv2).
+ * Copyright (c) 2011 Ozmo Inc
+ * -----------------------------------------------------------------------------
+ */
+
+#ifdef WANT_URB_PARANOIA
+void oz_remember_urb(struct urb *urb);
+int oz_forget_urb(struct urb *urb);
+#else
+#define oz_remember_urb(__x)
+#define oz_forget_urb(__x)	0
+#endif /* WANT_URB_PARANOIA */
+
+
+#endif /* _OZURBPARANOIA_H */
+
-- 
1.7.7.6


--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux