aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cachefiles/interface.c18
-rw-r--r--fs/cachefiles/internal.h2
-rw-r--r--fs/cachefiles/main.c1
-rw-r--r--fs/cachefiles/namei.c42
-rw-r--r--fs/fscache/cookie.c46
-rw-r--r--fs/fscache/internal.h16
-rw-r--r--fs/fscache/main.c1
-rw-r--r--fs/fscache/netfs.c3
-rw-r--r--fs/fscache/object.c36
-rw-r--r--include/linux/fscache-cache.h18
-rw-r--r--include/trace/events/cachefiles.h325
-rw-r--r--include/trace/events/fscache.h277
12 files changed, 731 insertions, 54 deletions
diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c
index e7f16a77a22a..405ebc3932c2 100644
--- a/fs/cachefiles/interface.c
+++ b/fs/cachefiles/interface.c
@@ -177,10 +177,12 @@ static void cachefiles_lookup_complete(struct fscache_object *_object)
177 * increment the usage count on an inode object (may fail if unmounting) 177 * increment the usage count on an inode object (may fail if unmounting)
178 */ 178 */
179static 179static
180struct fscache_object *cachefiles_grab_object(struct fscache_object *_object) 180struct fscache_object *cachefiles_grab_object(struct fscache_object *_object,
181 enum fscache_obj_ref_trace why)
181{ 182{
182 struct cachefiles_object *object = 183 struct cachefiles_object *object =
183 container_of(_object, struct cachefiles_object, fscache); 184 container_of(_object, struct cachefiles_object, fscache);
185 int u;
184 186
185 _enter("{OBJ%x,%d}", _object->debug_id, atomic_read(&object->usage)); 187 _enter("{OBJ%x,%d}", _object->debug_id, atomic_read(&object->usage));
186 188
@@ -188,7 +190,9 @@ struct fscache_object *cachefiles_grab_object(struct fscache_object *_object)
188 ASSERT((atomic_read(&object->usage) & 0xffff0000) != 0x6b6b0000); 190 ASSERT((atomic_read(&object->usage) & 0xffff0000) != 0x6b6b0000);
189#endif 191#endif
190 192
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);
192 return &object->fscache; 196 return &object->fscache;
193} 197}
194 198
@@ -309,10 +313,12 @@ static void cachefiles_drop_object(struct fscache_object *_object)
309/* 313/*
310 * dispose of a reference to an object 314 * dispose of a reference to an object
311 */ 315 */
312static void cachefiles_put_object(struct fscache_object *_object) 316static void cachefiles_put_object(struct fscache_object *_object,
317 enum fscache_obj_ref_trace why)
313{ 318{
314 struct cachefiles_object *object; 319 struct cachefiles_object *object;
315 struct fscache_cache *cache; 320 struct fscache_cache *cache;
321 int u;
316 322
317 ASSERT(_object); 323 ASSERT(_object);
318 324
@@ -328,7 +334,11 @@ static void cachefiles_put_object(struct fscache_object *_object)
328 ASSERTIFCMP(object->fscache.parent, 334 ASSERTIFCMP(object->fscache.parent,
329 object->fscache.parent->n_children, >, 0); 335 object->fscache.parent->n_children, >, 0);
330 336
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) {
332 _debug("- kill object OBJ%x", object->fscache.debug_id); 342 _debug("- kill object OBJ%x", object->fscache.debug_id);
333 343
334 ASSERT(!test_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags)); 344 ASSERT(!test_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags));
diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h
index bb3a02ca9da4..d2f6f996e65a 100644
--- a/fs/cachefiles/internal.h
+++ b/fs/cachefiles/internal.h
@@ -124,6 +124,8 @@ struct cachefiles_xattr {
124 uint8_t data[]; 124 uint8_t data[];
125}; 125};
126 126
127#include <trace/events/cachefiles.h>
128
127/* 129/*
128 * note change of state for daemon 130 * note change of state for daemon
129 */ 131 */
diff --git a/fs/cachefiles/main.c b/fs/cachefiles/main.c
index 711f13d8c2de..f54d3f5b2e40 100644
--- a/fs/cachefiles/main.c
+++ b/fs/cachefiles/main.c
@@ -22,6 +22,7 @@
22#include <linux/statfs.h> 22#include <linux/statfs.h>
23#include <linux/sysctl.h> 23#include <linux/sysctl.h>
24#include <linux/miscdevice.h> 24#include <linux/miscdevice.h>
25#define CREATE_TRACE_POINTS
25#include "internal.h" 26#include "internal.h"
26 27
27unsigned cachefiles_debug; 28unsigned cachefiles_debug;
diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c
index 3978b324cbca..5fc214256316 100644
--- a/fs/cachefiles/namei.c
+++ b/fs/cachefiles/namei.c
@@ -120,6 +120,7 @@ static void cachefiles_mark_object_buried(struct cachefiles_cache *cache,
120 } 120 }
121 121
122 write_unlock(&cache->active_lock); 122 write_unlock(&cache->active_lock);
123 trace_cachefiles_mark_buried(NULL, dentry, why);
123 _leave(" [no owner]"); 124 _leave(" [no owner]");
124 return; 125 return;
125 126
@@ -130,6 +131,8 @@ found_dentry:
130 object->fscache.state->name, 131 object->fscache.state->name,
131 dentry); 132 dentry);
132 133
134 trace_cachefiles_mark_buried(object, dentry, why);
135
133 if (fscache_object_is_live(&object->fscache)) { 136 if (fscache_object_is_live(&object->fscache)) {
134 pr_err("\n"); 137 pr_err("\n");
135 pr_err("Error: Can't preemptively bury live object\n"); 138 pr_err("Error: Can't preemptively bury live object\n");
@@ -158,13 +161,15 @@ static int cachefiles_mark_object_active(struct cachefiles_cache *cache,
158try_again: 161try_again:
159 write_lock(&cache->active_lock); 162 write_lock(&cache->active_lock);
160 163
164 dentry = object->dentry;
165 trace_cachefiles_mark_active(object, dentry);
166
161 if (test_and_set_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags)) { 167 if (test_and_set_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags)) {
162 pr_err("Error: Object already active\n"); 168 pr_err("Error: Object already active\n");
163 cachefiles_printk_object(object, NULL); 169 cachefiles_printk_object(object, NULL);
164 BUG(); 170 BUG();
165 } 171 }
166 172
167 dentry = object->dentry;
168 _p = &cache->active_nodes.rb_node; 173 _p = &cache->active_nodes.rb_node;
169 while (*_p) { 174 while (*_p) {
170 _parent = *_p; 175 _parent = *_p;
@@ -191,6 +196,8 @@ try_again:
191 /* an old object from a previous incarnation is hogging the slot - we 196 /* an old object from a previous incarnation is hogging the slot - we
192 * need to wait for it to be destroyed */ 197 * need to wait for it to be destroyed */
193wait_for_old_object: 198wait_for_old_object:
199 trace_cachefiles_wait_active(object, dentry, xobject);
200
194 if (fscache_object_is_live(&xobject->fscache)) { 201 if (fscache_object_is_live(&xobject->fscache)) {
195 pr_err("\n"); 202 pr_err("\n");
196 pr_err("Error: Unexpected object collision\n"); 203 pr_err("Error: Unexpected object collision\n");
@@ -248,12 +255,12 @@ wait_for_old_object:
248 255
249 ASSERT(!test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags)); 256 ASSERT(!test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags));
250 257
251 cache->cache.ops->put_object(&xobject->fscache); 258 cache->cache.ops->put_object(&xobject->fscache, cachefiles_obj_put_wait_retry);
252 goto try_again; 259 goto try_again;
253 260
254requeue: 261requeue:
255 clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags); 262 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);
257 _leave(" = -ETIMEDOUT"); 264 _leave(" = -ETIMEDOUT");
258 return -ETIMEDOUT; 265 return -ETIMEDOUT;
259} 266}
@@ -265,6 +272,11 @@ void cachefiles_mark_object_inactive(struct cachefiles_cache *cache,
265 struct cachefiles_object *object, 272 struct cachefiles_object *object,
266 blkcnt_t i_blocks) 273 blkcnt_t i_blocks)
267{ 274{
275 struct dentry *dentry = object->dentry;
276 struct inode *inode = d_backing_inode(dentry);
277
278 trace_cachefiles_mark_inactive(object, dentry, inode);
279
268 write_lock(&cache->active_lock); 280 write_lock(&cache->active_lock);
269 rb_erase(&object->active_node, &cache->active_nodes); 281 rb_erase(&object->active_node, &cache->active_nodes);
270 clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags); 282 clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags);
@@ -288,6 +300,7 @@ void cachefiles_mark_object_inactive(struct cachefiles_cache *cache,
288 * - unlocks the directory mutex 300 * - unlocks the directory mutex
289 */ 301 */
290static int cachefiles_bury_object(struct cachefiles_cache *cache, 302static int cachefiles_bury_object(struct cachefiles_cache *cache,
303 struct cachefiles_object *object,
291 struct dentry *dir, 304 struct dentry *dir,
292 struct dentry *rep, 305 struct dentry *rep,
293 bool preemptive, 306 bool preemptive,
@@ -312,6 +325,7 @@ static int cachefiles_bury_object(struct cachefiles_cache *cache,
312 if (ret < 0) { 325 if (ret < 0) {
313 cachefiles_io_error(cache, "Unlink security error"); 326 cachefiles_io_error(cache, "Unlink security error");
314 } else { 327 } else {
328 trace_cachefiles_unlink(object, rep, why);
315 ret = vfs_unlink(d_inode(dir), rep, NULL); 329 ret = vfs_unlink(d_inode(dir), rep, NULL);
316 330
317 if (preemptive) 331 if (preemptive)
@@ -413,6 +427,7 @@ try_again:
413 if (ret < 0) { 427 if (ret < 0) {
414 cachefiles_io_error(cache, "Rename security error %d", ret); 428 cachefiles_io_error(cache, "Rename security error %d", ret);
415 } else { 429 } else {
430 trace_cachefiles_rename(object, rep, grave, why);
416 ret = vfs_rename(d_inode(dir), rep, 431 ret = vfs_rename(d_inode(dir), rep,
417 d_inode(cache->graveyard), grave, NULL, 0); 432 d_inode(cache->graveyard), grave, NULL, 0);
418 if (ret != 0 && ret != -ENOMEM) 433 if (ret != 0 && ret != -ENOMEM)
@@ -458,7 +473,7 @@ int cachefiles_delete_object(struct cachefiles_cache *cache,
458 /* we need to check that our parent is _still_ our parent - it 473 /* we need to check that our parent is _still_ our parent - it
459 * may have been renamed */ 474 * may have been renamed */
460 if (dir == object->dentry->d_parent) { 475 if (dir == object->dentry->d_parent) {
461 ret = cachefiles_bury_object(cache, dir, 476 ret = cachefiles_bury_object(cache, object, dir,
462 object->dentry, false, 477 object->dentry, false,
463 FSCACHE_OBJECT_WAS_RETIRED); 478 FSCACHE_OBJECT_WAS_RETIRED);
464 } else { 479 } else {
@@ -486,6 +501,7 @@ int cachefiles_walk_to_object(struct cachefiles_object *parent,
486{ 501{
487 struct cachefiles_cache *cache; 502 struct cachefiles_cache *cache;
488 struct dentry *dir, *next = NULL; 503 struct dentry *dir, *next = NULL;
504 struct inode *inode;
489 struct path path; 505 struct path path;
490 unsigned long start; 506 unsigned long start;
491 const char *name; 507 const char *name;
@@ -529,13 +545,17 @@ lookup_again:
529 start = jiffies; 545 start = jiffies;
530 next = lookup_one_len(name, dir, nlen); 546 next = lookup_one_len(name, dir, nlen);
531 cachefiles_hist(cachefiles_lookup_histogram, start); 547 cachefiles_hist(cachefiles_lookup_histogram, start);
532 if (IS_ERR(next)) 548 if (IS_ERR(next)) {
549 trace_cachefiles_lookup(object, next, NULL);
533 goto lookup_error; 550 goto lookup_error;
551 }
534 552
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");
536 556
537 if (!key) 557 if (!key)
538 object->new = !d_backing_inode(next); 558 object->new = !inode;
539 559
540 /* if this element of the path doesn't exist, then the lookup phase 560 /* if this element of the path doesn't exist, then the lookup phase
541 * failed, and we can release any readers in the certain knowledge that 561 * failed, and we can release any readers in the certain knowledge that
@@ -558,6 +578,8 @@ lookup_again:
558 start = jiffies; 578 start = jiffies;
559 ret = vfs_mkdir(d_inode(dir), next, 0); 579 ret = vfs_mkdir(d_inode(dir), next, 0);
560 cachefiles_hist(cachefiles_mkdir_histogram, start); 580 cachefiles_hist(cachefiles_mkdir_histogram, start);
581 if (!key)
582 trace_cachefiles_mkdir(object, next, ret);
561 if (ret < 0) 583 if (ret < 0)
562 goto create_error; 584 goto create_error;
563 585
@@ -587,6 +609,7 @@ lookup_again:
587 start = jiffies; 609 start = jiffies;
588 ret = vfs_create(d_inode(dir), next, S_IFREG, true); 610 ret = vfs_create(d_inode(dir), next, S_IFREG, true);
589 cachefiles_hist(cachefiles_create_histogram, start); 611 cachefiles_hist(cachefiles_create_histogram, start);
612 trace_cachefiles_create(object, next, ret);
590 if (ret < 0) 613 if (ret < 0)
591 goto create_error; 614 goto create_error;
592 615
@@ -629,7 +652,8 @@ lookup_again:
629 * mutex) */ 652 * mutex) */
630 object->dentry = NULL; 653 object->dentry = NULL;
631 654
632 ret = cachefiles_bury_object(cache, dir, next, true, 655 ret = cachefiles_bury_object(cache, object, dir, next,
656 true,
633 FSCACHE_OBJECT_IS_STALE); 657 FSCACHE_OBJECT_IS_STALE);
634 dput(next); 658 dput(next);
635 next = NULL; 659 next = NULL;
@@ -955,7 +979,7 @@ int cachefiles_cull(struct cachefiles_cache *cache, struct dentry *dir,
955 /* actually remove the victim (drops the dir mutex) */ 979 /* actually remove the victim (drops the dir mutex) */
956 _debug("bury"); 980 _debug("bury");
957 981
958 ret = cachefiles_bury_object(cache, dir, victim, false, 982 ret = cachefiles_bury_object(cache, NULL, dir, victim, false,
959 FSCACHE_OBJECT_WAS_CULLED); 983 FSCACHE_OBJECT_WAS_CULLED);
960 if (ret < 0) 984 if (ret < 0)
961 goto error; 985 goto error;
diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c
index 98d22f495cd8..20bc3341f113 100644
--- a/fs/fscache/cookie.c
+++ b/fs/fscache/cookie.c
@@ -101,7 +101,7 @@ struct fscache_cookie *__fscache_acquire_cookie(
101 */ 101 */
102 atomic_set(&cookie->n_active, 1); 102 atomic_set(&cookie->n_active, 1);
103 103
104 atomic_inc(&parent->usage); 104 fscache_cookie_get(parent, fscache_cookie_get_acquire_parent);
105 atomic_inc(&parent->n_children); 105 atomic_inc(&parent->n_children);
106 106
107 cookie->def = def; 107 cookie->def = def;
@@ -125,6 +125,8 @@ struct fscache_cookie *__fscache_acquire_cookie(
125 break; 125 break;
126 } 126 }
127 127
128 trace_fscache_acquire(cookie);
129
128 if (enable) { 130 if (enable) {
129 /* if the object is an index then we need do nothing more here 131 /* if the object is an index then we need do nothing more here
130 * - we create indices on disk when we need them as an index 132 * - we create indices on disk when we need them as an index
@@ -134,7 +136,8 @@ struct fscache_cookie *__fscache_acquire_cookie(
134 set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags); 136 set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags);
135 } else { 137 } else {
136 atomic_dec(&parent->n_children); 138 atomic_dec(&parent->n_children);
137 __fscache_cookie_put(cookie); 139 fscache_cookie_put(cookie,
140 fscache_cookie_put_acquire_nobufs);
138 fscache_stat(&fscache_n_acquires_nobufs); 141 fscache_stat(&fscache_n_acquires_nobufs);
139 _leave(" = NULL"); 142 _leave(" = NULL");
140 return NULL; 143 return NULL;
@@ -159,6 +162,8 @@ void __fscache_enable_cookie(struct fscache_cookie *cookie,
159{ 162{
160 _enter("%p", cookie); 163 _enter("%p", cookie);
161 164
165 trace_fscache_enable(cookie);
166
162 wait_on_bit_lock(&cookie->flags, FSCACHE_COOKIE_ENABLEMENT_LOCK, 167 wait_on_bit_lock(&cookie->flags, FSCACHE_COOKIE_ENABLEMENT_LOCK,
163 TASK_UNINTERRUPTIBLE); 168 TASK_UNINTERRUPTIBLE);
164 169
@@ -318,7 +323,7 @@ static int fscache_alloc_object(struct fscache_cache *cache,
318 * attached to the cookie */ 323 * attached to the cookie */
319 if (fscache_attach_object(cookie, object) < 0) { 324 if (fscache_attach_object(cookie, object) < 0) {
320 fscache_stat(&fscache_n_cop_put_object); 325 fscache_stat(&fscache_n_cop_put_object);
321 cache->ops->put_object(object); 326 cache->ops->put_object(object, fscache_obj_put_attach_fail);
322 fscache_stat_d(&fscache_n_cop_put_object); 327 fscache_stat_d(&fscache_n_cop_put_object);
323 } 328 }
324 329
@@ -338,7 +343,7 @@ object_already_extant:
338 343
339error_put: 344error_put:
340 fscache_stat(&fscache_n_cop_put_object); 345 fscache_stat(&fscache_n_cop_put_object);
341 cache->ops->put_object(object); 346 cache->ops->put_object(object, fscache_obj_put_alloc_fail);
342 fscache_stat_d(&fscache_n_cop_put_object); 347 fscache_stat_d(&fscache_n_cop_put_object);
343error: 348error:
344 _leave(" = %d", ret); 349 _leave(" = %d", ret);
@@ -398,7 +403,7 @@ static int fscache_attach_object(struct fscache_cookie *cookie,
398 403
399 /* attach to the cookie */ 404 /* attach to the cookie */
400 object->cookie = cookie; 405 object->cookie = cookie;
401 atomic_inc(&cookie->usage); 406 fscache_cookie_get(cookie, fscache_cookie_get_attach_object);
402 hlist_add_head(&object->cookie_link, &cookie->backing_objects); 407 hlist_add_head(&object->cookie_link, &cookie->backing_objects);
403 408
404 fscache_objlist_add(object); 409 fscache_objlist_add(object);
@@ -516,6 +521,8 @@ void __fscache_disable_cookie(struct fscache_cookie *cookie, bool invalidate)
516 521
517 _enter("%p,%u", cookie, invalidate); 522 _enter("%p,%u", cookie, invalidate);
518 523
524 trace_fscache_disable(cookie);
525
519 ASSERTCMP(atomic_read(&cookie->n_active), >, 0); 526 ASSERTCMP(atomic_read(&cookie->n_active), >, 0);
520 527
521 if (atomic_read(&cookie->n_children) != 0) { 528 if (atomic_read(&cookie->n_children) != 0) {
@@ -601,6 +608,8 @@ void __fscache_relinquish_cookie(struct fscache_cookie *cookie, bool retire)
601 cookie, cookie->def->name, cookie->netfs_data, 608 cookie, cookie->def->name, cookie->netfs_data,
602 atomic_read(&cookie->n_active), retire); 609 atomic_read(&cookie->n_active), retire);
603 610
611 trace_fscache_relinquish(cookie, retire);
612
604 /* No further netfs-accessing operations on this cookie permitted */ 613 /* No further netfs-accessing operations on this cookie permitted */
605 if (test_and_set_bit(FSCACHE_COOKIE_RELINQUISHED, &cookie->flags)) 614 if (test_and_set_bit(FSCACHE_COOKIE_RELINQUISHED, &cookie->flags))
606 BUG(); 615 BUG();
@@ -620,35 +629,38 @@ void __fscache_relinquish_cookie(struct fscache_cookie *cookie, bool retire)
620 629
621 /* Dispose of the netfs's link to the cookie */ 630 /* Dispose of the netfs's link to the cookie */
622 ASSERTCMP(atomic_read(&cookie->usage), >, 0); 631 ASSERTCMP(atomic_read(&cookie->usage), >, 0);
623 fscache_cookie_put(cookie); 632 fscache_cookie_put(cookie, fscache_cookie_put_relinquish);
624 633
625 _leave(""); 634 _leave("");
626} 635}
627EXPORT_SYMBOL(__fscache_relinquish_cookie); 636EXPORT_SYMBOL(__fscache_relinquish_cookie);
628 637
629/* 638/*
630 * destroy a cookie 639 * Drop a reference to a cookie.
631 */ 640 */
632void __fscache_cookie_put(struct fscache_cookie *cookie) 641void fscache_cookie_put(struct fscache_cookie *cookie,
642 enum fscache_cookie_trace where)
633{ 643{
634 struct fscache_cookie *parent; 644 struct fscache_cookie *parent;
645 int usage;
635 646
636 _enter("%p", cookie); 647 _enter("%p", cookie);
637 648
638 for (;;) { 649 do {
639 _debug("FREE COOKIE %p", cookie); 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
640 parent = cookie->parent; 657 parent = cookie->parent;
641 BUG_ON(!hlist_empty(&cookie->backing_objects)); 658 BUG_ON(!hlist_empty(&cookie->backing_objects));
642 kmem_cache_free(fscache_cookie_jar, cookie); 659 kmem_cache_free(fscache_cookie_jar, cookie);
643 660
644 if (!parent)
645 break;
646
647 cookie = parent; 661 cookie = parent;
648 BUG_ON(atomic_read(&cookie->usage) <= 0); 662 where = fscache_cookie_put_parent;
649 if (!atomic_dec_and_test(&cookie->usage)) 663 } while (cookie);
650 break;
651 }
652 664
653 _leave(""); 665 _leave("");
654} 666}
diff --git a/fs/fscache/internal.h b/fs/fscache/internal.h
index 0ff4b49a0037..c27e2db3004e 100644
--- a/fs/fscache/internal.h
+++ b/fs/fscache/internal.h
@@ -29,6 +29,7 @@
29#define pr_fmt(fmt) "FS-Cache: " fmt 29#define pr_fmt(fmt) "FS-Cache: " fmt
30 30
31#include <linux/fscache-cache.h> 31#include <linux/fscache-cache.h>
32#include <trace/events/fscache.h>
32#include <linux/sched.h> 33#include <linux/sched.h>
33 34
34#define FSCACHE_MIN_THREADS 4 35#define FSCACHE_MIN_THREADS 4
@@ -49,7 +50,8 @@ extern struct fscache_cache *fscache_select_cache_for_object(
49extern struct kmem_cache *fscache_cookie_jar; 50extern struct kmem_cache *fscache_cookie_jar;
50 51
51extern void fscache_cookie_init_once(void *); 52extern void fscache_cookie_init_once(void *);
52extern void __fscache_cookie_put(struct fscache_cookie *); 53extern void fscache_cookie_put(struct fscache_cookie *,
54 enum fscache_cookie_trace);
53 55
54/* 56/*
55 * fsdef.c 57 * fsdef.c
@@ -311,14 +313,12 @@ static inline void fscache_raise_event(struct fscache_object *object,
311 fscache_enqueue_object(object); 313 fscache_enqueue_object(object);
312} 314}
313 315
314/* 316static inline void fscache_cookie_get(struct fscache_cookie *cookie,
315 * drop a reference to a cookie 317 enum fscache_cookie_trace where)
316 */
317static inline void fscache_cookie_put(struct fscache_cookie *cookie)
318{ 318{
319 BUG_ON(atomic_read(&cookie->usage) <= 0); 319 int usage = atomic_inc_return(&cookie->usage);
320 if (atomic_dec_and_test(&cookie->usage)) 320
321 __fscache_cookie_put(cookie); 321 trace_fscache_cookie(cookie, where, usage);
322} 322}
323 323
324/* 324/*
diff --git a/fs/fscache/main.c b/fs/fscache/main.c
index 249968dcbf5c..7dce110bf17d 100644
--- a/fs/fscache/main.c
+++ b/fs/fscache/main.c
@@ -16,6 +16,7 @@
16#include <linux/completion.h> 16#include <linux/completion.h>
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <linux/seq_file.h> 18#include <linux/seq_file.h>
19#define CREATE_TRACE_POINTS
19#include "internal.h" 20#include "internal.h"
20 21
21MODULE_DESCRIPTION("FS Cache Manager"); 22MODULE_DESCRIPTION("FS Cache Manager");
diff --git a/fs/fscache/netfs.c b/fs/fscache/netfs.c
index a8aa00be4444..c816600d1dde 100644
--- a/fs/fscache/netfs.c
+++ b/fs/fscache/netfs.c
@@ -60,7 +60,7 @@ int __fscache_register_netfs(struct fscache_netfs *netfs)
60 goto already_registered; 60 goto already_registered;
61 } 61 }
62 62
63 atomic_inc(&cookie->parent->usage); 63 fscache_cookie_get(cookie->parent, fscache_cookie_get_register_netfs);
64 atomic_inc(&cookie->parent->n_children); 64 atomic_inc(&cookie->parent->n_children);
65 65
66 netfs->primary_index = cookie; 66 netfs->primary_index = cookie;
@@ -68,6 +68,7 @@ int __fscache_register_netfs(struct fscache_netfs *netfs)
68 ret = 0; 68 ret = 0;
69 69
70 pr_notice("Netfs '%s' registered for caching\n", netfs->name); 70 pr_notice("Netfs '%s' registered for caching\n", netfs->name);
71 trace_fscache_netfs(netfs);
71 72
72already_registered: 73already_registered:
73 up_write(&fscache_addremove_sem); 74 up_write(&fscache_addremove_sem);
diff --git a/fs/fscache/object.c b/fs/fscache/object.c
index 7a182c87f378..99afe64352a5 100644
--- a/fs/fscache/object.c
+++ b/fs/fscache/object.c
@@ -138,8 +138,10 @@ static const struct fscache_transition fscache_osm_run_oob[] = {
138 { 0, NULL } 138 { 0, NULL }
139}; 139};
140 140
141static int fscache_get_object(struct fscache_object *); 141static int fscache_get_object(struct fscache_object *,
142static void fscache_put_object(struct fscache_object *); 142 enum fscache_obj_ref_trace);
143static void fscache_put_object(struct fscache_object *,
144 enum fscache_obj_ref_trace);
143static bool fscache_enqueue_dependents(struct fscache_object *, int); 145static bool fscache_enqueue_dependents(struct fscache_object *, int);
144static void fscache_dequeue_object(struct fscache_object *); 146static void fscache_dequeue_object(struct fscache_object *);
145 147
@@ -170,6 +172,7 @@ static void fscache_object_sm_dispatcher(struct fscache_object *object)
170 const struct fscache_transition *t; 172 const struct fscache_transition *t;
171 const struct fscache_state *state, *new_state; 173 const struct fscache_state *state, *new_state;
172 unsigned long events, event_mask; 174 unsigned long events, event_mask;
175 bool oob;
173 int event = -1; 176 int event = -1;
174 177
175 ASSERT(object != NULL); 178 ASSERT(object != NULL);
@@ -188,6 +191,7 @@ restart_masked:
188 if (events & object->oob_event_mask) { 191 if (events & object->oob_event_mask) {
189 _debug("{OBJ%x} oob %lx", 192 _debug("{OBJ%x} oob %lx",
190 object->debug_id, events & object->oob_event_mask); 193 object->debug_id, events & object->oob_event_mask);
194 oob = true;
191 for (t = object->oob_table; t->events; t++) { 195 for (t = object->oob_table; t->events; t++) {
192 if (events & t->events) { 196 if (events & t->events) {
193 state = t->transit_to; 197 state = t->transit_to;
@@ -199,6 +203,7 @@ restart_masked:
199 } 203 }
200 } 204 }
201 } 205 }
206 oob = false;
202 207
203 /* Wait states are just transition tables */ 208 /* Wait states are just transition tables */
204 if (!state->work) { 209 if (!state->work) {
@@ -207,6 +212,8 @@ restart_masked:
207 if (events & t->events) { 212 if (events & t->events) {
208 new_state = t->transit_to; 213 new_state = t->transit_to;
209 event = fls(events & t->events) - 1; 214 event = fls(events & t->events) - 1;
215 trace_fscache_osm(object, state,
216 true, false, event);
210 clear_bit(event, &object->events); 217 clear_bit(event, &object->events);
211 _debug("{OBJ%x} ev %d: %s -> %s", 218 _debug("{OBJ%x} ev %d: %s -> %s",
212 object->debug_id, event, 219 object->debug_id, event,
@@ -226,6 +233,7 @@ restart_masked:
226execute_work_state: 233execute_work_state:
227 _debug("{OBJ%x} exec %s", object->debug_id, state->name); 234 _debug("{OBJ%x} exec %s", object->debug_id, state->name);
228 235
236 trace_fscache_osm(object, state, false, oob, event);
229 new_state = state->work(object, event); 237 new_state = state->work(object, event);
230 event = -1; 238 event = -1;
231 if (new_state == NO_TRANSIT) { 239 if (new_state == NO_TRANSIT) {
@@ -279,7 +287,7 @@ static void fscache_object_work_func(struct work_struct *work)
279 start = jiffies; 287 start = jiffies;
280 fscache_object_sm_dispatcher(object); 288 fscache_object_sm_dispatcher(object);
281 fscache_hist(fscache_objs_histogram, start); 289 fscache_hist(fscache_objs_histogram, start);
282 fscache_put_object(object); 290 fscache_put_object(object, fscache_obj_put_work);
283} 291}
284 292
285/** 293/**
@@ -397,7 +405,7 @@ static const struct fscache_state *fscache_initialise_object(struct fscache_obje
397 fscache_stat(&fscache_n_cop_grab_object); 405 fscache_stat(&fscache_n_cop_grab_object);
398 success = false; 406 success = false;
399 if (fscache_object_is_live(parent) && 407 if (fscache_object_is_live(parent) &&
400 object->cache->ops->grab_object(object)) { 408 object->cache->ops->grab_object(object, fscache_obj_get_add_to_deps)) {
401 list_add(&object->dep_link, &parent->dependents); 409 list_add(&object->dep_link, &parent->dependents);
402 success = true; 410 success = true;
403 } 411 }
@@ -745,7 +753,7 @@ static const struct fscache_state *fscache_drop_object(struct fscache_object *ob
745 } 753 }
746 754
747 /* this just shifts the object release to the work processor */ 755 /* this just shifts the object release to the work processor */
748 fscache_put_object(object); 756 fscache_put_object(object, fscache_obj_put_drop_obj);
749 fscache_stat(&fscache_n_object_dead); 757 fscache_stat(&fscache_n_object_dead);
750 758
751 _leave(""); 759 _leave("");
@@ -755,12 +763,13 @@ static const struct fscache_state *fscache_drop_object(struct fscache_object *ob
755/* 763/*
756 * get a ref on an object 764 * get a ref on an object
757 */ 765 */
758static int fscache_get_object(struct fscache_object *object) 766static int fscache_get_object(struct fscache_object *object,
767 enum fscache_obj_ref_trace why)
759{ 768{
760 int ret; 769 int ret;
761 770
762 fscache_stat(&fscache_n_cop_grab_object); 771 fscache_stat(&fscache_n_cop_grab_object);
763 ret = object->cache->ops->grab_object(object) ? 0 : -EAGAIN; 772 ret = object->cache->ops->grab_object(object, why) ? 0 : -EAGAIN;
764 fscache_stat_d(&fscache_n_cop_grab_object); 773 fscache_stat_d(&fscache_n_cop_grab_object);
765 return ret; 774 return ret;
766} 775}
@@ -768,10 +777,11 @@ static int fscache_get_object(struct fscache_object *object)
768/* 777/*
769 * Discard a ref on an object 778 * Discard a ref on an object
770 */ 779 */
771static void fscache_put_object(struct fscache_object *object) 780static void fscache_put_object(struct fscache_object *object,
781 enum fscache_obj_ref_trace why)
772{ 782{
773 fscache_stat(&fscache_n_cop_put_object); 783 fscache_stat(&fscache_n_cop_put_object);
774 object->cache->ops->put_object(object); 784 object->cache->ops->put_object(object, why);
775 fscache_stat_d(&fscache_n_cop_put_object); 785 fscache_stat_d(&fscache_n_cop_put_object);
776} 786}
777 787
@@ -786,7 +796,7 @@ void fscache_object_destroy(struct fscache_object *object)
786 fscache_objlist_remove(object); 796 fscache_objlist_remove(object);
787 797
788 /* We can get rid of the cookie now */ 798 /* We can get rid of the cookie now */
789 fscache_cookie_put(object->cookie); 799 fscache_cookie_put(object->cookie, fscache_cookie_put_object);
790 object->cookie = NULL; 800 object->cookie = NULL;
791} 801}
792EXPORT_SYMBOL(fscache_object_destroy); 802EXPORT_SYMBOL(fscache_object_destroy);
@@ -798,7 +808,7 @@ void fscache_enqueue_object(struct fscache_object *object)
798{ 808{
799 _enter("{OBJ%x}", object->debug_id); 809 _enter("{OBJ%x}", object->debug_id);
800 810
801 if (fscache_get_object(object) >= 0) { 811 if (fscache_get_object(object, fscache_obj_get_queue) >= 0) {
802 wait_queue_head_t *cong_wq = 812 wait_queue_head_t *cong_wq =
803 &get_cpu_var(fscache_object_cong_wait); 813 &get_cpu_var(fscache_object_cong_wait);
804 814
@@ -806,7 +816,7 @@ void fscache_enqueue_object(struct fscache_object *object)
806 if (fscache_object_congested()) 816 if (fscache_object_congested())
807 wake_up(cong_wq); 817 wake_up(cong_wq);
808 } else 818 } else
809 fscache_put_object(object); 819 fscache_put_object(object, fscache_obj_put_queue);
810 820
811 put_cpu_var(fscache_object_cong_wait); 821 put_cpu_var(fscache_object_cong_wait);
812 } 822 }
@@ -866,7 +876,7 @@ static bool fscache_enqueue_dependents(struct fscache_object *object, int event)
866 list_del_init(&dep->dep_link); 876 list_del_init(&dep->dep_link);
867 877
868 fscache_raise_event(dep, event); 878 fscache_raise_event(dep, event);
869 fscache_put_object(dep); 879 fscache_put_object(dep, fscache_obj_put_enq_dep);
870 880
871 if (!list_empty(&object->dependents) && need_resched()) { 881 if (!list_empty(&object->dependents) && need_resched()) {
872 ret = false; 882 ret = false;
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;
29struct fscache_object; 29struct fscache_object;
30struct fscache_operation; 30struct fscache_operation;
31 31
32enum fscache_obj_ref_trace {
33 fscache_obj_get_add_to_deps,
34 fscache_obj_get_queue,
35 fscache_obj_put_alloc_fail,
36 fscache_obj_put_attach_fail,
37 fscache_obj_put_drop_obj,
38 fscache_obj_put_enq_dep,
39 fscache_obj_put_queue,
40 fscache_obj_put_work,
41 fscache_obj_ref__nr_traces
42};
43
32/* 44/*
33 * cache tag definition 45 * cache tag definition
34 */ 46 */
@@ -231,7 +243,8 @@ struct fscache_cache_ops {
231 void (*lookup_complete)(struct fscache_object *object); 243 void (*lookup_complete)(struct fscache_object *object);
232 244
233 /* increment the usage count on this object (may fail if unmounting) */ 245 /* increment the usage count on this object (may fail if unmounting) */
234 struct fscache_object *(*grab_object)(struct fscache_object *object); 246 struct fscache_object *(*grab_object)(struct fscache_object *object,
247 enum fscache_obj_ref_trace why);
235 248
236 /* pin an object in the cache */ 249 /* pin an object in the cache */
237 int (*pin_object)(struct fscache_object *object); 250 int (*pin_object)(struct fscache_object *object);
@@ -254,7 +267,8 @@ struct fscache_cache_ops {
254 void (*drop_object)(struct fscache_object *object); 267 void (*drop_object)(struct fscache_object *object);
255 268
256 /* dispose of a reference to an object */ 269 /* dispose of a reference to an object */
257 void (*put_object)(struct fscache_object *object); 270 void (*put_object)(struct fscache_object *object,
271 enum fscache_obj_ref_trace why);
258 272
259 /* sync a cache */ 273 /* sync a cache */
260 void (*sync_cache)(struct fscache_cache *cache); 274 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 @@
1/* CacheFiles tracepoints
2 *
3 * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11#undef TRACE_SYSTEM
12#define TRACE_SYSTEM cachefiles
13
14#if !defined(_TRACE_CACHEFILES_H) || defined(TRACE_HEADER_MULTI_READ)
15#define _TRACE_CACHEFILES_H
16
17#include <linux/tracepoint.h>
18
19/*
20 * Define enums for tracing information.
21 */
22#ifndef __CACHEFILES_DECLARE_TRACE_ENUMS_ONCE_ONLY
23#define __CACHEFILES_DECLARE_TRACE_ENUMS_ONCE_ONLY
24
25enum cachefiles_obj_ref_trace {
26 cachefiles_obj_put_wait_retry = fscache_obj_ref__nr_traces,
27 cachefiles_obj_put_wait_timeo,
28 cachefiles_obj_ref__nr_traces
29};
30
31#endif
32
33/*
34 * Define enum -> string mappings for display.
35 */
36#define cachefiles_obj_kill_traces \
37 EM(FSCACHE_OBJECT_IS_STALE, "stale") \
38 EM(FSCACHE_OBJECT_NO_SPACE, "no_space") \
39 EM(FSCACHE_OBJECT_WAS_RETIRED, "was_retired") \
40 E_(FSCACHE_OBJECT_WAS_CULLED, "was_culled")
41
42#define cachefiles_obj_ref_traces \
43 EM(fscache_obj_get_add_to_deps, "GET add_to_deps") \
44 EM(fscache_obj_get_queue, "GET queue") \
45 EM(fscache_obj_put_alloc_fail, "PUT alloc_fail") \
46 EM(fscache_obj_put_attach_fail, "PUT attach_fail") \
47 EM(fscache_obj_put_drop_obj, "PUT drop_obj") \
48 EM(fscache_obj_put_enq_dep, "PUT enq_dep") \
49 EM(fscache_obj_put_queue, "PUT queue") \
50 EM(fscache_obj_put_work, "PUT work") \
51 EM(cachefiles_obj_put_wait_retry, "PUT wait_retry") \
52 E_(cachefiles_obj_put_wait_timeo, "PUT wait_timeo")
53
54/*
55 * Export enum symbols via userspace.
56 */
57#undef EM
58#undef E_
59#define EM(a, b) TRACE_DEFINE_ENUM(a);
60#define E_(a, b) TRACE_DEFINE_ENUM(a);
61
62cachefiles_obj_kill_traces;
63cachefiles_obj_ref_traces;
64
65/*
66 * Now redefine the EM() and E_() macros to map the enums to the strings that
67 * will be printed in the output.
68 */
69#undef EM
70#undef E_
71#define EM(a, b) { a, b },
72#define E_(a, b) { a, b }
73
74
75TRACE_EVENT(cachefiles_ref,
76 TP_PROTO(struct cachefiles_object *obj,
77 struct fscache_cookie *cookie,
78 enum cachefiles_obj_ref_trace why,
79 int usage),
80
81 TP_ARGS(obj, cookie, why, usage),
82
83 /* Note that obj may be NULL */
84 TP_STRUCT__entry(
85 __field(struct cachefiles_object *, obj )
86 __field(struct fscache_cookie *, cookie )
87 __field(enum cachefiles_obj_ref_trace, why )
88 __field(int, usage )
89 ),
90
91 TP_fast_assign(
92 __entry->obj = obj;
93 __entry->cookie = cookie;
94 __entry->usage = usage;
95 __entry->why = why;
96 ),
97
98 TP_printk("c=%p o=%p u=%d %s",
99 __entry->cookie, __entry->obj, __entry->usage,
100 __print_symbolic(__entry->why, cachefiles_obj_ref_traces))
101 );
102
103TRACE_EVENT(cachefiles_lookup,
104 TP_PROTO(struct cachefiles_object *obj,
105 struct dentry *de,
106 struct inode *inode),
107
108 TP_ARGS(obj, de, inode),
109
110 TP_STRUCT__entry(
111 __field(struct cachefiles_object *, obj )
112 __field(struct dentry *, de )
113 __field(struct inode *, inode )
114 ),
115
116 TP_fast_assign(
117 __entry->obj = obj;
118 __entry->de = de;
119 __entry->inode = inode;
120 ),
121
122 TP_printk("o=%p d=%p i=%p",
123 __entry->obj, __entry->de, __entry->inode)
124 );
125
126TRACE_EVENT(cachefiles_mkdir,
127 TP_PROTO(struct cachefiles_object *obj,
128 struct dentry *de, int ret),
129
130 TP_ARGS(obj, de, ret),
131
132 TP_STRUCT__entry(
133 __field(struct cachefiles_object *, obj )
134 __field(struct dentry *, de )
135 __field(int, ret )
136 ),
137
138 TP_fast_assign(
139 __entry->obj = obj;
140 __entry->de = de;
141 __entry->ret = ret;
142 ),
143
144 TP_printk("o=%p d=%p r=%u",
145 __entry->obj, __entry->de, __entry->ret)
146 );
147
148TRACE_EVENT(cachefiles_create,
149 TP_PROTO(struct cachefiles_object *obj,
150 struct dentry *de, int ret),
151
152 TP_ARGS(obj, de, ret),
153
154 TP_STRUCT__entry(
155 __field(struct cachefiles_object *, obj )
156 __field(struct dentry *, de )
157 __field(int, ret )
158 ),
159
160 TP_fast_assign(
161 __entry->obj = obj;
162 __entry->de = de;
163 __entry->ret = ret;
164 ),
165
166 TP_printk("o=%p d=%p r=%u",
167 __entry->obj, __entry->de, __entry->ret)
168 );
169
170TRACE_EVENT(cachefiles_unlink,
171 TP_PROTO(struct cachefiles_object *obj,
172 struct dentry *de,
173 enum fscache_why_object_killed why),
174
175 TP_ARGS(obj, de, why),
176
177 /* Note that obj may be NULL */
178 TP_STRUCT__entry(
179 __field(struct cachefiles_object *, obj )
180 __field(struct dentry *, de )
181 __field(enum fscache_why_object_killed, why )
182 ),
183
184 TP_fast_assign(
185 __entry->obj = obj;
186 __entry->de = de;
187 __entry->why = why;
188 ),
189
190 TP_printk("o=%p d=%p w=%s",
191 __entry->obj, __entry->de,
192 __print_symbolic(__entry->why, cachefiles_obj_kill_traces))
193 );
194
195TRACE_EVENT(cachefiles_rename,
196 TP_PROTO(struct cachefiles_object *obj,
197 struct dentry *de,
198 struct dentry *to,
199 enum fscache_why_object_killed why),
200
201 TP_ARGS(obj, de, to, why),
202
203 /* Note that obj may be NULL */
204 TP_STRUCT__entry(
205 __field(struct cachefiles_object *, obj )
206 __field(struct dentry *, de )
207 __field(struct dentry *, to )
208 __field(enum fscache_why_object_killed, why )
209 ),
210
211 TP_fast_assign(
212 __entry->obj = obj;
213 __entry->de = de;
214 __entry->to = to;
215 __entry->why = why;
216 ),
217
218 TP_printk("o=%p d=%p t=%p w=%s",
219 __entry->obj, __entry->de, __entry->to,
220 __print_symbolic(__entry->why, cachefiles_obj_kill_traces))
221 );
222
223TRACE_EVENT(cachefiles_mark_active,
224 TP_PROTO(struct cachefiles_object *obj,
225 struct dentry *de),
226
227 TP_ARGS(obj, de),
228
229 /* Note that obj may be NULL */
230 TP_STRUCT__entry(
231 __field(struct cachefiles_object *, obj )
232 __field(struct dentry *, de )
233 ),
234
235 TP_fast_assign(
236 __entry->obj = obj;
237 __entry->de = de;
238 ),
239
240 TP_printk("o=%p d=%p",
241 __entry->obj, __entry->de)
242 );
243
244TRACE_EVENT(cachefiles_wait_active,
245 TP_PROTO(struct cachefiles_object *obj,
246 struct dentry *de,
247 struct cachefiles_object *xobj),
248
249 TP_ARGS(obj, de, xobj),
250
251 /* Note that obj may be NULL */
252 TP_STRUCT__entry(
253 __field(struct cachefiles_object *, obj )
254 __field(struct dentry *, de )
255 __field(struct cachefiles_object *, xobj )
256 __field(u16, flags )
257 __field(u16, fsc_flags )
258 ),
259
260 TP_fast_assign(
261 __entry->obj = obj;
262 __entry->de = de;
263 __entry->xobj = xobj;
264 __entry->flags = xobj->flags;
265 __entry->fsc_flags = xobj->fscache.flags;
266 ),
267
268 TP_printk("o=%p d=%p wo=%p wf=%x wff=%x",
269 __entry->obj, __entry->de, __entry->xobj,
270 __entry->flags, __entry->fsc_flags)
271 );
272
273TRACE_EVENT(cachefiles_mark_inactive,
274 TP_PROTO(struct cachefiles_object *obj,
275 struct dentry *de,
276 struct inode *inode),
277
278 TP_ARGS(obj, de, inode),
279
280 /* Note that obj may be NULL */
281 TP_STRUCT__entry(
282 __field(struct cachefiles_object *, obj )
283 __field(struct dentry *, de )
284 __field(struct inode *, inode )
285 ),
286
287 TP_fast_assign(
288 __entry->obj = obj;
289 __entry->de = de;
290 __entry->inode = inode;
291 ),
292
293 TP_printk("o=%p d=%p i=%p",
294 __entry->obj, __entry->de, __entry->inode)
295 );
296
297TRACE_EVENT(cachefiles_mark_buried,
298 TP_PROTO(struct cachefiles_object *obj,
299 struct dentry *de,
300 enum fscache_why_object_killed why),
301
302 TP_ARGS(obj, de, why),
303
304 /* Note that obj may be NULL */
305 TP_STRUCT__entry(
306 __field(struct cachefiles_object *, obj )
307 __field(struct dentry *, de )
308 __field(enum fscache_why_object_killed, why )
309 ),
310
311 TP_fast_assign(
312 __entry->obj = obj;
313 __entry->de = de;
314 __entry->why = why;
315 ),
316
317 TP_printk("o=%p d=%p w=%s",
318 __entry->obj, __entry->de,
319 __print_symbolic(__entry->why, cachefiles_obj_kill_traces))
320 );
321
322#endif /* _TRACE_CACHEFILES_H */
323
324/* This part must be outside protection */
325#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 @@
1/* FS-Cache tracepoints
2 *
3 * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11#undef TRACE_SYSTEM
12#define TRACE_SYSTEM fscache
13
14#if !defined(_TRACE_FSCACHE_H) || defined(TRACE_HEADER_MULTI_READ)
15#define _TRACE_FSCACHE_H
16
17#include <linux/fscache.h>
18#include <linux/tracepoint.h>
19
20/*
21 * Define enums for tracing information.
22 */
23#ifndef __FSCACHE_DECLARE_TRACE_ENUMS_ONCE_ONLY
24#define __FSCACHE_DECLARE_TRACE_ENUMS_ONCE_ONLY
25
26enum fscache_cookie_trace {
27 fscache_cookie_get_acquire_parent,
28 fscache_cookie_get_attach_object,
29 fscache_cookie_get_register_netfs,
30 fscache_cookie_put_acquire_nobufs,
31 fscache_cookie_put_relinquish,
32 fscache_cookie_put_object,
33 fscache_cookie_put_parent,
34};
35
36#endif
37
38/*
39 * Declare tracing information enums and their string mappings for display.
40 */
41#define fscache_cookie_traces \
42 EM(fscache_cookie_get_acquire_parent, "GET prn") \
43 EM(fscache_cookie_get_attach_object, "GET obj") \
44 EM(fscache_cookie_get_register_netfs, "GET net") \
45 EM(fscache_cookie_put_acquire_nobufs, "PUT nbf") \
46 EM(fscache_cookie_put_relinquish, "PUT rlq") \
47 EM(fscache_cookie_put_object, "PUT obj") \
48 E_(fscache_cookie_put_parent, "PUT prn")
49
50/*
51 * Export enum symbols via userspace.
52 */
53#undef EM
54#undef E_
55#define EM(a, b) TRACE_DEFINE_ENUM(a);
56#define E_(a, b) TRACE_DEFINE_ENUM(a);
57
58fscache_cookie_traces;
59
60/*
61 * Now redefine the EM() and E_() macros to map the enums to the strings that
62 * will be printed in the output.
63 */
64#undef EM
65#undef E_
66#define EM(a, b) { a, b },
67#define E_(a, b) { a, b }
68
69
70TRACE_EVENT(fscache_cookie,
71 TP_PROTO(struct fscache_cookie *cookie,
72 enum fscache_cookie_trace where,
73 int usage),
74
75 TP_ARGS(cookie, where, usage),
76
77 TP_STRUCT__entry(
78 __field(struct fscache_cookie *, cookie )
79 __field(struct fscache_cookie *, parent )
80 __field(enum fscache_cookie_trace, where )
81 __field(int, usage )
82 __field(int, n_children )
83 __field(int, n_active )
84 __field(u8, flags )
85 ),
86
87 TP_fast_assign(
88 __entry->cookie = cookie;
89 __entry->parent = cookie->parent;
90 __entry->where = where;
91 __entry->usage = usage;
92 __entry->n_children = atomic_read(&cookie->n_children);
93 __entry->n_active = atomic_read(&cookie->n_active);
94 __entry->flags = cookie->flags;
95 ),
96
97 TP_printk("%s c=%p u=%d p=%p Nc=%d Na=%d f=%02x",
98 __print_symbolic(__entry->where, fscache_cookie_traces),
99 __entry->cookie, __entry->usage,
100 __entry->parent, __entry->n_children, __entry->n_active,
101 __entry->flags)
102 );
103
104TRACE_EVENT(fscache_netfs,
105 TP_PROTO(struct fscache_netfs *netfs),
106
107 TP_ARGS(netfs),
108
109 TP_STRUCT__entry(
110 __field(struct fscache_cookie *, cookie )
111 __array(char, name, 8 )
112 ),
113
114 TP_fast_assign(
115 __entry->cookie = netfs->primary_index;
116 strncpy(__entry->name, netfs->name, 8);
117 __entry->name[7] = 0;
118 ),
119
120 TP_printk("c=%p n=%s",
121 __entry->cookie, __entry->name)
122 );
123
124TRACE_EVENT(fscache_acquire,
125 TP_PROTO(struct fscache_cookie *cookie),
126
127 TP_ARGS(cookie),
128
129 TP_STRUCT__entry(
130 __field(struct fscache_cookie *, cookie )
131 __field(struct fscache_cookie *, parent )
132 __array(char, name, 8 )
133 __field(int, p_usage )
134 __field(int, p_n_children )
135 __field(u8, p_flags )
136 ),
137
138 TP_fast_assign(
139 __entry->cookie = cookie;
140 __entry->parent = cookie->parent;
141 __entry->p_usage = atomic_read(&cookie->parent->usage);
142 __entry->p_n_children = atomic_read(&cookie->parent->n_children);
143 __entry->p_flags = cookie->parent->flags;
144 memcpy(__entry->name, cookie->def->name, 8);
145 __entry->name[7] = 0;
146 ),
147
148 TP_printk("c=%p p=%p pu=%d pc=%d pf=%02x n=%s",
149 __entry->cookie, __entry->parent, __entry->p_usage,
150 __entry->p_n_children, __entry->p_flags, __entry->name)
151 );
152
153TRACE_EVENT(fscache_relinquish,
154 TP_PROTO(struct fscache_cookie *cookie, bool retire),
155
156 TP_ARGS(cookie, retire),
157
158 TP_STRUCT__entry(
159 __field(struct fscache_cookie *, cookie )
160 __field(struct fscache_cookie *, parent )
161 __field(int, usage )
162 __field(int, n_children )
163 __field(int, n_active )
164 __field(u8, flags )
165 __field(bool, retire )
166 ),
167
168 TP_fast_assign(
169 __entry->cookie = cookie;
170 __entry->parent = cookie->parent;
171 __entry->usage = atomic_read(&cookie->usage);
172 __entry->n_children = atomic_read(&cookie->n_children);
173 __entry->n_active = atomic_read(&cookie->n_active);
174 __entry->flags = cookie->flags;
175 __entry->retire = retire;
176 ),
177
178 TP_printk("c=%p u=%d p=%p Nc=%d Na=%d f=%02x r=%u",
179 __entry->cookie, __entry->usage,
180 __entry->parent, __entry->n_children, __entry->n_active,
181 __entry->flags, __entry->retire)
182 );
183
184TRACE_EVENT(fscache_enable,
185 TP_PROTO(struct fscache_cookie *cookie),
186
187 TP_ARGS(cookie),
188
189 TP_STRUCT__entry(
190 __field(struct fscache_cookie *, cookie )
191 __field(int, usage )
192 __field(int, n_children )
193 __field(int, n_active )
194 __field(u8, flags )
195 ),
196
197 TP_fast_assign(
198 __entry->cookie = cookie;
199 __entry->usage = atomic_read(&cookie->usage);
200 __entry->n_children = atomic_read(&cookie->n_children);
201 __entry->n_active = atomic_read(&cookie->n_active);
202 __entry->flags = cookie->flags;
203 ),
204
205 TP_printk("c=%p u=%d Nc=%d Na=%d f=%02x",
206 __entry->cookie, __entry->usage,
207 __entry->n_children, __entry->n_active, __entry->flags)
208 );
209
210TRACE_EVENT(fscache_disable,
211 TP_PROTO(struct fscache_cookie *cookie),
212
213 TP_ARGS(cookie),
214
215 TP_STRUCT__entry(
216 __field(struct fscache_cookie *, cookie )
217 __field(int, usage )
218 __field(int, n_children )
219 __field(int, n_active )
220 __field(u8, flags )
221 ),
222
223 TP_fast_assign(
224 __entry->cookie = cookie;
225 __entry->usage = atomic_read(&cookie->usage);
226 __entry->n_children = atomic_read(&cookie->n_children);
227 __entry->n_active = atomic_read(&cookie->n_active);
228 __entry->flags = cookie->flags;
229 ),
230
231 TP_printk("c=%p u=%d Nc=%d Na=%d f=%02x",
232 __entry->cookie, __entry->usage,
233 __entry->n_children, __entry->n_active, __entry->flags)
234 );
235
236TRACE_EVENT(fscache_osm,
237 TP_PROTO(struct fscache_object *object,
238 const struct fscache_state *state,
239 bool wait, bool oob, s8 event_num),
240
241 TP_ARGS(object, state, wait, oob, event_num),
242
243 TP_STRUCT__entry(
244 __field(struct fscache_cookie *, cookie )
245 __field(struct fscache_object *, object )
246 __array(char, state, 8 )
247 __field(bool, wait )
248 __field(bool, oob )
249 __field(s8, event_num )
250 ),
251
252 TP_fast_assign(
253 __entry->cookie = object->cookie;
254 __entry->object = object;
255 __entry->wait = wait;
256 __entry->oob = oob;
257 __entry->event_num = event_num;
258 memcpy(__entry->state, state->short_name, 8);
259 ),
260
261 TP_printk("c=%p o=%p %s %s%sev=%d",
262 __entry->cookie,
263 __entry->object,
264 __entry->state,
265 __print_symbolic(__entry->wait,
266 { true, "WAIT" },
267 { false, "WORK" }),
268 __print_symbolic(__entry->oob,
269 { true, " OOB " },
270 { false, " " }),
271 __entry->event_num)
272 );
273
274#endif /* _TRACE_FSCACHE_H */
275
276/* This part must be outside protection */
277#include <trace/define_trace.h>