Commit cadb40cc authored by Kyungmin Park's avatar Kyungmin Park Committed by Artem Bityutskiy

UBI: avoid unnecessary division operations

UBI already checks that @min io size is the power of 2 at io_init.
It is save to use bit operations then.
Signed-off-by: default avatarKyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: default avatarArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
parent a0fd1efd
...@@ -530,7 +530,11 @@ static int io_init(struct ubi_device *ubi) ...@@ -530,7 +530,11 @@ static int io_init(struct ubi_device *ubi)
ubi->min_io_size = ubi->mtd->writesize; ubi->min_io_size = ubi->mtd->writesize;
ubi->hdrs_min_io_size = ubi->mtd->writesize >> ubi->mtd->subpage_sft; ubi->hdrs_min_io_size = ubi->mtd->writesize >> ubi->mtd->subpage_sft;
/* Make sure minimal I/O unit is power of 2 */ /*
* Make sure minimal I/O unit is power of 2. Note, there is no
* fundamental reason for this assumption. It is just an optimization
* which allows us to avoid costly division operations.
*/
if (!is_power_of_2(ubi->min_io_size)) { if (!is_power_of_2(ubi->min_io_size)) {
ubi_err("min. I/O unit (%d) is not power of 2", ubi_err("min. I/O unit (%d) is not power of 2",
ubi->min_io_size); ubi->min_io_size);
...@@ -581,7 +585,7 @@ static int io_init(struct ubi_device *ubi) ...@@ -581,7 +585,7 @@ static int io_init(struct ubi_device *ubi)
if (ubi->vid_hdr_offset < UBI_EC_HDR_SIZE || if (ubi->vid_hdr_offset < UBI_EC_HDR_SIZE ||
ubi->leb_start < ubi->vid_hdr_offset + UBI_VID_HDR_SIZE || ubi->leb_start < ubi->vid_hdr_offset + UBI_VID_HDR_SIZE ||
ubi->leb_start > ubi->peb_size - UBI_VID_HDR_SIZE || ubi->leb_start > ubi->peb_size - UBI_VID_HDR_SIZE ||
ubi->leb_start % ubi->min_io_size) { ubi->leb_start & (ubi->min_io_size - 1)) {
ubi_err("bad VID header (%d) or data offsets (%d)", ubi_err("bad VID header (%d) or data offsets (%d)",
ubi->vid_hdr_offset, ubi->leb_start); ubi->vid_hdr_offset, ubi->leb_start);
return -EINVAL; return -EINVAL;
......
...@@ -295,7 +295,7 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf, ...@@ -295,7 +295,7 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf,
off = do_div(tmp, vol->usable_leb_size); off = do_div(tmp, vol->usable_leb_size);
lnum = tmp; lnum = tmp;
if (off % ubi->min_io_size) { if (off & (ubi->min_io_size - 1)) {
dbg_err("unaligned position"); dbg_err("unaligned position");
return -EINVAL; return -EINVAL;
} }
...@@ -304,7 +304,7 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf, ...@@ -304,7 +304,7 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf,
count_save = count = vol->used_bytes - *offp; count_save = count = vol->used_bytes - *offp;
/* We can write only in fractions of the minimum I/O unit */ /* We can write only in fractions of the minimum I/O unit */
if (count % ubi->min_io_size) { if (count & (ubi->min_io_size - 1)) {
dbg_err("unaligned write length"); dbg_err("unaligned write length");
return -EINVAL; return -EINVAL;
} }
...@@ -564,7 +564,7 @@ static int verify_mkvol_req(const struct ubi_device *ubi, ...@@ -564,7 +564,7 @@ static int verify_mkvol_req(const struct ubi_device *ubi,
if (req->alignment > ubi->leb_size) if (req->alignment > ubi->leb_size)
goto bad; goto bad;
n = req->alignment % ubi->min_io_size; n = req->alignment & (ubi->min_io_size - 1);
if (req->alignment != 1 && n) if (req->alignment != 1 && n)
goto bad; goto bad;
......
...@@ -752,7 +752,7 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol, ...@@ -752,7 +752,7 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol,
/* If this is the last LEB @len may be unaligned */ /* If this is the last LEB @len may be unaligned */
len = ALIGN(data_size, ubi->min_io_size); len = ALIGN(data_size, ubi->min_io_size);
else else
ubi_assert(len % ubi->min_io_size == 0); ubi_assert(!(len & (ubi->min_io_size - 1)));
vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS);
if (!vid_hdr) if (!vid_hdr)
......
...@@ -397,8 +397,8 @@ int ubi_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf, ...@@ -397,8 +397,8 @@ int ubi_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf,
return -EROFS; return -EROFS;
if (lnum < 0 || lnum >= vol->reserved_pebs || offset < 0 || len < 0 || if (lnum < 0 || lnum >= vol->reserved_pebs || offset < 0 || len < 0 ||
offset + len > vol->usable_leb_size || offset % ubi->min_io_size || offset + len > vol->usable_leb_size ||
len % ubi->min_io_size) offset & (ubi->min_io_size - 1) || len & (ubi->min_io_size - 1))
return -EINVAL; return -EINVAL;
if (dtype != UBI_LONGTERM && dtype != UBI_SHORTTERM && if (dtype != UBI_LONGTERM && dtype != UBI_SHORTTERM &&
...@@ -447,7 +447,7 @@ int ubi_leb_change(struct ubi_volume_desc *desc, int lnum, const void *buf, ...@@ -447,7 +447,7 @@ int ubi_leb_change(struct ubi_volume_desc *desc, int lnum, const void *buf,
return -EROFS; return -EROFS;
if (lnum < 0 || lnum >= vol->reserved_pebs || len < 0 || if (lnum < 0 || lnum >= vol->reserved_pebs || len < 0 ||
len > vol->usable_leb_size || len % ubi->min_io_size) len > vol->usable_leb_size || len & (ubi->min_io_size - 1))
return -EINVAL; return -EINVAL;
if (dtype != UBI_LONGTERM && dtype != UBI_SHORTTERM && if (dtype != UBI_LONGTERM && dtype != UBI_SHORTTERM &&
......
...@@ -37,7 +37,7 @@ int ubi_calc_data_len(const struct ubi_device *ubi, const void *buf, ...@@ -37,7 +37,7 @@ int ubi_calc_data_len(const struct ubi_device *ubi, const void *buf,
{ {
int i; int i;
ubi_assert(length % ubi->min_io_size == 0); ubi_assert(!(length & (ubi->min_io_size - 1)));
for (i = length - 1; i >= 0; i--) for (i = length - 1; i >= 0; i--)
if (((const uint8_t *)buf)[i] != 0xFF) if (((const uint8_t *)buf)[i] != 0xFF)
......
...@@ -727,7 +727,7 @@ static void paranoid_check_volume(struct ubi_device *ubi, int vol_id) ...@@ -727,7 +727,7 @@ static void paranoid_check_volume(struct ubi_device *ubi, int vol_id)
goto fail; goto fail;
} }
n = vol->alignment % ubi->min_io_size; n = vol->alignment & (ubi->min_io_size - 1);
if (vol->alignment != 1 && n) { if (vol->alignment != 1 && n) {
ubi_err("alignment is not multiple of min I/O unit"); ubi_err("alignment is not multiple of min I/O unit");
goto fail; goto fail;
......
...@@ -170,7 +170,7 @@ static int vtbl_check(const struct ubi_device *ubi, ...@@ -170,7 +170,7 @@ static int vtbl_check(const struct ubi_device *ubi,
goto bad; goto bad;
} }
n = alignment % ubi->min_io_size; n = alignment & (ubi->min_io_size - 1);
if (alignment != 1 && n) { if (alignment != 1 && n) {
err = 5; err = 5;
goto bad; goto bad;
...@@ -684,14 +684,13 @@ static int check_scanning_info(const struct ubi_device *ubi, ...@@ -684,14 +684,13 @@ static int check_scanning_info(const struct ubi_device *ubi,
return -EINVAL; return -EINVAL;
} }
if (si->highest_vol_id >= ubi->vtbl_slots + UBI_INT_VOL_COUNT&& if (si->highest_vol_id >= ubi->vtbl_slots + UBI_INT_VOL_COUNT &&
si->highest_vol_id < UBI_INTERNAL_VOL_START) { si->highest_vol_id < UBI_INTERNAL_VOL_START) {
ubi_err("too large volume ID %d found by scanning", ubi_err("too large volume ID %d found by scanning",
si->highest_vol_id); si->highest_vol_id);
return -EINVAL; return -EINVAL;
} }
for (i = 0; i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++) { for (i = 0; i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++) {
cond_resched(); cond_resched();
......
...@@ -1368,7 +1368,7 @@ int ubi_thread(void *u) ...@@ -1368,7 +1368,7 @@ int ubi_thread(void *u)
int err; int err;
if (kthread_should_stop()) if (kthread_should_stop())
goto out; break;
if (try_to_freeze()) if (try_to_freeze())
continue; continue;
...@@ -1403,7 +1403,6 @@ int ubi_thread(void *u) ...@@ -1403,7 +1403,6 @@ int ubi_thread(void *u)
cond_resched(); cond_resched();
} }
out:
dbg_wl("background thread \"%s\" is killed", ubi->bgt_name); dbg_wl("background thread \"%s\" is killed", ubi->bgt_name);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment