summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2018-04-04 13:41:27 +0100
committerDavid Howells <dhowells@redhat.com>2018-04-04 13:41:27 +0100
commita18feb55769b705a44c4107786c4045eae2e87b6 (patch)
tree3db7d160e672aa9f16a0437b767b3d3bbb10ecc8 /include
parent2c98425720233ae3e135add0c7e869b32913502f (diff)
fscache: Add tracepoints
Add some tracepoints to fscache: (*) fscache_cookie - Tracks a cookie's usage count. (*) fscache_netfs - Logs registration of a network filesystem, including the pointer to the cookie allocated. (*) fscache_acquire - Logs cookie acquisition. (*) fscache_relinquish - Logs cookie relinquishment. (*) fscache_enable - Logs enablement of a cookie. (*) fscache_disable - Logs disablement of a cookie. (*) fscache_osm - Tracks execution of states in the object state machine. and cachefiles: (*) cachefiles_ref - Tracks a cachefiles object's usage count. (*) cachefiles_lookup - Logs result of lookup_one_len(). (*) cachefiles_mkdir - Logs result of vfs_mkdir(). (*) cachefiles_create - Logs result of vfs_create(). (*) cachefiles_unlink - Logs calls to vfs_unlink(). (*) cachefiles_rename - Logs calls to vfs_rename(). (*) cachefiles_mark_active - Logs an object becoming active. (*) cachefiles_wait_active - Logs a wait for an old object to be destroyed. (*) cachefiles_mark_inactive - Logs an object becoming inactive. (*) cachefiles_mark_buried - Logs the burial of an object. Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'include')
-rw-r--r--include/linux/fscache-cache.h18
-rw-r--r--include/trace/events/cachefiles.h325
-rw-r--r--include/trace/events/fscache.h277
3 files changed, 618 insertions, 2 deletions
diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h
index b19fa8592fc2..fbe102f37074 100644
--- a/include/linux/fscache-cache.h
+++ b/include/linux/fscache-cache.h
@@ -29,6 +29,18 @@ struct fscache_cache_ops;
struct fscache_object;
struct fscache_operation;
+enum fscache_obj_ref_trace {
+ fscache_obj_get_add_to_deps,
+ fscache_obj_get_queue,
+ fscache_obj_put_alloc_fail,
+ fscache_obj_put_attach_fail,
+ fscache_obj_put_drop_obj,
+ fscache_obj_put_enq_dep,
+ fscache_obj_put_queue,
+ fscache_obj_put_work,
+ fscache_obj_ref__nr_traces
+};
+
/*
* cache tag definition
*/
@@ -231,7 +243,8 @@ struct fscache_cache_ops {
void (*lookup_complete)(struct fscache_object *object);
/* increment the usage count on this object (may fail if unmounting) */
- struct fscache_object *(*grab_object)(struct fscache_object *object);
+ struct fscache_object *(*grab_object)(struct fscache_object *object,
+ enum fscache_obj_ref_trace why);
/* pin an object in the cache */
int (*pin_object)(struct fscache_object *object);
@@ -254,7 +267,8 @@ struct fscache_cache_ops {
void (*drop_object)(struct fscache_object *object);
/* dispose of a reference to an object */
- void (*put_object)(struct fscache_object *object);
+ void (*put_object)(struct fscache_object *object,
+ enum fscache_obj_ref_trace why);
/* sync a cache */
void (*sync_cache)(struct fscache_cache *cache);
diff --git a/include/trace/events/cachefiles.h b/include/trace/events/cachefiles.h
new file mode 100644
index 000000000000..aa86e7dba511
--- /dev/null
+++ b/include/trace/events/cachefiles.h
@@ -0,0 +1,325 @@
+/* CacheFiles tracepoints
+ *
+ * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM cachefiles
+
+#if !defined(_TRACE_CACHEFILES_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_CACHEFILES_H
+
+#include <linux/tracepoint.h>
+
+/*
+ * Define enums for tracing information.
+ */
+#ifndef __CACHEFILES_DECLARE_TRACE_ENUMS_ONCE_ONLY
+#define __CACHEFILES_DECLARE_TRACE_ENUMS_ONCE_ONLY
+
+enum cachefiles_obj_ref_trace {
+ cachefiles_obj_put_wait_retry = fscache_obj_ref__nr_traces,
+ cachefiles_obj_put_wait_timeo,
+ cachefiles_obj_ref__nr_traces
+};
+
+#endif
+
+/*
+ * Define enum -> string mappings for display.
+ */
+#define cachefiles_obj_kill_traces \
+ EM(FSCACHE_OBJECT_IS_STALE, "stale") \
+ EM(FSCACHE_OBJECT_NO_SPACE, "no_space") \
+ EM(FSCACHE_OBJECT_WAS_RETIRED, "was_retired") \
+ E_(FSCACHE_OBJECT_WAS_CULLED, "was_culled")
+
+#define cachefiles_obj_ref_traces \
+ EM(fscache_obj_get_add_to_deps, "GET add_to_deps") \
+ EM(fscache_obj_get_queue, "GET queue") \
+ EM(fscache_obj_put_alloc_fail, "PUT alloc_fail") \
+ EM(fscache_obj_put_attach_fail, "PUT attach_fail") \
+ EM(fscache_obj_put_drop_obj, "PUT drop_obj") \
+ EM(fscache_obj_put_enq_dep, "PUT enq_dep") \
+ EM(fscache_obj_put_queue, "PUT queue") \
+ EM(fscache_obj_put_work, "PUT work") \
+ EM(cachefiles_obj_put_wait_retry, "PUT wait_retry") \
+ E_(cachefiles_obj_put_wait_timeo, "PUT wait_timeo")
+
+/*
+ * Export enum symbols via userspace.
+ */
+#undef EM
+#undef E_
+#define EM(a, b) TRACE_DEFINE_ENUM(a);
+#define E_(a, b) TRACE_DEFINE_ENUM(a);
+
+cachefiles_obj_kill_traces;
+cachefiles_obj_ref_traces;
+
+/*
+ * Now redefine the EM() and E_() macros to map the enums to the strings that
+ * will be printed in the output.
+ */
+#undef EM
+#undef E_
+#define EM(a, b) { a, b },
+#define E_(a, b) { a, b }
+
+
+TRACE_EVENT(cachefiles_ref,
+ TP_PROTO(struct cachefiles_object *obj,
+ struct fscache_cookie *cookie,
+ enum cachefiles_obj_ref_trace why,
+ int usage),
+
+ TP_ARGS(obj, cookie, why, usage),
+
+ /* Note that obj may be NULL */
+ TP_STRUCT__entry(
+ __field(struct cachefiles_object *, obj )
+ __field(struct fscache_cookie *, cookie )
+ __field(enum cachefiles_obj_ref_trace, why )
+ __field(int, usage )
+ ),
+
+ TP_fast_assign(
+ __entry->obj = obj;
+ __entry->cookie = cookie;
+ __entry->usage = usage;
+ __entry->why = why;
+ ),
+
+ TP_printk("c=%p o=%p u=%d %s",
+ __entry->cookie, __entry->obj, __entry->usage,
+ __print_symbolic(__entry->why, cachefiles_obj_ref_traces))
+ );
+
+TRACE_EVENT(cachefiles_lookup,
+ TP_PROTO(struct cachefiles_object *obj,
+ struct dentry *de,
+ struct inode *inode),
+
+ TP_ARGS(obj, de, inode),
+
+ TP_STRUCT__entry(
+ __field(struct cachefiles_object *, obj )
+ __field(struct dentry *, de )
+ __field(struct inode *, inode )
+ ),
+
+ TP_fast_assign(
+ __entry->obj = obj;
+ __entry->de = de;
+ __entry->inode = inode;
+ ),
+
+ TP_printk("o=%p d=%p i=%p",
+ __entry->obj, __entry->de, __entry->inode)
+ );
+
+TRACE_EVENT(cachefiles_mkdir,
+ TP_PROTO(struct cachefiles_object *obj,
+ struct dentry *de, int ret),
+
+ TP_ARGS(obj, de, ret),
+
+ TP_STRUCT__entry(
+ __field(struct cachefiles_object *, obj )
+ __field(struct dentry *, de )
+ __field(int, ret )
+ ),
+
+ TP_fast_assign(
+ __entry->obj = obj;
+ __entry->de = de;
+ __entry->ret = ret;
+ ),
+
+ TP_printk("o=%p d=%p r=%u",
+ __entry->obj, __entry->de, __entry->ret)
+ );
+
+TRACE_EVENT(cachefiles_create,
+ TP_PROTO(struct cachefiles_object *obj,
+ struct dentry *de, int ret),
+
+ TP_ARGS(obj, de, ret),
+
+ TP_STRUCT__entry(
+ __field(struct cachefiles_object *, obj )
+ __field(struct dentry *, de )
+ __field(int, ret )
+ ),
+
+ TP_fast_assign(
+ __entry->obj = obj;
+ __entry->de = de;
+ __entry->ret = ret;
+ ),
+
+ TP_printk("o=%p d=%p r=%u",
+ __entry->obj, __entry->de, __entry->ret)
+ );
+
+TRACE_EVENT(cachefiles_unlink,
+ TP_PROTO(struct cachefiles_object *obj,
+ struct dentry *de,
+ enum fscache_why_object_killed why),
+
+ TP_ARGS(obj, de, why),
+
+ /* Note that obj may be NULL */
+ TP_STRUCT__entry(
+ __field(struct cachefiles_object *, obj )
+ __field(struct dentry *, de )
+ __field(enum fscache_why_object_killed, why )
+ ),
+
+ TP_fast_assign(
+ __entry->obj = obj;
+ __entry->de = de;
+ __entry->why = why;
+ ),
+
+ TP_printk("o=%p d=%p w=%s",
+ __entry->obj, __entry->de,
+ __print_symbolic(__entry->why, cachefiles_obj_kill_traces))
+ );
+
+TRACE_EVENT(cachefiles_rename,
+ TP_PROTO(struct cachefiles_object *obj,
+ struct dentry *de,
+ struct dentry *to,
+ enum fscache_why_object_killed why),
+
+ TP_ARGS(obj, de, to, why),
+
+ /* Note that obj may be NULL */
+ TP_STRUCT__entry(
+ __field(struct cachefiles_object *, obj )
+ __field(struct dentry *, de )
+ __field(struct dentry *, to )
+ __field(enum fscache_why_object_killed, why )
+ ),
+
+ TP_fast_assign(
+ __entry->obj = obj;
+ __entry->de = de;
+ __entry->to = to;
+ __entry->why = why;
+ ),
+
+ TP_printk("o=%p d=%p t=%p w=%s",
+ __entry->obj, __entry->de, __entry->to,
+ __print_symbolic(__entry->why, cachefiles_obj_kill_traces))
+ );
+
+TRACE_EVENT(cachefiles_mark_active,
+ TP_PROTO(struct cachefiles_object *obj,
+ struct dentry *de),
+
+ TP_ARGS(obj, de),
+
+ /* Note that obj may be NULL */
+ TP_STRUCT__entry(
+ __field(struct cachefiles_object *, obj )
+ __field(struct dentry *, de )
+ ),
+
+ TP_fast_assign(
+ __entry->obj = obj;
+ __entry->de = de;
+ ),
+
+ TP_printk("o=%p d=%p",
+ __entry->obj, __entry->de)
+ );
+
+TRACE_EVENT(cachefiles_wait_active,
+ TP_PROTO(struct cachefiles_object *obj,
+ struct dentry *de,
+ struct cachefiles_object *xobj),
+
+ TP_ARGS(obj, de, xobj),
+
+ /* Note that obj may be NULL */
+ TP_STRUCT__entry(
+ __field(struct cachefiles_object *, obj )
+ __field(struct dentry *, de )
+ __field(struct cachefiles_object *, xobj )
+ __field(u16, flags )
+ __field(u16, fsc_flags )
+ ),
+
+ TP_fast_assign(
+ __entry->obj = obj;
+ __entry->de = de;
+ __entry->xobj = xobj;
+ __entry->flags = xobj->flags;
+ __entry->fsc_flags = xobj->fscache.flags;
+ ),
+
+ TP_printk("o=%p d=%p wo=%p wf=%x wff=%x",
+ __entry->obj, __entry->de, __entry->xobj,
+ __entry->flags, __entry->fsc_flags)
+ );
+
+TRACE_EVENT(cachefiles_mark_inactive,
+ TP_PROTO(struct cachefiles_object *obj,
+ struct dentry *de,
+ struct inode *inode),
+
+ TP_ARGS(obj, de, inode),
+
+ /* Note that obj may be NULL */
+ TP_STRUCT__entry(
+ __field(struct cachefiles_object *, obj )
+ __field(struct dentry *, de )
+ __field(struct inode *, inode )
+ ),
+
+ TP_fast_assign(
+ __entry->obj = obj;
+ __entry->de = de;
+ __entry->inode = inode;
+ ),
+
+ TP_printk("o=%p d=%p i=%p",
+ __entry->obj, __entry->de, __entry->inode)
+ );
+
+TRACE_EVENT(cachefiles_mark_buried,
+ TP_PROTO(struct cachefiles_object *obj,
+ struct dentry *de,
+ enum fscache_why_object_killed why),
+
+ TP_ARGS(obj, de, why),
+
+ /* Note that obj may be NULL */
+ TP_STRUCT__entry(
+ __field(struct cachefiles_object *, obj )
+ __field(struct dentry *, de )
+ __field(enum fscache_why_object_killed, why )
+ ),
+
+ TP_fast_assign(
+ __entry->obj = obj;
+ __entry->de = de;
+ __entry->why = why;
+ ),
+
+ TP_printk("o=%p d=%p w=%s",
+ __entry->obj, __entry->de,
+ __print_symbolic(__entry->why, cachefiles_obj_kill_traces))
+ );
+
+#endif /* _TRACE_CACHEFILES_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/include/trace/events/fscache.h b/include/trace/events/fscache.h
new file mode 100644
index 000000000000..99f5355d6281
--- /dev/null
+++ b/include/trace/events/fscache.h
@@ -0,0 +1,277 @@
+/* FS-Cache tracepoints
+ *
+ * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM fscache
+
+#if !defined(_TRACE_FSCACHE_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_FSCACHE_H
+
+#include <linux/fscache.h>
+#include <linux/tracepoint.h>
+
+/*
+ * Define enums for tracing information.
+ */
+#ifndef __FSCACHE_DECLARE_TRACE_ENUMS_ONCE_ONLY
+#define __FSCACHE_DECLARE_TRACE_ENUMS_ONCE_ONLY
+
+enum fscache_cookie_trace {
+ fscache_cookie_get_acquire_parent,
+ fscache_cookie_get_attach_object,
+ fscache_cookie_get_register_netfs,
+ fscache_cookie_put_acquire_nobufs,
+ fscache_cookie_put_relinquish,
+ fscache_cookie_put_object,
+ fscache_cookie_put_parent,
+};
+
+#endif
+
+/*
+ * Declare tracing information enums and their string mappings for display.
+ */
+#define fscache_cookie_traces \
+ EM(fscache_cookie_get_acquire_parent, "GET prn") \
+ EM(fscache_cookie_get_attach_object, "GET obj") \
+ EM(fscache_cookie_get_register_netfs, "GET net") \
+ EM(fscache_cookie_put_acquire_nobufs, "PUT nbf") \
+ EM(fscache_cookie_put_relinquish, "PUT rlq") \
+ EM(fscache_cookie_put_object, "PUT obj") \
+ E_(fscache_cookie_put_parent, "PUT prn")
+
+/*
+ * Export enum symbols via userspace.
+ */
+#undef EM
+#undef E_
+#define EM(a, b) TRACE_DEFINE_ENUM(a);
+#define E_(a, b) TRACE_DEFINE_ENUM(a);
+
+fscache_cookie_traces;
+
+/*
+ * Now redefine the EM() and E_() macros to map the enums to the strings that
+ * will be printed in the output.
+ */
+#undef EM
+#undef E_
+#define EM(a, b) { a, b },
+#define E_(a, b) { a, b }
+
+
+TRACE_EVENT(fscache_cookie,
+ TP_PROTO(struct fscache_cookie *cookie,
+ enum fscache_cookie_trace where,
+ int usage),
+
+ TP_ARGS(cookie, where, usage),
+
+ TP_STRUCT__entry(
+ __field(struct fscache_cookie *, cookie )
+ __field(struct fscache_cookie *, parent )
+ __field(enum fscache_cookie_trace, where )
+ __field(int, usage )
+ __field(int, n_children )
+ __field(int, n_active )
+ __field(u8, flags )
+ ),
+
+ TP_fast_assign(
+ __entry->cookie = cookie;
+ __entry->parent = cookie->parent;
+ __entry->where = where;
+ __entry->usage = usage;
+ __entry->n_children = atomic_read(&cookie->n_children);
+ __entry->n_active = atomic_read(&cookie->n_active);
+ __entry->flags = cookie->flags;
+ ),
+
+ TP_printk("%s c=%p u=%d p=%p Nc=%d Na=%d f=%02x",
+ __print_symbolic(__entry->where, fscache_cookie_traces),
+ __entry->cookie, __entry->usage,
+ __entry->parent, __entry->n_children, __entry->n_active,
+ __entry->flags)
+ );
+
+TRACE_EVENT(fscache_netfs,
+ TP_PROTO(struct fscache_netfs *netfs),
+
+ TP_ARGS(netfs),
+
+ TP_STRUCT__entry(
+ __field(struct fscache_cookie *, cookie )
+ __array(char, name, 8 )
+ ),
+
+ TP_fast_assign(
+ __entry->cookie = netfs->primary_index;
+ strncpy(__entry->name, netfs->name, 8);
+ __entry->name[7] = 0;
+ ),
+
+ TP_printk("c=%p n=%s",
+ __entry->cookie, __entry->name)
+ );
+
+TRACE_EVENT(fscache_acquire,
+ TP_PROTO(struct fscache_cookie *cookie),
+
+ TP_ARGS(cookie),
+
+ TP_STRUCT__entry(
+ __field(struct fscache_cookie *, cookie )
+ __field(struct fscache_cookie *, parent )
+ __array(char, name, 8 )
+ __field(int, p_usage )
+ __field(int, p_n_children )
+ __field(u8, p_flags )
+ ),
+
+ TP_fast_assign(
+ __entry->cookie = cookie;
+ __entry->parent = cookie->parent;
+ __entry->p_usage = atomic_read(&cookie->parent->usage);
+ __entry->p_n_children = atomic_read(&cookie->parent->n_children);
+ __entry->p_flags = cookie->parent->flags;
+ memcpy(__entry->name, cookie->def->name, 8);
+ __entry->name[7] = 0;
+ ),
+
+ TP_printk("c=%p p=%p pu=%d pc=%d pf=%02x n=%s",
+ __entry->cookie, __entry->parent, __entry->p_usage,
+ __entry->p_n_children, __entry->p_flags, __entry->name)
+ );
+
+TRACE_EVENT(fscache_relinquish,
+ TP_PROTO(struct fscache_cookie *cookie, bool retire),
+
+ TP_ARGS(cookie, retire),
+
+ TP_STRUCT__entry(
+ __field(struct fscache_cookie *, cookie )
+ __field(struct fscache_cookie *, parent )
+ __field(int, usage )
+ __field(int, n_children )
+ __field(int, n_active )
+ __field(u8, flags )
+ __field(bool, retire )
+ ),
+
+ TP_fast_assign(
+ __entry->cookie = cookie;
+ __entry->parent = cookie->parent;
+ __entry->usage = atomic_read(&cookie->usage);
+ __entry->n_children = atomic_read(&cookie->n_children);
+ __entry->n_active = atomic_read(&cookie->n_active);
+ __entry->flags = cookie->flags;
+ __entry->retire = retire;
+ ),
+
+ TP_printk("c=%p u=%d p=%p Nc=%d Na=%d f=%02x r=%u",
+ __entry->cookie, __entry->usage,
+ __entry->parent, __entry->n_children, __entry->n_active,
+ __entry->flags, __entry->retire)
+ );
+
+TRACE_EVENT(fscache_enable,
+ TP_PROTO(struct fscache_cookie *cookie),
+
+ TP_ARGS(cookie),
+
+ TP_STRUCT__entry(
+ __field(struct fscache_cookie *, cookie )
+ __field(int, usage )
+ __field(int, n_children )
+ __field(int, n_active )
+ __field(u8, flags )
+ ),
+
+ TP_fast_assign(
+ __entry->cookie = cookie;
+ __entry->usage = atomic_read(&cookie->usage);
+ __entry->n_children = atomic_read(&cookie->n_children);
+ __entry->n_active = atomic_read(&cookie->n_active);
+ __entry->flags = cookie->flags;
+ ),
+
+ TP_printk("c=%p u=%d Nc=%d Na=%d f=%02x",
+ __entry->cookie, __entry->usage,
+ __entry->n_children, __entry->n_active, __entry->flags)
+ );
+
+TRACE_EVENT(fscache_disable,
+ TP_PROTO(struct fscache_cookie *cookie),
+
+ TP_ARGS(cookie),
+
+ TP_STRUCT__entry(
+ __field(struct fscache_cookie *, cookie )
+ __field(int, usage )
+ __field(int, n_children )
+ __field(int, n_active )
+ __field(u8, flags )
+ ),
+
+ TP_fast_assign(
+ __entry->cookie = cookie;
+ __entry->usage = atomic_read(&cookie->usage);
+ __entry->n_children = atomic_read(&cookie->n_children);
+ __entry->n_active = atomic_read(&cookie->n_active);
+ __entry->flags = cookie->flags;
+ ),
+
+ TP_printk("c=%p u=%d Nc=%d Na=%d f=%02x",
+ __entry->cookie, __entry->usage,
+ __entry->n_children, __entry->n_active, __entry->flags)
+ );
+
+TRACE_EVENT(fscache_osm,
+ TP_PROTO(struct fscache_object *object,
+ const struct fscache_state *state,
+ bool wait, bool oob, s8 event_num),
+
+ TP_ARGS(object, state, wait, oob, event_num),
+
+ TP_STRUCT__entry(
+ __field(struct fscache_cookie *, cookie )
+ __field(struct fscache_object *, object )
+ __array(char, state, 8 )
+ __field(bool, wait )
+ __field(bool, oob )
+ __field(s8, event_num )
+ ),
+
+ TP_fast_assign(
+ __entry->cookie = object->cookie;
+ __entry->object = object;
+ __entry->wait = wait;
+ __entry->oob = oob;
+ __entry->event_num = event_num;
+ memcpy(__entry->state, state->short_name, 8);
+ ),
+
+ TP_printk("c=%p o=%p %s %s%sev=%d",
+ __entry->cookie,
+ __entry->object,
+ __entry->state,
+ __print_symbolic(__entry->wait,
+ { true, "WAIT" },
+ { false, "WORK" }),
+ __print_symbolic(__entry->oob,
+ { true, " OOB " },
+ { false, " " }),
+ __entry->event_num)
+ );
+
+#endif /* _TRACE_FSCACHE_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>