aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMinchan Kim <minchan@kernel.org>2017-01-10 19:58:21 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-01-19 14:17:58 -0500
commit2e264fb546fa5eade611dca09d8734e3232ff9b2 (patch)
tree8563607f1b757e6c5bd6f6cd439fb7702b7074d2
parentad4764b4c8ebb48da0680ac0e7b20d4f49fc6cd1 (diff)
zram: support BDI_CAP_STABLE_WRITES
commit b09ab054b69b07077bd3292f67e777861ac796e5 upstream. zram has used per-cpu stream feature from v4.7. It aims for increasing cache hit ratio of scratch buffer for compressing. Downside of that approach is that zram should ask memory space for compressed page in per-cpu context which requires stricted gfp flag which could be failed. If so, it retries to allocate memory space out of per-cpu context so it could get memory this time and compress the data again, copies it to the memory space. In this scenario, zram assumes the data should never be changed but it is not true without stable page support. So, If the data is changed under us, zram can make buffer overrun so that zsmalloc free object chain is broken so system goes crash like below https://bugzilla.suse.com/show_bug.cgi?id=997574 This patch adds BDI_CAP_STABLE_WRITES to zram for declaring "I am block device needing *stable write*". Fixes: da9556a2367c ("zram: user per-cpu compression streams") Link: http://lkml.kernel.org/r/1482366980-3782-4-git-send-email-minchan@kernel.org Signed-off-by: Minchan Kim <minchan@kernel.org> Reviewed-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> Cc: Takashi Iwai <tiwai@suse.de> Cc: Hyeoncheol Lee <cheol.lee@lge.com> Cc: <yjay.kim@lge.com> Cc: Sangseok Lee <sangseok.lee@lge.com> Cc: Hugh Dickins <hughd@google.com> Cc: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/block/zram/zram_drv.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index c0b95dd36101..d2ef51ca9cf4 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -25,6 +25,7 @@
25#include <linux/genhd.h> 25#include <linux/genhd.h>
26#include <linux/highmem.h> 26#include <linux/highmem.h>
27#include <linux/slab.h> 27#include <linux/slab.h>
28#include <linux/backing-dev.h>
28#include <linux/string.h> 29#include <linux/string.h>
29#include <linux/vmalloc.h> 30#include <linux/vmalloc.h>
30#include <linux/err.h> 31#include <linux/err.h>
@@ -111,6 +112,14 @@ static inline bool is_partial_io(struct bio_vec *bvec)
111 return bvec->bv_len != PAGE_SIZE; 112 return bvec->bv_len != PAGE_SIZE;
112} 113}
113 114
115static void zram_revalidate_disk(struct zram *zram)
116{
117 revalidate_disk(zram->disk);
118 /* revalidate_disk reset the BDI_CAP_STABLE_WRITES so set again */
119 zram->disk->queue->backing_dev_info.capabilities |=
120 BDI_CAP_STABLE_WRITES;
121}
122
114/* 123/*
115 * Check if request is within bounds and aligned on zram logical blocks. 124 * Check if request is within bounds and aligned on zram logical blocks.
116 */ 125 */
@@ -1094,7 +1103,7 @@ static ssize_t disksize_store(struct device *dev,
1094 zram->comp = comp; 1103 zram->comp = comp;
1095 zram->disksize = disksize; 1104 zram->disksize = disksize;
1096 set_capacity(zram->disk, zram->disksize >> SECTOR_SHIFT); 1105 set_capacity(zram->disk, zram->disksize >> SECTOR_SHIFT);
1097 revalidate_disk(zram->disk); 1106 zram_revalidate_disk(zram);
1098 up_write(&zram->init_lock); 1107 up_write(&zram->init_lock);
1099 1108
1100 return len; 1109 return len;
@@ -1142,7 +1151,7 @@ static ssize_t reset_store(struct device *dev,
1142 /* Make sure all the pending I/O are finished */ 1151 /* Make sure all the pending I/O are finished */
1143 fsync_bdev(bdev); 1152 fsync_bdev(bdev);
1144 zram_reset_device(zram); 1153 zram_reset_device(zram);
1145 revalidate_disk(zram->disk); 1154 zram_revalidate_disk(zram);
1146 bdput(bdev); 1155 bdput(bdev);
1147 1156
1148 mutex_lock(&bdev->bd_mutex); 1157 mutex_lock(&bdev->bd_mutex);