aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSergey Senozhatsky <sergey.senozhatsky@gmail.com>2014-04-07 18:38:15 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-04-07 19:36:01 -0400
commitfe8eb122c82b2049c460fc6df6e8583a2f935cff (patch)
treebb01a02e6c451d96f379846195346bfde70baba7
parentbeca3ec71fe5490ee9237dc42400f50402baf83e (diff)
zram: add set_max_streams knob
This patch allows to change max_comp_streams on initialised zcomp. Introduce zcomp set_max_streams() knob, zcomp_strm_multi_set_max_streams() and zcomp_strm_single_set_max_streams() callbacks to change streams limit for zcomp_strm_multi and zcomp_strm_single, accordingly. set_max_streams for single steam zcomp does nothing. If user has lowered the limit, then zcomp_strm_multi_set_max_streams() attempts to immediately free extra streams (as much as it can, depending on idle streams availability). Note, this patch does not allow to change stream 'policy' from single to multi stream (or vice versa) on already initialised compression backend. Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> Acked-by: Minchan Kim <minchan@kernel.org> Cc: Jerome Marchand <jmarchan@redhat.com> Cc: Nitin Gupta <ngupta@vflare.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/block/zram/zcomp.c36
-rw-r--r--drivers/block/zram/zcomp.h3
-rw-r--r--drivers/block/zram/zram_drv.c5
3 files changed, 41 insertions, 3 deletions
diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c
index c06f75f54718..ac276f79f21c 100644
--- a/drivers/block/zram/zcomp.c
+++ b/drivers/block/zram/zcomp.c
@@ -136,6 +136,29 @@ static void zcomp_strm_multi_release(struct zcomp *comp, struct zcomp_strm *zstr
136 zcomp_strm_free(comp, zstrm); 136 zcomp_strm_free(comp, zstrm);
137} 137}
138 138
139/* change max_strm limit */
140static int zcomp_strm_multi_set_max_streams(struct zcomp *comp, int num_strm)
141{
142 struct zcomp_strm_multi *zs = comp->stream;
143 struct zcomp_strm *zstrm;
144
145 spin_lock(&zs->strm_lock);
146 zs->max_strm = num_strm;
147 /*
148 * if user has lowered the limit and there are idle streams,
149 * immediately free as much streams (and memory) as we can.
150 */
151 while (zs->avail_strm > num_strm && !list_empty(&zs->idle_strm)) {
152 zstrm = list_entry(zs->idle_strm.next,
153 struct zcomp_strm, list);
154 list_del(&zstrm->list);
155 zcomp_strm_free(comp, zstrm);
156 zs->avail_strm--;
157 }
158 spin_unlock(&zs->strm_lock);
159 return 0;
160}
161
139static void zcomp_strm_multi_destroy(struct zcomp *comp) 162static void zcomp_strm_multi_destroy(struct zcomp *comp)
140{ 163{
141 struct zcomp_strm_multi *zs = comp->stream; 164 struct zcomp_strm_multi *zs = comp->stream;
@@ -158,6 +181,7 @@ static int zcomp_strm_multi_create(struct zcomp *comp, int max_strm)
158 comp->destroy = zcomp_strm_multi_destroy; 181 comp->destroy = zcomp_strm_multi_destroy;
159 comp->strm_find = zcomp_strm_multi_find; 182 comp->strm_find = zcomp_strm_multi_find;
160 comp->strm_release = zcomp_strm_multi_release; 183 comp->strm_release = zcomp_strm_multi_release;
184 comp->set_max_streams = zcomp_strm_multi_set_max_streams;
161 zs = kmalloc(sizeof(struct zcomp_strm_multi), GFP_KERNEL); 185 zs = kmalloc(sizeof(struct zcomp_strm_multi), GFP_KERNEL);
162 if (!zs) 186 if (!zs)
163 return -ENOMEM; 187 return -ENOMEM;
@@ -192,6 +216,12 @@ static void zcomp_strm_single_release(struct zcomp *comp,
192 mutex_unlock(&zs->strm_lock); 216 mutex_unlock(&zs->strm_lock);
193} 217}
194 218
219static int zcomp_strm_single_set_max_streams(struct zcomp *comp, int num_strm)
220{
221 /* zcomp_strm_single support only max_comp_streams == 1 */
222 return -ENOTSUPP;
223}
224
195static void zcomp_strm_single_destroy(struct zcomp *comp) 225static void zcomp_strm_single_destroy(struct zcomp *comp)
196{ 226{
197 struct zcomp_strm_single *zs = comp->stream; 227 struct zcomp_strm_single *zs = comp->stream;
@@ -206,6 +236,7 @@ static int zcomp_strm_single_create(struct zcomp *comp)
206 comp->destroy = zcomp_strm_single_destroy; 236 comp->destroy = zcomp_strm_single_destroy;
207 comp->strm_find = zcomp_strm_single_find; 237 comp->strm_find = zcomp_strm_single_find;
208 comp->strm_release = zcomp_strm_single_release; 238 comp->strm_release = zcomp_strm_single_release;
239 comp->set_max_streams = zcomp_strm_single_set_max_streams;
209 zs = kmalloc(sizeof(struct zcomp_strm_single), GFP_KERNEL); 240 zs = kmalloc(sizeof(struct zcomp_strm_single), GFP_KERNEL);
210 if (!zs) 241 if (!zs)
211 return -ENOMEM; 242 return -ENOMEM;
@@ -220,6 +251,11 @@ static int zcomp_strm_single_create(struct zcomp *comp)
220 return 0; 251 return 0;
221} 252}
222 253
254int zcomp_set_max_streams(struct zcomp *comp, int num_strm)
255{
256 return comp->set_max_streams(comp, num_strm);
257}
258
223struct zcomp_strm *zcomp_strm_find(struct zcomp *comp) 259struct zcomp_strm *zcomp_strm_find(struct zcomp *comp)
224{ 260{
225 return comp->strm_find(comp); 261 return comp->strm_find(comp);
diff --git a/drivers/block/zram/zcomp.h b/drivers/block/zram/zcomp.h
index 2a3684446160..bd11d59c5dd1 100644
--- a/drivers/block/zram/zcomp.h
+++ b/drivers/block/zram/zcomp.h
@@ -46,6 +46,7 @@ struct zcomp {
46 46
47 struct zcomp_strm *(*strm_find)(struct zcomp *comp); 47 struct zcomp_strm *(*strm_find)(struct zcomp *comp);
48 void (*strm_release)(struct zcomp *comp, struct zcomp_strm *zstrm); 48 void (*strm_release)(struct zcomp *comp, struct zcomp_strm *zstrm);
49 int (*set_max_streams)(struct zcomp *comp, int num_strm);
49 void (*destroy)(struct zcomp *comp); 50 void (*destroy)(struct zcomp *comp);
50}; 51};
51 52
@@ -60,4 +61,6 @@ int zcomp_compress(struct zcomp *comp, struct zcomp_strm *zstrm,
60 61
61int zcomp_decompress(struct zcomp *comp, const unsigned char *src, 62int zcomp_decompress(struct zcomp *comp, const unsigned char *src,
62 size_t src_len, unsigned char *dst); 63 size_t src_len, unsigned char *dst);
64
65int zcomp_set_max_streams(struct zcomp *comp, int num_strm);
63#endif /* _ZCOMP_H_ */ 66#endif /* _ZCOMP_H_ */
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index bdc7eb8c6df7..3a5f24c341dc 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -133,9 +133,8 @@ static ssize_t max_comp_streams_store(struct device *dev,
133 return -EINVAL; 133 return -EINVAL;
134 down_write(&zram->init_lock); 134 down_write(&zram->init_lock);
135 if (init_done(zram)) { 135 if (init_done(zram)) {
136 up_write(&zram->init_lock); 136 if (zcomp_set_max_streams(zram->comp, num))
137 pr_info("Can't set max_comp_streams for initialized device\n"); 137 pr_info("Cannot change max compression streams\n");
138 return -EBUSY;
139 } 138 }
140 zram->max_comp_streams = num; 139 zram->max_comp_streams = num;
141 up_write(&zram->init_lock); 140 up_write(&zram->init_lock);