From: Julia Lawall <[email protected]>
The kernel.h macro DIV_ROUND_UP performs the computation (((n) + (d) - 1) /
(d)) but is perhaps more readable.
An extract of the semantic patch that makes this change is as follows:
(http://www.emn.fr/x-info/coccinelle/)
// <smpl>
@haskernel@
@@
#include <linux/kernel.h>
@depends on haskernel@
expression n,d;
@@
(
- (n + d - 1) / d
+ DIV_ROUND_UP(n,d)
|
- (n + (d - 1)) / d
+ DIV_ROUND_UP(n,d)
)
@depends on haskernel@
expression n,d;
@@
- DIV_ROUND_UP((n),d)
+ DIV_ROUND_UP(n,d)
@depends on haskernel@
expression n,d;
@@
- DIV_ROUND_UP(n,(d))
+ DIV_ROUND_UP(n,d)
// </smpl>
Signed-off-by: Julia Lawall <[email protected]>
---
diff -u -p a/fs/direct-io.c b/fs/direct-io.c
--- a/fs/direct-io.c 2008-02-08 08:58:17.000000000 +0100
+++ b/fs/direct-io.c 2008-02-13 20:58:53.000000000 +0100
@@ -976,7 +976,7 @@ direct_io_worker(int rw, struct kiocb *i
for (seg = 0; seg < nr_segs; seg++) {
user_addr = (unsigned long)iov[seg].iov_base;
dio->pages_in_io +=
- ((user_addr+iov[seg].iov_len +PAGE_SIZE-1)/PAGE_SIZE
+ (DIV_ROUND_UP(user_addr + iov[seg].iov_len, PAGE_SIZE)
- user_addr/PAGE_SIZE);
}
@@ -998,7 +998,7 @@ direct_io_worker(int rw, struct kiocb *i
dio->total_pages++;
bytes -= PAGE_SIZE - (user_addr & (PAGE_SIZE - 1));
}
- dio->total_pages += (bytes + PAGE_SIZE - 1) / PAGE_SIZE;
+ dio->total_pages += DIV_ROUND_UP(bytes, PAGE_SIZE);
dio->curr_user_address = user_addr;
ret = do_direct_IO(dio);
Julia Lawall wrote:
> From: Julia Lawall <[email protected]>
>
> The kernel.h macro DIV_ROUND_UP performs the computation (((n) + (d) - 1) /
> (d)) but is perhaps more readable.
It certainly looks better to me, thanks for doing this.
> Signed-off-by: Julia Lawall <[email protected]>
Acked-By: Zach Brown <[email protected]>
- z
On 14.02.2008 [16:14:33 +0100], Julia Lawall wrote:
> From: Julia Lawall <[email protected]>
>
> The kernel.h macro DIV_ROUND_UP performs the computation (((n) + (d) - 1) /
> (d)) but is perhaps more readable.
>
> An extract of the semantic patch that makes this change is as follows:
> (http://www.emn.fr/x-info/coccinelle/)
>
> // <smpl>
> @haskernel@
> @@
>
> #include <linux/kernel.h>
>
> @depends on haskernel@
> expression n,d;
> @@
>
> (
> - (n + d - 1) / d
> + DIV_ROUND_UP(n,d)
> |
> - (n + (d - 1)) / d
> + DIV_ROUND_UP(n,d)
> )
>
> @depends on haskernel@
> expression n,d;
> @@
>
> - DIV_ROUND_UP((n),d)
> + DIV_ROUND_UP(n,d)
>
> @depends on haskernel@
> expression n,d;
> @@
>
> - DIV_ROUND_UP(n,(d))
> + DIV_ROUND_UP(n,d)
> // </smpl>
>
> Signed-off-by: Julia Lawall <[email protected]>
>
> ---
>
> diff -u -p a/fs/direct-io.c b/fs/direct-io.c
> --- a/fs/direct-io.c 2008-02-08 08:58:17.000000000 +0100
> +++ b/fs/direct-io.c 2008-02-13 20:58:53.000000000 +0100
> @@ -976,7 +976,7 @@ direct_io_worker(int rw, struct kiocb *i
> for (seg = 0; seg < nr_segs; seg++) {
> user_addr = (unsigned long)iov[seg].iov_base;
> dio->pages_in_io +=
> - ((user_addr+iov[seg].iov_len +PAGE_SIZE-1)/PAGE_SIZE
> + (DIV_ROUND_UP(user_addr + iov[seg].iov_len, PAGE_SIZE)
> - user_addr/PAGE_SIZE);
Is it just me, or does
((user_addr + iov[seg].iov_len + PAGE_SIZE - 1)/PAGE_SIZE - user_addr/PAGE_SIZE)
not simplify to
= ((iov[seg].iov_len + PAGE_SIZE - 1)/PAGE_SIZE + user_addr/PAGE_SIZE - user_addr/PAGE_SIZE)
= ((iov[seg].iov_len + PAGE_SIZE - 1)/PAGE_SIZE)
= DIV_ROUND_UP(iov[seg].iov_len, PAGE_SIZE)
CMIIW.
Thanks,
Nish
--
Nishanth Aravamudan <[email protected]>
IBM Linux Technology Center
Hi Nishanth,
On Thu, Feb 14, 2008 at 7:38 PM, Nishanth Aravamudan <[email protected]> wrote:
> Is it just me, or does
>
> ((user_addr + iov[seg].iov_len + PAGE_SIZE - 1)/PAGE_SIZE - user_addr/PAGE_SIZE)
>
> not simplify to
>
> = ((iov[seg].iov_len + PAGE_SIZE - 1)/PAGE_SIZE + user_addr/PAGE_SIZE - user_addr/PAGE_SIZE)
>
> = ((iov[seg].iov_len + PAGE_SIZE - 1)/PAGE_SIZE)
>
> = DIV_ROUND_UP(iov[seg].iov_len, PAGE_SIZE)
>
> CMIIW.
I double-checked this and I believe you're correct. It's simpler to
see when you do:
x = user_addr
y = iov[seg].iov_len
z = PAGE_SIZE
So
(x + y + z - 1)/z - x/z
= [x + (y + z - 1)]/z - x/z
= [xz + z(y + z - 1)]/z^2 - x/z
= x/z + (y + z - 1)/z - x/z
And the rest follows from your simplifications.
Pekka
On Thu, 14 Feb 2008, Pekka Enberg wrote:
> Hi Nishanth,
>
> On Thu, Feb 14, 2008 at 7:38 PM, Nishanth Aravamudan <[email protected]> wrote:
> > Is it just me, or does
> >
> > ((user_addr + iov[seg].iov_len + PAGE_SIZE - 1)/PAGE_SIZE - user_addr/PAGE_SIZE)
> >
> > not simplify to
> >
> > = ((iov[seg].iov_len + PAGE_SIZE - 1)/PAGE_SIZE + user_addr/PAGE_SIZE - user_addr/PAGE_SIZE)
> >
> > = ((iov[seg].iov_len + PAGE_SIZE - 1)/PAGE_SIZE)
> >
> > = DIV_ROUND_UP(iov[seg].iov_len, PAGE_SIZE)
> >
> > CMIIW.
>
> I double-checked this and I believe you're correct. It's simpler to
> see when you do:
>
> x = user_addr
> y = iov[seg].iov_len
> z = PAGE_SIZE
>
> So
>
> (x + y + z - 1)/z - x/z
>
> = [x + (y + z - 1)]/z - x/z
>
> = [xz + z(y + z - 1)]/z^2 - x/z
>
> = x/z + (y + z - 1)/z - x/z
>
> And the rest follows from your simplifications.
It doesn't work:
((3+4+5-1)/5) - (3/5) = 2
((4+5-1)/5) = 1
julia
Hello,
> > > Is it just me, or does
> > >
> > > ((user_addr + iov[seg].iov_len + PAGE_SIZE - 1)/PAGE_SIZE - user_addr/PAGE_SIZE)
> > >
> > > not simplify to
> > >
> > > = ((iov[seg].iov_len + PAGE_SIZE - 1)/PAGE_SIZE + user_addr/PAGE_SIZE - user_addr/PAGE_SIZE)
> > >
> > > = ((iov[seg].iov_len + PAGE_SIZE - 1)/PAGE_SIZE)
> > >
> > > = DIV_ROUND_UP(iov[seg].iov_len, PAGE_SIZE)
> > >
> > > CMIIW.
> >
> > I double-checked this and I believe you're correct. It's simpler to
> > see when you do:
> >
> > x = user_addr
> > y = iov[seg].iov_len
> > z = PAGE_SIZE
> >
> > So
> >
> > (x + y + z - 1)/z - x/z
> >
> > = [x + (y + z - 1)]/z - x/z
> >
> > = [xz + z(y + z - 1)]/z^2 - x/z
> >
> > = x/z + (y + z - 1)/z - x/z
> >
> > And the rest follows from your simplifications.
>
> It doesn't work:
>
> ((3+4+5-1)/5) - (3/5) = 2
> ((4+5-1)/5) = 1
Logic was wrong but conclusion was right :) and so was Nishanth:
(a + b) + c = a + (b + c)
and
k l k + l
- + - = -----
m m m
thus:
(user_addr + iov[seg].iov_len + PAGE_SIZE - 1) = user_addr + (iov[seg].iov_len + PAGE_SIZE - 1)
and
user_addr + iov[seg].iov_len + PAGE_SIZE - 1 user_addr
-------------------------------------------- - --------- =
PAGE_SIZE PAGE_SIZE
user_addr iov[seg].iov_len + PAGE_SIZE - 1 user_addr
--------- + -------------------------------- - --------- =
PAGE_SIZE PAGE_SIZE PAGE_SIZE
iov[seg].iov_len + PAGE_SIZE - 1
--------------------------------
PAGE_SIZE
or even more:
iov[seg].iov_len - 1
-------------------- + 1
PAGE_SIZE
Regards,
Mariusz
On 14.02.2008 [23:16:44 +0100], Mariusz Kozlowski wrote:
> Hello,
>
> > > > Is it just me, or does
> > > >
> > > > ((user_addr + iov[seg].iov_len + PAGE_SIZE - 1)/PAGE_SIZE - user_addr/PAGE_SIZE)
> > > >
> > > > not simplify to
> > > >
> > > > = ((iov[seg].iov_len + PAGE_SIZE - 1)/PAGE_SIZE + user_addr/PAGE_SIZE - user_addr/PAGE_SIZE)
> > > >
> > > > = ((iov[seg].iov_len + PAGE_SIZE - 1)/PAGE_SIZE)
> > > >
> > > > = DIV_ROUND_UP(iov[seg].iov_len, PAGE_SIZE)
> > > >
> > > > CMIIW.
> > >
> > > I double-checked this and I believe you're correct. It's simpler to
> > > see when you do:
> > >
> > > x = user_addr
> > > y = iov[seg].iov_len
> > > z = PAGE_SIZE
> > >
> > > So
> > >
> > > (x + y + z - 1)/z - x/z
> > >
> > > = [x + (y + z - 1)]/z - x/z
> > >
> > > = [xz + z(y + z - 1)]/z^2 - x/z
> > >
> > > = x/z + (y + z - 1)/z - x/z
> > >
> > > And the rest follows from your simplifications.
> >
> > It doesn't work:
> >
> > ((3+4+5-1)/5) - (3/5) = 2
> > ((4+5-1)/5) = 1
>
> Logic was wrong but conclusion was right :) and so was Nishanth:
<snip>
As I replied to Julia off-list -- the math I and others have given is
correct, but assumes we're dealing with real-typed values. However, we
only have integer types in the kernel, meaning the divisions truncate.
Thus, while mathematically equivalent, the simplification is not
computationally so.
Thanks,
Nish
--
Nishanth Aravamudan <[email protected]>
IBM Linux Technology Center