Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7394daa8 authored by David Howells's avatar David Howells
Browse files

FS-Cache: Add use of /proc and presentation of statistics



Make FS-Cache create its /proc interface and present various statistical
information through it.  Also provide the functions for updating this
information.

These features are enabled by:

	CONFIG_FSCACHE_PROC
	CONFIG_FSCACHE_STATS
	CONFIG_FSCACHE_HISTOGRAM

The /proc directory for FS-Cache is also exported so that caching modules can
add their own statistics there too.

The FS-Cache module is loadable at this point, and the statistics files can be
examined by userspace:

	cat /proc/fs/fscache/stats
	cat /proc/fs/fscache/histogram

Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
Acked-by: default avatarSteve Dickson <steved@redhat.com>
Acked-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
Acked-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
Tested-by: default avatarDaire Byrne <Daire.Byrne@framestore.com>
parent 06b3db1b
Loading
Loading
Loading
Loading
+0 −6
Original line number Diff line number Diff line
@@ -100,12 +100,6 @@ A sysfs directory called /sys/fs/fscache/<cachetag>/ is created if CONFIG_SYSFS
is enabled.  This is accessible through the kobject struct fscache_cache::kobj
and is for use by the cache as it sees fit.

The cache driver may create itself a directory named for the cache type in the
/proc/fs/fscache/ directory.  This is available if CONFIG_FSCACHE_PROC is
enabled and is accessible through:

	struct proc_dir_entry *proc_fscache;


========================
RELEVANT DATA STRUCTURES
+5 −7
Original line number Diff line number Diff line
@@ -195,7 +195,6 @@ STATISTICAL INFORMATION

If FS-Cache is compiled with the following options enabled:

	CONFIG_FSCACHE_PROC=y (implied by the following two)
	CONFIG_FSCACHE_STATS=y
	CONFIG_FSCACHE_HISTOGRAM=y

@@ -275,7 +274,7 @@ proc files.
 (*) /proc/fs/fscache/histogram

	cat /proc/fs/fscache/histogram
	+HZ   +TIME OBJ INST  OP RUNS   OBJ RUNS  RETRV DLY RETRIEVLS
	JIFS  SECS  OBJ INST  OP RUNS   OBJ RUNS  RETRV DLY RETRIEVLS
	===== ===== ========= ========= ========= ========= =========

     This shows the breakdown of the number of times each amount of time
@@ -291,16 +290,16 @@ proc files.
	RETRIEVLS	Time between beginning and end of a retrieval

     Each row shows the number of events that took a particular range of times.
     Each step is 1 jiffy in size.  The +HZ column indicates the particular
     jiffy range covered, and the +TIME field the equivalent number of seconds.
     Each step is 1 jiffy in size.  The JIFS column indicates the particular
     jiffy range covered, and the SECS field the equivalent number of seconds.


=========
DEBUGGING
=========

The FS-Cache facility can have runtime debugging enabled by adjusting the value
in:
If CONFIG_FSCACHE_DEBUG is enabled, the FS-Cache facility can have runtime
debugging enabled by adjusting the value in:

	/sys/module/fscache/parameters/debug

@@ -327,4 +326,3 @@ the control file. For example:
	echo $((1|8|64)) >/sys/module/fscache/parameters/debug

will turn on all function entry debugging.
+34 −0
Original line number Diff line number Diff line
@@ -11,6 +11,40 @@ config FSCACHE

	  See Documentation/filesystems/caching/fscache.txt for more information.

config FSCACHE_STATS
	bool "Gather statistical information on local caching"
	depends on FSCACHE && PROC_FS
	help
	  This option causes statistical information to be gathered on local
	  caching and exported through file:

		/proc/fs/fscache/stats

	  The gathering of statistics adds a certain amount of overhead to
	  execution as there are a quite a few stats gathered, and on a
	  multi-CPU system these may be on cachelines that keep bouncing
	  between CPUs.  On the other hand, the stats are very useful for
	  debugging purposes.  Saying 'Y' here is recommended.

	  See Documentation/filesystems/caching/fscache.txt for more information.

config FSCACHE_HISTOGRAM
	bool "Gather latency information on local caching"
	depends on FSCACHE && PROC_FS
	help
	  This option causes latency information to be gathered on local
	  caching and exported through file:

		/proc/fs/fscache/histogram

	  The generation of this histogram adds a certain amount of overhead to
	  execution as there are a number of points at which data is gathered,
	  and on a multi-CPU system these may be on cachelines that keep
	  bouncing between CPUs.  On the other hand, the histogram may be
	  useful for debugging purposes.  Saying 'N' here is recommended.

	  See Documentation/filesystems/caching/fscache.txt for more information.

config FSCACHE_DEBUG
	bool "Debug FS-Cache"
	depends on FSCACHE
+4 −0
Original line number Diff line number Diff line
@@ -5,4 +5,8 @@
fscache-y := \
	main.o

fscache-$(CONFIG_PROC_FS) += proc.o
fscache-$(CONFIG_FSCACHE_STATS) += stats.o
fscache-$(CONFIG_FSCACHE_HISTOGRAM) += histogram.o

obj-$(CONFIG_FSCACHE) := fscache.o

fs/fscache/histogram.c

0 → 100644
+109 −0
Original line number Diff line number Diff line
/* FS-Cache latency histogram
 *
 * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public Licence
 * as published by the Free Software Foundation; either version
 * 2 of the Licence, or (at your option) any later version.
 */

#define FSCACHE_DEBUG_LEVEL THREAD
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include "internal.h"

atomic_t fscache_obj_instantiate_histogram[HZ];
atomic_t fscache_objs_histogram[HZ];
atomic_t fscache_ops_histogram[HZ];
atomic_t fscache_retrieval_delay_histogram[HZ];
atomic_t fscache_retrieval_histogram[HZ];

/*
 * display the time-taken histogram
 */
static int fscache_histogram_show(struct seq_file *m, void *v)
{
	unsigned long index;
	unsigned n[5], t;

	switch ((unsigned long) v) {
	case 1:
		seq_puts(m, "JIFS  SECS  OBJ INST  OP RUNS   OBJ RUNS "
			 " RETRV DLY RETRIEVLS\n");
		return 0;
	case 2:
		seq_puts(m, "===== ===== ========= ========= ========="
			 " ========= =========\n");
		return 0;
	default:
		index = (unsigned long) v - 3;
		n[0] = atomic_read(&fscache_obj_instantiate_histogram[index]);
		n[1] = atomic_read(&fscache_ops_histogram[index]);
		n[2] = atomic_read(&fscache_objs_histogram[index]);
		n[3] = atomic_read(&fscache_retrieval_delay_histogram[index]);
		n[4] = atomic_read(&fscache_retrieval_histogram[index]);
		if (!(n[0] | n[1] | n[2] | n[3] | n[4]))
			return 0;

		t = (index * 1000) / HZ;

		seq_printf(m, "%4lu  0.%03u %9u %9u %9u %9u %9u\n",
			   index, t, n[0], n[1], n[2], n[3], n[4]);
		return 0;
	}
}

/*
 * set up the iterator to start reading from the first line
 */
static void *fscache_histogram_start(struct seq_file *m, loff_t *_pos)
{
	if ((unsigned long long)*_pos >= HZ + 2)
		return NULL;
	if (*_pos == 0)
		*_pos = 1;
	return (void *)(unsigned long) *_pos;
}

/*
 * move to the next line
 */
static void *fscache_histogram_next(struct seq_file *m, void *v, loff_t *pos)
{
	(*pos)++;
	return (unsigned long long)*pos > HZ + 2 ?
		NULL : (void *)(unsigned long) *pos;
}

/*
 * clean up after reading
 */
static void fscache_histogram_stop(struct seq_file *m, void *v)
{
}

static const struct seq_operations fscache_histogram_ops = {
	.start		= fscache_histogram_start,
	.stop		= fscache_histogram_stop,
	.next		= fscache_histogram_next,
	.show		= fscache_histogram_show,
};

/*
 * open "/proc/fs/fscache/histogram" to provide latency data
 */
static int fscache_histogram_open(struct inode *inode, struct file *file)
{
	return seq_open(file, &fscache_histogram_ops);
}

const struct file_operations fscache_histogram_fops = {
	.owner		= THIS_MODULE,
	.open		= fscache_histogram_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= seq_release,
};
Loading