Skip to content

Commit

Permalink
UBI: use vmalloc for large buffers
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Artem Bityutskiy authored and Artem Bityutskiy committed Jul 18, 2007
1 parent 79b510c commit 92ad8f3
Show file tree
Hide file tree
Showing 9 changed files with 41 additions and 37 deletions.
2 changes: 1 addition & 1 deletion drivers/mtd/ubi/build.c
Original file line number Diff line number Diff line change
Expand Up @@ -650,7 +650,7 @@ static void detach_mtd_dev(struct ubi_device *ubi)
uif_close(ubi);
ubi_eba_close(ubi);
ubi_wl_close(ubi);
kfree(ubi->vtbl);
vfree(ubi->vtbl);
put_mtd_device(ubi->mtd);
kfree(ubi_devices[ubi_num]);
ubi_devices[ubi_num] = NULL;
Expand Down
10 changes: 5 additions & 5 deletions drivers/mtd/ubi/cdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ static int vol_cdev_release(struct inode *inode, struct file *file)
ubi_warn("update of volume %d not finished, volume is damaged",
vol->vol_id);
vol->updating = 0;
kfree(vol->upd_buf);
vfree(vol->upd_buf);
}

ubi_close_volume(desc);
Expand Down Expand Up @@ -232,7 +232,7 @@ static ssize_t vol_cdev_read(struct file *file, __user char *buf, size_t count,
tbuf_size = vol->usable_leb_size;
if (count < tbuf_size)
tbuf_size = ALIGN(count, ubi->min_io_size);
tbuf = kmalloc(tbuf_size, GFP_KERNEL);
tbuf = vmalloc(tbuf_size);
if (!tbuf)
return -ENOMEM;

Expand Down Expand Up @@ -271,7 +271,7 @@ static ssize_t vol_cdev_read(struct file *file, __user char *buf, size_t count,
len = count > tbuf_size ? tbuf_size : count;
} while (count);

kfree(tbuf);
vfree(tbuf);
return err ? err : count_save - count;
}

Expand Down Expand Up @@ -320,7 +320,7 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf,
tbuf_size = vol->usable_leb_size;
if (count < tbuf_size)
tbuf_size = ALIGN(count, ubi->min_io_size);
tbuf = kmalloc(tbuf_size, GFP_KERNEL);
tbuf = vmalloc(tbuf_size);
if (!tbuf)
return -ENOMEM;

Expand Down Expand Up @@ -355,7 +355,7 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf,
len = count > tbuf_size ? tbuf_size : count;
}

kfree(tbuf);
vfree(tbuf);
return err ? err : count_save - count;
}

Expand Down
22 changes: 11 additions & 11 deletions drivers/mtd/ubi/eba.c
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,7 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum,
goto write_error;

data_size = offset + len;
new_buf = kmalloc(data_size, GFP_KERNEL);
new_buf = vmalloc(data_size);
if (!new_buf) {
err = -ENOMEM;
goto out_put;
Expand All @@ -535,7 +535,7 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum,
if (offset > 0) {
err = ubi_io_read_data(ubi, new_buf, pnum, 0, offset);
if (err && err != UBI_IO_BITFLIPS) {
kfree(new_buf);
vfree(new_buf);
goto out_put;
}
}
Expand All @@ -544,11 +544,11 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum,

err = ubi_io_write_data(ubi, new_buf, new_pnum, 0, data_size);
if (err) {
kfree(new_buf);
vfree(new_buf);
goto write_error;
}

kfree(new_buf);
vfree(new_buf);
ubi_free_vid_hdr(ubi, vid_hdr);

vol->eba_tbl[lnum] = new_pnum;
Expand Down Expand Up @@ -977,7 +977,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
data_size = aldata_size =
ubi->leb_size - ubi32_to_cpu(vid_hdr->data_pad);

buf = kmalloc(aldata_size, GFP_KERNEL);
buf = vmalloc(aldata_size);
if (!buf)
return -ENOMEM;

Expand All @@ -987,7 +987,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
*/
err = leb_write_lock(ubi, vol_id, lnum);
if (err) {
kfree(buf);
vfree(buf);
return err;
}

Expand Down Expand Up @@ -1082,7 +1082,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
* We've written the data and are going to read it back to make
* sure it was written correctly.
*/
buf1 = kmalloc(aldata_size, GFP_KERNEL);
buf1 = vmalloc(aldata_size);
if (!buf1) {
err = -ENOMEM;
goto out_unlock;
Expand Down Expand Up @@ -1111,15 +1111,15 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
vol->eba_tbl[lnum] = to;

leb_write_unlock(ubi, vol_id, lnum);
kfree(buf);
kfree(buf1);
vfree(buf);
vfree(buf1);

return 0;

out_unlock:
leb_write_unlock(ubi, vol_id, lnum);
kfree(buf);
kfree(buf1);
vfree(buf);
vfree(buf1);
return err;
}

Expand Down
11 changes: 6 additions & 5 deletions drivers/mtd/ubi/io.c
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ static int torture_peb(const struct ubi_device *ubi, int pnum)
void *buf;
int err, i, patt_count;

buf = kmalloc(ubi->peb_size, GFP_KERNEL);
buf = vmalloc(ubi->peb_size);
if (!buf)
return -ENOMEM;

Expand Down Expand Up @@ -437,7 +437,7 @@ static int torture_peb(const struct ubi_device *ubi, int pnum)
* physical eraseblock which means something is wrong with it.
*/
err = -EIO;
kfree(buf);
vfree(buf);
return err;
}

Expand Down Expand Up @@ -1224,9 +1224,10 @@ static int paranoid_check_all_ff(const struct ubi_device *ubi, int pnum,
void *buf;
loff_t addr = (loff_t)pnum * ubi->peb_size + offset;

buf = kzalloc(len, GFP_KERNEL);
buf = vmalloc(len);
if (!buf)
return -ENOMEM;
memset(buf, 0, len);

err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf);
if (err && err != -EUCLEAN) {
Expand All @@ -1242,7 +1243,7 @@ static int paranoid_check_all_ff(const struct ubi_device *ubi, int pnum,
goto fail;
}

kfree(buf);
vfree(buf);
return 0;

fail:
Expand All @@ -1252,7 +1253,7 @@ static int paranoid_check_all_ff(const struct ubi_device *ubi, int pnum,
err = 1;
error:
ubi_dbg_dump_stack();
kfree(buf);
vfree(buf);
return err;
}

Expand Down
4 changes: 2 additions & 2 deletions drivers/mtd/ubi/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ int ubi_check_volume(struct ubi_device *ubi, int vol_id)
if (vol->vol_type != UBI_STATIC_VOLUME)
return 0;

buf = kmalloc(vol->usable_leb_size, GFP_KERNEL);
buf = vmalloc(vol->usable_leb_size);
if (!buf)
return -ENOMEM;

Expand All @@ -87,7 +87,7 @@ int ubi_check_volume(struct ubi_device *ubi, int vol_id)
}
}

kfree(buf);
vfree(buf);
return err;
}

Expand Down
6 changes: 3 additions & 3 deletions drivers/mtd/ubi/scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ static int compare_lebs(const struct ubi_device *ubi,
/* Read the data of the copy and check the CRC */

len = ubi32_to_cpu(vid_hdr->data_size);
buf = kmalloc(len, GFP_KERNEL);
buf = vmalloc(len);
if (!buf) {
err = -ENOMEM;
goto out_free_vidh;
Expand All @@ -379,7 +379,7 @@ static int compare_lebs(const struct ubi_device *ubi,
bitflips = !!err;
}

kfree(buf);
vfree(buf);
ubi_free_vid_hdr(ubi, vidh);

if (second_is_newer)
Expand All @@ -390,7 +390,7 @@ static int compare_lebs(const struct ubi_device *ubi,
return second_is_newer | (bitflips << 1) | (corrupted << 2);

out_free_buf:
kfree(buf);
vfree(buf);
out_free_vidh:
ubi_free_vid_hdr(ubi, vidh);
ubi_assert(err < 0);
Expand Down
1 change: 1 addition & 0 deletions drivers/mtd/ubi/ubi.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/string.h>
#include <linux/vmalloc.h>
#include <linux/mtd/mtd.h>

#include <mtd/ubi-header.h>
Expand Down
4 changes: 2 additions & 2 deletions drivers/mtd/ubi/upd.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ int ubi_start_update(struct ubi_device *ubi, int vol_id, long long bytes)
vol->updating = 0;
}

vol->upd_buf = kmalloc(ubi->leb_size, GFP_KERNEL);
vol->upd_buf = vmalloc(ubi->leb_size);
if (!vol->upd_buf)
return -ENOMEM;

Expand Down Expand Up @@ -339,7 +339,7 @@ int ubi_more_update_data(struct ubi_device *ubi, int vol_id,
err = ubi_wl_flush(ubi);
if (err == 0) {
err = to_write;
kfree(vol->upd_buf);
vfree(vol->upd_buf);
vol->updating = 0;
}
}
Expand Down
18 changes: 10 additions & 8 deletions drivers/mtd/ubi/vtbl.c
Original file line number Diff line number Diff line change
Expand Up @@ -381,11 +381,12 @@ static struct ubi_vtbl_record *process_lvol(const struct ubi_device *ubi,

/* Read both LEB 0 and LEB 1 into memory */
ubi_rb_for_each_entry(rb, seb, &sv->root, u.rb) {
leb[seb->lnum] = kzalloc(ubi->vtbl_size, GFP_KERNEL);
leb[seb->lnum] = vmalloc(ubi->vtbl_size);
if (!leb[seb->lnum]) {
err = -ENOMEM;
goto out_free;
}
memset(leb[seb->lnum], 0, ubi->vtbl_size);

err = ubi_io_read_data(ubi, leb[seb->lnum], seb->pnum, 0,
ubi->vtbl_size);
Expand Down Expand Up @@ -416,7 +417,7 @@ static struct ubi_vtbl_record *process_lvol(const struct ubi_device *ubi,
}

/* Both LEB 1 and LEB 2 are OK and consistent */
kfree(leb[1]);
vfree(leb[1]);
return leb[0];
} else {
/* LEB 0 is corrupted or does not exist */
Expand All @@ -437,13 +438,13 @@ static struct ubi_vtbl_record *process_lvol(const struct ubi_device *ubi,
goto out_free;
ubi_msg("volume table was restored");

kfree(leb[0]);
vfree(leb[0]);
return leb[1];
}

out_free:
kfree(leb[0]);
kfree(leb[1]);
vfree(leb[0]);
vfree(leb[1]);
return ERR_PTR(err);
}

Expand All @@ -461,9 +462,10 @@ static struct ubi_vtbl_record *create_empty_lvol(const struct ubi_device *ubi,
int i;
struct ubi_vtbl_record *vtbl;

vtbl = kzalloc(ubi->vtbl_size, GFP_KERNEL);
vtbl = vmalloc(ubi->vtbl_size);
if (!vtbl)
return ERR_PTR(-ENOMEM);
memset(vtbl, 0, ubi->vtbl_size);

for (i = 0; i < ubi->vtbl_slots; i++)
memcpy(&vtbl[i], &empty_vtbl_record, UBI_VTBL_RECORD_SIZE);
Expand All @@ -473,7 +475,7 @@ static struct ubi_vtbl_record *create_empty_lvol(const struct ubi_device *ubi,

err = create_vtbl(ubi, si, i, vtbl);
if (err) {
kfree(vtbl);
vfree(vtbl);
return ERR_PTR(err);
}
}
Expand Down Expand Up @@ -784,7 +786,7 @@ int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_scan_info *si)
return 0;

out_free:
kfree(ubi->vtbl);
vfree(ubi->vtbl);
for (i = 0; i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++)
if (ubi->volumes[i]) {
kfree(ubi->volumes[i]);
Expand Down

0 comments on commit 92ad8f3

Please sign in to comment.