[PATCH 1/3] kobject: add kobject trace points

From: Shuah Khan
Date: Tue Sep 06 2016 - 13:49:37 EST


Add kobject trace points to track kobject operations: init, add, set_name,
init_and_add, create_and_add, move, rename, get, put, cleanup, and del.

Kobject trace points can aid in debugging, generating status and graphs
on kobjects in the kernel and their hierarchy.

Signed-off-by: Shuah Khan <shuahkh@xxxxxxxxxxxxxxx>
---
include/trace/events/kobject.h | 259 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 259 insertions(+)
create mode 100644 include/trace/events/kobject.h

diff --git a/include/trace/events/kobject.h b/include/trace/events/kobject.h
new file mode 100644
index 0000000..6a29665
--- /dev/null
+++ b/include/trace/events/kobject.h
@@ -0,0 +1,259 @@
+/*
+ * kobject trace points
+ *
+ * Copyright (C) 2016 Shuah Khan <shuahkh@xxxxxxxxxxxxxxx>
+ *
+ */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM kobject
+
+#if !defined(_TRACE_KOBJECT_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_KOBJECT_H
+
+#include <linux/tracepoint.h>
+#include <linux/kobject.h>
+
+/* kobject_init_class */
+DECLARE_EVENT_CLASS(kobject_init_class,
+
+ TP_PROTO(struct kobject *kobj),
+
+ TP_ARGS(kobj),
+
+ TP_STRUCT__entry(
+ __field(void *, kobj)
+ __field(int, state_initialized)
+ ),
+
+ TP_fast_assign(
+ __entry->kobj = kobj;
+ __entry->state_initialized = kobj->state_initialized;
+ ),
+
+ TP_printk("KOBJECT: %p state=%d",
+ __entry->kobj,
+ __entry->state_initialized
+ ));
+
+/**
+ * kobject_init - called from kobject_init() when kobject is initialized
+ * @kobj: - pointer to struct kobject
+ */
+DEFINE_EVENT(kobject_init_class, kobject_init,
+
+ TP_PROTO(struct kobject *kobj),
+ TP_ARGS(kobj));
+
+/* kobject_class */
+DECLARE_EVENT_CLASS(kobject_class,
+
+ TP_PROTO(struct kobject *kobj),
+ TP_ARGS(kobj),
+
+ TP_STRUCT__entry(
+ __field(void *, kobj)
+ __string(name, kobject_name(kobj))
+ __field(int, state_initialized)
+ __field(void *, parent)
+ __string(pname, kobj->parent ? kobject_name(kobj->parent) : "")
+ __field(int, count)
+ ),
+
+ TP_fast_assign(
+ __entry->kobj = kobj;
+ __assign_str(name, kobject_name(kobj));
+ __entry->state_initialized = kobj->state_initialized;
+ __entry->parent = kobj->parent;
+ __assign_str(pname,
+ kobj->parent ? kobject_name(kobj->parent) : "");
+ __entry->count = atomic_read(&kobj->kref.refcount);
+ ),
+
+ TP_printk("KOBJECT: %s (%p) state=%d parent= %s (%p) counter= %d",
+ __get_str(name),
+ __entry->kobj,
+ __entry->state_initialized,
+ __get_str(pname),
+ __entry->parent,
+ __entry->count
+ ));
+
+/**
+ * kobject_add - called from kobject_add() when kobject is added
+ * @kobj: - pointer to struct kobject
+ */
+DEFINE_EVENT(kobject_class, kobject_add,
+
+ TP_PROTO(struct kobject *kobj),
+ TP_ARGS(kobj));
+
+/**
+ * kobject_init_and_add - called from kobject_init_and_add()
+ * @kobj: - pointer to struct kobject
+ */
+DEFINE_EVENT(kobject_class, kobject_init_and_add,
+
+ TP_PROTO(struct kobject *kobj),
+ TP_ARGS(kobj));
+
+/**
+ * kobject_create_and_add - called from kobject_create_and_add()
+ * @kobj: - pointer to struct kobject
+ */
+DEFINE_EVENT(kobject_class, kobject_create_and_add,
+
+ TP_PROTO(struct kobject *kobj),
+ TP_ARGS(kobj));
+
+/**
+ * kobject_set_name - called from kobject_set_name()
+ * @kobj: - pointer to struct kobject
+ */
+DEFINE_EVENT(kobject_class, kobject_set_name,
+
+ TP_PROTO(struct kobject *kobj),
+ TP_ARGS(kobj));
+
+/**
+ * kobject_del - called from kobject_del()
+ * @kobj: - pointer to struct kobject
+ */
+DEFINE_EVENT(kobject_class, kobject_del,
+
+ TP_PROTO(struct kobject *kobj),
+ TP_ARGS(kobj));
+
+/**
+ * kobject_cleanup - called from kobject_cleanup()
+ * @kobj: - pointer to struct kobject
+ */
+DEFINE_EVENT(kobject_class, kobject_cleanup,
+
+ TP_PROTO(struct kobject *kobj),
+ TP_ARGS(kobj));
+/**
+ * kobject_get - called from kobject_get()
+ * @kobj: - pointer to struct kobject
+ */
+DEFINE_EVENT(kobject_class, kobject_get,
+
+ TP_PROTO(struct kobject *kobj),
+ TP_ARGS(kobj));
+
+/**
+ * kobject_put - called from kobject_put()
+ * @kobj: - pointer to struct kobject
+ *
+ * Trace is called before kref_put() to avoid use-after-free on kobj, in case
+ * kobject is released. Decrement the counter before printing the value.
+ */
+TRACE_EVENT(kobject_put,
+
+ TP_PROTO(struct kobject *kobj),
+ TP_ARGS(kobj),
+
+ TP_STRUCT__entry(
+ __field(void *, kobj)
+ __string(name, kobject_name(kobj))
+ __field(int, state_initialized)
+ __field(void *, parent)
+ __string(pname, kobj->parent ? kobject_name(kobj->parent) : "")
+ __field(int, count)
+ ),
+
+ TP_fast_assign(
+ __entry->kobj = kobj;
+ __assign_str(name, kobject_name(kobj));
+ __entry->state_initialized = kobj->state_initialized;
+ __entry->parent = kobj->parent;
+ __assign_str(pname,
+ kobj->parent ? kobject_name(kobj->parent) : "");
+ __entry->count = atomic_read(&kobj->kref.refcount) - 1;
+ ),
+
+ TP_printk("KOBJECT: %s (%p) state=%d parent= %s (%p) counter= %d",
+ __get_str(name),
+ __entry->kobj,
+ __entry->state_initialized,
+ __get_str(pname),
+ __entry->parent,
+ __entry->count
+ ));
+
+/* kobject_move_class */
+DECLARE_EVENT_CLASS(kobject_move_class,
+
+ TP_PROTO(struct kobject *kobj, struct kobject *old_parent),
+ TP_ARGS(kobj, old_parent),
+
+ TP_STRUCT__entry(
+ __field(void *, kobj)
+ __string(name, kobject_name(kobj))
+ __field(int, state_initialized)
+ __field(void *, parent)
+ __string(pname, kobj->parent ? kobject_name(kobj->parent) : "")
+ ),
+
+ TP_fast_assign(
+ __entry->kobj = kobj;
+ __assign_str(name, kobject_name(kobj));
+ __entry->state_initialized = kobj->state_initialized;
+ __entry->parent = kobj->parent;
+ __assign_str(pname,
+ kobj->parent ? kobject_name(kobj->parent) : "");
+ ),
+
+ TP_printk("KOBJECT: %s (%p) state=%d parent= %s (%p)",
+ __get_str(name),
+ __entry->kobj,
+ __entry->state_initialized,
+ __get_str(pname),
+ __entry->parent
+ ));
+
+/**
+ * kobject_move - called from kobject_move()
+ * @kobj: - pointer to struct kobject
+ */
+DEFINE_EVENT(kobject_move_class, kobject_move,
+
+ TP_PROTO(struct kobject *kobj, struct kobject *old_parent),
+ TP_ARGS(kobj, old_parent));
+
+/* kobject_rename_class */
+DECLARE_EVENT_CLASS(kobject_rename_class,
+
+ TP_PROTO(struct kobject *kobj, const char *old),
+ TP_ARGS(kobj, old),
+
+ TP_STRUCT__entry(
+ __field(void *, kobj)
+ __string(name, kobject_name(kobj))
+ __string(oldname, old)
+ ),
+
+ TP_fast_assign(
+ __entry->kobj = kobj;
+ __assign_str(name, kobject_name(kobj));
+ __assign_str(oldname, old);
+ ),
+
+ TP_printk("KOBJECT: %s (%p) oldname= %s",
+ __get_str(name),
+ __entry->kobj,
+ __get_str(oldname)
+ ));
+
+/**
+ * kobject_rename - called from kobject_rename()
+ * @kobj: - pointer to struct kobject
+ */
+DEFINE_EVENT(kobject_rename_class, kobject_rename,
+
+ TP_PROTO(struct kobject *kobj, const char *old),
+ TP_ARGS(kobj, old));
+
+#endif /* #if !defined(_TRACE_KOBJECT_H) ... */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
--
2.7.4