diff --git a/packages/linux/patches/linux-2.6.36-rc8-zram_upstraem_patches-0.1.diff b/packages/linux/patches/linux-2.6.36-rc8-zram_upstraem_patches-0.1.diff new file mode 100644 index 0000000000..85f2347bc8 --- /dev/null +++ b/packages/linux/patches/linux-2.6.36-rc8-zram_upstraem_patches-0.1.diff @@ -0,0 +1,859 @@ +diff -Naur linux-2.6.36-rc8/drivers/staging/zram/Kconfig linux-2.6.36-rc8.patch/drivers/staging/zram/Kconfig +--- linux-2.6.36-rc8/drivers/staging/zram/Kconfig 2010-10-15 01:26:43.000000000 +0200 ++++ linux-2.6.36-rc8.patch/drivers/staging/zram/Kconfig 2010-10-18 03:33:51.000000000 +0200 +@@ -15,15 +15,3 @@ + + See zram.txt for more information. + Project home: http://compcache.googlecode.com/ +- +-config ZRAM_STATS +- bool "Enable statistics for compressed RAM disks" +- depends on ZRAM +- default y +- help +- Enable statistics collection for compressed RAM devices. Statistics +- are exported through ioctl interface, so you have to use zramconfig +- program to get them. This adds only a minimal overhead. +- +- If unsure, say Y. +- +diff -Naur linux-2.6.36-rc8/drivers/staging/zram/Makefile linux-2.6.36-rc8.patch/drivers/staging/zram/Makefile +--- linux-2.6.36-rc8/drivers/staging/zram/Makefile 2010-10-15 01:26:43.000000000 +0200 ++++ linux-2.6.36-rc8.patch/drivers/staging/zram/Makefile 2010-10-18 03:33:51.000000000 +0200 +@@ -1,3 +1,3 @@ +-zram-objs := zram_drv.o xvmalloc.o ++zram-y := zram_drv.o zram_sysfs.o xvmalloc.o + + obj-$(CONFIG_ZRAM) += zram.o +diff -Naur linux-2.6.36-rc8/drivers/staging/zram/zram_drv.c linux-2.6.36-rc8.patch/drivers/staging/zram/zram_drv.c +--- linux-2.6.36-rc8/drivers/staging/zram/zram_drv.c 2010-10-15 01:26:43.000000000 +0200 ++++ linux-2.6.36-rc8.patch/drivers/staging/zram/zram_drv.c 2010-10-18 03:33:51.000000000 +0200 +@@ -33,10 +33,39 @@ + + /* Globals */ + static int zram_major; +-static struct zram *devices; ++struct zram *devices; + + /* Module params (documentation at end) */ +-static unsigned int num_devices; ++unsigned int num_devices; ++ ++static void zram_stat_inc(u32 *v) ++{ ++ *v = *v + 1; ++} ++ ++static void zram_stat_dec(u32 *v) ++{ ++ *v = *v - 1; ++} ++ ++static void zram_stat64_add(struct zram *zram, u64 *v, u64 inc) ++{ ++ spin_lock(&zram->stat64_lock); ++ *v = *v + inc; ++ spin_unlock(&zram->stat64_lock); ++} ++ ++static void zram_stat64_sub(struct zram *zram, u64 *v, u64 dec) ++{ ++ spin_lock(&zram->stat64_lock); ++ *v = *v - dec; ++ spin_unlock(&zram->stat64_lock); ++} ++ ++static void zram_stat64_inc(struct zram *zram, u64 *v) ++{ ++ zram_stat64_add(zram, v, 1); ++} + + static int zram_test_flag(struct zram *zram, u32 index, + enum zram_pageflags flag) +@@ -91,7 +120,7 @@ + "the disk when not in use so a huge zram is " + "wasteful.\n" + "\tMemory Size: %zu kB\n" +- "\tSize you selected: %zu kB\n" ++ "\tSize you selected: %llu kB\n" + "Continuing anyway ...\n", + totalram_bytes >> 10, zram->disksize + ); +@@ -100,49 +129,6 @@ + zram->disksize &= PAGE_MASK; + } + +-static void zram_ioctl_get_stats(struct zram *zram, +- struct zram_ioctl_stats *s) +-{ +- s->disksize = zram->disksize; +- +-#if defined(CONFIG_ZRAM_STATS) +- { +- struct zram_stats *rs = &zram->stats; +- size_t succ_writes, mem_used; +- unsigned int good_compress_perc = 0, no_compress_perc = 0; +- +- mem_used = xv_get_total_size_bytes(zram->mem_pool) +- + (rs->pages_expand << PAGE_SHIFT); +- succ_writes = zram_stat64_read(zram, &rs->num_writes) - +- zram_stat64_read(zram, &rs->failed_writes); +- +- if (succ_writes && rs->pages_stored) { +- good_compress_perc = rs->good_compress * 100 +- / rs->pages_stored; +- no_compress_perc = rs->pages_expand * 100 +- / rs->pages_stored; +- } +- +- s->num_reads = zram_stat64_read(zram, &rs->num_reads); +- s->num_writes = zram_stat64_read(zram, &rs->num_writes); +- s->failed_reads = zram_stat64_read(zram, &rs->failed_reads); +- s->failed_writes = zram_stat64_read(zram, &rs->failed_writes); +- s->invalid_io = zram_stat64_read(zram, &rs->invalid_io); +- s->notify_free = zram_stat64_read(zram, &rs->notify_free); +- s->pages_zero = rs->pages_zero; +- +- s->good_compress_pct = good_compress_perc; +- s->pages_expand_pct = no_compress_perc; +- +- s->pages_stored = rs->pages_stored; +- s->pages_used = mem_used >> PAGE_SHIFT; +- s->orig_data_size = rs->pages_stored << PAGE_SHIFT; +- s->compr_data_size = rs->compr_size; +- s->mem_used_total = mem_used; +- } +-#endif /* CONFIG_ZRAM_STATS */ +-} +- + static void zram_free_page(struct zram *zram, size_t index) + { + u32 clen; +@@ -180,7 +166,7 @@ + zram_stat_dec(&zram->stats.good_compress); + + out: +- zram->stats.compr_size -= clen; ++ zram_stat64_sub(zram, &zram->stats.compr_size, clen); + zram_stat_dec(&zram->stats.pages_stored); + + zram->table[index].page = NULL; +@@ -221,9 +207,15 @@ + u32 index; + struct bio_vec *bvec; + +- zram_stat64_inc(zram, &zram->stats.num_reads); ++ if (unlikely(!zram->init_done)) { ++ set_bit(BIO_UPTODATE, &bio->bi_flags); ++ bio_endio(bio, 0); ++ return 0; ++ } + ++ zram_stat64_inc(zram, &zram->stats.num_reads); + index = bio->bi_sector >> SECTORS_PER_PAGE_SHIFT; ++ + bio_for_each_segment(bvec, bio, i) { + int ret; + size_t clen; +@@ -289,16 +281,20 @@ + + static int zram_write(struct zram *zram, struct bio *bio) + { +- int i; ++ int i, ret; + u32 index; + struct bio_vec *bvec; + +- zram_stat64_inc(zram, &zram->stats.num_writes); ++ if (unlikely(!zram->init_done)) { ++ ret = zram_init_device(zram); ++ if (ret) ++ goto out; ++ } + ++ zram_stat64_inc(zram, &zram->stats.num_writes); + index = bio->bi_sector >> SECTORS_PER_PAGE_SHIFT; + + bio_for_each_segment(bvec, bio, i) { +- int ret; + u32 offset; + size_t clen; + struct zobj_header *zheader; +@@ -396,7 +392,7 @@ + kunmap_atomic(src, KM_USER0); + + /* Update stats */ +- zram->stats.compr_size += clen; ++ zram_stat64_add(zram, &zram->stats.compr_size, clen); + zram_stat_inc(&zram->stats.pages_stored); + if (clen <= PAGE_SIZE / 2) + zram_stat_inc(&zram->stats.good_compress); +@@ -440,7 +436,8 @@ + struct zram *zram = queue->queuedata; + + if (unlikely(!zram->init_done)) { +- bio_io_error(bio); ++ set_bit(BIO_UPTODATE, &bio->bi_flags); ++ bio_endio(bio, 0); + return 0; + } + +@@ -463,11 +460,11 @@ + return ret; + } + +-static void reset_device(struct zram *zram) ++void zram_reset_device(struct zram *zram) + { + size_t index; + +- /* Do not accept any new I/O request */ ++ mutex_lock(&zram->init_lock); + zram->init_done = 0; + + /* Free various per-device buffers */ +@@ -504,16 +501,19 @@ + memset(&zram->stats, 0, sizeof(zram->stats)); + + zram->disksize = 0; ++ mutex_unlock(&zram->init_lock); + } + +-static int zram_ioctl_init_device(struct zram *zram) ++int zram_init_device(struct zram *zram) + { + int ret; + size_t num_pages; + ++ mutex_lock(&zram->init_lock); ++ + if (zram->init_done) { +- pr_info("Device already initialized!\n"); +- return -EBUSY; ++ mutex_unlock(&zram->init_lock); ++ return 0; + } + + zram_set_disksize(zram, totalram_pages << PAGE_SHIFT); +@@ -556,96 +556,19 @@ + } + + zram->init_done = 1; ++ mutex_unlock(&zram->init_lock); + + pr_debug("Initialization done!\n"); + return 0; + + fail: +- reset_device(zram); ++ mutex_unlock(&zram->init_lock); ++ zram_reset_device(zram); + + pr_err("Initialization failed: err=%d\n", ret); + return ret; + } + +-static int zram_ioctl_reset_device(struct zram *zram) +-{ +- if (zram->init_done) +- reset_device(zram); +- +- return 0; +-} +- +-static int zram_ioctl(struct block_device *bdev, fmode_t mode, +- unsigned int cmd, unsigned long arg) +-{ +- int ret = 0; +- size_t disksize_kb; +- +- struct zram *zram = bdev->bd_disk->private_data; +- +- switch (cmd) { +- case ZRAMIO_SET_DISKSIZE_KB: +- if (zram->init_done) { +- ret = -EBUSY; +- goto out; +- } +- if (copy_from_user(&disksize_kb, (void *)arg, +- _IOC_SIZE(cmd))) { +- ret = -EFAULT; +- goto out; +- } +- zram->disksize = disksize_kb << 10; +- pr_info("Disk size set to %zu kB\n", disksize_kb); +- break; +- +- case ZRAMIO_GET_STATS: +- { +- struct zram_ioctl_stats *stats; +- if (!zram->init_done) { +- ret = -ENOTTY; +- goto out; +- } +- stats = kzalloc(sizeof(*stats), GFP_KERNEL); +- if (!stats) { +- ret = -ENOMEM; +- goto out; +- } +- zram_ioctl_get_stats(zram, stats); +- if (copy_to_user((void *)arg, stats, sizeof(*stats))) { +- kfree(stats); +- ret = -EFAULT; +- goto out; +- } +- kfree(stats); +- break; +- } +- case ZRAMIO_INIT: +- ret = zram_ioctl_init_device(zram); +- break; +- +- case ZRAMIO_RESET: +- /* Do not reset an active device! */ +- if (bdev->bd_holders) { +- ret = -EBUSY; +- goto out; +- } +- +- /* Make sure all pending I/O is finished */ +- if (bdev) +- fsync_bdev(bdev); +- +- ret = zram_ioctl_reset_device(zram); +- break; +- +- default: +- pr_info("Invalid ioctl %u\n", cmd); +- ret = -ENOTTY; +- } +- +-out: +- return ret; +-} +- + void zram_slot_free_notify(struct block_device *bdev, unsigned long index) + { + struct zram *zram; +@@ -656,7 +579,6 @@ + } + + static const struct block_device_operations zram_devops = { +- .ioctl = zram_ioctl, + .swap_slot_free_notify = zram_slot_free_notify, + .owner = THIS_MODULE + }; +@@ -666,6 +588,7 @@ + int ret = 0; + + mutex_init(&zram->lock); ++ mutex_init(&zram->init_lock); + spin_lock_init(&zram->stat64_lock); + + zram->queue = blk_alloc_queue(GFP_KERNEL); +@@ -696,7 +619,7 @@ + zram->disk->private_data = zram; + snprintf(zram->disk->disk_name, 16, "zram%d", device_id); + +- /* Actual capacity set using ZRAMIO_SET_DISKSIZE_KB ioctl */ ++ /* Actual capacity set using syfs (/sys/block/zram/disksize */ + set_capacity(zram->disk, 0); + + /* +@@ -710,6 +633,15 @@ + + add_disk(zram->disk); + ++#ifdef CONFIG_SYSFS ++ ret = sysfs_create_group(&disk_to_dev(zram->disk)->kobj, ++ &zram_disk_attr_group); ++ if (ret < 0) { ++ pr_warning("Error creating sysfs group"); ++ goto out; ++ } ++#endif ++ + zram->init_done = 0; + + out: +@@ -718,6 +650,11 @@ + + static void destroy_device(struct zram *zram) + { ++#ifdef CONFIG_SYSFS ++ sysfs_remove_group(&disk_to_dev(zram->disk)->kobj, ++ &zram_disk_attr_group); ++#endif ++ + if (zram->disk) { + del_gendisk(zram->disk); + put_disk(zram->disk); +@@ -786,7 +723,7 @@ + + destroy_device(zram); + if (zram->init_done) +- reset_device(zram); ++ zram_reset_device(zram); + } + + unregister_blkdev(zram_major, "zram"); +diff -Naur linux-2.6.36-rc8/drivers/staging/zram/zram_drv.h linux-2.6.36-rc8.patch/drivers/staging/zram/zram_drv.h +--- linux-2.6.36-rc8/drivers/staging/zram/zram_drv.h 2010-10-15 01:26:43.000000000 +0200 ++++ linux-2.6.36-rc8.patch/drivers/staging/zram/zram_drv.h 2010-10-18 03:33:51.000000000 +0200 +@@ -18,7 +18,6 @@ + #include + #include + +-#include "zram_ioctl.h" + #include "xvmalloc.h" + + /* +@@ -85,11 +84,7 @@ + } __attribute__((aligned(4))); + + struct zram_stats { +- /* basic stats */ +- size_t compr_size; /* compressed size of pages stored - +- * needed to enforce memlimit */ +- /* more stats */ +-#if defined(CONFIG_ZRAM_STATS) ++ u64 compr_size; /* compressed size of pages stored */ + u64 num_reads; /* failed + successful */ + u64 num_writes; /* --do-- */ + u64 failed_reads; /* should NEVER! happen */ +@@ -100,7 +95,6 @@ + u32 pages_stored; /* no. of pages currently stored */ + u32 good_compress; /* % of pages with compression ratio<=50% */ + u32 pages_expand; /* % of incompressible pages */ +-#endif + }; + + struct zram { +@@ -114,51 +108,24 @@ + struct request_queue *queue; + struct gendisk *disk; + int init_done; ++ /* Prevent concurrent execution of device init and reset */ ++ struct mutex init_lock; + /* + * This is the limit on amount of *uncompressed* worth of data + * we can store in a disk. + */ +- size_t disksize; /* bytes */ ++ u64 disksize; /* bytes */ + + struct zram_stats stats; + }; + +-/*-- */ ++extern struct zram *devices; ++extern unsigned int num_devices; ++#ifdef CONFIG_SYSFS ++extern struct attribute_group zram_disk_attr_group; ++#endif + +-/* Debugging and Stats */ +-#if defined(CONFIG_ZRAM_STATS) +-static void zram_stat_inc(u32 *v) +-{ +- *v = *v + 1; +-} +- +-static void zram_stat_dec(u32 *v) +-{ +- *v = *v - 1; +-} +- +-static void zram_stat64_inc(struct zram *zram, u64 *v) +-{ +- spin_lock(&zram->stat64_lock); +- *v = *v + 1; +- spin_unlock(&zram->stat64_lock); +-} +- +-static u64 zram_stat64_read(struct zram *zram, u64 *v) +-{ +- u64 val; +- +- spin_lock(&zram->stat64_lock); +- val = *v; +- spin_unlock(&zram->stat64_lock); +- +- return val; +-} +-#else +-#define zram_stat_inc(v) +-#define zram_stat_dec(v) +-#define zram_stat64_inc(r, v) +-#define zram_stat64_read(r, v) +-#endif /* CONFIG_ZRAM_STATS */ ++extern int zram_init_device(struct zram *zram); ++extern void zram_reset_device(struct zram *zram); + + #endif +diff -Naur linux-2.6.36-rc8/drivers/staging/zram/zram_ioctl.h linux-2.6.36-rc8.patch/drivers/staging/zram/zram_ioctl.h +--- linux-2.6.36-rc8/drivers/staging/zram/zram_ioctl.h 2010-10-15 01:26:43.000000000 +0200 ++++ linux-2.6.36-rc8.patch/drivers/staging/zram/zram_ioctl.h 1970-01-01 01:00:00.000000000 +0100 +@@ -1,41 +0,0 @@ +-/* +- * Compressed RAM block device +- * +- * Copyright (C) 2008, 2009, 2010 Nitin Gupta +- * +- * This code is released using a dual license strategy: BSD/GPL +- * You can choose the licence that better fits your requirements. +- * +- * Released under the terms of 3-clause BSD License +- * Released under the terms of GNU General Public License Version 2.0 +- * +- * Project home: http://compcache.googlecode.com +- */ +- +-#ifndef _ZRAM_IOCTL_H_ +-#define _ZRAM_IOCTL_H_ +- +-struct zram_ioctl_stats { +- u64 disksize; /* disksize in bytes (user specifies in KB) */ +- u64 num_reads; /* failed + successful */ +- u64 num_writes; /* --do-- */ +- u64 failed_reads; /* should NEVER! happen */ +- u64 failed_writes; /* can happen when memory is too low */ +- u64 invalid_io; /* non-page-aligned I/O requests */ +- u64 notify_free; /* no. of swap slot free notifications */ +- u32 pages_zero; /* no. of zero filled pages */ +- u32 good_compress_pct; /* no. of pages with compression ratio<=50% */ +- u32 pages_expand_pct; /* no. of incompressible pages */ +- u32 pages_stored; +- u32 pages_used; +- u64 orig_data_size; +- u64 compr_data_size; +- u64 mem_used_total; +-} __attribute__ ((packed, aligned(4))); +- +-#define ZRAMIO_SET_DISKSIZE_KB _IOW('z', 0, size_t) +-#define ZRAMIO_GET_STATS _IOR('z', 1, struct zram_ioctl_stats) +-#define ZRAMIO_INIT _IO('z', 2) +-#define ZRAMIO_RESET _IO('z', 3) +- +-#endif +diff -Naur linux-2.6.36-rc8/drivers/staging/zram/zram_sysfs.c linux-2.6.36-rc8.patch/drivers/staging/zram/zram_sysfs.c +--- linux-2.6.36-rc8/drivers/staging/zram/zram_sysfs.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.36-rc8.patch/drivers/staging/zram/zram_sysfs.c 2010-10-18 03:33:51.000000000 +0200 +@@ -0,0 +1,224 @@ ++/* ++ * Compressed RAM block device ++ * ++ * Copyright (C) 2008, 2009, 2010 Nitin Gupta ++ * ++ * This code is released using a dual license strategy: BSD/GPL ++ * You can choose the licence that better fits your requirements. ++ * ++ * Released under the terms of 3-clause BSD License ++ * Released under the terms of GNU General Public License Version 2.0 ++ * ++ * Project home: http://compcache.googlecode.com/ ++ */ ++ ++#include ++#include ++ ++#include "zram_drv.h" ++ ++#ifdef CONFIG_SYSFS ++ ++static u64 zram_stat64_read(struct zram *zram, u64 *v) ++{ ++ u64 val; ++ ++ spin_lock(&zram->stat64_lock); ++ val = *v; ++ spin_unlock(&zram->stat64_lock); ++ ++ return val; ++} ++ ++static struct zram *dev_to_zram(struct device *dev) ++{ ++ int i; ++ struct zram *zram = NULL; ++ ++ for (i = 0; i < num_devices; i++) { ++ zram = &devices[i]; ++ if (disk_to_dev(zram->disk) == dev) ++ break; ++ } ++ ++ return zram; ++} ++ ++static ssize_t disksize_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct zram *zram = dev_to_zram(dev); ++ ++ return sprintf(buf, "%llu\n", zram->disksize); ++} ++ ++static ssize_t disksize_store(struct device *dev, ++ struct device_attribute *attr, const char *buf, size_t len) ++{ ++ int ret; ++ struct zram *zram = dev_to_zram(dev); ++ ++ if (zram->init_done) { ++ pr_info("Cannot change disksize for initialized device\n"); ++ return -EBUSY; ++ } ++ ++ ret = strict_strtoull(buf, 10, &zram->disksize); ++ if (ret) ++ return ret; ++ ++ zram->disksize &= PAGE_MASK; ++ set_capacity(zram->disk, zram->disksize >> SECTOR_SHIFT); ++ ++ return len; ++} ++ ++static ssize_t initstate_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct zram *zram = dev_to_zram(dev); ++ ++ return sprintf(buf, "%u\n", zram->init_done); ++} ++ ++static ssize_t reset_store(struct device *dev, ++ struct device_attribute *attr, const char *buf, size_t len) ++{ ++ int ret; ++ unsigned long do_reset; ++ struct zram *zram; ++ struct block_device *bdev; ++ ++ zram = dev_to_zram(dev); ++ bdev = bdget_disk(zram->disk, 0); ++ ++ /* Do not reset an active device! */ ++ if (bdev->bd_holders) ++ return -EBUSY; ++ ++ ret = strict_strtoul(buf, 10, &do_reset); ++ if (ret) ++ return ret; ++ ++ if (!do_reset) ++ return -EINVAL; ++ ++ /* Make sure all pending I/O is finished */ ++ if (bdev) ++ fsync_bdev(bdev); ++ ++ if (zram->init_done) ++ zram_reset_device(zram); ++ ++ return len; ++} ++ ++static ssize_t num_reads_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct zram *zram = dev_to_zram(dev); ++ ++ return sprintf(buf, "%llu\n", ++ zram_stat64_read(zram, &zram->stats.num_reads)); ++} ++ ++static ssize_t num_writes_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct zram *zram = dev_to_zram(dev); ++ ++ return sprintf(buf, "%llu\n", ++ zram_stat64_read(zram, &zram->stats.num_writes)); ++} ++ ++static ssize_t invalid_io_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct zram *zram = dev_to_zram(dev); ++ ++ return sprintf(buf, "%llu\n", ++ zram_stat64_read(zram, &zram->stats.invalid_io)); ++} ++ ++static ssize_t notify_free_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct zram *zram = dev_to_zram(dev); ++ ++ return sprintf(buf, "%llu\n", ++ zram_stat64_read(zram, &zram->stats.notify_free)); ++} ++ ++static ssize_t zero_pages_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct zram *zram = dev_to_zram(dev); ++ ++ return sprintf(buf, "%u\n", zram->stats.pages_zero); ++} ++ ++static ssize_t orig_data_size_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct zram *zram = dev_to_zram(dev); ++ ++ return sprintf(buf, "%llu\n", ++ (u64)(zram->stats.pages_stored) << PAGE_SHIFT); ++} ++ ++static ssize_t compr_data_size_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ struct zram *zram = dev_to_zram(dev); ++ ++ return sprintf(buf, "%llu\n", ++ zram_stat64_read(zram, &zram->stats.compr_size)); ++} ++ ++static ssize_t mem_used_total_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ u64 val = 0; ++ struct zram *zram = dev_to_zram(dev); ++ ++ if (zram->init_done) { ++ val = xv_get_total_size_bytes(zram->mem_pool) + ++ ((u64)(zram->stats.pages_expand) << PAGE_SHIFT); ++ } ++ ++ return sprintf(buf, "%llu\n", val); ++} ++ ++static DEVICE_ATTR(disksize, S_IRUGO | S_IWUGO, ++ disksize_show, disksize_store); ++static DEVICE_ATTR(initstate, S_IRUGO, initstate_show, NULL); ++static DEVICE_ATTR(reset, S_IWUGO, NULL, reset_store); ++static DEVICE_ATTR(num_reads, S_IRUGO, num_reads_show, NULL); ++static DEVICE_ATTR(num_writes, S_IRUGO, num_writes_show, NULL); ++static DEVICE_ATTR(invalid_io, S_IRUGO, invalid_io_show, NULL); ++static DEVICE_ATTR(notify_free, S_IRUGO, notify_free_show, NULL); ++static DEVICE_ATTR(zero_pages, S_IRUGO, zero_pages_show, NULL); ++static DEVICE_ATTR(orig_data_size, S_IRUGO, orig_data_size_show, NULL); ++static DEVICE_ATTR(compr_data_size, S_IRUGO, compr_data_size_show, NULL); ++static DEVICE_ATTR(mem_used_total, S_IRUGO, mem_used_total_show, NULL); ++ ++static struct attribute *zram_disk_attrs[] = { ++ &dev_attr_disksize.attr, ++ &dev_attr_initstate.attr, ++ &dev_attr_reset.attr, ++ &dev_attr_num_reads.attr, ++ &dev_attr_num_writes.attr, ++ &dev_attr_invalid_io.attr, ++ &dev_attr_notify_free.attr, ++ &dev_attr_zero_pages.attr, ++ &dev_attr_orig_data_size.attr, ++ &dev_attr_compr_data_size.attr, ++ &dev_attr_mem_used_total.attr, ++ NULL, ++}; ++ ++struct attribute_group zram_disk_attr_group = { ++ .attrs = zram_disk_attrs, ++}; ++ ++#endif /* CONFIG_SYSFS */ +diff -Naur linux-2.6.36-rc8/drivers/staging/zram/zram.txt linux-2.6.36-rc8.patch/drivers/staging/zram/zram.txt +--- linux-2.6.36-rc8/drivers/staging/zram/zram.txt 2010-10-15 01:26:43.000000000 +0200 ++++ linux-2.6.36-rc8.patch/drivers/staging/zram/zram.txt 2010-10-18 03:33:51.000000000 +0200 +@@ -5,33 +5,35 @@ + + * Introduction + +-The zram module creates RAM based block devices: /dev/ramX (X = 0, 1, ...). +-Pages written to these disks are compressed and stored in memory itself. +-These disks allow very fast I/O and compression provides good amounts of +-memory savings. +- +-See project home for use cases, performance numbers and a lot more. +- +-Individual zram devices are configured and initialized using zramconfig +-userspace utility as shown in examples below. See zramconfig man page for +-more details. ++The zram module creates RAM based block devices named /dev/zram ++( = 0, 1, ...). Pages written to these disks are compressed and stored ++in memory itself. These disks allow very fast I/O and compression provides ++good amounts of memory savings. Some of the usecases include /tmp storage, ++use as swap disks, various caches under /var and maybe many more :) ++ ++Statistics for individual zram devices are exported through sysfs nodes at ++/sys/block/zram/ + + * Usage + + Following shows a typical sequence of steps for using zram. + +-1) Load Modules: ++1) Load Module: + modprobe zram num_devices=4 +- This creates 4 (uninitialized) devices: /dev/zram{0,1,2,3} ++ This creates 4 devices: /dev/zram{0,1,2,3} + (num_devices parameter is optional. Default: 1) + +-2) Initialize: +- Use zramconfig utility to configure and initialize individual +- zram devices. For example: +- zramconfig /dev/zram0 --init # uses default value of disksize_kb +- zramconfig /dev/zram1 --disksize_kb=102400 # 100MB /dev/zram1 +- +- *See zramconfig man page for more details and examples* ++2) Set Disksize (Optional): ++ Set disk size by writing the value to sysfs node 'disksize' ++ (in bytes). If disksize is not given, default value of 25% ++ of RAM is used. ++ ++ # Initialize /dev/zram0 with 50MB disksize ++ echo $((50*1024*1024)) > /sys/block/zram0/disksize ++ ++ NOTE: disksize cannot be changed if the disk contains any ++ data. So, for such a disk, you need to issue 'reset' (see below) ++ before you can change its disksize. + + 3) Activate: + mkswap /dev/zram0 +@@ -41,17 +43,29 @@ + mount /dev/zram1 /tmp + + 4) Stats: +- zramconfig /dev/zram0 --stats +- zramconfig /dev/zram1 --stats ++ Per-device statistics are exported as various nodes under ++ /sys/block/zram/ ++ disksize ++ num_reads ++ num_writes ++ invalid_io ++ notify_free ++ discard ++ zero_pages ++ orig_data_size ++ compr_data_size ++ mem_used_total + + 5) Deactivate: + swapoff /dev/zram0 + umount /dev/zram1 + + 6) Reset: +- zramconfig /dev/zram0 --reset +- zramconfig /dev/zram1 --reset +- (This frees memory allocated for the given device). ++ Write any positive value to 'reset' sysfs node ++ echo 1 > /sys/block/zram0/reset ++ echo 1 > /sys/block/zram1/reset ++ ++ (This frees all the memory allocated for the given device). + + + Please report any problems at: