Create some new stat counters appropriate to the new routines and display them in /proc/fs/fscache/stats. Signed-off-by: David Howells <dhowells@xxxxxxxxxx> --- fs/fscache/dispatcher.c | 6 ++++ fs/fscache/internal.h | 25 +++++++++++++++++ fs/fscache/io.c | 2 + fs/fscache/read_helper.c | 38 +++++++++++++++++++++++-- fs/fscache/stats.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 137 insertions(+), 3 deletions(-) diff --git a/fs/fscache/dispatcher.c b/fs/fscache/dispatcher.c index fba71b99c951..489b8ab8cccd 100644 --- a/fs/fscache/dispatcher.c +++ b/fs/fscache/dispatcher.c @@ -41,6 +41,8 @@ void fscache_dispatch(struct fscache_cookie *cookie, struct fscache_work *work; bool queued = false; + fscache_stat(&fscache_n_dispatch_count); + work = kzalloc(sizeof(struct fscache_work), GFP_KERNEL); if (work) { work->cookie = cookie; @@ -57,10 +59,13 @@ void fscache_dispatch(struct fscache_cookie *cookie, queued = true; } spin_unlock(&fscache_work_lock); + if (queued) + fscache_stat(&fscache_n_dispatch_deferred); } if (!queued) { kfree(work); + fscache_stat(&fscache_n_dispatch_inline); func(cookie, object, param); } } @@ -86,6 +91,7 @@ static int fscache_dispatcher(void *data) if (work) { work->func(work->cookie, work->object, work->param); + fscache_stat(&fscache_n_dispatch_in_pool); fscache_cookie_put(work->cookie, fscache_cookie_put_work); kfree(work); } diff --git a/fs/fscache/internal.h b/fs/fscache/internal.h index d2b856aa5f0e..d9391d3974d1 100644 --- a/fs/fscache/internal.h +++ b/fs/fscache/internal.h @@ -209,6 +209,30 @@ extern atomic_t fscache_n_cache_stale_objects; extern atomic_t fscache_n_cache_retired_objects; extern atomic_t fscache_n_cache_culled_objects; +extern atomic_t fscache_n_dispatch_count; +extern atomic_t fscache_n_dispatch_deferred; +extern atomic_t fscache_n_dispatch_inline; +extern atomic_t fscache_n_dispatch_in_pool; + +extern atomic_t fscache_n_read; +extern atomic_t fscache_n_write; + +extern atomic_t fscache_n_read_helper; +extern atomic_t fscache_n_read_helper_stop_nomem; +extern atomic_t fscache_n_read_helper_stop_uptodate; +extern atomic_t fscache_n_read_helper_stop_exist; +extern atomic_t fscache_n_read_helper_stop_kill; +extern atomic_t fscache_n_read_helper_read; +extern atomic_t fscache_n_read_helper_download; +extern atomic_t fscache_n_read_helper_zero; +extern atomic_t fscache_n_read_helper_beyond_eof; +extern atomic_t fscache_n_read_helper_reissue; +extern atomic_t fscache_n_read_helper_read_done; +extern atomic_t fscache_n_read_helper_read_failed; +extern atomic_t fscache_n_read_helper_copy; +extern atomic_t fscache_n_read_helper_copy_done; +extern atomic_t fscache_n_read_helper_copy_failed; + static inline void fscache_stat(atomic_t *stat) { atomic_inc(stat); @@ -256,6 +280,7 @@ void fscache_update_aux(struct fscache_cookie *cookie, #else /* CONFIG_FSCACHE */ +#define fscache_stat(stat) do {} while(0) #define fscache_op_wq system_wq #endif /* CONFIG_FSCACHE */ diff --git a/fs/fscache/io.c b/fs/fscache/io.c index 8d7f79551699..d38101d77d27 100644 --- a/fs/fscache/io.c +++ b/fs/fscache/io.c @@ -138,6 +138,7 @@ int __fscache_read(struct fscache_io_request *req, struct iov_iter *iter) fscache_begin_io_operation(req->cookie, FSCACHE_WANT_READ, req); if (!IS_ERR(object)) { + fscache_stat(&fscache_n_read); req->object = object; return object->cache->ops->read(object, req, iter); } else { @@ -158,6 +159,7 @@ int __fscache_write(struct fscache_io_request *req, struct iov_iter *iter) fscache_begin_io_operation(req->cookie, FSCACHE_WANT_WRITE, req); if (!IS_ERR(object)) { + fscache_stat(&fscache_n_write); req->object = object; return object->cache->ops->write(object, req, iter); } else { diff --git a/fs/fscache/read_helper.c b/fs/fscache/read_helper.c index 62fed27aa938..227b326a54e2 100644 --- a/fs/fscache/read_helper.c +++ b/fs/fscache/read_helper.c @@ -68,6 +68,11 @@ static void fscache_read_copy_done(struct fscache_io_request *req) _enter("%lx,%x,%llx", index, req->nr_pages, req->transferred); + if (req->error == 0) + fscache_stat(&fscache_n_read_helper_copy_done); + else + fscache_stat(&fscache_n_read_helper_copy_failed); + /* Clear PG_fscache on the pages that were being written out. */ rcu_read_lock(); xas_for_each(&xas, page, last) { @@ -90,6 +95,8 @@ static void fscache_do_read_copy_to_cache(struct work_struct *work) _enter(""); + fscache_stat(&fscache_n_read_helper_copy); + iov_iter_mapping(&iter, WRITE, req->mapping, req->pos, round_up(req->len, req->dio_block_size)); @@ -142,6 +149,11 @@ static void fscache_read_done(struct fscache_io_request *req) _enter("%lx,%x,%llx,%d", start, req->nr_pages, req->transferred, req->error); + if (req->error == 0) + fscache_stat(&fscache_n_read_helper_read_done); + else + fscache_stat(&fscache_n_read_helper_read_failed); + if (req->transferred < req->len) fscache_clear_unread(req); @@ -195,6 +207,7 @@ static void fscache_file_read_maybe_reissue(struct fscache_io_request *req) if (req->error == 0) { fscache_read_done(req); } else { + fscache_stat(&fscache_n_read_helper_reissue); INIT_WORK(&req->work, fscache_reissue_read); fscache_get_io_request(req); queue_work(fscache_op_wq, &req->work); @@ -279,6 +292,8 @@ static int fscache_read_helper(struct fscache_io_request *req, loff_t new_size; int ret; + fscache_stat(&fscache_n_read_helper); + shape.granularity = 1; shape.max_io_pages = max_pages; shape.i_size = i_size_read(mapping->host); @@ -341,8 +356,10 @@ static int fscache_read_helper(struct fscache_io_request *req, while (cursor < shape.proposed_start) { page = find_or_create_page(mapping, cursor, readahead_gfp_mask(mapping)); - if (!page) + if (!page) { + fscache_stat(&fscache_n_read_helper_stop_nomem); goto nomem; + } if (!PageUptodate(page)) { req->nr_pages++; /* Add to the reading list */ cursor++; @@ -355,6 +372,7 @@ static int fscache_read_helper(struct fscache_io_request *req, */ notes |= FSCACHE_RHLP_NOTE_U2D_IN_PREFACE; notes &= ~FSCACHE_RHLP_NOTE_DO_WRITE_TO_CACHE; + fscache_stat(&fscache_n_read_helper_stop_uptodate); fscache_ignore_pages(mapping, start, cursor + 1); start = cursor = shape.proposed_start; req->nr_pages = 0; @@ -378,18 +396,23 @@ static int fscache_read_helper(struct fscache_io_request *req, _debug("prewrite req %lx", cursor); page = *requested_page; ret = -ERESTARTSYS; - if (lock_page_killable(page) < 0) + if (lock_page_killable(page) < 0) { + fscache_stat(&fscache_n_read_helper_stop_kill); goto dont; + } } else { _debug("prewrite new %lx %lx", cursor, eof); page = grab_cache_page_write_begin(mapping, shape.proposed_start, aop_flags); - if (!page) + if (!page) { + fscache_stat(&fscache_n_read_helper_stop_nomem); goto nomem; + } *requested_page = page; } if (PageUptodate(page)) { + fscache_stat(&fscache_n_read_helper_stop_uptodate); notes |= FSCACHE_RHLP_NOTE_LIST_U2D; trace_fscache_read_helper(req->cookie, @@ -450,12 +473,14 @@ static int fscache_read_helper(struct fscache_io_request *req, readahead_gfp_mask(mapping)); if (!page) { notes |= FSCACHE_RHLP_NOTE_LIST_NOMEM; + fscache_stat(&fscache_n_read_helper_stop_nomem); goto stop; } if (PageUptodate(page)) { unlock_page(page); put_page(page); /* Avoid overwriting */ + fscache_stat(&fscache_n_read_helper_stop_exist); ret = 0; notes |= FSCACHE_RHLP_NOTE_LIST_U2D; goto stop; @@ -468,6 +493,7 @@ static int fscache_read_helper(struct fscache_io_request *req, default: _debug("add fail %lx %d", cursor, ret); put_page(page); + fscache_stat(&fscache_n_read_helper_stop_nomem); page = NULL; notes |= FSCACHE_RHLP_NOTE_LIST_ERROR; goto stop; @@ -500,12 +526,14 @@ static int fscache_read_helper(struct fscache_io_request *req, readahead_gfp_mask(mapping)); if (!page) { notes |= FSCACHE_RHLP_NOTE_TRAILER_NOMEM; + fscache_stat(&fscache_n_read_helper_stop_nomem); goto stop; } if (PageUptodate(page)) { unlock_page(page); put_page(page); /* Avoid overwriting */ notes |= FSCACHE_RHLP_NOTE_TRAILER_U2D; + fscache_stat(&fscache_n_read_helper_stop_uptodate); goto stop; } @@ -587,18 +615,22 @@ static int fscache_read_helper(struct fscache_io_request *req, * the pages. */ _debug("SKIP READ: %llu", req->len); + fscache_stat(&fscache_n_read_helper_beyond_eof); fscache_read_done(req); break; case fscache_read_helper_zero: _debug("ZERO READ: %llu", req->len); + fscache_stat(&fscache_n_read_helper_zero); fscache_read_done(req); break; case fscache_read_helper_read: + fscache_stat(&fscache_n_read_helper_read); req->io_done = fscache_file_read_maybe_reissue; fscache_read_from_cache(req); break; case fscache_read_helper_download: _debug("DOWNLOAD: %llu", req->len); + fscache_stat(&fscache_n_read_helper_download); req->io_done = fscache_read_done; fscache_read_from_server(req); break; diff --git a/fs/fscache/stats.c b/fs/fscache/stats.c index ccca0016fd26..63fb4d831f4d 100644 --- a/fs/fscache/stats.c +++ b/fs/fscache/stats.c @@ -58,6 +58,46 @@ atomic_t fscache_n_cache_stale_objects; atomic_t fscache_n_cache_retired_objects; atomic_t fscache_n_cache_culled_objects; +atomic_t fscache_n_dispatch_count; +atomic_t fscache_n_dispatch_deferred; +atomic_t fscache_n_dispatch_inline; +atomic_t fscache_n_dispatch_in_pool; + +atomic_t fscache_n_read; +atomic_t fscache_n_write; + +atomic_t fscache_n_read_helper; +atomic_t fscache_n_read_helper_stop_nomem; +atomic_t fscache_n_read_helper_stop_uptodate; +atomic_t fscache_n_read_helper_stop_exist; +atomic_t fscache_n_read_helper_stop_kill; +atomic_t fscache_n_read_helper_read; +atomic_t fscache_n_read_helper_download; +atomic_t fscache_n_read_helper_zero; +atomic_t fscache_n_read_helper_beyond_eof; +atomic_t fscache_n_read_helper_reissue; +atomic_t fscache_n_read_helper_read_done; +atomic_t fscache_n_read_helper_read_failed; +atomic_t fscache_n_read_helper_copy; +atomic_t fscache_n_read_helper_copy_done; +atomic_t fscache_n_read_helper_copy_failed; + +EXPORT_SYMBOL(fscache_n_read_helper); +EXPORT_SYMBOL(fscache_n_read_helper_stop_nomem); +EXPORT_SYMBOL(fscache_n_read_helper_stop_uptodate); +EXPORT_SYMBOL(fscache_n_read_helper_stop_exist); +EXPORT_SYMBOL(fscache_n_read_helper_stop_kill); +EXPORT_SYMBOL(fscache_n_read_helper_read); +EXPORT_SYMBOL(fscache_n_read_helper_download); +EXPORT_SYMBOL(fscache_n_read_helper_zero); +EXPORT_SYMBOL(fscache_n_read_helper_beyond_eof); +EXPORT_SYMBOL(fscache_n_read_helper_reissue); +EXPORT_SYMBOL(fscache_n_read_helper_read_done); +EXPORT_SYMBOL(fscache_n_read_helper_read_failed); +EXPORT_SYMBOL(fscache_n_read_helper_copy); +EXPORT_SYMBOL(fscache_n_read_helper_copy_done); +EXPORT_SYMBOL(fscache_n_read_helper_copy_failed); + /* * display the general statistics */ @@ -117,5 +157,34 @@ int fscache_stats_show(struct seq_file *m, void *v) atomic_read(&fscache_n_cache_stale_objects), atomic_read(&fscache_n_cache_retired_objects), atomic_read(&fscache_n_cache_culled_objects)); + + seq_printf(m, "Disp : n=%u il=%u df=%u pl=%u\n", + atomic_read(&fscache_n_dispatch_count), + atomic_read(&fscache_n_dispatch_inline), + atomic_read(&fscache_n_dispatch_deferred), + atomic_read(&fscache_n_dispatch_in_pool)); + + seq_printf(m, "IO : rd=%u wr=%u\n", + atomic_read(&fscache_n_read), + atomic_read(&fscache_n_write)); + + seq_printf(m, "RdHelp : nm=%u ud=%u ex=%u kl=%u\n", + atomic_read(&fscache_n_read_helper_stop_nomem), + atomic_read(&fscache_n_read_helper_stop_uptodate), + atomic_read(&fscache_n_read_helper_stop_exist), + atomic_read(&fscache_n_read_helper_stop_kill)); + seq_printf(m, "RdHelp : n=%u rd=%u dl=%u zr=%u eo=%u\n", + atomic_read(&fscache_n_read_helper), + atomic_read(&fscache_n_read_helper_read), + atomic_read(&fscache_n_read_helper_download), + atomic_read(&fscache_n_read_helper_zero), + atomic_read(&fscache_n_read_helper_beyond_eof)); + seq_printf(m, "RdHelp : ri=%u dn=%u fl=%u cp=%u cd=%u cf=%u\n", + atomic_read(&fscache_n_read_helper_reissue), + atomic_read(&fscache_n_read_helper_read_done), + atomic_read(&fscache_n_read_helper_read_failed), + atomic_read(&fscache_n_read_helper_copy), + atomic_read(&fscache_n_read_helper_copy_done), + atomic_read(&fscache_n_read_helper_copy_failed)); return 0; }