aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2007-05-06 09:12:54 -0400
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2007-07-18 09:53:08 -0400
commit92ad8f37509a7d9d5dd6e0092211b092a7ca7fb1 (patch)
tree96c0f9c524b80e8d1d247e3f462c0c0d6fb782a5
parent79b510c0f21174f4bd055d1aab156e548ae3a5f2 (diff)
UBI: use vmalloc for large buffers
UBI allocates temporary buffers of PEB size, which may be 256KiB. Use vmalloc instead of kmalloc for such big temporary buffers. Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
-rw-r--r--drivers/mtd/ubi/build.c2
-rw-r--r--drivers/mtd/ubi/cdev.c10
-rw-r--r--drivers/mtd/ubi/eba.c22
-rw-r--r--drivers/mtd/ubi/io.c11
-rw-r--r--drivers/mtd/ubi/misc.c4
-rw-r--r--drivers/mtd/ubi/scan.c6
-rw-r--r--drivers/mtd/ubi/ubi.h1
-rw-r--r--drivers/mtd/ubi/upd.c4
-rw-r--r--drivers/mtd/ubi/vtbl.c18
9 files changed, 41 insertions, 37 deletions
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index 555d594d1811..054a88dcc7a1 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -650,7 +650,7 @@ static void detach_mtd_dev(struct ubi_device *ubi)
650 uif_close(ubi); 650 uif_close(ubi);
651 ubi_eba_close(ubi); 651 ubi_eba_close(ubi);
652 ubi_wl_close(ubi); 652 ubi_wl_close(ubi);
653 kfree(ubi->vtbl); 653 vfree(ubi->vtbl);
654 put_mtd_device(ubi->mtd); 654 put_mtd_device(ubi->mtd);
655 kfree(ubi_devices[ubi_num]); 655 kfree(ubi_devices[ubi_num]);
656 ubi_devices[ubi_num] = NULL; 656 ubi_devices[ubi_num] = NULL;
diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c
index 959044a2ddbf..34375ee6d4a4 100644
--- a/drivers/mtd/ubi/cdev.c
+++ b/drivers/mtd/ubi/cdev.c
@@ -153,7 +153,7 @@ static int vol_cdev_release(struct inode *inode, struct file *file)
153 ubi_warn("update of volume %d not finished, volume is damaged", 153 ubi_warn("update of volume %d not finished, volume is damaged",
154 vol->vol_id); 154 vol->vol_id);
155 vol->updating = 0; 155 vol->updating = 0;
156 kfree(vol->upd_buf); 156 vfree(vol->upd_buf);
157 } 157 }
158 158
159 ubi_close_volume(desc); 159 ubi_close_volume(desc);
@@ -232,7 +232,7 @@ static ssize_t vol_cdev_read(struct file *file, __user char *buf, size_t count,
232 tbuf_size = vol->usable_leb_size; 232 tbuf_size = vol->usable_leb_size;
233 if (count < tbuf_size) 233 if (count < tbuf_size)
234 tbuf_size = ALIGN(count, ubi->min_io_size); 234 tbuf_size = ALIGN(count, ubi->min_io_size);
235 tbuf = kmalloc(tbuf_size, GFP_KERNEL); 235 tbuf = vmalloc(tbuf_size);
236 if (!tbuf) 236 if (!tbuf)
237 return -ENOMEM; 237 return -ENOMEM;
238 238
@@ -271,7 +271,7 @@ static ssize_t vol_cdev_read(struct file *file, __user char *buf, size_t count,
271 len = count > tbuf_size ? tbuf_size : count; 271 len = count > tbuf_size ? tbuf_size : count;
272 } while (count); 272 } while (count);
273 273
274 kfree(tbuf); 274 vfree(tbuf);
275 return err ? err : count_save - count; 275 return err ? err : count_save - count;
276} 276}
277 277
@@ -320,7 +320,7 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf,
320 tbuf_size = vol->usable_leb_size; 320 tbuf_size = vol->usable_leb_size;
321 if (count < tbuf_size) 321 if (count < tbuf_size)
322 tbuf_size = ALIGN(count, ubi->min_io_size); 322 tbuf_size = ALIGN(count, ubi->min_io_size);
323 tbuf = kmalloc(tbuf_size, GFP_KERNEL); 323 tbuf = vmalloc(tbuf_size);
324 if (!tbuf) 324 if (!tbuf)
325 return -ENOMEM; 325 return -ENOMEM;
326 326
@@ -355,7 +355,7 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf,
355 len = count > tbuf_size ? tbuf_size : count; 355 len = count > tbuf_size ? tbuf_size : count;
356 } 356 }
357 357
358 kfree(tbuf); 358 vfree(tbuf);
359 return err ? err : count_save - count; 359 return err ? err : count_save - count;
360} 360}
361 361
diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c
index 7c6b223b3f8a..6964fe4ab41a 100644
--- a/drivers/mtd/ubi/eba.c
+++ b/drivers/mtd/ubi/eba.c
@@ -524,7 +524,7 @@ retry:
524 goto write_error; 524 goto write_error;
525 525
526 data_size = offset + len; 526 data_size = offset + len;
527 new_buf = kmalloc(data_size, GFP_KERNEL); 527 new_buf = vmalloc(data_size);
528 if (!new_buf) { 528 if (!new_buf) {
529 err = -ENOMEM; 529 err = -ENOMEM;
530 goto out_put; 530 goto out_put;
@@ -535,7 +535,7 @@ retry:
535 if (offset > 0) { 535 if (offset > 0) {
536 err = ubi_io_read_data(ubi, new_buf, pnum, 0, offset); 536 err = ubi_io_read_data(ubi, new_buf, pnum, 0, offset);
537 if (err && err != UBI_IO_BITFLIPS) { 537 if (err && err != UBI_IO_BITFLIPS) {
538 kfree(new_buf); 538 vfree(new_buf);
539 goto out_put; 539 goto out_put;
540 } 540 }
541 } 541 }
@@ -544,11 +544,11 @@ retry:
544 544
545 err = ubi_io_write_data(ubi, new_buf, new_pnum, 0, data_size); 545 err = ubi_io_write_data(ubi, new_buf, new_pnum, 0, data_size);
546 if (err) { 546 if (err) {
547 kfree(new_buf); 547 vfree(new_buf);
548 goto write_error; 548 goto write_error;
549 } 549 }
550 550
551 kfree(new_buf); 551 vfree(new_buf);
552 ubi_free_vid_hdr(ubi, vid_hdr); 552 ubi_free_vid_hdr(ubi, vid_hdr);
553 553
554 vol->eba_tbl[lnum] = new_pnum; 554 vol->eba_tbl[lnum] = new_pnum;
@@ -977,7 +977,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
977 data_size = aldata_size = 977 data_size = aldata_size =
978 ubi->leb_size - ubi32_to_cpu(vid_hdr->data_pad); 978 ubi->leb_size - ubi32_to_cpu(vid_hdr->data_pad);
979 979
980 buf = kmalloc(aldata_size, GFP_KERNEL); 980 buf = vmalloc(aldata_size);
981 if (!buf) 981 if (!buf)
982 return -ENOMEM; 982 return -ENOMEM;
983 983
@@ -987,7 +987,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
987 */ 987 */
988 err = leb_write_lock(ubi, vol_id, lnum); 988 err = leb_write_lock(ubi, vol_id, lnum);
989 if (err) { 989 if (err) {
990 kfree(buf); 990 vfree(buf);
991 return err; 991 return err;
992 } 992 }
993 993
@@ -1082,7 +1082,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
1082 * We've written the data and are going to read it back to make 1082 * We've written the data and are going to read it back to make
1083 * sure it was written correctly. 1083 * sure it was written correctly.
1084 */ 1084 */
1085 buf1 = kmalloc(aldata_size, GFP_KERNEL); 1085 buf1 = vmalloc(aldata_size);
1086 if (!buf1) { 1086 if (!buf1) {
1087 err = -ENOMEM; 1087 err = -ENOMEM;
1088 goto out_unlock; 1088 goto out_unlock;
@@ -1111,15 +1111,15 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
1111 vol->eba_tbl[lnum] = to; 1111 vol->eba_tbl[lnum] = to;
1112 1112
1113 leb_write_unlock(ubi, vol_id, lnum); 1113 leb_write_unlock(ubi, vol_id, lnum);
1114 kfree(buf); 1114 vfree(buf);
1115 kfree(buf1); 1115 vfree(buf1);
1116 1116
1117 return 0; 1117 return 0;
1118 1118
1119out_unlock: 1119out_unlock:
1120 leb_write_unlock(ubi, vol_id, lnum); 1120 leb_write_unlock(ubi, vol_id, lnum);
1121 kfree(buf); 1121 vfree(buf);
1122 kfree(buf1); 1122 vfree(buf1);
1123 return err; 1123 return err;
1124} 1124}
1125 1125
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c
index 438914d05151..7bb473e646e3 100644
--- a/drivers/mtd/ubi/io.c
+++ b/drivers/mtd/ubi/io.c
@@ -382,7 +382,7 @@ static int torture_peb(const struct ubi_device *ubi, int pnum)
382 void *buf; 382 void *buf;
383 int err, i, patt_count; 383 int err, i, patt_count;
384 384
385 buf = kmalloc(ubi->peb_size, GFP_KERNEL); 385 buf = vmalloc(ubi->peb_size);
386 if (!buf) 386 if (!buf)
387 return -ENOMEM; 387 return -ENOMEM;
388 388
@@ -437,7 +437,7 @@ out:
437 * physical eraseblock which means something is wrong with it. 437 * physical eraseblock which means something is wrong with it.
438 */ 438 */
439 err = -EIO; 439 err = -EIO;
440 kfree(buf); 440 vfree(buf);
441 return err; 441 return err;
442} 442}
443 443
@@ -1224,9 +1224,10 @@ static int paranoid_check_all_ff(const struct ubi_device *ubi, int pnum,
1224 void *buf; 1224 void *buf;
1225 loff_t addr = (loff_t)pnum * ubi->peb_size + offset; 1225 loff_t addr = (loff_t)pnum * ubi->peb_size + offset;
1226 1226
1227 buf = kzalloc(len, GFP_KERNEL); 1227 buf = vmalloc(len);
1228 if (!buf) 1228 if (!buf)
1229 return -ENOMEM; 1229 return -ENOMEM;
1230 memset(buf, 0, len);
1230 1231
1231 err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf); 1232 err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf);
1232 if (err && err != -EUCLEAN) { 1233 if (err && err != -EUCLEAN) {
@@ -1242,7 +1243,7 @@ static int paranoid_check_all_ff(const struct ubi_device *ubi, int pnum,
1242 goto fail; 1243 goto fail;
1243 } 1244 }
1244 1245
1245 kfree(buf); 1246 vfree(buf);
1246 return 0; 1247 return 0;
1247 1248
1248fail: 1249fail:
@@ -1252,7 +1253,7 @@ fail:
1252 err = 1; 1253 err = 1;
1253error: 1254error:
1254 ubi_dbg_dump_stack(); 1255 ubi_dbg_dump_stack();
1255 kfree(buf); 1256 vfree(buf);
1256 return err; 1257 return err;
1257} 1258}
1258 1259
diff --git a/drivers/mtd/ubi/misc.c b/drivers/mtd/ubi/misc.c
index 38d4e6757dc7..9e2338c8e2cf 100644
--- a/drivers/mtd/ubi/misc.c
+++ b/drivers/mtd/ubi/misc.c
@@ -67,7 +67,7 @@ int ubi_check_volume(struct ubi_device *ubi, int vol_id)
67 if (vol->vol_type != UBI_STATIC_VOLUME) 67 if (vol->vol_type != UBI_STATIC_VOLUME)
68 return 0; 68 return 0;
69 69
70 buf = kmalloc(vol->usable_leb_size, GFP_KERNEL); 70 buf = vmalloc(vol->usable_leb_size);
71 if (!buf) 71 if (!buf)
72 return -ENOMEM; 72 return -ENOMEM;
73 73
@@ -87,7 +87,7 @@ int ubi_check_volume(struct ubi_device *ubi, int vol_id)
87 } 87 }
88 } 88 }
89 89
90 kfree(buf); 90 vfree(buf);
91 return err; 91 return err;
92} 92}
93 93
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c
index b24af2104a2a..cbd588d60168 100644
--- a/drivers/mtd/ubi/scan.c
+++ b/drivers/mtd/ubi/scan.c
@@ -356,7 +356,7 @@ static int compare_lebs(const struct ubi_device *ubi,
356 /* Read the data of the copy and check the CRC */ 356 /* Read the data of the copy and check the CRC */
357 357
358 len = ubi32_to_cpu(vid_hdr->data_size); 358 len = ubi32_to_cpu(vid_hdr->data_size);
359 buf = kmalloc(len, GFP_KERNEL); 359 buf = vmalloc(len);
360 if (!buf) { 360 if (!buf) {
361 err = -ENOMEM; 361 err = -ENOMEM;
362 goto out_free_vidh; 362 goto out_free_vidh;
@@ -379,7 +379,7 @@ static int compare_lebs(const struct ubi_device *ubi,
379 bitflips = !!err; 379 bitflips = !!err;
380 } 380 }
381 381
382 kfree(buf); 382 vfree(buf);
383 ubi_free_vid_hdr(ubi, vidh); 383 ubi_free_vid_hdr(ubi, vidh);
384 384
385 if (second_is_newer) 385 if (second_is_newer)
@@ -390,7 +390,7 @@ static int compare_lebs(const struct ubi_device *ubi,
390 return second_is_newer | (bitflips << 1) | (corrupted << 2); 390 return second_is_newer | (bitflips << 1) | (corrupted << 2);
391 391
392out_free_buf: 392out_free_buf:
393 kfree(buf); 393 vfree(buf);
394out_free_vidh: 394out_free_vidh:
395 ubi_free_vid_hdr(ubi, vidh); 395 ubi_free_vid_hdr(ubi, vidh);
396 ubi_assert(err < 0); 396 ubi_assert(err < 0);
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
index c26edea96818..5959f91be240 100644
--- a/drivers/mtd/ubi/ubi.h
+++ b/drivers/mtd/ubi/ubi.h
@@ -35,6 +35,7 @@
35#include <linux/cdev.h> 35#include <linux/cdev.h>
36#include <linux/device.h> 36#include <linux/device.h>
37#include <linux/string.h> 37#include <linux/string.h>
38#include <linux/vmalloc.h>
38#include <linux/mtd/mtd.h> 39#include <linux/mtd/mtd.h>
39 40
40#include <mtd/ubi-header.h> 41#include <mtd/ubi-header.h>
diff --git a/drivers/mtd/ubi/upd.c b/drivers/mtd/ubi/upd.c
index 8925b977e3dc..0efc586a8328 100644
--- a/drivers/mtd/ubi/upd.c
+++ b/drivers/mtd/ubi/upd.c
@@ -150,7 +150,7 @@ int ubi_start_update(struct ubi_device *ubi, int vol_id, long long bytes)
150 vol->updating = 0; 150 vol->updating = 0;
151 } 151 }
152 152
153 vol->upd_buf = kmalloc(ubi->leb_size, GFP_KERNEL); 153 vol->upd_buf = vmalloc(ubi->leb_size);
154 if (!vol->upd_buf) 154 if (!vol->upd_buf)
155 return -ENOMEM; 155 return -ENOMEM;
156 156
@@ -339,7 +339,7 @@ int ubi_more_update_data(struct ubi_device *ubi, int vol_id,
339 err = ubi_wl_flush(ubi); 339 err = ubi_wl_flush(ubi);
340 if (err == 0) { 340 if (err == 0) {
341 err = to_write; 341 err = to_write;
342 kfree(vol->upd_buf); 342 vfree(vol->upd_buf);
343 vol->updating = 0; 343 vol->updating = 0;
344 } 344 }
345 } 345 }
diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c
index 9926f1f9aad8..e3557b987efd 100644
--- a/drivers/mtd/ubi/vtbl.c
+++ b/drivers/mtd/ubi/vtbl.c
@@ -381,11 +381,12 @@ static struct ubi_vtbl_record *process_lvol(const struct ubi_device *ubi,
381 381
382 /* Read both LEB 0 and LEB 1 into memory */ 382 /* Read both LEB 0 and LEB 1 into memory */
383 ubi_rb_for_each_entry(rb, seb, &sv->root, u.rb) { 383 ubi_rb_for_each_entry(rb, seb, &sv->root, u.rb) {
384 leb[seb->lnum] = kzalloc(ubi->vtbl_size, GFP_KERNEL); 384 leb[seb->lnum] = vmalloc(ubi->vtbl_size);
385 if (!leb[seb->lnum]) { 385 if (!leb[seb->lnum]) {
386 err = -ENOMEM; 386 err = -ENOMEM;
387 goto out_free; 387 goto out_free;
388 } 388 }
389 memset(leb[seb->lnum], 0, ubi->vtbl_size);
389 390
390 err = ubi_io_read_data(ubi, leb[seb->lnum], seb->pnum, 0, 391 err = ubi_io_read_data(ubi, leb[seb->lnum], seb->pnum, 0,
391 ubi->vtbl_size); 392 ubi->vtbl_size);
@@ -416,7 +417,7 @@ static struct ubi_vtbl_record *process_lvol(const struct ubi_device *ubi,
416 } 417 }
417 418
418 /* Both LEB 1 and LEB 2 are OK and consistent */ 419 /* Both LEB 1 and LEB 2 are OK and consistent */
419 kfree(leb[1]); 420 vfree(leb[1]);
420 return leb[0]; 421 return leb[0];
421 } else { 422 } else {
422 /* LEB 0 is corrupted or does not exist */ 423 /* LEB 0 is corrupted or does not exist */
@@ -437,13 +438,13 @@ static struct ubi_vtbl_record *process_lvol(const struct ubi_device *ubi,
437 goto out_free; 438 goto out_free;
438 ubi_msg("volume table was restored"); 439 ubi_msg("volume table was restored");
439 440
440 kfree(leb[0]); 441 vfree(leb[0]);
441 return leb[1]; 442 return leb[1];
442 } 443 }
443 444
444out_free: 445out_free:
445 kfree(leb[0]); 446 vfree(leb[0]);
446 kfree(leb[1]); 447 vfree(leb[1]);
447 return ERR_PTR(err); 448 return ERR_PTR(err);
448} 449}
449 450
@@ -461,9 +462,10 @@ static struct ubi_vtbl_record *create_empty_lvol(const struct ubi_device *ubi,
461 int i; 462 int i;
462 struct ubi_vtbl_record *vtbl; 463 struct ubi_vtbl_record *vtbl;
463 464
464 vtbl = kzalloc(ubi->vtbl_size, GFP_KERNEL); 465 vtbl = vmalloc(ubi->vtbl_size);
465 if (!vtbl) 466 if (!vtbl)
466 return ERR_PTR(-ENOMEM); 467 return ERR_PTR(-ENOMEM);
468 memset(vtbl, 0, ubi->vtbl_size);
467 469
468 for (i = 0; i < ubi->vtbl_slots; i++) 470 for (i = 0; i < ubi->vtbl_slots; i++)
469 memcpy(&vtbl[i], &empty_vtbl_record, UBI_VTBL_RECORD_SIZE); 471 memcpy(&vtbl[i], &empty_vtbl_record, UBI_VTBL_RECORD_SIZE);
@@ -473,7 +475,7 @@ static struct ubi_vtbl_record *create_empty_lvol(const struct ubi_device *ubi,
473 475
474 err = create_vtbl(ubi, si, i, vtbl); 476 err = create_vtbl(ubi, si, i, vtbl);
475 if (err) { 477 if (err) {
476 kfree(vtbl); 478 vfree(vtbl);
477 return ERR_PTR(err); 479 return ERR_PTR(err);
478 } 480 }
479 } 481 }
@@ -784,7 +786,7 @@ int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_scan_info *si)
784 return 0; 786 return 0;
785 787
786out_free: 788out_free:
787 kfree(ubi->vtbl); 789 vfree(ubi->vtbl);
788 for (i = 0; i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++) 790 for (i = 0; i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++)
789 if (ubi->volumes[i]) { 791 if (ubi->volumes[i]) {
790 kfree(ubi->volumes[i]); 792 kfree(ubi->volumes[i]);