2008-02-14 15:14:54

by Julia Lawall

[permalink] [raw]
Subject: [PATCH 2/6] fs/direct-io.c: Use DIV_ROUND_UP

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);


2008-02-14 17:25:51

by Zach Brown

[permalink] [raw]
Subject: Re: [PATCH 2/6] fs/direct-io.c: Use DIV_ROUND_UP

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

2008-02-14 17:39:23

by Nishanth Aravamudan

[permalink] [raw]
Subject: Re: [PATCH 2/6] fs/direct-io.c: Use DIV_ROUND_UP

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

2008-02-14 18:18:21

by Pekka Enberg

[permalink] [raw]
Subject: Re: [PATCH 2/6] fs/direct-io.c: Use DIV_ROUND_UP

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

2008-02-14 19:50:57

by Julia Lawall

[permalink] [raw]
Subject: Re: [PATCH 2/6] fs/direct-io.c: Use DIV_ROUND_UP

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

2008-02-14 22:17:03

by Mariusz Kozlowski

[permalink] [raw]
Subject: Re: [PATCH 2/6] fs/direct-io.c: Use DIV_ROUND_UP

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

2008-02-14 23:38:24

by Nishanth Aravamudan

[permalink] [raw]
Subject: Re: [PATCH 2/6] fs/direct-io.c: Use DIV_ROUND_UP

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