Skip to content

Commit a18feb5

Browse files
committed
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 <[email protected]>
1 parent 2c98425 commit a18feb5

File tree

12 files changed

+731
-54
lines changed

12 files changed

+731
-54
lines changed

fs/cachefiles/interface.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,18 +177,22 @@ static void cachefiles_lookup_complete(struct fscache_object *_object)
177177
* increment the usage count on an inode object (may fail if unmounting)
178178
*/
179179
static
180-
struct fscache_object *cachefiles_grab_object(struct fscache_object *_object)
180+
struct fscache_object *cachefiles_grab_object(struct fscache_object *_object,
181+
enum fscache_obj_ref_trace why)
181182
{
182183
struct cachefiles_object *object =
183184
container_of(_object, struct cachefiles_object, fscache);
185+
int u;
184186

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

187189
#ifdef CACHEFILES_DEBUG_SLAB
188190
ASSERT((atomic_read(&object->usage) & 0xffff0000) != 0x6b6b0000);
189191
#endif
190192

191-
atomic_inc(&object->usage);
193+
u = atomic_inc_return(&object->usage);
194+
trace_cachefiles_ref(object, _object->cookie,
195+
(enum cachefiles_obj_ref_trace)why, u);
192196
return &object->fscache;
193197
}
194198

@@ -309,10 +313,12 @@ static void cachefiles_drop_object(struct fscache_object *_object)
309313
/*
310314
* dispose of a reference to an object
311315
*/
312-
static void cachefiles_put_object(struct fscache_object *_object)
316+
static void cachefiles_put_object(struct fscache_object *_object,
317+
enum fscache_obj_ref_trace why)
313318
{
314319
struct cachefiles_object *object;
315320
struct fscache_cache *cache;
321+
int u;
316322

317323
ASSERT(_object);
318324

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

331-
if (atomic_dec_and_test(&object->usage)) {
337+
u = atomic_dec_return(&object->usage);
338+
trace_cachefiles_ref(object, _object->cookie,
339+
(enum cachefiles_obj_ref_trace)why, u);
340+
ASSERTCMP(u, !=, -1);
341+
if (u == 0) {
332342
_debug("- kill object OBJ%x", object->fscache.debug_id);
333343

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

fs/cachefiles/internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ struct cachefiles_xattr {
124124
uint8_t data[];
125125
};
126126

127+
#include <trace/events/cachefiles.h>
128+
127129
/*
128130
* note change of state for daemon
129131
*/

fs/cachefiles/main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <linux/statfs.h>
2323
#include <linux/sysctl.h>
2424
#include <linux/miscdevice.h>
25+
#define CREATE_TRACE_POINTS
2526
#include "internal.h"
2627

2728
unsigned cachefiles_debug;

fs/cachefiles/namei.c

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ static void cachefiles_mark_object_buried(struct cachefiles_cache *cache,
120120
}
121121

122122
write_unlock(&cache->active_lock);
123+
trace_cachefiles_mark_buried(NULL, dentry, why);
123124
_leave(" [no owner]");
124125
return;
125126

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

134+
trace_cachefiles_mark_buried(object, dentry, why);
135+
133136
if (fscache_object_is_live(&object->fscache)) {
134137
pr_err("\n");
135138
pr_err("Error: Can't preemptively bury live object\n");
@@ -158,13 +161,15 @@ static int cachefiles_mark_object_active(struct cachefiles_cache *cache,
158161
try_again:
159162
write_lock(&cache->active_lock);
160163

164+
dentry = object->dentry;
165+
trace_cachefiles_mark_active(object, dentry);
166+
161167
if (test_and_set_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags)) {
162168
pr_err("Error: Object already active\n");
163169
cachefiles_printk_object(object, NULL);
164170
BUG();
165171
}
166172

167-
dentry = object->dentry;
168173
_p = &cache->active_nodes.rb_node;
169174
while (*_p) {
170175
_parent = *_p;
@@ -191,6 +196,8 @@ static int cachefiles_mark_object_active(struct cachefiles_cache *cache,
191196
/* an old object from a previous incarnation is hogging the slot - we
192197
* need to wait for it to be destroyed */
193198
wait_for_old_object:
199+
trace_cachefiles_wait_active(object, dentry, xobject);
200+
194201
if (fscache_object_is_live(&xobject->fscache)) {
195202
pr_err("\n");
196203
pr_err("Error: Unexpected object collision\n");
@@ -248,12 +255,12 @@ static int cachefiles_mark_object_active(struct cachefiles_cache *cache,
248255

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

251-
cache->cache.ops->put_object(&xobject->fscache);
258+
cache->cache.ops->put_object(&xobject->fscache, cachefiles_obj_put_wait_retry);
252259
goto try_again;
253260

254261
requeue:
255262
clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags);
256-
cache->cache.ops->put_object(&xobject->fscache);
263+
cache->cache.ops->put_object(&xobject->fscache, cachefiles_obj_put_wait_timeo);
257264
_leave(" = -ETIMEDOUT");
258265
return -ETIMEDOUT;
259266
}
@@ -265,6 +272,11 @@ void cachefiles_mark_object_inactive(struct cachefiles_cache *cache,
265272
struct cachefiles_object *object,
266273
blkcnt_t i_blocks)
267274
{
275+
struct dentry *dentry = object->dentry;
276+
struct inode *inode = d_backing_inode(dentry);
277+
278+
trace_cachefiles_mark_inactive(object, dentry, inode);
279+
268280
write_lock(&cache->active_lock);
269281
rb_erase(&object->active_node, &cache->active_nodes);
270282
clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags);
@@ -288,6 +300,7 @@ void cachefiles_mark_object_inactive(struct cachefiles_cache *cache,
288300
* - unlocks the directory mutex
289301
*/
290302
static int cachefiles_bury_object(struct cachefiles_cache *cache,
303+
struct cachefiles_object *object,
291304
struct dentry *dir,
292305
struct dentry *rep,
293306
bool preemptive,
@@ -312,6 +325,7 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache,
312325
if (ret < 0) {
313326
cachefiles_io_error(cache, "Unlink security error");
314327
} else {
328+
trace_cachefiles_unlink(object, rep, why);
315329
ret = vfs_unlink(d_inode(dir), rep, NULL);
316330

317331
if (preemptive)
@@ -413,6 +427,7 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache,
413427
if (ret < 0) {
414428
cachefiles_io_error(cache, "Rename security error %d", ret);
415429
} else {
430+
trace_cachefiles_rename(object, rep, grave, why);
416431
ret = vfs_rename(d_inode(dir), rep,
417432
d_inode(cache->graveyard), grave, NULL, 0);
418433
if (ret != 0 && ret != -ENOMEM)
@@ -458,7 +473,7 @@ int cachefiles_delete_object(struct cachefiles_cache *cache,
458473
/* we need to check that our parent is _still_ our parent - it
459474
* may have been renamed */
460475
if (dir == object->dentry->d_parent) {
461-
ret = cachefiles_bury_object(cache, dir,
476+
ret = cachefiles_bury_object(cache, object, dir,
462477
object->dentry, false,
463478
FSCACHE_OBJECT_WAS_RETIRED);
464479
} else {
@@ -486,6 +501,7 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent,
486501
{
487502
struct cachefiles_cache *cache;
488503
struct dentry *dir, *next = NULL;
504+
struct inode *inode;
489505
struct path path;
490506
unsigned long start;
491507
const char *name;
@@ -529,13 +545,17 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent,
529545
start = jiffies;
530546
next = lookup_one_len(name, dir, nlen);
531547
cachefiles_hist(cachefiles_lookup_histogram, start);
532-
if (IS_ERR(next))
548+
if (IS_ERR(next)) {
549+
trace_cachefiles_lookup(object, next, NULL);
533550
goto lookup_error;
551+
}
534552

535-
_debug("next -> %p %s", next, d_backing_inode(next) ? "positive" : "negative");
553+
inode = d_backing_inode(next);
554+
trace_cachefiles_lookup(object, next, inode);
555+
_debug("next -> %p %s", next, inode ? "positive" : "negative");
536556

537557
if (!key)
538-
object->new = !d_backing_inode(next);
558+
object->new = !inode;
539559

540560
/* if this element of the path doesn't exist, then the lookup phase
541561
* 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,
558578
start = jiffies;
559579
ret = vfs_mkdir(d_inode(dir), next, 0);
560580
cachefiles_hist(cachefiles_mkdir_histogram, start);
581+
if (!key)
582+
trace_cachefiles_mkdir(object, next, ret);
561583
if (ret < 0)
562584
goto create_error;
563585

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

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

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

958-
ret = cachefiles_bury_object(cache, dir, victim, false,
982+
ret = cachefiles_bury_object(cache, NULL, dir, victim, false,
959983
FSCACHE_OBJECT_WAS_CULLED);
960984
if (ret < 0)
961985
goto error;

fs/fscache/cookie.c

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ struct fscache_cookie *__fscache_acquire_cookie(
101101
*/
102102
atomic_set(&cookie->n_active, 1);
103103

104-
atomic_inc(&parent->usage);
104+
fscache_cookie_get(parent, fscache_cookie_get_acquire_parent);
105105
atomic_inc(&parent->n_children);
106106

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

128+
trace_fscache_acquire(cookie);
129+
128130
if (enable) {
129131
/* if the object is an index then we need do nothing more here
130132
* - we create indices on disk when we need them as an index
@@ -134,7 +136,8 @@ struct fscache_cookie *__fscache_acquire_cookie(
134136
set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags);
135137
} else {
136138
atomic_dec(&parent->n_children);
137-
__fscache_cookie_put(cookie);
139+
fscache_cookie_put(cookie,
140+
fscache_cookie_put_acquire_nobufs);
138141
fscache_stat(&fscache_n_acquires_nobufs);
139142
_leave(" = NULL");
140143
return NULL;
@@ -159,6 +162,8 @@ void __fscache_enable_cookie(struct fscache_cookie *cookie,
159162
{
160163
_enter("%p", cookie);
161164

165+
trace_fscache_enable(cookie);
166+
162167
wait_on_bit_lock(&cookie->flags, FSCACHE_COOKIE_ENABLEMENT_LOCK,
163168
TASK_UNINTERRUPTIBLE);
164169

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

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

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

399404
/* attach to the cookie */
400405
object->cookie = cookie;
401-
atomic_inc(&cookie->usage);
406+
fscache_cookie_get(cookie, fscache_cookie_get_attach_object);
402407
hlist_add_head(&object->cookie_link, &cookie->backing_objects);
403408

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

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

524+
trace_fscache_disable(cookie);
525+
519526
ASSERTCMP(atomic_read(&cookie->n_active), >, 0);
520527

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

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

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

625634
_leave("");
626635
}
627636
EXPORT_SYMBOL(__fscache_relinquish_cookie);
628637

629638
/*
630-
* destroy a cookie
639+
* Drop a reference to a cookie.
631640
*/
632-
void __fscache_cookie_put(struct fscache_cookie *cookie)
641+
void fscache_cookie_put(struct fscache_cookie *cookie,
642+
enum fscache_cookie_trace where)
633643
{
634644
struct fscache_cookie *parent;
645+
int usage;
635646

636647
_enter("%p", cookie);
637648

638-
for (;;) {
639-
_debug("FREE COOKIE %p", cookie);
649+
do {
650+
usage = atomic_dec_return(&cookie->usage);
651+
trace_fscache_cookie(cookie, where, usage);
652+
653+
if (usage > 0)
654+
return;
655+
BUG_ON(usage < 0);
656+
640657
parent = cookie->parent;
641658
BUG_ON(!hlist_empty(&cookie->backing_objects));
642659
kmem_cache_free(fscache_cookie_jar, cookie);
643660

644-
if (!parent)
645-
break;
646-
647661
cookie = parent;
648-
BUG_ON(atomic_read(&cookie->usage) <= 0);
649-
if (!atomic_dec_and_test(&cookie->usage))
650-
break;
651-
}
662+
where = fscache_cookie_put_parent;
663+
} while (cookie);
652664

653665
_leave("");
654666
}

0 commit comments

Comments
 (0)