linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
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>

  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).