aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/zram
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/zram')
-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);