All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] /dev/mem cleanups and bug fix
@ 2009-09-11  2:23 Wu Fengguang
  2009-09-11  2:23 ` [PATCH 1/3] devmem: remove redundant test on len Wu Fengguang
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Wu Fengguang @ 2009-09-11  2:23 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Marcelo Tosatti, Greg Kroah-Hartman, Mark Brown, Johannes Berg,
	Avi Kivity, Andi Kleen, Wu Fengguang, LKML

Hi Andrew,

Here are three patches for /dev/[k]mem.
They are mostly code cleanups, plus a minor bug fix:
if someone read high mem via /dev/kmem starting from
an unaligned address, it's calculation of 'len' will
go wrong.

I would recommend them for .32.

Thanks,
Fengguang
-- 


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/3] devmem: remove redundant test on len
  2009-09-11  2:23 [PATCH 0/3] /dev/mem cleanups and bug fix Wu Fengguang
@ 2009-09-11  2:23 ` Wu Fengguang
  2009-09-12  0:00   ` Andrew Morton
  2009-09-11  2:23 ` [PATCH 2/3] devmem: introduce size_inside_page() Wu Fengguang
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 11+ messages in thread
From: Wu Fengguang @ 2009-09-11  2:23 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Marcelo Tosatti, Greg Kroah-Hartman, Mark Brown, Johannes Berg,
	Avi Kivity, Wu Fengguang, Andi Kleen, LKML

[-- Attachment #1: kmem-cleanup.patch --]
[-- Type: text/plain, Size: 1100 bytes --]

The len test in write_kmem() is always true, so can be reduced.

CC: Marcelo Tosatti <mtosatti@redhat.com>
CC: Greg Kroah-Hartman <gregkh@suse.de>
CC: Mark Brown <broonie@opensource.wolfsonmicro.com>
CC: Johannes Berg <johannes@sipsolutions.net>
CC: Avi Kivity <avi@qumranet.com>
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
---
 drivers/char/mem.c |   14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

--- linux.orig/drivers/char/mem.c
+++ linux/drivers/char/mem.c
@@ -580,18 +580,16 @@ static ssize_t write_kmem(struct file * 
 		while (count > 0) {
 			int len = count;
 
 			if (len > PAGE_SIZE)
 				len = PAGE_SIZE;
-			if (len) {
-				written = copy_from_user(kbuf, buf, len);
-				if (written) {
-					if (wrote + virtr)
-						break;
-					free_page((unsigned long)kbuf);
-					return -EFAULT;
-				}
+			written = copy_from_user(kbuf, buf, len);
+			if (written) {
+				if (wrote + virtr)
+					break;
+				free_page((unsigned long)kbuf);
+				return -EFAULT;
 			}
 			len = vwrite(kbuf, (char *)p, len);
 			count -= len;
 			buf += len;
 			virtr += len;

-- 


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 2/3] devmem: introduce size_inside_page()
  2009-09-11  2:23 [PATCH 0/3] /dev/mem cleanups and bug fix Wu Fengguang
  2009-09-11  2:23 ` [PATCH 1/3] devmem: remove redundant test on len Wu Fengguang
@ 2009-09-11  2:23 ` Wu Fengguang
  2009-09-11 23:55   ` Andrew Morton
  2009-09-11  2:23 ` [PATCH 3/3] devmem: cleanup unxlate_dev_mem_ptr() calls Wu Fengguang
  2009-09-11  7:44 ` [PATCH 0/3] /dev/mem cleanups and bug fix Andi Kleen
  3 siblings, 1 reply; 11+ messages in thread
From: Wu Fengguang @ 2009-09-11  2:23 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Marcelo Tosatti, Greg Kroah-Hartman, Mark Brown, Johannes Berg,
	Avi Kivity, Wu Fengguang, Andi Kleen, LKML

[-- Attachment #1: kmem-round-to-page-size.patch --]
[-- Type: text/plain, Size: 3236 bytes --]

Introduce size_inside_page() to replace duplicate /dev/mem code.

Also apply it to /dev/kmem, whose alignment logic was buggy.


CC: Marcelo Tosatti <mtosatti@redhat.com>
CC: Greg Kroah-Hartman <gregkh@suse.de>
CC: Mark Brown <broonie@opensource.wolfsonmicro.com>
CC: Johannes Berg <johannes@sipsolutions.net>
CC: Avi Kivity <avi@qumranet.com>
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
---
 drivers/char/mem.c |   60 +++++++++++++------------------------------
 1 file changed, 19 insertions(+), 41 deletions(-)

--- linux.orig/drivers/char/mem.c
+++ linux/drivers/char/mem.c
@@ -35,6 +35,19 @@
 # include <linux/efi.h>
 #endif
 
+static inline unsigned long size_inside_page(unsigned long start,
+					     unsigned long size)
+{
+	unsigned long sz;
+
+	if (-start & (PAGE_SIZE - 1))
+		sz = -start & (PAGE_SIZE - 1);
+	else
+		sz = PAGE_SIZE;
+
+	return min_t(unsigned long, sz, size);
+}
+
 /*
  * Architectures vary in how they handle caching for addresses
  * outside of main memory.
@@ -142,15 +155,7 @@ static ssize_t read_mem(struct file * fi
 #endif
 
 	while (count > 0) {
-		/*
-		 * Handle first page in case it's not aligned
-		 */
-		if (-p & (PAGE_SIZE - 1))
-			sz = -p & (PAGE_SIZE - 1);
-		else
-			sz = PAGE_SIZE;
-
-		sz = min_t(unsigned long, sz, count);
+		sz = size_inside_page(p, count);
 
 		if (!range_is_allowed(p >> PAGE_SHIFT, count))
 			return -EPERM;
@@ -209,15 +214,7 @@ static ssize_t write_mem(struct file * f
 #endif
 
 	while (count > 0) {
-		/*
-		 * Handle first page in case it's not aligned
-		 */
-		if (-p & (PAGE_SIZE - 1))
-			sz = -p & (PAGE_SIZE - 1);
-		else
-			sz = PAGE_SIZE;
-
-		sz = min_t(unsigned long, sz, count);
+		sz = size_inside_page(p, count);
 
 		if (!range_is_allowed(p >> PAGE_SHIFT, sz))
 			return -EPERM;
@@ -430,15 +427,7 @@ static ssize_t read_kmem(struct file *fi
 		}
 #endif
 		while (low_count > 0) {
-			/*
-			 * Handle first page in case it's not aligned
-			 */
-			if (-p & (PAGE_SIZE - 1))
-				sz = -p & (PAGE_SIZE - 1);
-			else
-				sz = PAGE_SIZE;
-
-			sz = min_t(unsigned long, sz, low_count);
+			sz = size_inside_page(p, low_count);
 
 			/*
 			 * On ia64 if a page has been mapped somewhere as
@@ -462,10 +451,8 @@ static ssize_t read_kmem(struct file *fi
 		if (!kbuf)
 			return -ENOMEM;
 		while (count > 0) {
-			int len = count;
+			int len = size_inside_page(p, count);
 
-			if (len > PAGE_SIZE)
-				len = PAGE_SIZE;
 			len = vread(kbuf, (char *)p, len);
 			if (!len)
 				break;
@@ -510,15 +497,8 @@ do_write_kmem(void *p, unsigned long rea
 
 	while (count > 0) {
 		char *ptr;
-		/*
-		 * Handle first page in case it's not aligned
-		 */
-		if (-realp & (PAGE_SIZE - 1))
-			sz = -realp & (PAGE_SIZE - 1);
-		else
-			sz = PAGE_SIZE;
 
-		sz = min_t(unsigned long, sz, count);
+		sz = size_inside_page(realp, count);
 
 		/*
 		 * On ia64 if a page has been mapped somewhere as
@@ -578,10 +558,8 @@ static ssize_t write_kmem(struct file * 
 		if (!kbuf)
 			return wrote ? wrote : -ENOMEM;
 		while (count > 0) {
-			int len = count;
+			int len = size_inside_page(p, count);
 
-			if (len > PAGE_SIZE)
-				len = PAGE_SIZE;
 			written = copy_from_user(kbuf, buf, len);
 			if (written) {
 				if (wrote + virtr)

-- 


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 3/3] devmem: cleanup unxlate_dev_mem_ptr() calls
  2009-09-11  2:23 [PATCH 0/3] /dev/mem cleanups and bug fix Wu Fengguang
  2009-09-11  2:23 ` [PATCH 1/3] devmem: remove redundant test on len Wu Fengguang
  2009-09-11  2:23 ` [PATCH 2/3] devmem: introduce size_inside_page() Wu Fengguang
@ 2009-09-11  2:23 ` Wu Fengguang
  2009-09-12  0:05   ` Andrew Morton
  2009-09-11  7:44 ` [PATCH 0/3] /dev/mem cleanups and bug fix Andi Kleen
  3 siblings, 1 reply; 11+ messages in thread
From: Wu Fengguang @ 2009-09-11  2:23 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Marcelo Tosatti, Greg Kroah-Hartman, Mark Brown, Johannes Berg,
	Avi Kivity, Wu Fengguang, Andi Kleen, LKML

[-- Attachment #1: kmem-dev-mem-cleanup.patch --]
[-- Type: text/plain, Size: 1388 bytes --]

No behavior change.

CC: Marcelo Tosatti <mtosatti@redhat.com>
CC: Greg Kroah-Hartman <gregkh@suse.de>
CC: Mark Brown <broonie@opensource.wolfsonmicro.com>
CC: Johannes Berg <johannes@sipsolutions.net>
CC: Avi Kivity <avi@qumranet.com>
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
---
 drivers/char/mem.c |   13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

--- linux-mm.orig/drivers/char/mem.c	2009-09-10 21:59:39.000000000 +0800
+++ linux-mm/drivers/char/mem.c	2009-09-10 22:00:12.000000000 +0800
@@ -131,6 +131,7 @@ static ssize_t read_mem(struct file * fi
 			size_t count, loff_t *ppos)
 {
 	unsigned long p = *ppos;
+	unsigned long ret;
 	ssize_t read, sz;
 	char *ptr;
 
@@ -169,12 +170,10 @@ static ssize_t read_mem(struct file * fi
 		if (!ptr)
 			return -EFAULT;
 
-		if (copy_to_user(buf, ptr, sz)) {
-			unxlate_dev_mem_ptr(p, ptr);
-			return -EFAULT;
-		}
-
+		ret = copy_to_user(buf, ptr, sz);
 		unxlate_dev_mem_ptr(p, ptr);
+		if (ret)
+			return -EFAULT;
 
 		buf += sz;
 		p += sz;
@@ -232,16 +231,14 @@ static ssize_t write_mem(struct file * f
 		}
 
 		copied = copy_from_user(ptr, buf, sz);
+		unxlate_dev_mem_ptr(p, ptr);
 		if (copied) {
 			written += sz - copied;
-			unxlate_dev_mem_ptr(p, ptr);
 			if (written)
 				break;
 			return -EFAULT;
 		}
 
-		unxlate_dev_mem_ptr(p, ptr);
-
 		buf += sz;
 		p += sz;
 		count -= sz;

-- 


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 0/3] /dev/mem cleanups and bug fix
  2009-09-11  2:23 [PATCH 0/3] /dev/mem cleanups and bug fix Wu Fengguang
                   ` (2 preceding siblings ...)
  2009-09-11  2:23 ` [PATCH 3/3] devmem: cleanup unxlate_dev_mem_ptr() calls Wu Fengguang
@ 2009-09-11  7:44 ` Andi Kleen
  3 siblings, 0 replies; 11+ messages in thread
From: Andi Kleen @ 2009-09-11  7:44 UTC (permalink / raw)
  To: Wu Fengguang
  Cc: Andrew Morton, Marcelo Tosatti, Greg Kroah-Hartman, Mark Brown,
	Johannes Berg, Avi Kivity, Andi Kleen, LKML

On Fri, Sep 11, 2009 at 10:23:33AM +0800, Wu Fengguang wrote:
> Hi Andrew,
> 
> Here are three patches for /dev/[k]mem.
> They are mostly code cleanups, plus a minor bug fix:
> if someone read high mem via /dev/kmem starting from
> an unaligned address, it's calculation of 'len' will
> go wrong.
> 
> I would recommend them for .32.

I reviewed the three patches and they all look good to me.

Acked-by: Andi Kleen <ak@linux.intel.com>

-Andi

-- 
ak@linux.intel.com -- Speaking for myself only.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/3] devmem: introduce size_inside_page()
  2009-09-11  2:23 ` [PATCH 2/3] devmem: introduce size_inside_page() Wu Fengguang
@ 2009-09-11 23:55   ` Andrew Morton
  2009-09-12 14:41     ` Wu Fengguang
  0 siblings, 1 reply; 11+ messages in thread
From: Andrew Morton @ 2009-09-11 23:55 UTC (permalink / raw)
  To: Wu Fengguang
  Cc: mtosatti, gregkh, broonie, johannes, avi, fengguang.wu, andi,
	linux-kernel

On Fri, 11 Sep 2009 10:23:35 +0800
Wu Fengguang <fengguang.wu@intel.com> wrote:

> Introduce size_inside_page() to replace duplicate /dev/mem code.
> 
> Also apply it to /dev/kmem, whose alignment logic was buggy.
> 
> 
> CC: Marcelo Tosatti <mtosatti@redhat.com>
> CC: Greg Kroah-Hartman <gregkh@suse.de>
> CC: Mark Brown <broonie@opensource.wolfsonmicro.com>
> CC: Johannes Berg <johannes@sipsolutions.net>
> CC: Avi Kivity <avi@qumranet.com>
> Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
> ---
>  drivers/char/mem.c |   60 +++++++++++++------------------------------
>  1 file changed, 19 insertions(+), 41 deletions(-)
> 
> --- linux.orig/drivers/char/mem.c
> +++ linux/drivers/char/mem.c
> @@ -35,6 +35,19 @@
>  # include <linux/efi.h>
>  #endif
>  
> +static inline unsigned long size_inside_page(unsigned long start,
> +					     unsigned long size)
> +{
> +	unsigned long sz;
> +
> +	if (-start & (PAGE_SIZE - 1))
> +		sz = -start & (PAGE_SIZE - 1);

What on earth is this doing?  Negating an unsigned number?

Can we get rid of these party tricks and use something more
conventional here?  In a separate patch I guess.

> +	else
> +		sz = PAGE_SIZE;
> +
> +	return min_t(unsigned long, sz, size);

Can use min() here.

> +}

Please have a think about the types.  Should we be using unsigned long,
or size_t?  Which makes more sense?  Which maps better onto reality?

I suspect that the min_t which you inherited was added somewhere
because someone didn't get the types right: int-vs-size_t or something.
If we actually get the types right, this sort of thing goes away.


> @@ -462,10 +451,8 @@ static ssize_t read_kmem(struct file *fi
>  		if (!kbuf)
>  			return -ENOMEM;
>  		while (count > 0) {
> -			int len = count;
> +			int len = size_inside_page(p, count);

int?



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/3] devmem: remove redundant test on len
  2009-09-11  2:23 ` [PATCH 1/3] devmem: remove redundant test on len Wu Fengguang
@ 2009-09-12  0:00   ` Andrew Morton
  2009-09-12 14:32     ` Wu Fengguang
  0 siblings, 1 reply; 11+ messages in thread
From: Andrew Morton @ 2009-09-12  0:00 UTC (permalink / raw)
  To: Wu Fengguang
  Cc: mtosatti, gregkh, broonie, johannes, avi, fengguang.wu, andi,
	linux-kernel

On Fri, 11 Sep 2009 10:23:34 +0800
Wu Fengguang <fengguang.wu@intel.com> wrote:

> The len test in write_kmem() is always true, so can be reduced.
> 
> CC: Marcelo Tosatti <mtosatti@redhat.com>
> CC: Greg Kroah-Hartman <gregkh@suse.de>
> CC: Mark Brown <broonie@opensource.wolfsonmicro.com>
> CC: Johannes Berg <johannes@sipsolutions.net>
> CC: Avi Kivity <avi@qumranet.com>
> Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
> ---
>  drivers/char/mem.c |   14 ++++++--------
>  1 file changed, 6 insertions(+), 8 deletions(-)
> 
> --- linux.orig/drivers/char/mem.c
> +++ linux/drivers/char/mem.c
> @@ -580,18 +580,16 @@ static ssize_t write_kmem(struct file * 
>  		while (count > 0) {
>  			int len = count;
>  
>  			if (len > PAGE_SIZE)
>  				len = PAGE_SIZE;
> -			if (len) {
> -				written = copy_from_user(kbuf, buf, len);
> -				if (written) {
> -					if (wrote + virtr)
> -						break;
> -					free_page((unsigned long)kbuf);
> -					return -EFAULT;
> -				}
> +			written = copy_from_user(kbuf, buf, len);
> +			if (written) {
> +				if (wrote + virtr)
> +					break;
> +				free_page((unsigned long)kbuf);
> +				return -EFAULT;
>  			}
>  			len = vwrite(kbuf, (char *)p, len);
>  			count -= len;
>  			buf += len;
>  			virtr += len;

humpf.  But take a closer look at what remains.


Local var `written' is unneeded here.


Which makes us look at what `written' _does_ do:

		if (written != wrote)
			return written;
		wrote = written;

lolwhowrotethat?

local var `written' can at least be made local to the first loop.

write_kmem() has a lot of typecasts which indicates that the choices of
types were inappropriate.



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/3] devmem: cleanup unxlate_dev_mem_ptr() calls
  2009-09-11  2:23 ` [PATCH 3/3] devmem: cleanup unxlate_dev_mem_ptr() calls Wu Fengguang
@ 2009-09-12  0:05   ` Andrew Morton
  2009-09-12 14:57     ` Wu Fengguang
  0 siblings, 1 reply; 11+ messages in thread
From: Andrew Morton @ 2009-09-12  0:05 UTC (permalink / raw)
  To: Wu Fengguang
  Cc: mtosatti, gregkh, broonie, johannes, avi, fengguang.wu, andi,
	linux-kernel

On Fri, 11 Sep 2009 10:23:36 +0800
Wu Fengguang <fengguang.wu@intel.com> wrote:

> No behavior change.
> 
> CC: Marcelo Tosatti <mtosatti@redhat.com>
> CC: Greg Kroah-Hartman <gregkh@suse.de>
> CC: Mark Brown <broonie@opensource.wolfsonmicro.com>
> CC: Johannes Berg <johannes@sipsolutions.net>
> CC: Avi Kivity <avi@qumranet.com>
> Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
> ---
>  drivers/char/mem.c |   13 +++++--------
>  1 file changed, 5 insertions(+), 8 deletions(-)
> 
> --- linux-mm.orig/drivers/char/mem.c	2009-09-10 21:59:39.000000000 +0800
> +++ linux-mm/drivers/char/mem.c	2009-09-10 22:00:12.000000000 +0800
> @@ -131,6 +131,7 @@ static ssize_t read_mem(struct file * fi
>  			size_t count, loff_t *ppos)
>  {
>  	unsigned long p = *ppos;
> +	unsigned long ret;
>  	ssize_t read, sz;
>  	char *ptr;
>  
> @@ -169,12 +170,10 @@ static ssize_t read_mem(struct file * fi
>  		if (!ptr)
>  			return -EFAULT;
>  
> -		if (copy_to_user(buf, ptr, sz)) {
> -			unxlate_dev_mem_ptr(p, ptr);
> -			return -EFAULT;
> -		}
> -
> +		ret = copy_to_user(buf, ptr, sz);
>  		unxlate_dev_mem_ptr(p, ptr);
> +		if (ret)
> +			return -EFAULT;
>  
>  		buf += sz;
>  		p += sz;

- local var `ret' didn't need function-wide scope.  I think it's
  better to reduce its scope if poss.

- conventionally the identifier `ret' refers to "the value which this
  function will return".  Ditto `retval' and `rc'.

  But that's not what `ret' does here so let's call it something
  else?  `remaining' is rather verbose and formal, but accurate.


--- a/drivers/char/mem.c~dev-mem-cleanup-unxlate_dev_mem_ptr-calls-fix
+++ a/drivers/char/mem.c
@@ -131,7 +131,6 @@ static ssize_t read_mem(struct file * fi
 			size_t count, loff_t *ppos)
 {
 	unsigned long p = *ppos;
-	unsigned long ret;
 	ssize_t read, sz;
 	char *ptr;
 
@@ -156,6 +155,8 @@ static ssize_t read_mem(struct file * fi
 #endif
 
 	while (count > 0) {
+		unsigned long remaining;
+
 		sz = size_inside_page(p, count);
 
 		if (!range_is_allowed(p >> PAGE_SHIFT, count))
@@ -170,9 +171,9 @@ static ssize_t read_mem(struct file * fi
 		if (!ptr)
 			return -EFAULT;
 
-		ret = copy_to_user(buf, ptr, sz);
+		remaining = copy_to_user(buf, ptr, sz);
 		unxlate_dev_mem_ptr(p, ptr);
-		if (ret)
+		if (remaining)
 			return -EFAULT;
 
 		buf += sz;
_


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/3] devmem: remove redundant test on len
  2009-09-12  0:00   ` Andrew Morton
@ 2009-09-12 14:32     ` Wu Fengguang
  0 siblings, 0 replies; 11+ messages in thread
From: Wu Fengguang @ 2009-09-12 14:32 UTC (permalink / raw)
  To: Andrew Morton
  Cc: mtosatti, gregkh, broonie, johannes, avi, andi, linux-kernel

On Sat, Sep 12, 2009 at 08:00:47AM +0800, Andrew Morton wrote:
> On Fri, 11 Sep 2009 10:23:34 +0800
> Wu Fengguang <fengguang.wu@intel.com> wrote:
> 
> > The len test in write_kmem() is always true, so can be reduced.
> > 
> > CC: Marcelo Tosatti <mtosatti@redhat.com>
> > CC: Greg Kroah-Hartman <gregkh@suse.de>
> > CC: Mark Brown <broonie@opensource.wolfsonmicro.com>
> > CC: Johannes Berg <johannes@sipsolutions.net>
> > CC: Avi Kivity <avi@qumranet.com>
> > Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
> > ---
> >  drivers/char/mem.c |   14 ++++++--------
> >  1 file changed, 6 insertions(+), 8 deletions(-)
> > 
> > --- linux.orig/drivers/char/mem.c
> > +++ linux/drivers/char/mem.c
> > @@ -580,18 +580,16 @@ static ssize_t write_kmem(struct file * 
> >  		while (count > 0) {
> >  			int len = count;
> >  
> >  			if (len > PAGE_SIZE)
> >  				len = PAGE_SIZE;
> > -			if (len) {
> > -				written = copy_from_user(kbuf, buf, len);
> > -				if (written) {
> > -					if (wrote + virtr)
> > -						break;
> > -					free_page((unsigned long)kbuf);
> > -					return -EFAULT;
> > -				}
> > +			written = copy_from_user(kbuf, buf, len);
> > +			if (written) {
> > +				if (wrote + virtr)
> > +					break;
> > +				free_page((unsigned long)kbuf);
> > +				return -EFAULT;
> >  			}
> >  			len = vwrite(kbuf, (char *)p, len);
> >  			count -= len;
> >  			buf += len;
> >  			virtr += len;
> 
> humpf.  But take a closer look at what remains.

Yeah, it asks for more cleanup patches..

> 
> Local var `written' is unneeded here.
> 
> 
> Which makes us look at what `written' _does_ do:
> 
> 		if (written != wrote)
> 			return written;
> 		wrote = written;
> 
> lolwhowrotethat?
> 
> local var `written' can at least be made local to the first loop.

Right, I'll make this straight.

> write_kmem() has a lot of typecasts which indicates that the choices of
> types were inappropriate.

It seems hard to improve because of a fundamental issue: the same
value is taken as both virtual and physical address, and also be
compared and calculated as numbers..

Thanks,
Fengguang


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/3] devmem: introduce size_inside_page()
  2009-09-11 23:55   ` Andrew Morton
@ 2009-09-12 14:41     ` Wu Fengguang
  0 siblings, 0 replies; 11+ messages in thread
From: Wu Fengguang @ 2009-09-12 14:41 UTC (permalink / raw)
  To: Andrew Morton
  Cc: mtosatti, gregkh, broonie, johannes, avi, andi, linux-kernel

On Sat, Sep 12, 2009 at 07:55:43AM +0800, Andrew Morton wrote:
> On Fri, 11 Sep 2009 10:23:35 +0800
> Wu Fengguang <fengguang.wu@intel.com> wrote:
> 
> > Introduce size_inside_page() to replace duplicate /dev/mem code.
> > 
> > Also apply it to /dev/kmem, whose alignment logic was buggy.
> > 
> > 
> > CC: Marcelo Tosatti <mtosatti@redhat.com>
> > CC: Greg Kroah-Hartman <gregkh@suse.de>
> > CC: Mark Brown <broonie@opensource.wolfsonmicro.com>
> > CC: Johannes Berg <johannes@sipsolutions.net>
> > CC: Avi Kivity <avi@qumranet.com>
> > Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
> > ---
> >  drivers/char/mem.c |   60 +++++++++++++------------------------------
> >  1 file changed, 19 insertions(+), 41 deletions(-)
> > 
> > --- linux.orig/drivers/char/mem.c
> > +++ linux/drivers/char/mem.c
> > @@ -35,6 +35,19 @@
> >  # include <linux/efi.h>
> >  #endif
> >  
> > +static inline unsigned long size_inside_page(unsigned long start,
> > +					     unsigned long size)
> > +{
> > +	unsigned long sz;
> > +
> > +	if (-start & (PAGE_SIZE - 1))
> > +		sz = -start & (PAGE_SIZE - 1);
> 
> What on earth is this doing?  Negating an unsigned number?
> 
> Can we get rid of these party tricks and use something more
> conventional here?  In a separate patch I guess.

OK. See the followed patches.

> > +	else
> > +		sz = PAGE_SIZE;
> > +
> > +	return min_t(unsigned long, sz, size);
> 
> Can use min() here.

Done.

> > +}
> 
> Please have a think about the types.  Should we be using unsigned long,
> or size_t?  Which makes more sense?  Which maps better onto reality?
> 
> I suspect that the min_t which you inherited was added somewhere
> because someone didn't get the types right: int-vs-size_t or something.
> If we actually get the types right, this sort of thing goes away.

I tend to just use unsigned long because even though the value itself
is small, it will be elevated to unsigned long in majority use cases.

Does that make sense?

> 
> > @@ -462,10 +451,8 @@ static ssize_t read_kmem(struct file *fi
> >  		if (!kbuf)
> >  			return -ENOMEM;
> >  		while (count > 0) {
> > -			int len = count;
> > +			int len = size_inside_page(p, count);
> 
> int?

Err, changed it to unsigned long sz.

Thanks,
Fengguang

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 3/3] devmem: cleanup unxlate_dev_mem_ptr() calls
  2009-09-12  0:05   ` Andrew Morton
@ 2009-09-12 14:57     ` Wu Fengguang
  0 siblings, 0 replies; 11+ messages in thread
From: Wu Fengguang @ 2009-09-12 14:57 UTC (permalink / raw)
  To: Andrew Morton
  Cc: mtosatti, gregkh, broonie, johannes, avi, andi, linux-kernel

On Sat, Sep 12, 2009 at 08:05:00AM +0800, Andrew Morton wrote:
> On Fri, 11 Sep 2009 10:23:36 +0800
> Wu Fengguang <fengguang.wu@intel.com> wrote:
> 
> > No behavior change.
> > 
> > CC: Marcelo Tosatti <mtosatti@redhat.com>
> > CC: Greg Kroah-Hartman <gregkh@suse.de>
> > CC: Mark Brown <broonie@opensource.wolfsonmicro.com>
> > CC: Johannes Berg <johannes@sipsolutions.net>
> > CC: Avi Kivity <avi@qumranet.com>
> > Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
> > ---
> >  drivers/char/mem.c |   13 +++++--------
> >  1 file changed, 5 insertions(+), 8 deletions(-)
> > 
> > --- linux-mm.orig/drivers/char/mem.c	2009-09-10 21:59:39.000000000 +0800
> > +++ linux-mm/drivers/char/mem.c	2009-09-10 22:00:12.000000000 +0800
> > @@ -131,6 +131,7 @@ static ssize_t read_mem(struct file * fi
> >  			size_t count, loff_t *ppos)
> >  {
> >  	unsigned long p = *ppos;
> > +	unsigned long ret;
> >  	ssize_t read, sz;
> >  	char *ptr;
> >  
> > @@ -169,12 +170,10 @@ static ssize_t read_mem(struct file * fi
> >  		if (!ptr)
> >  			return -EFAULT;
> >  
> > -		if (copy_to_user(buf, ptr, sz)) {
> > -			unxlate_dev_mem_ptr(p, ptr);
> > -			return -EFAULT;
> > -		}
> > -
> > +		ret = copy_to_user(buf, ptr, sz);
> >  		unxlate_dev_mem_ptr(p, ptr);
> > +		if (ret)
> > +			return -EFAULT;
> >  
> >  		buf += sz;
> >  		p += sz;
> 
> - local var `ret' didn't need function-wide scope.  I think it's
>   better to reduce its scope if poss.

OK.

> - conventionally the identifier `ret' refers to "the value which this
>   function will return".  Ditto `retval' and `rc'.

Good to know that, thanks!

>   But that's not what `ret' does here so let's call it something
>   else?  `remaining' is rather verbose and formal, but accurate.
> 
> 
> --- a/drivers/char/mem.c~dev-mem-cleanup-unxlate_dev_mem_ptr-calls-fix
> +++ a/drivers/char/mem.c
> @@ -131,7 +131,6 @@ static ssize_t read_mem(struct file * fi
>  			size_t count, loff_t *ppos)
>  {
>  	unsigned long p = *ppos;
> -	unsigned long ret;

I got compile error because another place in read_mem() used ret.
I'll send you an updated fix.

Thanks,
Fengguang

>  	ssize_t read, sz;
>  	char *ptr;
>  
> @@ -156,6 +155,8 @@ static ssize_t read_mem(struct file * fi
>  #endif
>  
>  	while (count > 0) {
> +		unsigned long remaining;
> +
>  		sz = size_inside_page(p, count);
>  
>  		if (!range_is_allowed(p >> PAGE_SHIFT, count))
> @@ -170,9 +171,9 @@ static ssize_t read_mem(struct file * fi
>  		if (!ptr)
>  			return -EFAULT;
>  
> -		ret = copy_to_user(buf, ptr, sz);
> +		remaining = copy_to_user(buf, ptr, sz);
>  		unxlate_dev_mem_ptr(p, ptr);
> -		if (ret)
> +		if (remaining)
>  			return -EFAULT;
>  
>  		buf += sz;
> _

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2009-09-12 14:57 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-09-11  2:23 [PATCH 0/3] /dev/mem cleanups and bug fix Wu Fengguang
2009-09-11  2:23 ` [PATCH 1/3] devmem: remove redundant test on len Wu Fengguang
2009-09-12  0:00   ` Andrew Morton
2009-09-12 14:32     ` Wu Fengguang
2009-09-11  2:23 ` [PATCH 2/3] devmem: introduce size_inside_page() Wu Fengguang
2009-09-11 23:55   ` Andrew Morton
2009-09-12 14:41     ` Wu Fengguang
2009-09-11  2:23 ` [PATCH 3/3] devmem: cleanup unxlate_dev_mem_ptr() calls Wu Fengguang
2009-09-12  0:05   ` Andrew Morton
2009-09-12 14:57     ` Wu Fengguang
2009-09-11  7:44 ` [PATCH 0/3] /dev/mem cleanups and bug fix Andi Kleen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.