From: Nitin Gupta <ngupta@vflare.org>
To: Pekka Enberg <penberg@cs.helsinki.fi>,
Hugh Dickins <hugh.dickins@tiscali.co.uk>,
Andrew Morton <akpm@linux-foundation.org>,
Greg KH <greg@kroah.com>,
Dan Magenheimer <dan.magenheimer@oracle.com>,
Rik van Riel <riel@redhat.com>, Avi Kivity <avi@redhat.com>,
Christoph Hellwig <hch@infradead.org>,
Minchan Kim <minchan.kim@gmail.com>,
Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: linux-mm <linux-mm@kvack.org>,
linux-kernel <linux-kernel@vger.kernel.org>
Subject: [PATCH 3/8] Create sysfs nodes and export basic statistics
Date: Fri, 16 Jul 2010 18:07:45 +0530 [thread overview]
Message-ID: <1279283870-18549-4-git-send-email-ngupta@vflare.org> (raw)
In-Reply-To: <1279283870-18549-1-git-send-email-ngupta@vflare.org>
Creates per-pool sysfs nodes: /sys/kernel/vm/zcache/pool<id>/
(<id> = 0, 1, 2, ...) to export following statistics:
- orig_data_size: Uncompressed worth of data stored in the pool.
- memlimit: Memory limit of the pool. This also allows changing
it at runtime (default: 10% of RAM).
If memlimit is set to a value smaller than the current number
of page stored, then excess pages are not freed immediately but
further puts are blocked till sufficient number of pages are
flushed/freed.
Signed-off-by: Nitin Gupta <ngupta@vflare.org>
---
drivers/staging/zram/zcache_drv.c | 132 ++++++++++++++++++++++++++++++++++++-
drivers/staging/zram/zcache_drv.h | 8 ++
2 files changed, 137 insertions(+), 3 deletions(-)
diff --git a/drivers/staging/zram/zcache_drv.c b/drivers/staging/zram/zcache_drv.c
index 160c172..f680f19 100644
--- a/drivers/staging/zram/zcache_drv.c
+++ b/drivers/staging/zram/zcache_drv.c
@@ -440,6 +440,85 @@ static void zcache_free_inode_pages(struct zcache_inode_rb *znode)
} while (count == FREE_BATCH);
}
+#ifdef CONFIG_SYSFS
+
+#define ZCACHE_POOL_ATTR_RO(_name) \
+ static struct kobj_attribute _name##_attr = __ATTR_RO(_name)
+
+#define ZCACHE_POOL_ATTR(_name) \
+ static struct kobj_attribute _name##_attr = \
+ __ATTR(_name, 0644, _name##_show, _name##_store)
+
+static struct zcache_pool *zcache_kobj_to_pool(struct kobject *kobj)
+{
+ int i;
+
+ spin_lock(&zcache->pool_lock);
+ for (i = 0; i < MAX_ZCACHE_POOLS; i++)
+ if (zcache->pools[i]->kobj == kobj)
+ break;
+ spin_unlock(&zcache->pool_lock);
+
+ return zcache->pools[i];
+}
+
+static ssize_t orig_data_size_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct zcache_pool *zpool = zcache_kobj_to_pool(kobj);
+
+ return sprintf(buf, "%llu\n", zcache_get_stat(
+ zpool, ZPOOL_STAT_PAGES_STORED) << PAGE_SHIFT);
+}
+ZCACHE_POOL_ATTR_RO(orig_data_size);
+
+static void memlimit_sysfs_common(struct kobject *kobj, u64 *value, int store)
+{
+ struct zcache_pool *zpool = zcache_kobj_to_pool(kobj);
+
+ if (store)
+ zcache_set_memlimit(zpool, *value);
+ else
+ *value = zcache_get_memlimit(zpool);
+}
+
+static ssize_t memlimit_store(struct kobject *kobj,
+ struct kobj_attribute *attr, const char *buf, size_t len)
+{
+ int ret;
+ u64 memlimit;
+
+ ret = strict_strtoull(buf, 10, &memlimit);
+ if (ret)
+ return ret;
+
+ memlimit &= PAGE_MASK;
+ memlimit_sysfs_common(kobj, &memlimit, 1);
+
+ return len;
+}
+
+static ssize_t memlimit_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ u64 memlimit;
+
+ memlimit_sysfs_common(kobj, &memlimit, 0);
+ return sprintf(buf, "%llu\n", memlimit);
+}
+ZCACHE_POOL_ATTR(memlimit);
+
+static struct attribute *zcache_pool_attrs[] = {
+ &orig_data_size_attr.attr,
+ &memlimit_attr.attr,
+ NULL,
+};
+
+static struct attribute_group zcache_pool_attr_group = {
+ .attrs = zcache_pool_attrs,
+};
+#endif /* CONFIG_SYSFS */
+
/*
* cleancache_ops.init_fs
*
@@ -451,7 +530,8 @@ static void zcache_free_inode_pages(struct zcache_inode_rb *znode)
*/
static int zcache_init_fs(size_t pagesize)
{
- int ret;
+ int ret, pool_id;
+ struct zcache_pool *zpool = NULL;
/*
* pagesize parameter probably makes sense only for Xen's
@@ -469,14 +549,38 @@ static int zcache_init_fs(size_t pagesize)
goto out;
}
- ret = zcache_create_pool();
- if (ret < 0) {
+ pool_id = zcache_create_pool();
+ if (pool_id < 0) {
pr_info("Failed to create new pool\n");
ret = -ENOMEM;
goto out;
}
+ zpool = zcache->pools[pool_id];
+
+#ifdef CONFIG_SYSFS
+ snprintf(zpool->name, MAX_ZPOOL_NAME_LEN, "pool%d", pool_id);
+
+ /* Create /sys/kernel/mm/zcache/pool<id> (<id> = 0, 1, ...) */
+ zpool->kobj = kobject_create_and_add(zpool->name, zcache->kobj);
+ if (!zpool->kobj) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ /* Create various nodes under /sys/.../pool<id>/ */
+ ret = sysfs_create_group(zpool->kobj, &zcache_pool_attr_group);
+ if (ret) {
+ kobject_put(zpool->kobj);
+ goto out;
+ }
+#endif
+
+ ret = pool_id; /* success */
out:
+ if (ret < 0) /* failure */
+ zcache_destroy_pool(zpool);
+
return ret;
}
@@ -580,6 +684,13 @@ static void zcache_put_page(int pool_id, ino_t inode_no,
*/
zcache_inc_stat(zpool, ZPOOL_STAT_PAGES_STORED);
+ /*
+ * memlimit can be changed any time by user using sysfs. If
+ * it is set to a value smaller than current number of pages
+ * stored, then excess pages are not freed immediately but
+ * further puts are blocked till sufficient number of pages
+ * are flushed/freed.
+ */
if (zcache_get_stat(zpool, ZPOOL_STAT_PAGES_STORED) >
zcache_get_memlimit(zpool) >> PAGE_SHIFT) {
zcache_dec_stat(zpool, ZPOOL_STAT_PAGES_STORED);
@@ -690,6 +801,12 @@ static void zcache_flush_fs(int pool_id)
struct zcache_inode_rb *znode;
struct zcache_pool *zpool = zcache->pools[pool_id];
+#ifdef CONFIG_SYSFS
+ /* Remove per-pool sysfs entries */
+ sysfs_remove_group(zpool->kobj, &zcache_pool_attr_group);
+ kobject_put(zpool->kobj);
+#endif
+
/*
* At this point, there is no active I/O on this filesystem.
* So we can free all its pages without holding any locks.
@@ -722,6 +839,15 @@ static int __init zcache_init(void)
if (!zcache)
return -ENOMEM;
+#ifdef CONFIG_SYSFS
+ /* Create /sys/kernel/mm/zcache/ */
+ zcache->kobj = kobject_create_and_add("zcache", mm_kobj);
+ if (!zcache->kobj) {
+ kfree(zcache);
+ return -ENOMEM;
+ }
+#endif
+
spin_lock_init(&zcache->pool_lock);
cleancache_ops = ops;
diff --git a/drivers/staging/zram/zcache_drv.h b/drivers/staging/zram/zcache_drv.h
index bfba5d7..808cfb2 100644
--- a/drivers/staging/zram/zcache_drv.h
+++ b/drivers/staging/zram/zcache_drv.h
@@ -19,6 +19,7 @@
#include <linux/types.h>
#define MAX_ZCACHE_POOLS 32 /* arbitrary */
+#define MAX_ZPOOL_NAME_LEN 8 /* "pool"+id (shown in sysfs) */
enum zcache_pool_stats_index {
ZPOOL_STAT_PAGES_STORED,
@@ -51,6 +52,10 @@ struct zcache_pool {
seqlock_t memlimit_lock; /* protects memlimit */
u64 memlimit; /* bytes */
struct zcache_pool_stats_cpu *stats; /* percpu stats */
+#ifdef CONFIG_SYSFS
+ unsigned char name[MAX_ZPOOL_NAME_LEN];
+ struct kobject *kobj; /* sysfs */
+#endif
};
/* Manage all zcache pools */
@@ -58,6 +63,9 @@ struct zcache {
struct zcache_pool *pools[MAX_ZCACHE_POOLS];
u32 num_pools; /* current no. of zcache pools */
spinlock_t pool_lock; /* protects pools[] and num_pools */
+#ifdef CONFIG_SYSFS
+ struct kobject *kobj; /* sysfs */
+#endif
};
#endif
--
1.7.1.1
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
next prev parent reply other threads:[~2010-07-16 12:37 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-07-16 12:37 [PATCH 0/8] zcache: page cache compression support Nitin Gupta
2010-07-16 12:37 ` [PATCH 1/8] Allow sharing xvmalloc for zram and zcache Nitin Gupta
2010-07-17 18:10 ` Rik van Riel
2010-07-16 12:37 ` [PATCH 2/8] Basic zcache functionality Nitin Gupta
2010-07-18 8:14 ` Pekka Enberg
2010-07-18 9:45 ` Nitin Gupta
2010-07-18 8:27 ` Pekka Enberg
2010-07-18 8:44 ` Eric Dumazet
2010-07-18 9:51 ` Nitin Gupta
2010-07-16 12:37 ` Nitin Gupta [this message]
2010-07-16 12:37 ` [PATCH 4/8] Shrink zcache based on memlimit Nitin Gupta
2010-07-20 23:03 ` Minchan Kim
2010-07-21 4:52 ` Nitin Gupta
2010-07-21 11:32 ` Ed Tomlinson
2010-07-23 19:23 ` Nitin Gupta
2010-07-16 12:37 ` [PATCH 5/8] Eliminate zero-filled pages Nitin Gupta
2010-07-16 12:37 ` [PATCH 6/8] Compress pages using LZO Nitin Gupta
2010-07-16 12:37 ` [PATCH 7/8] Use xvmalloc to store compressed chunks Nitin Gupta
2010-07-18 7:53 ` Pekka Enberg
2010-07-18 8:21 ` Nitin Gupta
2010-07-19 4:36 ` Minchan Kim
2010-07-19 6:48 ` Nitin Gupta
2010-07-16 12:37 ` [PATCH 8/8] Document sysfs entries Nitin Gupta
2010-07-17 21:13 ` [PATCH 0/8] zcache: page cache compression support Ed Tomlinson
2010-07-18 2:23 ` Nitin Gupta
2010-07-18 7:50 ` Pekka Enberg
2010-07-18 8:12 ` Nitin Gupta
2010-07-19 19:57 ` Dan Magenheimer
2010-07-20 13:50 ` Nitin Gupta
2010-07-20 14:28 ` Dan Magenheimer
2010-07-21 4:27 ` Nitin Gupta
2010-07-21 17:37 ` Dan Magenheimer
2010-07-22 19:14 ` Greg KH
2010-07-22 19:54 ` Dan Magenheimer
2010-07-22 21:00 ` Greg KH
2011-01-10 13:16 ` Kirill A. Shutemov
2011-01-18 17:53 ` Dan Magenheimer
2011-01-20 12:33 ` Nitin Gupta
2011-01-20 12:47 ` Christoph Hellwig
2011-01-20 13:16 ` Pekka Enberg
2011-01-20 13:58 ` Nitin Gupta
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1279283870-18549-4-git-send-email-ngupta@vflare.org \
--to=ngupta@vflare.org \
--cc=akpm@linux-foundation.org \
--cc=avi@redhat.com \
--cc=dan.magenheimer@oracle.com \
--cc=greg@kroah.com \
--cc=hch@infradead.org \
--cc=hugh.dickins@tiscali.co.uk \
--cc=konrad.wilk@oracle.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=minchan.kim@gmail.com \
--cc=penberg@cs.helsinki.fi \
--cc=riel@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).