Skip to content

Commit

Permalink
fscache: Add tracepoints
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
dhowells committed Apr 4, 2018
1 parent 2c98425 commit a18feb5
Show file tree
Hide file tree
Showing 12 changed files with 731 additions and 54 deletions.
18 changes: 14 additions & 4 deletions fs/cachefiles/interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,18 +177,22 @@ 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));

#ifdef CACHEFILES_DEBUG_SLAB
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;
}

Expand Down Expand Up @@ -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);

Expand All @@ -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));
Expand Down
2 changes: 2 additions & 0 deletions fs/cachefiles/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ struct cachefiles_xattr {
uint8_t data[];
};

#include <trace/events/cachefiles.h>

/*
* note change of state for daemon
*/
Expand Down
1 change: 1 addition & 0 deletions fs/cachefiles/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
42 changes: 33 additions & 9 deletions fs/cachefiles/namei.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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");
Expand Down Expand Up @@ -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;
Expand All @@ -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");
Expand Down Expand Up @@ -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;
}
Expand All @@ -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);
Expand All @@ -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,
Expand All @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
46 changes: 29 additions & 17 deletions fs/fscache/cookie.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand All @@ -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;
Expand All @@ -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);

Expand Down Expand Up @@ -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);
}

Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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();
Expand All @@ -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("");
}
Expand Down
Loading

0 comments on commit a18feb5

Please sign in to comment.