Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a18feb55 authored by David Howells's avatar David Howells
Browse files

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: default avatarDavid Howells <dhowells@redhat.com>
parent 2c984257
Loading
Loading
Loading
Loading
+14 −4
Original line number Diff line number Diff line
@@ -177,10 +177,12 @@ static void cachefiles_lookup_complete(struct fscache_object *_object)
 * increment the usage count on an inode object (may fail if unmounting)
 */
static
struct fscache_object *cachefiles_grab_object(struct fscache_object *_object)
struct fscache_object *cachefiles_grab_object(struct fscache_object *_object,
					      enum fscache_obj_ref_trace why)
{
	struct cachefiles_object *object =
		container_of(_object, struct cachefiles_object, fscache);
	int u;

	_enter("{OBJ%x,%d}", _object->debug_id, atomic_read(&object->usage));

@@ -188,7 +190,9 @@ struct fscache_object *cachefiles_grab_object(struct fscache_object *_object)
	ASSERT((atomic_read(&object->usage) & 0xffff0000) != 0x6b6b0000);
#endif

	atomic_inc(&object->usage);
	u = atomic_inc_return(&object->usage);
	trace_cachefiles_ref(object, _object->cookie,
			     (enum cachefiles_obj_ref_trace)why, u);
	return &object->fscache;
}

@@ -309,10 +313,12 @@ static void cachefiles_drop_object(struct fscache_object *_object)
/*
 * dispose of a reference to an object
 */
static void cachefiles_put_object(struct fscache_object *_object)
static void cachefiles_put_object(struct fscache_object *_object,
				  enum fscache_obj_ref_trace why)
{
	struct cachefiles_object *object;
	struct fscache_cache *cache;
	int u;

	ASSERT(_object);

@@ -328,7 +334,11 @@ static void cachefiles_put_object(struct fscache_object *_object)
	ASSERTIFCMP(object->fscache.parent,
		    object->fscache.parent->n_children, >, 0);

	if (atomic_dec_and_test(&object->usage)) {
	u = atomic_dec_return(&object->usage);
	trace_cachefiles_ref(object, _object->cookie,
			     (enum cachefiles_obj_ref_trace)why, u);
	ASSERTCMP(u, !=, -1);
	if (u == 0) {
		_debug("- kill object OBJ%x", object->fscache.debug_id);

		ASSERT(!test_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags));
+2 −0
Original line number Diff line number Diff line
@@ -124,6 +124,8 @@ struct cachefiles_xattr {
	uint8_t				data[];
};

#include <trace/events/cachefiles.h>

/*
 * note change of state for daemon
 */
+1 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <linux/statfs.h>
#include <linux/sysctl.h>
#include <linux/miscdevice.h>
#define CREATE_TRACE_POINTS
#include "internal.h"

unsigned cachefiles_debug;
+33 −9
Original line number Diff line number Diff line
@@ -120,6 +120,7 @@ static void cachefiles_mark_object_buried(struct cachefiles_cache *cache,
	}

	write_unlock(&cache->active_lock);
	trace_cachefiles_mark_buried(NULL, dentry, why);
	_leave(" [no owner]");
	return;

@@ -130,6 +131,8 @@ static void cachefiles_mark_object_buried(struct cachefiles_cache *cache,
	       object->fscache.state->name,
	       dentry);

	trace_cachefiles_mark_buried(object, dentry, why);

	if (fscache_object_is_live(&object->fscache)) {
		pr_err("\n");
		pr_err("Error: Can't preemptively bury live object\n");
@@ -158,13 +161,15 @@ static int cachefiles_mark_object_active(struct cachefiles_cache *cache,
try_again:
	write_lock(&cache->active_lock);

	dentry = object->dentry;
	trace_cachefiles_mark_active(object, dentry);

	if (test_and_set_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags)) {
		pr_err("Error: Object already active\n");
		cachefiles_printk_object(object, NULL);
		BUG();
	}

	dentry = object->dentry;
	_p = &cache->active_nodes.rb_node;
	while (*_p) {
		_parent = *_p;
@@ -191,6 +196,8 @@ static int cachefiles_mark_object_active(struct cachefiles_cache *cache,
	/* an old object from a previous incarnation is hogging the slot - we
	 * need to wait for it to be destroyed */
wait_for_old_object:
	trace_cachefiles_wait_active(object, dentry, xobject);

	if (fscache_object_is_live(&xobject->fscache)) {
		pr_err("\n");
		pr_err("Error: Unexpected object collision\n");
@@ -248,12 +255,12 @@ static int cachefiles_mark_object_active(struct cachefiles_cache *cache,

	ASSERT(!test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags));

	cache->cache.ops->put_object(&xobject->fscache);
	cache->cache.ops->put_object(&xobject->fscache, cachefiles_obj_put_wait_retry);
	goto try_again;

requeue:
	clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags);
	cache->cache.ops->put_object(&xobject->fscache);
	cache->cache.ops->put_object(&xobject->fscache, cachefiles_obj_put_wait_timeo);
	_leave(" = -ETIMEDOUT");
	return -ETIMEDOUT;
}
@@ -265,6 +272,11 @@ void cachefiles_mark_object_inactive(struct cachefiles_cache *cache,
				     struct cachefiles_object *object,
				     blkcnt_t i_blocks)
{
	struct dentry *dentry = object->dentry;
	struct inode *inode = d_backing_inode(dentry);

	trace_cachefiles_mark_inactive(object, dentry, inode);

	write_lock(&cache->active_lock);
	rb_erase(&object->active_node, &cache->active_nodes);
	clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags);
@@ -288,6 +300,7 @@ void cachefiles_mark_object_inactive(struct cachefiles_cache *cache,
 * - unlocks the directory mutex
 */
static int cachefiles_bury_object(struct cachefiles_cache *cache,
				  struct cachefiles_object *object,
				  struct dentry *dir,
				  struct dentry *rep,
				  bool preemptive,
@@ -312,6 +325,7 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache,
		if (ret < 0) {
			cachefiles_io_error(cache, "Unlink security error");
		} else {
			trace_cachefiles_unlink(object, rep, why);
			ret = vfs_unlink(d_inode(dir), rep, NULL);

			if (preemptive)
@@ -413,6 +427,7 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache,
	if (ret < 0) {
		cachefiles_io_error(cache, "Rename security error %d", ret);
	} else {
		trace_cachefiles_rename(object, rep, grave, why);
		ret = vfs_rename(d_inode(dir), rep,
				 d_inode(cache->graveyard), grave, NULL, 0);
		if (ret != 0 && ret != -ENOMEM)
@@ -458,7 +473,7 @@ int cachefiles_delete_object(struct cachefiles_cache *cache,
		/* we need to check that our parent is _still_ our parent - it
		 * may have been renamed */
		if (dir == object->dentry->d_parent) {
			ret = cachefiles_bury_object(cache, dir,
			ret = cachefiles_bury_object(cache, object, dir,
						     object->dentry, false,
						     FSCACHE_OBJECT_WAS_RETIRED);
		} else {
@@ -486,6 +501,7 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent,
{
	struct cachefiles_cache *cache;
	struct dentry *dir, *next = NULL;
	struct inode *inode;
	struct path path;
	unsigned long start;
	const char *name;
@@ -529,13 +545,17 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent,
	start = jiffies;
	next = lookup_one_len(name, dir, nlen);
	cachefiles_hist(cachefiles_lookup_histogram, start);
	if (IS_ERR(next))
	if (IS_ERR(next)) {
		trace_cachefiles_lookup(object, next, NULL);
		goto lookup_error;
	}

	_debug("next -> %p %s", next, d_backing_inode(next) ? "positive" : "negative");
	inode = d_backing_inode(next);
	trace_cachefiles_lookup(object, next, inode);
	_debug("next -> %p %s", next, inode ? "positive" : "negative");

	if (!key)
		object->new = !d_backing_inode(next);
		object->new = !inode;

	/* if this element of the path doesn't exist, then the lookup phase
	 * failed, and we can release any readers in the certain knowledge that
@@ -558,6 +578,8 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent,
			start = jiffies;
			ret = vfs_mkdir(d_inode(dir), next, 0);
			cachefiles_hist(cachefiles_mkdir_histogram, start);
			if (!key)
				trace_cachefiles_mkdir(object, next, ret);
			if (ret < 0)
				goto create_error;

@@ -587,6 +609,7 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent,
			start = jiffies;
			ret = vfs_create(d_inode(dir), next, S_IFREG, true);
			cachefiles_hist(cachefiles_create_histogram, start);
			trace_cachefiles_create(object, next, ret);
			if (ret < 0)
				goto create_error;

@@ -629,7 +652,8 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent,
			 * mutex) */
			object->dentry = NULL;

			ret = cachefiles_bury_object(cache, dir, next, true,
			ret = cachefiles_bury_object(cache, object, dir, next,
						     true,
						     FSCACHE_OBJECT_IS_STALE);
			dput(next);
			next = NULL;
@@ -955,7 +979,7 @@ int cachefiles_cull(struct cachefiles_cache *cache, struct dentry *dir,
	/*  actually remove the victim (drops the dir mutex) */
	_debug("bury");

	ret = cachefiles_bury_object(cache, dir, victim, false,
	ret = cachefiles_bury_object(cache, NULL, dir, victim, false,
				     FSCACHE_OBJECT_WAS_CULLED);
	if (ret < 0)
		goto error;
+29 −17
Original line number Diff line number Diff line
@@ -101,7 +101,7 @@ struct fscache_cookie *__fscache_acquire_cookie(
	 */
	atomic_set(&cookie->n_active, 1);

	atomic_inc(&parent->usage);
	fscache_cookie_get(parent, fscache_cookie_get_acquire_parent);
	atomic_inc(&parent->n_children);

	cookie->def		= def;
@@ -125,6 +125,8 @@ struct fscache_cookie *__fscache_acquire_cookie(
		break;
	}

	trace_fscache_acquire(cookie);

	if (enable) {
		/* if the object is an index then we need do nothing more here
		 * - we create indices on disk when we need them as an index
@@ -134,7 +136,8 @@ struct fscache_cookie *__fscache_acquire_cookie(
				set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags);
			} else {
				atomic_dec(&parent->n_children);
				__fscache_cookie_put(cookie);
				fscache_cookie_put(cookie,
						   fscache_cookie_put_acquire_nobufs);
				fscache_stat(&fscache_n_acquires_nobufs);
				_leave(" = NULL");
				return NULL;
@@ -159,6 +162,8 @@ void __fscache_enable_cookie(struct fscache_cookie *cookie,
{
	_enter("%p", cookie);

	trace_fscache_enable(cookie);

	wait_on_bit_lock(&cookie->flags, FSCACHE_COOKIE_ENABLEMENT_LOCK,
			 TASK_UNINTERRUPTIBLE);

@@ -318,7 +323,7 @@ static int fscache_alloc_object(struct fscache_cache *cache,
	 * attached to the cookie */
	if (fscache_attach_object(cookie, object) < 0) {
		fscache_stat(&fscache_n_cop_put_object);
		cache->ops->put_object(object);
		cache->ops->put_object(object, fscache_obj_put_attach_fail);
		fscache_stat_d(&fscache_n_cop_put_object);
	}

@@ -338,7 +343,7 @@ static int fscache_alloc_object(struct fscache_cache *cache,

error_put:
	fscache_stat(&fscache_n_cop_put_object);
	cache->ops->put_object(object);
	cache->ops->put_object(object, fscache_obj_put_alloc_fail);
	fscache_stat_d(&fscache_n_cop_put_object);
error:
	_leave(" = %d", ret);
@@ -398,7 +403,7 @@ static int fscache_attach_object(struct fscache_cookie *cookie,

	/* attach to the cookie */
	object->cookie = cookie;
	atomic_inc(&cookie->usage);
	fscache_cookie_get(cookie, fscache_cookie_get_attach_object);
	hlist_add_head(&object->cookie_link, &cookie->backing_objects);

	fscache_objlist_add(object);
@@ -516,6 +521,8 @@ void __fscache_disable_cookie(struct fscache_cookie *cookie, bool invalidate)

	_enter("%p,%u", cookie, invalidate);

	trace_fscache_disable(cookie);

	ASSERTCMP(atomic_read(&cookie->n_active), >, 0);

	if (atomic_read(&cookie->n_children) != 0) {
@@ -601,6 +608,8 @@ void __fscache_relinquish_cookie(struct fscache_cookie *cookie, bool retire)
	       cookie, cookie->def->name, cookie->netfs_data,
	       atomic_read(&cookie->n_active), retire);

	trace_fscache_relinquish(cookie, retire);

	/* No further netfs-accessing operations on this cookie permitted */
	if (test_and_set_bit(FSCACHE_COOKIE_RELINQUISHED, &cookie->flags))
		BUG();
@@ -620,35 +629,38 @@ void __fscache_relinquish_cookie(struct fscache_cookie *cookie, bool retire)

	/* Dispose of the netfs's link to the cookie */
	ASSERTCMP(atomic_read(&cookie->usage), >, 0);
	fscache_cookie_put(cookie);
	fscache_cookie_put(cookie, fscache_cookie_put_relinquish);

	_leave("");
}
EXPORT_SYMBOL(__fscache_relinquish_cookie);

/*
 * destroy a cookie
 * Drop a reference to a cookie.
 */
void __fscache_cookie_put(struct fscache_cookie *cookie)
void fscache_cookie_put(struct fscache_cookie *cookie,
			enum fscache_cookie_trace where)
{
	struct fscache_cookie *parent;
	int usage;

	_enter("%p", cookie);

	for (;;) {
		_debug("FREE COOKIE %p", cookie);
	do {
		usage = atomic_dec_return(&cookie->usage);
		trace_fscache_cookie(cookie, where, usage);

		if (usage > 0)
			return;
		BUG_ON(usage < 0);

		parent = cookie->parent;
		BUG_ON(!hlist_empty(&cookie->backing_objects));
		kmem_cache_free(fscache_cookie_jar, cookie);

		if (!parent)
			break;

		cookie = parent;
		BUG_ON(atomic_read(&cookie->usage) <= 0);
		if (!atomic_dec_and_test(&cookie->usage))
			break;
	}
		where = fscache_cookie_put_parent;
	} while (cookie);

	_leave("");
}
Loading