[RFC PATCH 41/61] fscache: New stats

From: David Howells
Date: Mon May 04 2020 - 13:13:56 EST


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 | 55 ++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 123 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 d168e37011af..b9cad60e3c4e 100644
--- a/fs/fscache/internal.h
+++ b/fs/fscache/internal.h
@@ -207,6 +207,31 @@ 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_noncontig;
+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);
diff --git a/fs/fscache/io.c b/fs/fscache/io.c
index 0cea98bbb8ad..66005c9d2d99 100644
--- a/fs/fscache/io.c
+++ b/fs/fscache/io.c
@@ -141,6 +141,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 {
@@ -161,6 +162,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 9ed6e76ef255..b36ad2a0b749 100644
--- a/fs/fscache/read_helper.c
+++ b/fs/fscache/read_helper.c
@@ -32,6 +32,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) {
@@ -54,6 +59,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));

@@ -106,6 +113,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);

@@ -157,6 +169,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);
@@ -255,6 +268,8 @@ int fscache_read_helper(struct fscache_io_request *req,
loff_t i_size;
int ret;

+ fscache_stat(&fscache_n_read_helper);
+
first_index = extent->start;
_enter("{%lx,%lx}", first_index, extent->limit);

@@ -300,8 +315,10 @@ int fscache_read_helper(struct fscache_io_request *req,
while (cursor < first_index) {
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++;
@@ -313,6 +330,7 @@ int fscache_read_helper(struct fscache_io_request *req,
* cache.
*/
notes |= FSCACHE_RHLP_NOTE_U2D_IN_PREFACE;
+ fscache_stat(&fscache_n_read_helper_stop_uptodate);
fscache_ignore_pages(mapping, start, cursor + 1);
req->write_to_cache = false;
start = cursor = first_index;
@@ -337,14 +355,18 @@ 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, first_index,
aop_flags);
- if (!page)
+ if (!page) {
+ fscache_stat(&fscache_n_read_helper_stop_nomem);
goto nomem;
+ }
*requested_page = page;
}
get_page(page);
@@ -376,6 +398,7 @@ int fscache_read_helper(struct fscache_io_request *req,
page = lru_to_page(pages);
if (page->index != cursor) {
notes |= FSCACHE_RHLP_NOTE_LIST_NOTCONTIG;
+ fscache_stat(&fscache_n_read_helper_stop_noncontig);
break;
}

@@ -399,12 +422,14 @@ 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;
@@ -417,6 +442,7 @@ 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;
@@ -450,12 +476,14 @@ 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;
}

@@ -513,18 +541,22 @@ 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..fdea31ff8e69 100644
--- a/fs/fscache/stats.c
+++ b/fs/fscache/stats.c
@@ -58,6 +58,31 @@ 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_noncontig;
+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;
+
/*
* display the general statistics
*/
@@ -117,5 +142,35 @@ 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 nc=%u ud=%u ex=%u kl=%u\n",
+ atomic_read(&fscache_n_read_helper_stop_nomem),
+ atomic_read(&fscache_n_read_helper_stop_noncontig),
+ 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;
}