Skip to content

Commit

Permalink
blk-iocost: fix divide by 0 error in calc_lcoefs()
Browse files Browse the repository at this point in the history
[ Upstream commit 984af1e ]

echo max of u64 to cost.model can cause divide by 0 error.

  # echo 8:0 rbps=18446744073709551615 > /sys/fs/cgroup/io.cost.model

  divide error: 0000 [#1] PREEMPT SMP
  RIP: 0010:calc_lcoefs+0x4c/0xc0
  Call Trace:
   <TASK>
   ioc_refresh_params+0x2b3/0x4f0
   ioc_cost_model_write+0x3cb/0x4c0
   ? _copy_from_iter+0x6d/0x6c0
   ? kernfs_fop_write_iter+0xfc/0x270
   cgroup_file_write+0xa0/0x200
   kernfs_fop_write_iter+0x17d/0x270
   vfs_write+0x414/0x620
   ksys_write+0x73/0x160
   __x64_sys_write+0x1e/0x30
   do_syscall_64+0x35/0x80
   entry_SYSCALL_64_after_hwframe+0x63/0xcd

calc_lcoefs() uses the input value of cost.model in DIV_ROUND_UP_ULL,
overflow would happen if bps plus IOC_PAGE_SIZE is greater than
ULLONG_MAX, it can cause divide by 0 error.

Fix the problem by setting basecost

Signed-off-by: Li Nan <[email protected]>
Signed-off-by: Yu Kuai <[email protected]>
Acked-by: Tejun Heo <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jens Axboe <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
  • Loading branch information
Li Nan authored and Sasha Levin committed Mar 11, 2023
1 parent 3f4afdb commit bbe9453
Showing 1 changed file with 8 additions and 3 deletions.
11 changes: 8 additions & 3 deletions block/blk-iocost.c
Original file line number Diff line number Diff line change
Expand Up @@ -785,9 +785,14 @@ static void calc_lcoefs(u64 bps, u64 seqiops, u64 randiops,

*page = *seqio = *randio = 0;

if (bps)
*page = DIV64_U64_ROUND_UP(VTIME_PER_SEC,
DIV_ROUND_UP_ULL(bps, IOC_PAGE_SIZE));
if (bps) {
u64 bps_pages = DIV_ROUND_UP_ULL(bps, IOC_PAGE_SIZE);

if (bps_pages)
*page = DIV64_U64_ROUND_UP(VTIME_PER_SEC, bps_pages);
else
*page = 1;
}

if (seqiops) {
v = DIV64_U64_ROUND_UP(VTIME_PER_SEC, seqiops);
Expand Down

0 comments on commit bbe9453

Please sign in to comment.