diff options
-rw-r--r-- | fs/fscache/cookie.c | 3 | ||||
-rw-r--r-- | fs/fscache/object.c | 3 | ||||
-rw-r--r-- | fs/fscache/operation.c | 26 | ||||
-rw-r--r-- | fs/fscache/page.c | 51 | ||||
-rw-r--r-- | include/linux/fscache-cache.h | 3 | ||||
-rw-r--r-- | include/trace/events/fscache.h | 252 |
6 files changed, 330 insertions, 8 deletions
diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c index 20bc3341f113..ea1f80daaff4 100644 --- a/fs/fscache/cookie.c +++ b/fs/fscache/cookie.c | |||
@@ -691,10 +691,11 @@ int __fscache_check_consistency(struct fscache_cookie *cookie) | |||
691 | if (!op) | 691 | if (!op) |
692 | return -ENOMEM; | 692 | return -ENOMEM; |
693 | 693 | ||
694 | fscache_operation_init(op, NULL, NULL, NULL); | 694 | fscache_operation_init(cookie, op, NULL, NULL, NULL); |
695 | op->flags = FSCACHE_OP_MYTHREAD | | 695 | op->flags = FSCACHE_OP_MYTHREAD | |
696 | (1 << FSCACHE_OP_WAITING) | | 696 | (1 << FSCACHE_OP_WAITING) | |
697 | (1 << FSCACHE_OP_UNUSE_COOKIE); | 697 | (1 << FSCACHE_OP_UNUSE_COOKIE); |
698 | trace_fscache_page_op(cookie, NULL, op, fscache_page_op_check_consistency); | ||
698 | 699 | ||
699 | spin_lock(&cookie->lock); | 700 | spin_lock(&cookie->lock); |
700 | 701 | ||
diff --git a/fs/fscache/object.c b/fs/fscache/object.c index 99afe64352a5..7c0ddb7ae29a 100644 --- a/fs/fscache/object.c +++ b/fs/fscache/object.c | |||
@@ -982,11 +982,12 @@ static const struct fscache_state *_fscache_invalidate_object(struct fscache_obj | |||
982 | if (!op) | 982 | if (!op) |
983 | goto nomem; | 983 | goto nomem; |
984 | 984 | ||
985 | fscache_operation_init(op, object->cache->ops->invalidate_object, | 985 | fscache_operation_init(cookie, op, object->cache->ops->invalidate_object, |
986 | NULL, NULL); | 986 | NULL, NULL); |
987 | op->flags = FSCACHE_OP_ASYNC | | 987 | op->flags = FSCACHE_OP_ASYNC | |
988 | (1 << FSCACHE_OP_EXCLUSIVE) | | 988 | (1 << FSCACHE_OP_EXCLUSIVE) | |
989 | (1 << FSCACHE_OP_UNUSE_COOKIE); | 989 | (1 << FSCACHE_OP_UNUSE_COOKIE); |
990 | trace_fscache_page_op(cookie, NULL, op, fscache_page_op_invalidate); | ||
990 | 991 | ||
991 | spin_lock(&cookie->lock); | 992 | spin_lock(&cookie->lock); |
992 | if (fscache_submit_exclusive_op(object, op) < 0) | 993 | if (fscache_submit_exclusive_op(object, op) < 0) |
diff --git a/fs/fscache/operation.c b/fs/fscache/operation.c index de67745e1cd7..7a071e1e952d 100644 --- a/fs/fscache/operation.c +++ b/fs/fscache/operation.c | |||
@@ -32,7 +32,8 @@ static void fscache_operation_dummy_cancel(struct fscache_operation *op) | |||
32 | * Do basic initialisation of an operation. The caller must still set flags, | 32 | * Do basic initialisation of an operation. The caller must still set flags, |
33 | * object and processor if needed. | 33 | * object and processor if needed. |
34 | */ | 34 | */ |
35 | void fscache_operation_init(struct fscache_operation *op, | 35 | void fscache_operation_init(struct fscache_cookie *cookie, |
36 | struct fscache_operation *op, | ||
36 | fscache_operation_processor_t processor, | 37 | fscache_operation_processor_t processor, |
37 | fscache_operation_cancel_t cancel, | 38 | fscache_operation_cancel_t cancel, |
38 | fscache_operation_release_t release) | 39 | fscache_operation_release_t release) |
@@ -46,6 +47,7 @@ void fscache_operation_init(struct fscache_operation *op, | |||
46 | op->release = release; | 47 | op->release = release; |
47 | INIT_LIST_HEAD(&op->pend_link); | 48 | INIT_LIST_HEAD(&op->pend_link); |
48 | fscache_stat(&fscache_n_op_initialised); | 49 | fscache_stat(&fscache_n_op_initialised); |
50 | trace_fscache_op(cookie, op, fscache_op_init); | ||
49 | } | 51 | } |
50 | EXPORT_SYMBOL(fscache_operation_init); | 52 | EXPORT_SYMBOL(fscache_operation_init); |
51 | 53 | ||
@@ -59,6 +61,8 @@ EXPORT_SYMBOL(fscache_operation_init); | |||
59 | */ | 61 | */ |
60 | void fscache_enqueue_operation(struct fscache_operation *op) | 62 | void fscache_enqueue_operation(struct fscache_operation *op) |
61 | { | 63 | { |
64 | struct fscache_cookie *cookie = op->object->cookie; | ||
65 | |||
62 | _enter("{OBJ%x OP%x,%u}", | 66 | _enter("{OBJ%x OP%x,%u}", |
63 | op->object->debug_id, op->debug_id, atomic_read(&op->usage)); | 67 | op->object->debug_id, op->debug_id, atomic_read(&op->usage)); |
64 | 68 | ||
@@ -71,12 +75,14 @@ void fscache_enqueue_operation(struct fscache_operation *op) | |||
71 | fscache_stat(&fscache_n_op_enqueue); | 75 | fscache_stat(&fscache_n_op_enqueue); |
72 | switch (op->flags & FSCACHE_OP_TYPE) { | 76 | switch (op->flags & FSCACHE_OP_TYPE) { |
73 | case FSCACHE_OP_ASYNC: | 77 | case FSCACHE_OP_ASYNC: |
78 | trace_fscache_op(cookie, op, fscache_op_enqueue_async); | ||
74 | _debug("queue async"); | 79 | _debug("queue async"); |
75 | atomic_inc(&op->usage); | 80 | atomic_inc(&op->usage); |
76 | if (!queue_work(fscache_op_wq, &op->work)) | 81 | if (!queue_work(fscache_op_wq, &op->work)) |
77 | fscache_put_operation(op); | 82 | fscache_put_operation(op); |
78 | break; | 83 | break; |
79 | case FSCACHE_OP_MYTHREAD: | 84 | case FSCACHE_OP_MYTHREAD: |
85 | trace_fscache_op(cookie, op, fscache_op_enqueue_mythread); | ||
80 | _debug("queue for caller's attention"); | 86 | _debug("queue for caller's attention"); |
81 | break; | 87 | break; |
82 | default: | 88 | default: |
@@ -101,6 +107,8 @@ static void fscache_run_op(struct fscache_object *object, | |||
101 | wake_up_bit(&op->flags, FSCACHE_OP_WAITING); | 107 | wake_up_bit(&op->flags, FSCACHE_OP_WAITING); |
102 | if (op->processor) | 108 | if (op->processor) |
103 | fscache_enqueue_operation(op); | 109 | fscache_enqueue_operation(op); |
110 | else | ||
111 | trace_fscache_op(object->cookie, op, fscache_op_run); | ||
104 | fscache_stat(&fscache_n_op_run); | 112 | fscache_stat(&fscache_n_op_run); |
105 | } | 113 | } |
106 | 114 | ||
@@ -155,6 +163,8 @@ int fscache_submit_exclusive_op(struct fscache_object *object, | |||
155 | 163 | ||
156 | _enter("{OBJ%x OP%x},", object->debug_id, op->debug_id); | 164 | _enter("{OBJ%x OP%x},", object->debug_id, op->debug_id); |
157 | 165 | ||
166 | trace_fscache_op(object->cookie, op, fscache_op_submit_ex); | ||
167 | |||
158 | ASSERTCMP(op->state, ==, FSCACHE_OP_ST_INITIALISED); | 168 | ASSERTCMP(op->state, ==, FSCACHE_OP_ST_INITIALISED); |
159 | ASSERTCMP(atomic_read(&op->usage), >, 0); | 169 | ASSERTCMP(atomic_read(&op->usage), >, 0); |
160 | 170 | ||
@@ -240,6 +250,8 @@ int fscache_submit_op(struct fscache_object *object, | |||
240 | _enter("{OBJ%x OP%x},{%u}", | 250 | _enter("{OBJ%x OP%x},{%u}", |
241 | object->debug_id, op->debug_id, atomic_read(&op->usage)); | 251 | object->debug_id, op->debug_id, atomic_read(&op->usage)); |
242 | 252 | ||
253 | trace_fscache_op(object->cookie, op, fscache_op_submit); | ||
254 | |||
243 | ASSERTCMP(op->state, ==, FSCACHE_OP_ST_INITIALISED); | 255 | ASSERTCMP(op->state, ==, FSCACHE_OP_ST_INITIALISED); |
244 | ASSERTCMP(atomic_read(&op->usage), >, 0); | 256 | ASSERTCMP(atomic_read(&op->usage), >, 0); |
245 | 257 | ||
@@ -357,6 +369,8 @@ int fscache_cancel_op(struct fscache_operation *op, | |||
357 | 369 | ||
358 | _enter("OBJ%x OP%x}", op->object->debug_id, op->debug_id); | 370 | _enter("OBJ%x OP%x}", op->object->debug_id, op->debug_id); |
359 | 371 | ||
372 | trace_fscache_op(object->cookie, op, fscache_op_cancel); | ||
373 | |||
360 | ASSERTCMP(op->state, >=, FSCACHE_OP_ST_PENDING); | 374 | ASSERTCMP(op->state, >=, FSCACHE_OP_ST_PENDING); |
361 | ASSERTCMP(op->state, !=, FSCACHE_OP_ST_CANCELLED); | 375 | ASSERTCMP(op->state, !=, FSCACHE_OP_ST_CANCELLED); |
362 | ASSERTCMP(atomic_read(&op->usage), >, 0); | 376 | ASSERTCMP(atomic_read(&op->usage), >, 0); |
@@ -419,6 +433,8 @@ void fscache_cancel_all_ops(struct fscache_object *object) | |||
419 | fscache_stat(&fscache_n_op_cancelled); | 433 | fscache_stat(&fscache_n_op_cancelled); |
420 | list_del_init(&op->pend_link); | 434 | list_del_init(&op->pend_link); |
421 | 435 | ||
436 | trace_fscache_op(object->cookie, op, fscache_op_cancel_all); | ||
437 | |||
422 | ASSERTCMP(op->state, ==, FSCACHE_OP_ST_PENDING); | 438 | ASSERTCMP(op->state, ==, FSCACHE_OP_ST_PENDING); |
423 | op->cancel(op); | 439 | op->cancel(op); |
424 | op->state = FSCACHE_OP_ST_CANCELLED; | 440 | op->state = FSCACHE_OP_ST_CANCELLED; |
@@ -454,9 +470,11 @@ void fscache_op_complete(struct fscache_operation *op, bool cancelled) | |||
454 | spin_lock(&object->lock); | 470 | spin_lock(&object->lock); |
455 | 471 | ||
456 | if (!cancelled) { | 472 | if (!cancelled) { |
473 | trace_fscache_op(object->cookie, op, fscache_op_completed); | ||
457 | op->state = FSCACHE_OP_ST_COMPLETE; | 474 | op->state = FSCACHE_OP_ST_COMPLETE; |
458 | } else { | 475 | } else { |
459 | op->cancel(op); | 476 | op->cancel(op); |
477 | trace_fscache_op(object->cookie, op, fscache_op_cancelled); | ||
460 | op->state = FSCACHE_OP_ST_CANCELLED; | 478 | op->state = FSCACHE_OP_ST_CANCELLED; |
461 | } | 479 | } |
462 | 480 | ||
@@ -488,6 +506,8 @@ void fscache_put_operation(struct fscache_operation *op) | |||
488 | if (!atomic_dec_and_test(&op->usage)) | 506 | if (!atomic_dec_and_test(&op->usage)) |
489 | return; | 507 | return; |
490 | 508 | ||
509 | trace_fscache_op(op->object->cookie, op, fscache_op_put); | ||
510 | |||
491 | _debug("PUT OP"); | 511 | _debug("PUT OP"); |
492 | ASSERTIFCMP(op->state != FSCACHE_OP_ST_INITIALISED && | 512 | ASSERTIFCMP(op->state != FSCACHE_OP_ST_INITIALISED && |
493 | op->state != FSCACHE_OP_ST_COMPLETE, | 513 | op->state != FSCACHE_OP_ST_COMPLETE, |
@@ -563,6 +583,8 @@ void fscache_operation_gc(struct work_struct *work) | |||
563 | spin_unlock(&cache->op_gc_list_lock); | 583 | spin_unlock(&cache->op_gc_list_lock); |
564 | 584 | ||
565 | object = op->object; | 585 | object = op->object; |
586 | trace_fscache_op(object->cookie, op, fscache_op_gc); | ||
587 | |||
566 | spin_lock(&object->lock); | 588 | spin_lock(&object->lock); |
567 | 589 | ||
568 | _debug("GC DEFERRED REL OBJ%x OP%x", | 590 | _debug("GC DEFERRED REL OBJ%x OP%x", |
@@ -601,6 +623,8 @@ void fscache_op_work_func(struct work_struct *work) | |||
601 | _enter("{OBJ%x OP%x,%d}", | 623 | _enter("{OBJ%x OP%x,%d}", |
602 | op->object->debug_id, op->debug_id, atomic_read(&op->usage)); | 624 | op->object->debug_id, op->debug_id, atomic_read(&op->usage)); |
603 | 625 | ||
626 | trace_fscache_op(op->object->cookie, op, fscache_op_work); | ||
627 | |||
604 | ASSERT(op->processor != NULL); | 628 | ASSERT(op->processor != NULL); |
605 | start = jiffies; | 629 | start = jiffies; |
606 | op->processor(op); | 630 | op->processor(op); |
diff --git a/fs/fscache/page.c b/fs/fscache/page.c index b9f18bf4227d..810b33aced1c 100644 --- a/fs/fscache/page.c +++ b/fs/fscache/page.c | |||
@@ -27,6 +27,7 @@ bool __fscache_check_page_write(struct fscache_cookie *cookie, struct page *page | |||
27 | rcu_read_lock(); | 27 | rcu_read_lock(); |
28 | val = radix_tree_lookup(&cookie->stores, page->index); | 28 | val = radix_tree_lookup(&cookie->stores, page->index); |
29 | rcu_read_unlock(); | 29 | rcu_read_unlock(); |
30 | trace_fscache_check_page(cookie, page, val, 0); | ||
30 | 31 | ||
31 | return val != NULL; | 32 | return val != NULL; |
32 | } | 33 | } |
@@ -39,6 +40,8 @@ void __fscache_wait_on_page_write(struct fscache_cookie *cookie, struct page *pa | |||
39 | { | 40 | { |
40 | wait_queue_head_t *wq = bit_waitqueue(&cookie->flags, 0); | 41 | wait_queue_head_t *wq = bit_waitqueue(&cookie->flags, 0); |
41 | 42 | ||
43 | trace_fscache_page(cookie, page, fscache_page_write_wait); | ||
44 | |||
42 | wait_event(*wq, !__fscache_check_page_write(cookie, page)); | 45 | wait_event(*wq, !__fscache_check_page_write(cookie, page)); |
43 | } | 46 | } |
44 | EXPORT_SYMBOL(__fscache_wait_on_page_write); | 47 | EXPORT_SYMBOL(__fscache_wait_on_page_write); |
@@ -69,6 +72,8 @@ bool __fscache_maybe_release_page(struct fscache_cookie *cookie, | |||
69 | 72 | ||
70 | _enter("%p,%p,%x", cookie, page, gfp); | 73 | _enter("%p,%p,%x", cookie, page, gfp); |
71 | 74 | ||
75 | trace_fscache_page(cookie, page, fscache_page_maybe_release); | ||
76 | |||
72 | try_again: | 77 | try_again: |
73 | rcu_read_lock(); | 78 | rcu_read_lock(); |
74 | val = radix_tree_lookup(&cookie->stores, page->index); | 79 | val = radix_tree_lookup(&cookie->stores, page->index); |
@@ -101,6 +106,7 @@ try_again: | |||
101 | } | 106 | } |
102 | 107 | ||
103 | xpage = radix_tree_delete(&cookie->stores, page->index); | 108 | xpage = radix_tree_delete(&cookie->stores, page->index); |
109 | trace_fscache_page(cookie, page, fscache_page_radix_delete); | ||
104 | spin_unlock(&cookie->stores_lock); | 110 | spin_unlock(&cookie->stores_lock); |
105 | 111 | ||
106 | if (xpage) { | 112 | if (xpage) { |
@@ -112,6 +118,7 @@ try_again: | |||
112 | } | 118 | } |
113 | 119 | ||
114 | wake_up_bit(&cookie->flags, 0); | 120 | wake_up_bit(&cookie->flags, 0); |
121 | trace_fscache_wake_cookie(cookie); | ||
115 | if (xpage) | 122 | if (xpage) |
116 | put_page(xpage); | 123 | put_page(xpage); |
117 | __fscache_uncache_page(cookie, page); | 124 | __fscache_uncache_page(cookie, page); |
@@ -144,7 +151,7 @@ static void fscache_end_page_write(struct fscache_object *object, | |||
144 | struct page *page) | 151 | struct page *page) |
145 | { | 152 | { |
146 | struct fscache_cookie *cookie; | 153 | struct fscache_cookie *cookie; |
147 | struct page *xpage = NULL; | 154 | struct page *xpage = NULL, *val; |
148 | 155 | ||
149 | spin_lock(&object->lock); | 156 | spin_lock(&object->lock); |
150 | cookie = object->cookie; | 157 | cookie = object->cookie; |
@@ -154,13 +161,24 @@ static void fscache_end_page_write(struct fscache_object *object, | |||
154 | spin_lock(&cookie->stores_lock); | 161 | spin_lock(&cookie->stores_lock); |
155 | radix_tree_tag_clear(&cookie->stores, page->index, | 162 | radix_tree_tag_clear(&cookie->stores, page->index, |
156 | FSCACHE_COOKIE_STORING_TAG); | 163 | FSCACHE_COOKIE_STORING_TAG); |
164 | trace_fscache_page(cookie, page, fscache_page_radix_clear_store); | ||
157 | if (!radix_tree_tag_get(&cookie->stores, page->index, | 165 | if (!radix_tree_tag_get(&cookie->stores, page->index, |
158 | FSCACHE_COOKIE_PENDING_TAG)) { | 166 | FSCACHE_COOKIE_PENDING_TAG)) { |
159 | fscache_stat(&fscache_n_store_radix_deletes); | 167 | fscache_stat(&fscache_n_store_radix_deletes); |
160 | xpage = radix_tree_delete(&cookie->stores, page->index); | 168 | xpage = radix_tree_delete(&cookie->stores, page->index); |
169 | trace_fscache_page(cookie, page, fscache_page_radix_delete); | ||
170 | trace_fscache_page(cookie, page, fscache_page_write_end); | ||
171 | |||
172 | val = radix_tree_lookup(&cookie->stores, page->index); | ||
173 | trace_fscache_check_page(cookie, page, val, 1); | ||
174 | } else { | ||
175 | trace_fscache_page(cookie, page, fscache_page_write_end_pend); | ||
161 | } | 176 | } |
162 | spin_unlock(&cookie->stores_lock); | 177 | spin_unlock(&cookie->stores_lock); |
163 | wake_up_bit(&cookie->flags, 0); | 178 | wake_up_bit(&cookie->flags, 0); |
179 | trace_fscache_wake_cookie(cookie); | ||
180 | } else { | ||
181 | trace_fscache_page(cookie, page, fscache_page_write_end_noc); | ||
164 | } | 182 | } |
165 | spin_unlock(&object->lock); | 183 | spin_unlock(&object->lock); |
166 | if (xpage) | 184 | if (xpage) |
@@ -215,7 +233,8 @@ int __fscache_attr_changed(struct fscache_cookie *cookie) | |||
215 | return -ENOMEM; | 233 | return -ENOMEM; |
216 | } | 234 | } |
217 | 235 | ||
218 | fscache_operation_init(op, fscache_attr_changed_op, NULL, NULL); | 236 | fscache_operation_init(cookie, op, fscache_attr_changed_op, NULL, NULL); |
237 | trace_fscache_page_op(cookie, NULL, op, fscache_page_op_attr_changed); | ||
219 | op->flags = FSCACHE_OP_ASYNC | | 238 | op->flags = FSCACHE_OP_ASYNC | |
220 | (1 << FSCACHE_OP_EXCLUSIVE) | | 239 | (1 << FSCACHE_OP_EXCLUSIVE) | |
221 | (1 << FSCACHE_OP_UNUSE_COOKIE); | 240 | (1 << FSCACHE_OP_UNUSE_COOKIE); |
@@ -299,7 +318,7 @@ static struct fscache_retrieval *fscache_alloc_retrieval( | |||
299 | return NULL; | 318 | return NULL; |
300 | } | 319 | } |
301 | 320 | ||
302 | fscache_operation_init(&op->op, NULL, | 321 | fscache_operation_init(cookie, &op->op, NULL, |
303 | fscache_do_cancel_retrieval, | 322 | fscache_do_cancel_retrieval, |
304 | fscache_release_retrieval_op); | 323 | fscache_release_retrieval_op); |
305 | op->op.flags = FSCACHE_OP_MYTHREAD | | 324 | op->op.flags = FSCACHE_OP_MYTHREAD | |
@@ -370,6 +389,7 @@ int fscache_wait_for_operation_activation(struct fscache_object *object, | |||
370 | fscache_stat(stat_op_waits); | 389 | fscache_stat(stat_op_waits); |
371 | if (wait_on_bit(&op->flags, FSCACHE_OP_WAITING, | 390 | if (wait_on_bit(&op->flags, FSCACHE_OP_WAITING, |
372 | TASK_INTERRUPTIBLE) != 0) { | 391 | TASK_INTERRUPTIBLE) != 0) { |
392 | trace_fscache_op(object->cookie, op, fscache_op_signal); | ||
373 | ret = fscache_cancel_op(op, false); | 393 | ret = fscache_cancel_op(op, false); |
374 | if (ret == 0) | 394 | if (ret == 0) |
375 | return -ERESTARTSYS; | 395 | return -ERESTARTSYS; |
@@ -391,6 +411,7 @@ check_if_dead: | |||
391 | if (unlikely(fscache_object_is_dying(object) || | 411 | if (unlikely(fscache_object_is_dying(object) || |
392 | fscache_cache_is_broken(object))) { | 412 | fscache_cache_is_broken(object))) { |
393 | enum fscache_operation_state state = op->state; | 413 | enum fscache_operation_state state = op->state; |
414 | trace_fscache_op(object->cookie, op, fscache_op_signal); | ||
394 | fscache_cancel_op(op, true); | 415 | fscache_cancel_op(op, true); |
395 | if (stat_object_dead) | 416 | if (stat_object_dead) |
396 | fscache_stat(stat_object_dead); | 417 | fscache_stat(stat_object_dead); |
@@ -445,6 +466,7 @@ int __fscache_read_or_alloc_page(struct fscache_cookie *cookie, | |||
445 | return -ENOMEM; | 466 | return -ENOMEM; |
446 | } | 467 | } |
447 | atomic_set(&op->n_pages, 1); | 468 | atomic_set(&op->n_pages, 1); |
469 | trace_fscache_page_op(cookie, page, &op->op, fscache_page_op_retr_one); | ||
448 | 470 | ||
449 | spin_lock(&cookie->lock); | 471 | spin_lock(&cookie->lock); |
450 | 472 | ||
@@ -573,6 +595,7 @@ int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie, | |||
573 | if (!op) | 595 | if (!op) |
574 | return -ENOMEM; | 596 | return -ENOMEM; |
575 | atomic_set(&op->n_pages, *nr_pages); | 597 | atomic_set(&op->n_pages, *nr_pages); |
598 | trace_fscache_page_op(cookie, NULL, &op->op, fscache_page_op_retr_multi); | ||
576 | 599 | ||
577 | spin_lock(&cookie->lock); | 600 | spin_lock(&cookie->lock); |
578 | 601 | ||
@@ -684,6 +707,7 @@ int __fscache_alloc_page(struct fscache_cookie *cookie, | |||
684 | if (!op) | 707 | if (!op) |
685 | return -ENOMEM; | 708 | return -ENOMEM; |
686 | atomic_set(&op->n_pages, 1); | 709 | atomic_set(&op->n_pages, 1); |
710 | trace_fscache_page_op(cookie, page, &op->op, fscache_page_op_alloc_one); | ||
687 | 711 | ||
688 | spin_lock(&cookie->lock); | 712 | spin_lock(&cookie->lock); |
689 | 713 | ||
@@ -813,9 +837,11 @@ again: | |||
813 | fscache_stat(&fscache_n_store_calls); | 837 | fscache_stat(&fscache_n_store_calls); |
814 | 838 | ||
815 | /* find a page to store */ | 839 | /* find a page to store */ |
840 | results[0] = NULL; | ||
816 | page = NULL; | 841 | page = NULL; |
817 | n = radix_tree_gang_lookup_tag(&cookie->stores, results, 0, 1, | 842 | n = radix_tree_gang_lookup_tag(&cookie->stores, results, 0, 1, |
818 | FSCACHE_COOKIE_PENDING_TAG); | 843 | FSCACHE_COOKIE_PENDING_TAG); |
844 | trace_fscache_gang_lookup(cookie, &op->op, results, n, op->store_limit); | ||
819 | if (n != 1) | 845 | if (n != 1) |
820 | goto superseded; | 846 | goto superseded; |
821 | page = results[0]; | 847 | page = results[0]; |
@@ -825,6 +851,7 @@ again: | |||
825 | FSCACHE_COOKIE_STORING_TAG); | 851 | FSCACHE_COOKIE_STORING_TAG); |
826 | radix_tree_tag_clear(&cookie->stores, page->index, | 852 | radix_tree_tag_clear(&cookie->stores, page->index, |
827 | FSCACHE_COOKIE_PENDING_TAG); | 853 | FSCACHE_COOKIE_PENDING_TAG); |
854 | trace_fscache_page(cookie, page, fscache_page_radix_pend2store); | ||
828 | 855 | ||
829 | spin_unlock(&cookie->stores_lock); | 856 | spin_unlock(&cookie->stores_lock); |
830 | spin_unlock(&object->lock); | 857 | spin_unlock(&object->lock); |
@@ -836,6 +863,7 @@ again: | |||
836 | fscache_stat(&fscache_n_cop_write_page); | 863 | fscache_stat(&fscache_n_cop_write_page); |
837 | ret = object->cache->ops->write_page(op, page); | 864 | ret = object->cache->ops->write_page(op, page); |
838 | fscache_stat_d(&fscache_n_cop_write_page); | 865 | fscache_stat_d(&fscache_n_cop_write_page); |
866 | trace_fscache_wrote_page(cookie, page, &op->op, ret); | ||
839 | fscache_end_page_write(object, page); | 867 | fscache_end_page_write(object, page); |
840 | if (ret < 0) { | 868 | if (ret < 0) { |
841 | fscache_abort_object(object); | 869 | fscache_abort_object(object); |
@@ -849,6 +877,7 @@ again: | |||
849 | 877 | ||
850 | discard_page: | 878 | discard_page: |
851 | fscache_stat(&fscache_n_store_pages_over_limit); | 879 | fscache_stat(&fscache_n_store_pages_over_limit); |
880 | trace_fscache_wrote_page(cookie, page, &op->op, -ENOBUFS); | ||
852 | fscache_end_page_write(object, page); | 881 | fscache_end_page_write(object, page); |
853 | goto again; | 882 | goto again; |
854 | 883 | ||
@@ -887,6 +916,8 @@ void fscache_invalidate_writes(struct fscache_cookie *cookie) | |||
887 | for (i = n - 1; i >= 0; i--) { | 916 | for (i = n - 1; i >= 0; i--) { |
888 | page = results[i]; | 917 | page = results[i]; |
889 | radix_tree_delete(&cookie->stores, page->index); | 918 | radix_tree_delete(&cookie->stores, page->index); |
919 | trace_fscache_page(cookie, page, fscache_page_radix_delete); | ||
920 | trace_fscache_page(cookie, page, fscache_page_inval); | ||
890 | } | 921 | } |
891 | 922 | ||
892 | spin_unlock(&cookie->stores_lock); | 923 | spin_unlock(&cookie->stores_lock); |
@@ -896,6 +927,7 @@ void fscache_invalidate_writes(struct fscache_cookie *cookie) | |||
896 | } | 927 | } |
897 | 928 | ||
898 | wake_up_bit(&cookie->flags, 0); | 929 | wake_up_bit(&cookie->flags, 0); |
930 | trace_fscache_wake_cookie(cookie); | ||
899 | 931 | ||
900 | _leave(""); | 932 | _leave(""); |
901 | } | 933 | } |
@@ -954,7 +986,7 @@ int __fscache_write_page(struct fscache_cookie *cookie, | |||
954 | if (!op) | 986 | if (!op) |
955 | goto nomem; | 987 | goto nomem; |
956 | 988 | ||
957 | fscache_operation_init(&op->op, fscache_write_op, NULL, | 989 | fscache_operation_init(cookie, &op->op, fscache_write_op, NULL, |
958 | fscache_release_write_op); | 990 | fscache_release_write_op); |
959 | op->op.flags = FSCACHE_OP_ASYNC | | 991 | op->op.flags = FSCACHE_OP_ASYNC | |
960 | (1 << FSCACHE_OP_WAITING) | | 992 | (1 << FSCACHE_OP_WAITING) | |
@@ -964,6 +996,8 @@ int __fscache_write_page(struct fscache_cookie *cookie, | |||
964 | if (ret < 0) | 996 | if (ret < 0) |
965 | goto nomem_free; | 997 | goto nomem_free; |
966 | 998 | ||
999 | trace_fscache_page_op(cookie, page, &op->op, fscache_page_op_write_one); | ||
1000 | |||
967 | ret = -ENOBUFS; | 1001 | ret = -ENOBUFS; |
968 | spin_lock(&cookie->lock); | 1002 | spin_lock(&cookie->lock); |
969 | 1003 | ||
@@ -975,6 +1009,8 @@ int __fscache_write_page(struct fscache_cookie *cookie, | |||
975 | if (test_bit(FSCACHE_IOERROR, &object->cache->flags)) | 1009 | if (test_bit(FSCACHE_IOERROR, &object->cache->flags)) |
976 | goto nobufs; | 1010 | goto nobufs; |
977 | 1011 | ||
1012 | trace_fscache_page(cookie, page, fscache_page_write); | ||
1013 | |||
978 | /* add the page to the pending-storage radix tree on the backing | 1014 | /* add the page to the pending-storage radix tree on the backing |
979 | * object */ | 1015 | * object */ |
980 | spin_lock(&object->lock); | 1016 | spin_lock(&object->lock); |
@@ -990,8 +1026,10 @@ int __fscache_write_page(struct fscache_cookie *cookie, | |||
990 | goto nobufs_unlock_obj; | 1026 | goto nobufs_unlock_obj; |
991 | } | 1027 | } |
992 | 1028 | ||
1029 | trace_fscache_page(cookie, page, fscache_page_radix_insert); | ||
993 | radix_tree_tag_set(&cookie->stores, page->index, | 1030 | radix_tree_tag_set(&cookie->stores, page->index, |
994 | FSCACHE_COOKIE_PENDING_TAG); | 1031 | FSCACHE_COOKIE_PENDING_TAG); |
1032 | trace_fscache_page(cookie, page, fscache_page_radix_set_pend); | ||
995 | get_page(page); | 1033 | get_page(page); |
996 | 1034 | ||
997 | /* we only want one writer at a time, but we do need to queue new | 1035 | /* we only want one writer at a time, but we do need to queue new |
@@ -1034,6 +1072,7 @@ already_pending: | |||
1034 | submit_failed: | 1072 | submit_failed: |
1035 | spin_lock(&cookie->stores_lock); | 1073 | spin_lock(&cookie->stores_lock); |
1036 | radix_tree_delete(&cookie->stores, page->index); | 1074 | radix_tree_delete(&cookie->stores, page->index); |
1075 | trace_fscache_page(cookie, page, fscache_page_radix_delete); | ||
1037 | spin_unlock(&cookie->stores_lock); | 1076 | spin_unlock(&cookie->stores_lock); |
1038 | wake_cookie = __fscache_unuse_cookie(cookie); | 1077 | wake_cookie = __fscache_unuse_cookie(cookie); |
1039 | put_page(page); | 1078 | put_page(page); |
@@ -1080,6 +1119,8 @@ void __fscache_uncache_page(struct fscache_cookie *cookie, struct page *page) | |||
1080 | if (!PageFsCache(page)) | 1119 | if (!PageFsCache(page)) |
1081 | goto done; | 1120 | goto done; |
1082 | 1121 | ||
1122 | trace_fscache_page(cookie, page, fscache_page_uncache); | ||
1123 | |||
1083 | /* get the object */ | 1124 | /* get the object */ |
1084 | spin_lock(&cookie->lock); | 1125 | spin_lock(&cookie->lock); |
1085 | 1126 | ||
@@ -1128,6 +1169,8 @@ void fscache_mark_page_cached(struct fscache_retrieval *op, struct page *page) | |||
1128 | atomic_inc(&fscache_n_marks); | 1169 | atomic_inc(&fscache_n_marks); |
1129 | #endif | 1170 | #endif |
1130 | 1171 | ||
1172 | trace_fscache_page(cookie, page, fscache_page_cached); | ||
1173 | |||
1131 | _debug("- mark %p{%lx}", page, page->index); | 1174 | _debug("- mark %p{%lx}", page, page->index); |
1132 | if (TestSetPageFsCache(page)) { | 1175 | if (TestSetPageFsCache(page)) { |
1133 | static bool once_only; | 1176 | static bool once_only; |
diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h index fbe102f37074..3e764fd38d9f 100644 --- a/include/linux/fscache-cache.h +++ b/include/linux/fscache-cache.h | |||
@@ -135,7 +135,8 @@ extern void fscache_op_work_func(struct work_struct *work); | |||
135 | extern void fscache_enqueue_operation(struct fscache_operation *); | 135 | extern void fscache_enqueue_operation(struct fscache_operation *); |
136 | extern void fscache_op_complete(struct fscache_operation *, bool); | 136 | extern void fscache_op_complete(struct fscache_operation *, bool); |
137 | extern void fscache_put_operation(struct fscache_operation *); | 137 | extern void fscache_put_operation(struct fscache_operation *); |
138 | extern void fscache_operation_init(struct fscache_operation *, | 138 | extern void fscache_operation_init(struct fscache_cookie *, |
139 | struct fscache_operation *, | ||
139 | fscache_operation_processor_t, | 140 | fscache_operation_processor_t, |
140 | fscache_operation_cancel_t, | 141 | fscache_operation_cancel_t, |
141 | fscache_operation_release_t); | 142 | fscache_operation_release_t); |
diff --git a/include/trace/events/fscache.h b/include/trace/events/fscache.h index 99f5355d6281..82c060fe6635 100644 --- a/include/trace/events/fscache.h +++ b/include/trace/events/fscache.h | |||
@@ -33,6 +33,53 @@ enum fscache_cookie_trace { | |||
33 | fscache_cookie_put_parent, | 33 | fscache_cookie_put_parent, |
34 | }; | 34 | }; |
35 | 35 | ||
36 | enum fscache_page_trace { | ||
37 | fscache_page_cached, | ||
38 | fscache_page_inval, | ||
39 | fscache_page_maybe_release, | ||
40 | fscache_page_radix_clear_store, | ||
41 | fscache_page_radix_delete, | ||
42 | fscache_page_radix_insert, | ||
43 | fscache_page_radix_pend2store, | ||
44 | fscache_page_radix_set_pend, | ||
45 | fscache_page_uncache, | ||
46 | fscache_page_write, | ||
47 | fscache_page_write_end, | ||
48 | fscache_page_write_end_pend, | ||
49 | fscache_page_write_end_noc, | ||
50 | fscache_page_write_wait, | ||
51 | fscache_page_trace__nr | ||
52 | }; | ||
53 | |||
54 | enum fscache_op_trace { | ||
55 | fscache_op_cancel, | ||
56 | fscache_op_cancel_all, | ||
57 | fscache_op_cancelled, | ||
58 | fscache_op_completed, | ||
59 | fscache_op_enqueue_async, | ||
60 | fscache_op_enqueue_mythread, | ||
61 | fscache_op_gc, | ||
62 | fscache_op_init, | ||
63 | fscache_op_put, | ||
64 | fscache_op_run, | ||
65 | fscache_op_signal, | ||
66 | fscache_op_submit, | ||
67 | fscache_op_submit_ex, | ||
68 | fscache_op_work, | ||
69 | fscache_op_trace__nr | ||
70 | }; | ||
71 | |||
72 | enum fscache_page_op_trace { | ||
73 | fscache_page_op_alloc_one, | ||
74 | fscache_page_op_attr_changed, | ||
75 | fscache_page_op_check_consistency, | ||
76 | fscache_page_op_invalidate, | ||
77 | fscache_page_op_retr_multi, | ||
78 | fscache_page_op_retr_one, | ||
79 | fscache_page_op_write_one, | ||
80 | fscache_page_op_trace__nr | ||
81 | }; | ||
82 | |||
36 | #endif | 83 | #endif |
37 | 84 | ||
38 | /* | 85 | /* |
@@ -47,6 +94,47 @@ enum fscache_cookie_trace { | |||
47 | EM(fscache_cookie_put_object, "PUT obj") \ | 94 | EM(fscache_cookie_put_object, "PUT obj") \ |
48 | E_(fscache_cookie_put_parent, "PUT prn") | 95 | E_(fscache_cookie_put_parent, "PUT prn") |
49 | 96 | ||
97 | #define fscache_page_traces \ | ||
98 | EM(fscache_page_cached, "Cached ") \ | ||
99 | EM(fscache_page_inval, "InvalPg") \ | ||
100 | EM(fscache_page_maybe_release, "MayRels") \ | ||
101 | EM(fscache_page_uncache, "Uncache") \ | ||
102 | EM(fscache_page_radix_clear_store, "RxCStr ") \ | ||
103 | EM(fscache_page_radix_delete, "RxDel ") \ | ||
104 | EM(fscache_page_radix_insert, "RxIns ") \ | ||
105 | EM(fscache_page_radix_pend2store, "RxP2S ") \ | ||
106 | EM(fscache_page_radix_set_pend, "RxSPend ") \ | ||
107 | EM(fscache_page_write, "WritePg") \ | ||
108 | EM(fscache_page_write_end, "EndPgWr") \ | ||
109 | EM(fscache_page_write_end_pend, "EndPgWP") \ | ||
110 | EM(fscache_page_write_end_noc, "EndPgNC") \ | ||
111 | E_(fscache_page_write_wait, "WtOnWrt") | ||
112 | |||
113 | #define fscache_op_traces \ | ||
114 | EM(fscache_op_cancel, "Cancel1") \ | ||
115 | EM(fscache_op_cancel_all, "CancelA") \ | ||
116 | EM(fscache_op_cancelled, "Canclld") \ | ||
117 | EM(fscache_op_completed, "Complet") \ | ||
118 | EM(fscache_op_enqueue_async, "EnqAsyn") \ | ||
119 | EM(fscache_op_enqueue_mythread, "EnqMyTh") \ | ||
120 | EM(fscache_op_gc, "GC ") \ | ||
121 | EM(fscache_op_init, "Init ") \ | ||
122 | EM(fscache_op_put, "Put ") \ | ||
123 | EM(fscache_op_run, "Run ") \ | ||
124 | EM(fscache_op_signal, "Signal ") \ | ||
125 | EM(fscache_op_submit, "Submit ") \ | ||
126 | EM(fscache_op_submit_ex, "SubmitX") \ | ||
127 | E_(fscache_op_work, "Work ") | ||
128 | |||
129 | #define fscache_page_op_traces \ | ||
130 | EM(fscache_page_op_alloc_one, "Alloc1 ") \ | ||
131 | EM(fscache_page_op_attr_changed, "AttrChg") \ | ||
132 | EM(fscache_page_op_check_consistency, "CheckCn") \ | ||
133 | EM(fscache_page_op_invalidate, "Inval ") \ | ||
134 | EM(fscache_page_op_retr_multi, "RetrMul") \ | ||
135 | EM(fscache_page_op_retr_one, "Retr1 ") \ | ||
136 | E_(fscache_page_op_write_one, "Write1 ") | ||
137 | |||
50 | /* | 138 | /* |
51 | * Export enum symbols via userspace. | 139 | * Export enum symbols via userspace. |
52 | */ | 140 | */ |
@@ -271,6 +359,170 @@ TRACE_EVENT(fscache_osm, | |||
271 | __entry->event_num) | 359 | __entry->event_num) |
272 | ); | 360 | ); |
273 | 361 | ||
362 | TRACE_EVENT(fscache_page, | ||
363 | TP_PROTO(struct fscache_cookie *cookie, struct page *page, | ||
364 | enum fscache_page_trace why), | ||
365 | |||
366 | TP_ARGS(cookie, page, why), | ||
367 | |||
368 | TP_STRUCT__entry( | ||
369 | __field(struct fscache_cookie *, cookie ) | ||
370 | __field(pgoff_t, page ) | ||
371 | __field(enum fscache_page_trace, why ) | ||
372 | ), | ||
373 | |||
374 | TP_fast_assign( | ||
375 | __entry->cookie = cookie; | ||
376 | __entry->page = page->index; | ||
377 | __entry->why = why; | ||
378 | ), | ||
379 | |||
380 | TP_printk("c=%p %s pg=%lx", | ||
381 | __entry->cookie, | ||
382 | __print_symbolic(__entry->why, fscache_page_traces), | ||
383 | __entry->page) | ||
384 | ); | ||
385 | |||
386 | TRACE_EVENT(fscache_check_page, | ||
387 | TP_PROTO(struct fscache_cookie *cookie, struct page *page, | ||
388 | void *val, int n), | ||
389 | |||
390 | TP_ARGS(cookie, page, val, n), | ||
391 | |||
392 | TP_STRUCT__entry( | ||
393 | __field(struct fscache_cookie *, cookie ) | ||
394 | __field(void *, page ) | ||
395 | __field(void *, val ) | ||
396 | __field(int, n ) | ||
397 | ), | ||
398 | |||
399 | TP_fast_assign( | ||
400 | __entry->cookie = cookie; | ||
401 | __entry->page = page; | ||
402 | __entry->val = val; | ||
403 | __entry->n = n; | ||
404 | ), | ||
405 | |||
406 | TP_printk("c=%p pg=%p val=%p n=%d", | ||
407 | __entry->cookie, __entry->page, __entry->val, __entry->n) | ||
408 | ); | ||
409 | |||
410 | TRACE_EVENT(fscache_wake_cookie, | ||
411 | TP_PROTO(struct fscache_cookie *cookie), | ||
412 | |||
413 | TP_ARGS(cookie), | ||
414 | |||
415 | TP_STRUCT__entry( | ||
416 | __field(struct fscache_cookie *, cookie ) | ||
417 | ), | ||
418 | |||
419 | TP_fast_assign( | ||
420 | __entry->cookie = cookie; | ||
421 | ), | ||
422 | |||
423 | TP_printk("c=%p", __entry->cookie) | ||
424 | ); | ||
425 | |||
426 | TRACE_EVENT(fscache_op, | ||
427 | TP_PROTO(struct fscache_cookie *cookie, struct fscache_operation *op, | ||
428 | enum fscache_op_trace why), | ||
429 | |||
430 | TP_ARGS(cookie, op, why), | ||
431 | |||
432 | TP_STRUCT__entry( | ||
433 | __field(struct fscache_cookie *, cookie ) | ||
434 | __field(struct fscache_operation *, op ) | ||
435 | __field(enum fscache_op_trace, why ) | ||
436 | ), | ||
437 | |||
438 | TP_fast_assign( | ||
439 | __entry->cookie = cookie; | ||
440 | __entry->op = op; | ||
441 | __entry->why = why; | ||
442 | ), | ||
443 | |||
444 | TP_printk("c=%p op=%p %s", | ||
445 | __entry->cookie, __entry->op, | ||
446 | __print_symbolic(__entry->why, fscache_op_traces)) | ||
447 | ); | ||
448 | |||
449 | TRACE_EVENT(fscache_page_op, | ||
450 | TP_PROTO(struct fscache_cookie *cookie, struct page *page, | ||
451 | struct fscache_operation *op, enum fscache_page_op_trace what), | ||
452 | |||
453 | TP_ARGS(cookie, page, op, what), | ||
454 | |||
455 | TP_STRUCT__entry( | ||
456 | __field(struct fscache_cookie *, cookie ) | ||
457 | __field(pgoff_t, page ) | ||
458 | __field(struct fscache_operation *, op ) | ||
459 | __field(enum fscache_page_op_trace, what ) | ||
460 | ), | ||
461 | |||
462 | TP_fast_assign( | ||
463 | __entry->cookie = cookie; | ||
464 | __entry->page = page ? page->index : 0; | ||
465 | __entry->op = op; | ||
466 | __entry->what = what; | ||
467 | ), | ||
468 | |||
469 | TP_printk("c=%p %s pg=%lx op=%p", | ||
470 | __entry->cookie, | ||
471 | __print_symbolic(__entry->what, fscache_page_op_traces), | ||
472 | __entry->page, __entry->op) | ||
473 | ); | ||
474 | |||
475 | TRACE_EVENT(fscache_wrote_page, | ||
476 | TP_PROTO(struct fscache_cookie *cookie, struct page *page, | ||
477 | struct fscache_operation *op, int ret), | ||
478 | |||
479 | TP_ARGS(cookie, page, op, ret), | ||
480 | |||
481 | TP_STRUCT__entry( | ||
482 | __field(struct fscache_cookie *, cookie ) | ||
483 | __field(pgoff_t, page ) | ||
484 | __field(struct fscache_operation *, op ) | ||
485 | __field(int, ret ) | ||
486 | ), | ||
487 | |||
488 | TP_fast_assign( | ||
489 | __entry->cookie = cookie; | ||
490 | __entry->page = page->index; | ||
491 | __entry->op = op; | ||
492 | __entry->ret = ret; | ||
493 | ), | ||
494 | |||
495 | TP_printk("c=%p pg=%lx op=%p ret=%d", | ||
496 | __entry->cookie, __entry->page, __entry->op, __entry->ret) | ||
497 | ); | ||
498 | |||
499 | TRACE_EVENT(fscache_gang_lookup, | ||
500 | TP_PROTO(struct fscache_cookie *cookie, struct fscache_operation *op, | ||
501 | void **results, int n, pgoff_t store_limit), | ||
502 | |||
503 | TP_ARGS(cookie, op, results, n, store_limit), | ||
504 | |||
505 | TP_STRUCT__entry( | ||
506 | __field(struct fscache_cookie *, cookie ) | ||
507 | __field(struct fscache_operation *, op ) | ||
508 | __field(pgoff_t, results0 ) | ||
509 | __field(int, n ) | ||
510 | __field(pgoff_t, store_limit ) | ||
511 | ), | ||
512 | |||
513 | TP_fast_assign( | ||
514 | __entry->cookie = cookie; | ||
515 | __entry->op = op; | ||
516 | __entry->results0 = results[0] ? ((struct page *)results[0])->index : (pgoff_t)-1; | ||
517 | __entry->n = n; | ||
518 | __entry->store_limit = store_limit; | ||
519 | ), | ||
520 | |||
521 | TP_printk("c=%p op=%p r0=%lx n=%d sl=%lx", | ||
522 | __entry->cookie, __entry->op, __entry->results0, __entry->n, | ||
523 | __entry->store_limit) | ||
524 | ); | ||
525 | |||
274 | #endif /* _TRACE_FSCACHE_H */ | 526 | #endif /* _TRACE_FSCACHE_H */ |
275 | 527 | ||
276 | /* This part must be outside protection */ | 528 | /* This part must be outside protection */ |