From: "Luiz Fernando N. Capitulino" <[EMAIL PROTECTED]>
[PATCH]: VM tail statistics support
This patch is a hack which introduces initial statistics support
for the VM tail functionality.
It uses debugfs and does accouting of:
1. Number of times vm_file_tail_pack() have been called
2. Number of times vm_file_tail_unpack() have been called
3. Total size of file tails allocations
4. Number of file tail allocations
5. Bytes saved
Signed-off-by: Luiz Fernando N. Capitulino <[EMAIL PROTECTED]>
Signed-off-by: Dave Kleikamp <[EMAIL PROTECTED]>
---
mm/file_tail.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 126 insertions(+), 1 deletion(-)
diff -Nurp linux008/mm/file_tail.c linux009/mm/file_tail.c
--- linux008/mm/file_tail.c 2007-11-08 10:49:46.000000000 -0600
+++ linux009/mm/file_tail.c 2007-11-08 10:49:46.000000000 -0600
@@ -12,10 +12,51 @@
#include <linux/buffer_head.h>
#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/debugfs.h>
#include <linux/hardirq.h>
#include <linux/module.h>
+#include <linux/spinlock.h>
#include <linux/vm_file_tail.h>
+struct {
+ struct dentry *root_dir;
+ struct dentry *nr_tails;
+ struct dentry *tail_size;
+ struct dentry *saved_bytes;
+ struct dentry *pack_called;
+ struct dentry *unpack_called;
+ struct dentry *read_called;
+} vm_tail_debugfs;
+
+struct {
+ u32 nr_tails;
+ u32 tail_size;
+ u32 saved_bytes;
+ u32 pack_called;
+ u32 unpack_called;
+ u32 read_called;
+ spinlock_t lock;
+} vm_tail_stats = { .lock = __SPIN_LOCK_UNLOCKED(lock) };
+
+static void vm_file_tail_stats_inc(int length)
+{
+ spin_lock(&vm_tail_stats.lock);
+ vm_tail_stats.nr_tails++;
+ vm_tail_stats.tail_size += length;
+ vm_tail_stats.saved_bytes += (PAGE_SIZE - length);
+ spin_unlock(&vm_tail_stats.lock);
+}
+
+static void vm_file_tail_stats_dec(int length)
+{
+ spin_lock(&vm_tail_stats.lock);
+ vm_tail_stats.nr_tails--;
+ vm_tail_stats.tail_size -= length;
+ vm_tail_stats.saved_bytes -= (PAGE_SIZE - length);
+ spin_unlock(&vm_tail_stats.lock);
+}
+
/*
* Free the file tail
*
@@ -29,7 +70,10 @@ void __vm_file_tail_free(struct address_
spin_lock_irqsave(&mapping->tail_lock, flags);
tail = mapping->tail;
- mapping->tail = NULL;
+ if (tail) {
+ vm_file_tail_stats_dec(vm_file_tail_length(mapping));
+ mapping->tail = NULL;
+ }
spin_unlock_irqrestore(&mapping->tail_lock, flags);
kfree(tail);
}
@@ -49,6 +93,8 @@ void vm_file_tail_unpack(struct address_
struct page *page;
void *tail;
+ vm_tail_stats.unpack_called++;
+
if (!mapping->tail)
return;
@@ -85,6 +131,7 @@ void vm_file_tail_unpack(struct address_
add_to_page_cache_lru(page, mapping, index, gfp_mask);
unlock_page(page);
page_cache_release(page);
+ vm_file_tail_stats_dec(length);
} else
/* Free the tail */
__vm_file_tail_free(mapping);
@@ -120,6 +167,8 @@ int vm_file_tail_pack(struct page *page)
struct address_space *mapping;
void *tail;
+ vm_tail_stats.pack_called++;
+
if (TestSetPageLocked(page))
return 0;
@@ -163,12 +212,86 @@ int vm_file_tail_pack(struct page *page)
remove_from_page_cache(page);
page_cache_release(page); /* pagecache ref */
ret = 1;
+ vm_file_tail_stats_inc(length);
out:
unlock_page(page);
return ret;
}
+static int __init create_debugfs_file(const char *name, struct dentry **dir,
+ u32 *var)
+{
+ *dir = debugfs_create_u32(name, S_IFREG|S_IRUGO,
+ vm_tail_debugfs.root_dir, var);
+ if (!*dir) {
+ printk(KERN_ERR "ERROR: vm_tail: could not create %s\n", name);
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+static int __init vm_file_tail_init(void)
+{
+ int err;
+
+ vm_tail_debugfs.root_dir = debugfs_create_dir("vm_tail", NULL);
+ if (!vm_tail_debugfs.root_dir) {
+ printk(KERN_ERR "ERROR: %s Could not create root directory\n",
+ __FUNCTION__);
+ return -ENOMEM;
+ }
+
+ err = create_debugfs_file("nr_tails", &vm_tail_debugfs.nr_tails,
+ &vm_tail_stats.nr_tails);
+ if (err)
+ goto out_err;
+
+ err = create_debugfs_file("tail_size", &vm_tail_debugfs.tail_size,
+ &vm_tail_stats.tail_size);
+ if (err)
+ goto out_err1;
+
+ err = create_debugfs_file("saved_bytes", &vm_tail_debugfs.saved_bytes,
+ &vm_tail_stats.saved_bytes);
+ if (err)
+ goto out_err2;
+
+ err = create_debugfs_file("unpack_called",
+ &vm_tail_debugfs.unpack_called,
+ &vm_tail_stats.unpack_called);
+ if (err)
+ goto out_err3;
+
+ err = create_debugfs_file("pack_called", &vm_tail_debugfs.pack_called,
+ &vm_tail_stats.pack_called);
+ if (err)
+ goto out_err4;
+
+ err = create_debugfs_file("read_called", &vm_tail_debugfs.read_called,
+ &vm_tail_stats.read_called);
+ if (err)
+ goto out_err5;
+
+ return 0;
+
+out_err5:
+ debugfs_remove(vm_tail_debugfs.pack_called);
+out_err4:
+ debugfs_remove(vm_tail_debugfs.unpack_called);
+out_err3:
+ debugfs_remove(vm_tail_debugfs.saved_bytes);
+out_err2:
+ debugfs_remove(vm_tail_debugfs.tail_size);
+out_err1:
+ debugfs_remove(vm_tail_debugfs.nr_tails);
+out_err:
+ debugfs_remove(vm_tail_debugfs.root_dir);
+ return err;
+}
+
+postcore_initcall(vm_file_tail_init);
+
void __vm_file_tail_unpack_on_resize(struct inode *inode, loff_t new_size)
{
loff_t old_size = i_size_read(inode);
@@ -211,6 +334,8 @@ int __vm_file_tail_read(struct file *fil
return 0;
}
+ vm_tail_stats.read_called++;
+
size = vm_file_tail_length(mapping) - offset;
if (size > count)
size = count;
-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html