Re: [PATCH] drivers: uio_dmem_genirq: Fix memory leak in uio_dmem_genirq_probe()

2014-05-22 Thread Hans J. Koch
On Thu, May 22, 2014 at 09:46:12AM +0900, Daeseok Youn wrote:
> When platform_get_irq() is failed after "priv" allocated,
> it need to free "priv". But the label of bad0 doesn't try
> to free about "priv". So this patch changes that lable to "bad1".
> But "bad1" has pm_runtime_disable() call, this function should
> be called when uio_register_device() is failed. So it is moved
> into handling error for uio_register_device().

Looks alright to me. Thanks for your contribution.

Signed-off-by: Hans J. Koch 

> 
> Signed-off-by: Daeseok Youn 
> ---
>  drivers/uio/uio_dmem_genirq.c |4 ++--
>  1 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/uio/uio_dmem_genirq.c b/drivers/uio/uio_dmem_genirq.c
> index 1270f3b..8d0bba4 100644
> --- a/drivers/uio/uio_dmem_genirq.c
> +++ b/drivers/uio/uio_dmem_genirq.c
> @@ -204,7 +204,7 @@ static int uio_dmem_genirq_probe(struct platform_device 
> *pdev)
>   ret = platform_get_irq(pdev, 0);
>   if (ret < 0) {
>   dev_err(>dev, "failed to get IRQ\n");
> - goto bad0;
> + goto bad1;
>   }
>   uioinfo->irq = ret;
>   }
> @@ -275,6 +275,7 @@ static int uio_dmem_genirq_probe(struct platform_device 
> *pdev)
>   ret = uio_register_device(>dev, priv->uioinfo);
>   if (ret) {
>   dev_err(>dev, "unable to register uio device\n");
> + pm_runtime_disable(>dev);
>   goto bad1;
>   }
>  
> @@ -282,7 +283,6 @@ static int uio_dmem_genirq_probe(struct platform_device 
> *pdev)
>   return 0;
>   bad1:
>   kfree(priv);
> - pm_runtime_disable(>dev);
>   bad0:
>   /* kfree uioinfo for OF */
>   if (pdev->dev.of_node)
> -- 
> 1.7.1
> 
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] drivers: uio_dmem_genirq: Fix memory leak in uio_dmem_genirq_probe()

2014-05-22 Thread Hans J. Koch
On Thu, May 22, 2014 at 09:46:12AM +0900, Daeseok Youn wrote:
 When platform_get_irq() is failed after priv allocated,
 it need to free priv. But the label of bad0 doesn't try
 to free about priv. So this patch changes that lable to bad1.
 But bad1 has pm_runtime_disable() call, this function should
 be called when uio_register_device() is failed. So it is moved
 into handling error for uio_register_device().

Looks alright to me. Thanks for your contribution.

Signed-off-by: Hans J. Koch h...@hansjkoch.de

 
 Signed-off-by: Daeseok Youn daeseok.y...@gmail.com
 ---
  drivers/uio/uio_dmem_genirq.c |4 ++--
  1 files changed, 2 insertions(+), 2 deletions(-)
 
 diff --git a/drivers/uio/uio_dmem_genirq.c b/drivers/uio/uio_dmem_genirq.c
 index 1270f3b..8d0bba4 100644
 --- a/drivers/uio/uio_dmem_genirq.c
 +++ b/drivers/uio/uio_dmem_genirq.c
 @@ -204,7 +204,7 @@ static int uio_dmem_genirq_probe(struct platform_device 
 *pdev)
   ret = platform_get_irq(pdev, 0);
   if (ret  0) {
   dev_err(pdev-dev, failed to get IRQ\n);
 - goto bad0;
 + goto bad1;
   }
   uioinfo-irq = ret;
   }
 @@ -275,6 +275,7 @@ static int uio_dmem_genirq_probe(struct platform_device 
 *pdev)
   ret = uio_register_device(pdev-dev, priv-uioinfo);
   if (ret) {
   dev_err(pdev-dev, unable to register uio device\n);
 + pm_runtime_disable(pdev-dev);
   goto bad1;
   }
  
 @@ -282,7 +283,6 @@ static int uio_dmem_genirq_probe(struct platform_device 
 *pdev)
   return 0;
   bad1:
   kfree(priv);
 - pm_runtime_disable(pdev-dev);
   bad0:
   /* kfree uioinfo for OF */
   if (pdev-dev.of_node)
 -- 
 1.7.1
 
 
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] MAINTAINERS: Remove Hans J. Koch entries

2013-06-20 Thread Hans J. Koch
On Thu, Jun 20, 2013 at 09:20:27AM -0700, Joe Perches wrote:
> On Thu, 2013-06-20 at 18:01 +0200, Pavel Machek wrote:
> > Anyway, Hans disappeared, so Greg takes patches, again.

I wasn't able to take part in kernel development because I was heavily
involved in hardware development project. I always thought it would be just
a few more days, but then it became half a year. I know I should have given
an explanation and didn't. Sorry for that.

> 
> Maybe this is appropriate then.
> 
> Signed-off-by: Joe Perches 
> ---
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 69fea4f..dc9d04a 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -5253,9 +5253,8 @@ F:  Documentation/hwmon/max16065
>  F:   drivers/hwmon/max16065.c
>  
>  MAX6650 HARDWARE MONITOR AND FAN CONTROLLER DRIVER
> -M:   "Hans J. Koch" 
>  L:   lm-sens...@lm-sensors.org
> -S:   Maintained
> +S:   Orphan
>  F:   Documentation/hwmon/max6650
>  F:   drivers/hwmon/max6650.c

ACK to that one. It was never my idea to have a MAINTAINERS entry for that.
Jean Delvare suggested it, so it came in. The MAX6650 was in a project I was
working on 6 years ago, and I wrote the driver at that time. Meanwhile, I
don't even have hardware with a MAX6650 anymore.

Does each little driver really need a MAINTAINERS entry? In my opinion, it
should only be there if it is clear that it's not just a short project work.

>  
> @@ -8795,7 +8794,6 @@ F:  fs/hostfs/
>  F:   fs/hppfs/
>  
>  USERSPACE I/O (UIO)
> -M:   "Hans J. Koch" 
>  M:   Greg Kroah-Hartman 
>  S:   Maintained
>  F:   Documentation/DocBook/uio-howto.tmpl

Well, you can do that if you want. But I still feel associated with UIO
and sincerely hope I'm back again to fulfill my duties as a maintainer.

Thanks,
Hans
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] MAINTAINERS: Remove Hans J. Koch entries

2013-06-20 Thread Hans J. Koch
On Thu, Jun 20, 2013 at 09:20:27AM -0700, Joe Perches wrote:
 On Thu, 2013-06-20 at 18:01 +0200, Pavel Machek wrote:
  Anyway, Hans disappeared, so Greg takes patches, again.

I wasn't able to take part in kernel development because I was heavily
involved in hardware development project. I always thought it would be just
a few more days, but then it became half a year. I know I should have given
an explanation and didn't. Sorry for that.

 
 Maybe this is appropriate then.
 
 Signed-off-by: Joe Perches j...@perches.com
 ---
 diff --git a/MAINTAINERS b/MAINTAINERS
 index 69fea4f..dc9d04a 100644
 --- a/MAINTAINERS
 +++ b/MAINTAINERS
 @@ -5253,9 +5253,8 @@ F:  Documentation/hwmon/max16065
  F:   drivers/hwmon/max16065.c
  
  MAX6650 HARDWARE MONITOR AND FAN CONTROLLER DRIVER
 -M:   Hans J. Koch h...@hansjkoch.de
  L:   lm-sens...@lm-sensors.org
 -S:   Maintained
 +S:   Orphan
  F:   Documentation/hwmon/max6650
  F:   drivers/hwmon/max6650.c

ACK to that one. It was never my idea to have a MAINTAINERS entry for that.
Jean Delvare suggested it, so it came in. The MAX6650 was in a project I was
working on 6 years ago, and I wrote the driver at that time. Meanwhile, I
don't even have hardware with a MAX6650 anymore.

Does each little driver really need a MAINTAINERS entry? In my opinion, it
should only be there if it is clear that it's not just a short project work.

  
 @@ -8795,7 +8794,6 @@ F:  fs/hostfs/
  F:   fs/hppfs/
  
  USERSPACE I/O (UIO)
 -M:   Hans J. Koch h...@hansjkoch.de
  M:   Greg Kroah-Hartman gre...@linuxfoundation.org
  S:   Maintained
  F:   Documentation/DocBook/uio-howto.tmpl

Well, you can do that if you want. But I still feel associated with UIO
and sincerely hope I'm back again to fulfill my duties as a maintainer.

Thanks,
Hans
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v4 1/2] New driver: Xillybus generic interface for FPGA (programmable logic)

2013-05-20 Thread Hans J. Koch
On Fri, May 17, 2013 at 05:53:39PM +0300, Eli Billauer wrote:
> This is the documentation for the Xillybus driver. It's intended for kernel
> maintainers, since actual users will most likely rely on other documentation.
> 
> It has turned out somewhat tricky to put Xillybus in one of the existing
> categories of device drivers. I placed it under drivers/uio, mainly because it
> shares the spirit of a generic driver allowing userspace programs to talk
> directly with hardware. Unlike the classic UIO devices, Xillybus' char files
> shouldn't be memory mapped, but rather used in the regular manner as streams
> of data.

In that case it simply isn't a UIO device.

> 
> This driver was previously posted under drivers/misc/. The misc device
> framework turned out to be inadequate, as the driver may create more than 100
> device files in some cases.

And that is a problem? If yes, try something else like sysfs. From your
description, this is a drivers/misc device for me.

Thanks,
Hans

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v4 1/2] New driver: Xillybus generic interface for FPGA (programmable logic)

2013-05-20 Thread Hans J. Koch
On Fri, May 17, 2013 at 05:53:39PM +0300, Eli Billauer wrote:
 This is the documentation for the Xillybus driver. It's intended for kernel
 maintainers, since actual users will most likely rely on other documentation.
 
 It has turned out somewhat tricky to put Xillybus in one of the existing
 categories of device drivers. I placed it under drivers/uio, mainly because it
 shares the spirit of a generic driver allowing userspace programs to talk
 directly with hardware. Unlike the classic UIO devices, Xillybus' char files
 shouldn't be memory mapped, but rather used in the regular manner as streams
 of data.

In that case it simply isn't a UIO device.

 
 This driver was previously posted under drivers/misc/. The misc device
 framework turned out to be inadequate, as the driver may create more than 100
 device files in some cases.

And that is a problem? If yes, try something else like sysfs. From your
description, this is a drivers/misc device for me.

Thanks,
Hans

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 1/1] uio.c: solve memory leak

2013-01-20 Thread Hans J. Koch
On Fri, Jan 18, 2013 at 02:00:50PM -0800, Greg Kroah-Hartman wrote:
> On Fri, Jan 18, 2013 at 10:05:45PM +0100, Cong Ding wrote:
> > On Tue, Dec 11, 2012 at 2:21 AM, Hans J. Koch  wrote:
> > > On Thu, Nov 29, 2012 at 05:40:00PM +, Cong Ding wrote:
> > >> In version 1, I forgot to modify the same bug in the first loop.
> > >>
> > >> we have to call kobject_put() to clean up the kobject after function
> > >> kobject_init(), kobject_add(), or kobject_uevent() is called.
> > >>
> > >> Signed-off-by: Cong Ding 
> > >
> > > Signed-off-by: "Hans J. Koch" 
> > 
> > Hi Greg, is this patch stil in the queue?
> 
> Hans is queueing up UIO patches to send to me, I'm waiting for him to
> send them as I don't have any in my trees.

I'll set that up tonight or tomorrow. Sorry, I was delayed by illness
and a lot of other work.

Thanks,
Hans

> 
> thanks,
> 
> greg k-h
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 1/1] uio.c: solve memory leak

2013-01-20 Thread Hans J. Koch
On Fri, Jan 18, 2013 at 02:00:50PM -0800, Greg Kroah-Hartman wrote:
 On Fri, Jan 18, 2013 at 10:05:45PM +0100, Cong Ding wrote:
  On Tue, Dec 11, 2012 at 2:21 AM, Hans J. Koch h...@hansjkoch.de wrote:
   On Thu, Nov 29, 2012 at 05:40:00PM +, Cong Ding wrote:
   In version 1, I forgot to modify the same bug in the first loop.
  
   we have to call kobject_put() to clean up the kobject after function
   kobject_init(), kobject_add(), or kobject_uevent() is called.
  
   Signed-off-by: Cong Ding ding...@gmail.com
  
   Signed-off-by: Hans J. Koch h...@hansjkoch.de
  
  Hi Greg, is this patch stil in the queue?
 
 Hans is queueing up UIO patches to send to me, I'm waiting for him to
 send them as I don't have any in my trees.

I'll set that up tonight or tomorrow. Sorry, I was delayed by illness
and a lot of other work.

Thanks,
Hans

 
 thanks,
 
 greg k-h
 
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/2 v3] Fix memory freeing issues

2012-12-15 Thread Hans J. Koch
On Fri, Dec 14, 2012 at 11:33:50AM +0200, Vitalii Demianets wrote:
> 
> Hans, why do you want to put in this patch, which is dealing with 
> memory-freeing issues only, completely unrelated functional changes?

Because during review of your patch we happened to find another issue
a few lines up and down. Why not fix it on the way?

What I'd like is simply

[PATCH] Fix uio_pdrv_genirq issues

If you like, make it two patches, one with your memory-freeing issue
and one "Remove irq tracking" or something like that. That's just
three or four lines difference, I'd even accept it if it were only
one patch.

I don't want to fix one thing now and leave the other one unresolved.
That would just be a waste of time.

To be clear, I have no objections regarding your memory freeing ideas.

Thanks,
Hans

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/2 v3] Fix memory freeing issues

2012-12-15 Thread Hans J. Koch
On Fri, Dec 14, 2012 at 11:33:50AM +0200, Vitalii Demianets wrote:
 
 Hans, why do you want to put in this patch, which is dealing with 
 memory-freeing issues only, completely unrelated functional changes?

Because during review of your patch we happened to find another issue
a few lines up and down. Why not fix it on the way?

What I'd like is simply

[PATCH] Fix uio_pdrv_genirq issues

If you like, make it two patches, one with your memory-freeing issue
and one Remove irq tracking or something like that. That's just
three or four lines difference, I'd even accept it if it were only
one patch.

I don't want to fix one thing now and leave the other one unresolved.
That would just be a waste of time.

To be clear, I have no objections regarding your memory freeing ideas.

Thanks,
Hans

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[GIT PULL] UIO changes for v3.8

2012-12-13 Thread Hans J. Koch
Hi Greg,
my new UIO tree is based on your current char-misc tree. Please pull the
following two patches.

Thanks,
Hans

The following changes since commit 1ebaf4f4e6912199f8a4e30ba3ab55da2b71bcdf:

  Merge branch 'x86-timers-for-linus' of 
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip (2012-12-11 20:01:33 
-0800)

are available in the git repository at:


  git://hansjkoch.de:/home/repos/git/char-misc.git uio-devel

for you to fetch changes up to d91796fe825b7ebd8ed4150c6886faeb7c3982b1:

  uio: fix possible memory leak in uio.c (2012-12-13 18:55:59 +0100)


Cong Ding (1):
  uio: fix possible memory leak in uio.c

Hans J. Koch (1):
  uio: Fix warning: 'ret' might be used uninitialized

 drivers/uio/uio.c |   18 --
 1 files changed, 12 insertions(+), 6 deletions(-)
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/2 v3] Fix memory freeing issues

2012-12-13 Thread Hans J. Koch
On Mon, Dec 10, 2012 at 11:44:45AM +0200, Vitalii Demianets wrote:
> 1. uioinfo was kfreed based on the presence of pdev->dev.of_node, which was
> obviously wrong and unrelated to the fact if uioinfo was allocated statically
> or dynamically. This patch introduces new flag which clearly shows if uioinfo
> was allocated dynamically and kfrees uioinfo based on that flag;
> 2. Fix: priv data was not freed in case platform_get_irq() failed. As it was
> caused mainly by improper exit labels naming, labels were renamed too;
> 3. The case of uioinfo AND pdev->dev.of_node both NULL (not initialized
> in platform data) was not treated properly.
> 
> Signed-off-by: Vitalii Demianets 
> ---
> v2: Constants naming style
> v3: Comments: better wording in comment accompanying flags initialization &
>  removed obsoleted OF comment

That comment is obsolete as well.

> 
> ---
>  drivers/uio/uio_pdrv_genirq.c |   47 
>  1 files changed, 28 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c
> index 42202cd..cc5233b 100644
> --- a/drivers/uio/uio_pdrv_genirq.c
> +++ b/drivers/uio/uio_pdrv_genirq.c
> @@ -30,6 +30,11 @@
>  
>  #define DRIVER_NAME "uio_pdrv_genirq"
>  
> +enum {
> + UIO_IRQ_DISABLED = 0,
> + UIO_INFO_ALLOCED = 1,
> +};

We don't need these flags.

> +
>  struct uio_pdrv_genirq_platdata {
>   struct uio_info *uioinfo;
>   spinlock_t lock;
> @@ -63,7 +68,7 @@ static irqreturn_t uio_pdrv_genirq_handler(int irq, struct 
> uio_info *dev_info)
>* remember the state so we can allow user space to enable it later.
>*/
>  
> - if (!test_and_set_bit(0, >flags))
> + if (!test_and_set_bit(UIO_IRQ_DISABLED, >flags))

Remove the "if" completely, we need to disable the irq unconditionally.

>   disable_irq_nosync(irq);
>  
>   return IRQ_HANDLED;
> @@ -83,10 +88,10 @@ static int uio_pdrv_genirq_irqcontrol(struct uio_info 
> *dev_info, s32 irq_on)
>  
>   spin_lock_irqsave(>lock, flags);
>   if (irq_on) {
> - if (test_and_clear_bit(0, >flags))
> + if (test_and_clear_bit(UIO_IRQ_DISABLED, >flags))
>   enable_irq(dev_info->irq);
>   } else {
> - if (!test_and_set_bit(0, >flags))
> + if (!test_and_set_bit(UIO_IRQ_DISABLED, >flags))
>   disable_irq(dev_info->irq);

Same here: irqcontrol has to enable/disable the irq unconditionally.

>   }
>   spin_unlock_irqrestore(>lock, flags);
> @@ -101,8 +106,9 @@ static int uio_pdrv_genirq_probe(struct platform_device 
> *pdev)
>   struct uio_mem *uiomem;
>   int ret = -EINVAL;
>   int i;
> + bool uioinfo_alloced = false;
>  
> - if (!uioinfo) {
> + if (!uioinfo && pdev->dev.of_node) {
>   int irq;
>  
>   /* alloc uioinfo for one device */
> @@ -110,10 +116,11 @@ static int uio_pdrv_genirq_probe(struct platform_device 
> *pdev)
>   if (!uioinfo) {
>   ret = -ENOMEM;
>   dev_err(>dev, "unable to kmalloc\n");
> - goto bad2;
> + goto out;
>   }
>   uioinfo->name = pdev->dev.of_node->name;
>   uioinfo->version = "devicetree";
> + uioinfo_alloced = true;
>  
>   /* Multiple IRQs are not supported */
>   irq = platform_get_irq(pdev, 0);
> @@ -125,32 +132,35 @@ static int uio_pdrv_genirq_probe(struct platform_device 
> *pdev)
>  
>   if (!uioinfo || !uioinfo->name || !uioinfo->version) {
>   dev_err(>dev, "missing platform_data\n");
> - goto bad0;
> + goto out_uioinfo;
>   }
>  
>   if (uioinfo->handler || uioinfo->irqcontrol ||
>   uioinfo->irq_flags & IRQF_SHARED) {
>   dev_err(>dev, "interrupt configuration error\n");
> - goto bad0;
> + goto out_uioinfo;
>   }
>  
>   priv = kzalloc(sizeof(*priv), GFP_KERNEL);
>   if (!priv) {
>   ret = -ENOMEM;
>   dev_err(>dev, "unable to kmalloc\n");
> - goto bad0;
> + goto out_uioinfo;
>   }
>  
>   priv->uioinfo = uioinfo;
>   spin_lock_init(>lock);
> - priv->flags = 0; /* interrupt is enabled to begin with */
> + /* Interrupt is enabled to begin with,
> +  * that's why UIO_IRQ_DISABLED flag is not initially set.
> +  */
> + priv->flags = uioinfo_alloced ? BIT_MASK(UIO_INFO_ALLOCED) : 0;
>   priv->pdev = pdev;
>  
>   if (!uioinfo->irq) {
>   ret = platform_get_irq(pdev, 0);
>   if (ret < 0) {
>   dev_err(>dev, "failed to get IRQ\n");
> - goto bad0;
> + goto out_priv;
>   }
>   uioinfo->irq = ret;
>   }
> @@ -205,19 +215,19 @@ static int uio_pdrv_genirq_probe(struct platform_device 
> *pdev)

Re: [PATCH v2] drivers/uio/uio_pdrv_genirq.c: Fix memory freeing issues

2012-12-13 Thread Hans J. Koch
On Thu, Dec 13, 2012 at 07:23:21PM +0200, Vitalii Demianets wrote:
> On Thursday 13 December 2012 19:11:09 Hans J. Koch wrote:
> > On Tue, Dec 11, 2012 at 12:47:35PM +0200, Vitalii Demianets wrote:
> > > Please, review the v3 of "Fix memory freeing issues" patch (first in the
> > > series I posted yesterday) and ignore the second, as we haven't agreed
> > > on it.
> >
> > I can't find a v3. Please resend it.
> >
> 
> I've posted v3 as a [PATCH 1/2 v3] in series:
> http://www.spinics.net/lists/kernel/msg1450101.html
> 
> You were CC-ed. If for some reason you didn't get it in your mailbox, I'll 
> resend.

OK, found it, sorry. I ignored that one because it does the same flag-testing
stuff. It is unnecessary and only tries to fix userspace stupidity in the
kernel. I won't buy that one, and I already gave an explanation why.
I won't take it just because you disagree with my opinion.

Thanks,
Hans
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2] drivers/uio/uio_pdrv_genirq.c: Fix memory freeing issues

2012-12-13 Thread Hans J. Koch
On Tue, Dec 11, 2012 at 12:47:35PM +0200, Vitalii Demianets wrote:
> 
> Please, review the v3 of "Fix memory freeing issues" patch (first in the 
> series I posted yesterday) and ignore the second, as we haven't agreed 
> on it.
> 

I can't find a v3. Please resend it.

Thanks,
Hans

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2] drivers/uio/uio_pdrv_genirq.c: Fix memory freeing issues

2012-12-13 Thread Hans J. Koch
On Tue, Dec 11, 2012 at 12:47:35PM +0200, Vitalii Demianets wrote:
 
 Please, review the v3 of Fix memory freeing issues patch (first in the 
 series I posted yesterday) and ignore the second, as we haven't agreed 
 on it.
 

I can't find a v3. Please resend it.

Thanks,
Hans

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2] drivers/uio/uio_pdrv_genirq.c: Fix memory freeing issues

2012-12-13 Thread Hans J. Koch
On Thu, Dec 13, 2012 at 07:23:21PM +0200, Vitalii Demianets wrote:
 On Thursday 13 December 2012 19:11:09 Hans J. Koch wrote:
  On Tue, Dec 11, 2012 at 12:47:35PM +0200, Vitalii Demianets wrote:
   Please, review the v3 of Fix memory freeing issues patch (first in the
   series I posted yesterday) and ignore the second, as we haven't agreed
   on it.
 
  I can't find a v3. Please resend it.
 
 
 I've posted v3 as a [PATCH 1/2 v3] in series:
 http://www.spinics.net/lists/kernel/msg1450101.html
 
 You were CC-ed. If for some reason you didn't get it in your mailbox, I'll 
 resend.

OK, found it, sorry. I ignored that one because it does the same flag-testing
stuff. It is unnecessary and only tries to fix userspace stupidity in the
kernel. I won't buy that one, and I already gave an explanation why.
I won't take it just because you disagree with my opinion.

Thanks,
Hans
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/2 v3] Fix memory freeing issues

2012-12-13 Thread Hans J. Koch
On Mon, Dec 10, 2012 at 11:44:45AM +0200, Vitalii Demianets wrote:
 1. uioinfo was kfreed based on the presence of pdev-dev.of_node, which was
 obviously wrong and unrelated to the fact if uioinfo was allocated statically
 or dynamically. This patch introduces new flag which clearly shows if uioinfo
 was allocated dynamically and kfrees uioinfo based on that flag;
 2. Fix: priv data was not freed in case platform_get_irq() failed. As it was
 caused mainly by improper exit labels naming, labels were renamed too;
 3. The case of uioinfo AND pdev-dev.of_node both NULL (not initialized
 in platform data) was not treated properly.
 
 Signed-off-by: Vitalii Demianets vi...@nppfactor.kiev.ua
 ---
 v2: Constants naming style
 v3: Comments: better wording in comment accompanying flags initialization 
  removed obsoleted OF comment

That comment is obsolete as well.

 
 ---
  drivers/uio/uio_pdrv_genirq.c |   47 
  1 files changed, 28 insertions(+), 19 deletions(-)
 
 diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c
 index 42202cd..cc5233b 100644
 --- a/drivers/uio/uio_pdrv_genirq.c
 +++ b/drivers/uio/uio_pdrv_genirq.c
 @@ -30,6 +30,11 @@
  
  #define DRIVER_NAME uio_pdrv_genirq
  
 +enum {
 + UIO_IRQ_DISABLED = 0,
 + UIO_INFO_ALLOCED = 1,
 +};

We don't need these flags.

 +
  struct uio_pdrv_genirq_platdata {
   struct uio_info *uioinfo;
   spinlock_t lock;
 @@ -63,7 +68,7 @@ static irqreturn_t uio_pdrv_genirq_handler(int irq, struct 
 uio_info *dev_info)
* remember the state so we can allow user space to enable it later.
*/
  
 - if (!test_and_set_bit(0, priv-flags))
 + if (!test_and_set_bit(UIO_IRQ_DISABLED, priv-flags))

Remove the if completely, we need to disable the irq unconditionally.

   disable_irq_nosync(irq);
  
   return IRQ_HANDLED;
 @@ -83,10 +88,10 @@ static int uio_pdrv_genirq_irqcontrol(struct uio_info 
 *dev_info, s32 irq_on)
  
   spin_lock_irqsave(priv-lock, flags);
   if (irq_on) {
 - if (test_and_clear_bit(0, priv-flags))
 + if (test_and_clear_bit(UIO_IRQ_DISABLED, priv-flags))
   enable_irq(dev_info-irq);
   } else {
 - if (!test_and_set_bit(0, priv-flags))
 + if (!test_and_set_bit(UIO_IRQ_DISABLED, priv-flags))
   disable_irq(dev_info-irq);

Same here: irqcontrol has to enable/disable the irq unconditionally.

   }
   spin_unlock_irqrestore(priv-lock, flags);
 @@ -101,8 +106,9 @@ static int uio_pdrv_genirq_probe(struct platform_device 
 *pdev)
   struct uio_mem *uiomem;
   int ret = -EINVAL;
   int i;
 + bool uioinfo_alloced = false;
  
 - if (!uioinfo) {
 + if (!uioinfo  pdev-dev.of_node) {
   int irq;
  
   /* alloc uioinfo for one device */
 @@ -110,10 +116,11 @@ static int uio_pdrv_genirq_probe(struct platform_device 
 *pdev)
   if (!uioinfo) {
   ret = -ENOMEM;
   dev_err(pdev-dev, unable to kmalloc\n);
 - goto bad2;
 + goto out;
   }
   uioinfo-name = pdev-dev.of_node-name;
   uioinfo-version = devicetree;
 + uioinfo_alloced = true;
  
   /* Multiple IRQs are not supported */
   irq = platform_get_irq(pdev, 0);
 @@ -125,32 +132,35 @@ static int uio_pdrv_genirq_probe(struct platform_device 
 *pdev)
  
   if (!uioinfo || !uioinfo-name || !uioinfo-version) {
   dev_err(pdev-dev, missing platform_data\n);
 - goto bad0;
 + goto out_uioinfo;
   }
  
   if (uioinfo-handler || uioinfo-irqcontrol ||
   uioinfo-irq_flags  IRQF_SHARED) {
   dev_err(pdev-dev, interrupt configuration error\n);
 - goto bad0;
 + goto out_uioinfo;
   }
  
   priv = kzalloc(sizeof(*priv), GFP_KERNEL);
   if (!priv) {
   ret = -ENOMEM;
   dev_err(pdev-dev, unable to kmalloc\n);
 - goto bad0;
 + goto out_uioinfo;
   }
  
   priv-uioinfo = uioinfo;
   spin_lock_init(priv-lock);
 - priv-flags = 0; /* interrupt is enabled to begin with */
 + /* Interrupt is enabled to begin with,
 +  * that's why UIO_IRQ_DISABLED flag is not initially set.
 +  */
 + priv-flags = uioinfo_alloced ? BIT_MASK(UIO_INFO_ALLOCED) : 0;
   priv-pdev = pdev;
  
   if (!uioinfo-irq) {
   ret = platform_get_irq(pdev, 0);
   if (ret  0) {
   dev_err(pdev-dev, failed to get IRQ\n);
 - goto bad0;
 + goto out_priv;
   }
   uioinfo-irq = ret;
   }
 @@ -205,19 +215,19 @@ static int uio_pdrv_genirq_probe(struct platform_device 
 *pdev)
   ret = uio_register_device(pdev-dev, priv-uioinfo);
   if (ret) {
   

[GIT PULL] UIO changes for v3.8

2012-12-13 Thread Hans J. Koch
Hi Greg,
my new UIO tree is based on your current char-misc tree. Please pull the
following two patches.

Thanks,
Hans

The following changes since commit 1ebaf4f4e6912199f8a4e30ba3ab55da2b71bcdf:

  Merge branch 'x86-timers-for-linus' of 
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip (2012-12-11 20:01:33 
-0800)

are available in the git repository at:


  git://hansjkoch.de:/home/repos/git/char-misc.git uio-devel

for you to fetch changes up to d91796fe825b7ebd8ed4150c6886faeb7c3982b1:

  uio: fix possible memory leak in uio.c (2012-12-13 18:55:59 +0100)


Cong Ding (1):
  uio: fix possible memory leak in uio.c

Hans J. Koch (1):
  uio: Fix warning: 'ret' might be used uninitialized

 drivers/uio/uio.c |   18 --
 1 files changed, 12 insertions(+), 6 deletions(-)
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/2] uio: do not expose inode to uio open/release hooks

2012-12-12 Thread Hans J. Koch
On Wed, Dec 12, 2012 at 07:08:18AM -0800, Greg KH wrote:
> On Wed, Dec 12, 2012 at 09:56:16AM +0100, Benedikt Spranger wrote:
> > Am Wed, 12 Dec 2012 09:50:54 +0100
> > schrieb "Hans J. Koch" :
> > 
> > > On Tue, Dec 11, 2012 at 08:46:48PM -0800, Greg KH wrote:
> > > > Yes, but what does that have to do with this in-kernel, internal api?
> > > 
> > > Ah, OK. You're right, the commit message is confusing.
> > > 
> > > Bene, it's enough to say we drop the inode parameter because nobody
> > > ever needed it.
> > I am fine with that.
> > 
> > > I cannot see why this also helps with the other problem.
> > It would help, because we can defer calling the release hook until the
> > last mmap user is gone. In this case the inode pointer may not be valid
> > anymore.
> 
> Which, again, is the same for any in-kernel driver with these types of
> callbacks.

Is that a general mmap problem that wants to be fixed?

hjk

> 
> greg k-h
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/2] uio: do not expose inode to uio open/release hooks

2012-12-12 Thread Hans J. Koch
On Tue, Dec 11, 2012 at 08:46:48PM -0800, Greg KH wrote:
> On Wed, Dec 12, 2012 at 02:42:22AM +0100, Hans J. Koch wrote:
> > On Tue, Dec 11, 2012 at 03:20:32PM -0800, Greg KH wrote:
> > > On Wed, Dec 12, 2012 at 12:12:02AM +0100, Benedikt Spranger wrote:
> > > > The inode parameter is unused by in kernel users of UIO.
> > > 
> > > Ok.
> > > 
> > > > Also the inode parameter makes it hard to resolve the existing open(),
> > > > mmap() and close() difficulty.
> > > 
> > > I don't understand, what do you mean by this?  What is this parameter
> > > causing problems with?
> > 
> > The problem is that according to POSIX, it is guaranteed that in userspace
> > you can do
> > 
> > fd = open("/dev/uio0", ...)
> > ptr = mmap(...fd...)
> > close(fd)
> > 
> > with ptr still being valid and useable after that.
> 
> Yes, but what does that have to do with this in-kernel, internal api?

Ah, OK. You're right, the commit message is confusing.

Bene, it's enough to say we drop the inode parameter because nobody
ever needed it. I cannot see why this also helps with the other problem.

Thanks,
Hans
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/2] uio: do not expose inode to uio open/release hooks

2012-12-12 Thread Hans J. Koch
On Tue, Dec 11, 2012 at 08:46:48PM -0800, Greg KH wrote:
 On Wed, Dec 12, 2012 at 02:42:22AM +0100, Hans J. Koch wrote:
  On Tue, Dec 11, 2012 at 03:20:32PM -0800, Greg KH wrote:
   On Wed, Dec 12, 2012 at 12:12:02AM +0100, Benedikt Spranger wrote:
The inode parameter is unused by in kernel users of UIO.
   
   Ok.
   
Also the inode parameter makes it hard to resolve the existing open(),
mmap() and close() difficulty.
   
   I don't understand, what do you mean by this?  What is this parameter
   causing problems with?
  
  The problem is that according to POSIX, it is guaranteed that in userspace
  you can do
  
  fd = open(/dev/uio0, ...)
  ptr = mmap(...fd...)
  close(fd)
  
  with ptr still being valid and useable after that.
 
 Yes, but what does that have to do with this in-kernel, internal api?

Ah, OK. You're right, the commit message is confusing.

Bene, it's enough to say we drop the inode parameter because nobody
ever needed it. I cannot see why this also helps with the other problem.

Thanks,
Hans
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/2] uio: do not expose inode to uio open/release hooks

2012-12-12 Thread Hans J. Koch
On Wed, Dec 12, 2012 at 07:08:18AM -0800, Greg KH wrote:
 On Wed, Dec 12, 2012 at 09:56:16AM +0100, Benedikt Spranger wrote:
  Am Wed, 12 Dec 2012 09:50:54 +0100
  schrieb Hans J. Koch h...@hansjkoch.de:
  
   On Tue, Dec 11, 2012 at 08:46:48PM -0800, Greg KH wrote:
Yes, but what does that have to do with this in-kernel, internal api?
   
   Ah, OK. You're right, the commit message is confusing.
   
   Bene, it's enough to say we drop the inode parameter because nobody
   ever needed it.
  I am fine with that.
  
   I cannot see why this also helps with the other problem.
  It would help, because we can defer calling the release hook until the
  last mmap user is gone. In this case the inode pointer may not be valid
  anymore.
 
 Which, again, is the same for any in-kernel driver with these types of
 callbacks.

Is that a general mmap problem that wants to be fixed?

hjk

 
 greg k-h
 
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/2] uio: add warning to documentation

2012-12-11 Thread Hans J. Koch
On Tue, Dec 11, 2012 at 03:18:16PM -0800, Greg KH wrote:
> On Wed, Dec 12, 2012 at 12:12:01AM +0100, Benedikt Spranger wrote:
> > The documentation has no clear statement to the POSIX 1003.1 mmap()
> > feature, wich allows open(), mmap(), close() while the mmaped pointer is 
> > valid.
> > The release() hook inveigled driver programmer to activate owermanagement
> > functuonality in the release hook. This may harm.
> > 
> > Signed-off-by: Benedikt Spranger 
> > ---
> >  Documentation/DocBook/uio-howto.tmpl |7 ++-
> >  1 file changed, 6 insertions(+), 1 deletion(-)
> > 
> > diff --git a/Documentation/DocBook/uio-howto.tmpl 
> > b/Documentation/DocBook/uio-howto.tmpl
> > index ac3d001..59a886d 100644
> > --- a/Documentation/DocBook/uio-howto.tmpl
> > +++ b/Documentation/DocBook/uio-howto.tmpl
> > @@ -499,8 +499,13 @@ device is actually used.
> >  
> >  int (*release)(struct uio_info *info, struct inode *inode)
> >  : Optional. If you define your own
> > -open(), you will probably also want a custom
> > +release(), you will probably also want a custom
> >  release() function.
> 
> That sentance no longer makes sense.
> 
> > +CAVE: The release hook may be processed, even if a mmap is 
> > aktive.
> 
> Huh?

I think that's right. You can successfully close() a device while userspace is 
still
using a mapping. If the driver doesn't prevent it, userspace will fail with a 
SIGBUS
when accessing the mapping the next time.

> 
> > +Disabling clocks or other powermanagement functionality may cause a system
> > +crash, hangup or other unwanted sideeffects.
> > +The mmap() function shall add an extra reference to 
> > the file associated with the file descriptor fildes which is not removed by 
> > a subsequent close() on that file descriptor. This reference shall be 
> > removed when there are no more mappings to the file.
> > + > xlink:href="http://pubs.opengroup.org/onlinepubs/009695399/functions/mmap.html;>IEEE
> >  Std 1003.1, 2004 Edition, mmap()
> 
> It's not up to us to document the mmap system call here, you should know
> how to use it if you write a program with it, right?

In general, I agree. But in this case, I don't think that this is an mmap()
feature well known to all programmers (In fact, I wasn't aware of that until
Bene told me).

Thanks,
Hans

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/2] uio: do not expose inode to uio open/release hooks

2012-12-11 Thread Hans J. Koch
On Tue, Dec 11, 2012 at 03:20:32PM -0800, Greg KH wrote:
> On Wed, Dec 12, 2012 at 12:12:02AM +0100, Benedikt Spranger wrote:
> > The inode parameter is unused by in kernel users of UIO.
> 
> Ok.
> 
> > Also the inode parameter makes it hard to resolve the existing open(),
> > mmap() and close() difficulty.
> 
> I don't understand, what do you mean by this?  What is this parameter
> causing problems with?

The problem is that according to POSIX, it is guaranteed that in userspace
you can do

fd = open("/dev/uio0", ...)
ptr = mmap(...fd...)
close(fd)

with ptr still being valid and useable after that.

Thanks,
Hans
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/2] uio: do not expose inode to uio open/release hooks

2012-12-11 Thread Hans J. Koch
On Tue, Dec 11, 2012 at 03:20:32PM -0800, Greg KH wrote:
 On Wed, Dec 12, 2012 at 12:12:02AM +0100, Benedikt Spranger wrote:
  The inode parameter is unused by in kernel users of UIO.
 
 Ok.
 
  Also the inode parameter makes it hard to resolve the existing open(),
  mmap() and close() difficulty.
 
 I don't understand, what do you mean by this?  What is this parameter
 causing problems with?

The problem is that according to POSIX, it is guaranteed that in userspace
you can do

fd = open(/dev/uio0, ...)
ptr = mmap(...fd...)
close(fd)

with ptr still being valid and useable after that.

Thanks,
Hans
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/2] uio: add warning to documentation

2012-12-11 Thread Hans J. Koch
On Tue, Dec 11, 2012 at 03:18:16PM -0800, Greg KH wrote:
 On Wed, Dec 12, 2012 at 12:12:01AM +0100, Benedikt Spranger wrote:
  The documentation has no clear statement to the POSIX 1003.1 mmap()
  feature, wich allows open(), mmap(), close() while the mmaped pointer is 
  valid.
  The release() hook inveigled driver programmer to activate owermanagement
  functuonality in the release hook. This may harm.
  
  Signed-off-by: Benedikt Spranger b.spran...@linutronix.de
  ---
   Documentation/DocBook/uio-howto.tmpl |7 ++-
   1 file changed, 6 insertions(+), 1 deletion(-)
  
  diff --git a/Documentation/DocBook/uio-howto.tmpl 
  b/Documentation/DocBook/uio-howto.tmpl
  index ac3d001..59a886d 100644
  --- a/Documentation/DocBook/uio-howto.tmpl
  +++ b/Documentation/DocBook/uio-howto.tmpl
  @@ -499,8 +499,13 @@ device is actually used.
   listitempara
   varnameint (*release)(struct uio_info *info, struct inode *inode)
   /varname: Optional. If you define your own
  -functionopen()/function, you will probably also want a custom
  +functionrelease()/function, you will probably also want a custom
   functionrelease()/function function.
 
 That sentance no longer makes sense.
 
  +/paraparaCAVE: The release hook may be processed, even if a mmap is 
  aktive.
 
 Huh?

I think that's right. You can successfully close() a device while userspace is 
still
using a mapping. If the driver doesn't prevent it, userspace will fail with a 
SIGBUS
when accessing the mapping the next time.

 
  +Disabling clocks or other powermanagement functionality may cause a system
  +crash, hangup or other unwanted sideeffects.
  +/paraparaemphasisThe mmap() function shall add an extra reference to 
  the file associated with the file descriptor fildes which is not removed by 
  a subsequent close() on that file descriptor. This reference shall be 
  removed when there are no more mappings to the file./emphasis/parapara
  +link 
  xlink:href=http://pubs.opengroup.org/onlinepubs/009695399/functions/mmap.html;IEEE
   Std 1003.1, 2004 Edition, mmap()/link
 
 It's not up to us to document the mmap system call here, you should know
 how to use it if you write a program with it, right?

In general, I agree. But in this case, I don't think that this is an mmap()
feature well known to all programmers (In fact, I wasn't aware of that until
Bene told me).

Thanks,
Hans

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 1/1] uio.c: solve memory leak

2012-12-10 Thread Hans J. Koch
On Thu, Nov 29, 2012 at 05:40:00PM +, Cong Ding wrote:
> In version 1, I forgot to modify the same bug in the first loop.
> 
> we have to call kobject_put() to clean up the kobject after function
> kobject_init(), kobject_add(), or kobject_uevent() is called.
> 
> Signed-off-by: Cong Ding 

Signed-off-by: "Hans J. Koch" 

> ---
>  drivers/uio/uio.c |   16 ++--
>  1 files changed, 10 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
> index 5110f36..79774d3 100644
> --- a/drivers/uio/uio.c
> +++ b/drivers/uio/uio.c
> @@ -291,10 +291,10 @@ static int uio_dev_add_attributes(struct uio_device 
> *idev)
>   mem->map = map;
>   ret = kobject_add(>kobj, idev->map_dir, "map%d", mi);
>   if (ret)
> - goto err_map;
> + goto err_map_kobj;
>   ret = kobject_uevent(>kobj, KOBJ_ADD);
>   if (ret)
> - goto err_map;
> + goto err_map_kobj;
>   }
>  
>   for (pi = 0; pi < MAX_UIO_PORT_REGIONS; pi++) {
> @@ -317,23 +317,27 @@ static int uio_dev_add_attributes(struct uio_device 
> *idev)
>   ret = kobject_add(>kobj, idev->portio_dir,
>   "port%d", pi);
>   if (ret)
> - goto err_portio;
> + goto err_portio_kobj;
>   ret = kobject_uevent(>kobj, KOBJ_ADD);
>   if (ret)
> - goto err_portio;
> + goto err_portio_kobj;
>   }
>  
>   return 0;
>  
>  err_portio:
> - for (pi--; pi >= 0; pi--) {
> + pi--;
> +err_portio_kobj:
> + for (; pi >= 0; pi--) {
>   port = >info->port[pi];
>   portio = port->portio;
>   kobject_put(>kobj);
>   }
>   kobject_put(idev->portio_dir);
>  err_map:
> - for (mi--; mi>=0; mi--) {
> + mi--;
> +err_map_kobj:
> + for (; mi >= 0; mi--) {
>   mem = >info->mem[mi];
>   map = mem->map;
>   kobject_put(>kobj);
> -- 
> 1.7.4.5
> 
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2] drivers/uio/uio_pdrv_genirq.c: Fix memory freeing issues

2012-12-10 Thread Hans J. Koch
On Mon, Dec 10, 2012 at 12:24:04PM +0200, Vitalii Demianets wrote:
> > > > Hi Vitalii,
> > > > thanks a lot for analyzing the problem so thoroughly. It made me review
> > > > uio_pdrv_genirq.c again, and I noticed several issues and came to the
> > > > following conclusions:
> > > >
> > > > 1.) priv->lock is completely unnecessary. It is only used in one 
> > > >function,
> > > > so there's nothing it could possibly protect.
> > > >
> > > > 2.) All these "test_and_clear_bit" and "test_and_set_bit" calls are also
> > > > unnecessary. We can simply use enable_irq and disable_irq in both the
> > > > irq handler and in uio_pdrv_genirq_irqcontrol.
> > > >
> > > > We should go "back to the roots" and have a look at how UIO works.
> > > > The workflow it is intended for is like this:
> > > >
> > > > 1.) Hardware is in Reset State (e.g. after boot). Any decent hardware
> > > > has its interrupt disabled at that time.
> > > >
> > > > 2.) uio_pdrv_genirq is loaded. Kernel enables the irq.
> > > >
> > > > 3.) Userspace part of the driver comes up. It will initialize the 
> > > > hardware
> > > > (including setting the bits that enable the interrupt).
> > > >
> > > > 4.) Userspace will then issue a blocking read() on /dev/uioX. Typically,
> > > > there'll be a loop or a thread with this blocking read() at the 
> > > > beginning
> > > > (usually using the select() call).
> > > >
> > > > 5.) At some time, a hardware interrupt will occur. The irq handler in
> > > > kernel space will be called, only to disable the irq. This will also 
> > > > cause the UIO core to make /dev/uioX readable.
> > > >
> > > > 6.) Userspace's blocking read returns. Userspace does its work by
> > > > reading/writing device memory.
> > > >
> > > > 7.) As the last thing, Userspace writes a "1" to /dev/uioX, which causes
> > > > uio_pdrv_genirq_irqcontrol to be called, re-enabling the interrupt.
> > > >
> > > > 8.) Goto 4.)
> > > >
> > > > We should also remember that uio_pdrv_genirq_handler() is NOT a real
> > > > hardware irq handler. The real handler is in the UIO core, which will
> > > > increment the event number and wake up userspace.
> > > >
> > > > So, although your scenario clearly shows a subtle race condition, there 
> > > > is none. If userspace does stupid things, no harm will be done to the 
> > > > kernel.
> > > 
> > > With all due respect, I disagree here. If userspace does stupid things, 
> > > unintentionally because of poorly written code or intentionally because 
> > > of 
> a 
> > > malicious purpose, we could have irq depth counter disbalanced which, in 
> > > turn, could lead to the interrupt not enabled when it should be.
> > 
> > It's just the interrupt of a broken UIO userspace driver. Note that this is
> > also a security mechanism, disabling the irq when it is not handled 
> > properly.
> > 
> > > In which 
> > > case the whole system would stop doing useful things which it was 
> > > designed 
> > > to do.
> > 
> > If the kernel irq depth counter can't track the irq, I don't really see a
> > point in fixing it by adding extra flags in a simple driver.
> > 
> 
> The flag in driver would be needed if we supposed that userspace can do 
> stupid 
> things. For example, userspace can call write() twice with zero data. Which 
> would lead to disabling irq twice. Which means that someone would need to 
> enable irq twice. Which is not in the userspace-kernel interaction scenario 
> you so clearly described above previously.

Indeed. It means that somebody wrote bad userspace code, and it needs to be
fixed there.

> 
> Also, without that flag the irq could be disabled twice even when userspace 
> do 
> not do double-disable. It could happen when userspace is writing to the 
> device file AND irq is running at this same moment on another CPU core 
> concurrently.

If that happens, then either userspace is broken or the device cannot be
handled by a UIO driver (e.g. because irq rate is too high which is usually
an indicator for bad hardware design).

> Yes, you are right that such a situation could be avoided if userspace code 
> was written carefully. But how can you assure that every user will write good 
> code?

I don't care at all. I know the quality of code written in industry too well.
They'll write bad code. All we can do is prevent damage to others.

> 
> > > 
> > > > If userspace is designed the way described above (and in the
> > > > documentation), it will always wake up with its interrupt disabled, do 
> > > > its work, and then re-enable the interrupt. You can probably think of
> > > > a few things userspace could do to screw things up. But that's not our 
> > > > problem.
> > > >
> > > 
> > > Disagree again. I think we can not leave a hole in kernel which opens DOS 
> > > possibilities and hope userspace will behave well. There are always 
> > > errors  
> > > in the code. And security issues, too.
> > 
> > UIO is a risky thing to begin with. There are many more possibilities to
> > do bad things. That's why UIO 

Re: [PATCH v2] drivers/uio/uio_pdrv_genirq.c: Fix memory freeing issues

2012-12-10 Thread Hans J. Koch
On Mon, Dec 10, 2012 at 11:03:59AM +0200, Vitalii Demianets wrote:
> On Saturday 08 December 2012 01:47:21 Hans J. Koch wrote:
> > On Fri, Dec 07, 2012 at 05:00:54PM +0200, Vitalii Demianets wrote:
> > > > On second thought, we can't call enable_irq()/disable_irq()
> > > > unconditionally because of the potential disable counter
> > > > (irq_desc->depth) disbalance. That's why we need UIO_IRQ_DISABLED flag,
> > > > and that's why we should check it in uio_pdrv_genirq_irqcontrol().
> > > > On the other hand, you are right in that we don't need to check it
> > > > inside irq handler. Inside irq handler we can disable irq and set the
> > > > flag unconditionally, because:
> > > > a) We know for sure that irqs are enabled, because we are inside
> > > > (not-shared) irq handler;
> > > >  and
> > > > b) We are guarded from potential race conditions by spin_lock_irqsave()
> > > > call in uio_pdrv_genirq_irqcontrol().
> > > >
> > > > So,yes, we can get rid of costly atomic call to
> > > > test_and_set_bit(UIO_IRQ_DISABLED,..) inside irq handler. But I still
> > > > don't like the idea of mixing this optimization with bug fixes in a
> > > > single patch.
> > >
> > > On the third thought, we can't ;)
> > > Imagine the SMP system where uio_pdrv_genirq_irqcontrol() is being
> > > executed on CPU0 and irq handler is running concurrently on CPU1. To
> > > protect from disable_irq counter disbalance we must first check current
> > > irq status, and in atomic manner. Thus we prevent  double-disable, one
> > > from
> > > uio_pdrv_genirq_irqcontrol() running on CPU0 and another form irq handler
> > > running on CPU1.
> > > Above consideration justifies current code.
> > >
> > > But it seems we have potential concurrency problem here anyway. Here is
> > > theoretical scenario:
> > > 1) Initial state: irq is enabled, uio_pdrv_genirq_irqcontrol() starts
> > > being executed on CPU0 with irq_on=1 and at the same time, concurrently,
> > > irq handler starts being executed on CPU1;
> > > 2) irq handler executes line
> > >if (!test_and_set_bit(UIO_IRQ_DISABLED, >flags))
> > > as irq was enabled, the condition holds. And now UIO_IRQ_DISABLED is set.
> > > 3) uio_pdrv_genirq_irqcontrol() executes line
> > >if (test_and_clear_bit(UIO_IRQ_DISABLED, >flags))
> > > as UIO_IRQ_DISABLED was set by CPU1, the condition holds. And now
> > > UIO_IRQ_DISABLED is cleared.
> > > 4) CPU0 executes enable_irq() . IRQ is enabled. "Unbalanced enable for
> > > IRQ %d\n" warning is issued.
> > > 5) irq handler on CPU1 executes disable_irq_nosync(). IRQ is disabled.
> > >
> > > And now we are in situation where IRQ is disabled, but UIO_IRQ_DISABLED
> > > is cleared. Bad.
> > >
> > > The above scenario is purely theoretical, I have no means to check it in
> > > hardware.
> > > The (theoretical) solution is to guard UIO_IRQ_DISABLED test and actual
> > > irq disabling inside irq handler by priv->lock.
> > >
> > > What do you think about it? Is it worth worrying about?
> >
> > Hi Vitalii,
> > thanks a lot for analyzing the problem so thoroughly. It made me review
> > uio_pdrv_genirq.c again, and I noticed several issues and came to the
> > following conclusions:
> >
> > 1.) priv->lock is completely unnecessary. It is only used in one function,
> > so there's nothing it could possibly protect.
> >
> > 2.) All these "test_and_clear_bit" and "test_and_set_bit" calls are also
> > unnecessary. We can simply use enable_irq and disable_irq in both the
> > irq handler and in uio_pdrv_genirq_irqcontrol.
> >
> > We should go "back to the roots" and have a look at how UIO works.
> > The workflow it is intended for is like this:
> >
> > 1.) Hardware is in Reset State (e.g. after boot). Any decent hardware
> > has its interrupt disabled at that time.
> >
> > 2.) uio_pdrv_genirq is loaded. Kernel enables the irq.
> >
> > 3.) Userspace part of the driver comes up. It will initialize the hardware
> > (including setting the bits that enable the interrupt).
> >
> > 4.) Userspace will then issue a blocking read() on /dev/uioX. Typically,
> > there'll be a loop or a thread with this blocking read() at the beginning
> > (usually using the select() call).
> >
> > 5.) At some time, a hardware interrupt will occur

Re: [PATCH v2] drivers/uio/uio_pdrv_genirq.c: Fix memory freeing issues

2012-12-10 Thread Hans J. Koch
On Mon, Dec 10, 2012 at 11:03:59AM +0200, Vitalii Demianets wrote:
 On Saturday 08 December 2012 01:47:21 Hans J. Koch wrote:
  On Fri, Dec 07, 2012 at 05:00:54PM +0200, Vitalii Demianets wrote:
On second thought, we can't call enable_irq()/disable_irq()
unconditionally because of the potential disable counter
(irq_desc-depth) disbalance. That's why we need UIO_IRQ_DISABLED flag,
and that's why we should check it in uio_pdrv_genirq_irqcontrol().
On the other hand, you are right in that we don't need to check it
inside irq handler. Inside irq handler we can disable irq and set the
flag unconditionally, because:
a) We know for sure that irqs are enabled, because we are inside
(not-shared) irq handler;
 and
b) We are guarded from potential race conditions by spin_lock_irqsave()
call in uio_pdrv_genirq_irqcontrol().
   
So,yes, we can get rid of costly atomic call to
test_and_set_bit(UIO_IRQ_DISABLED,..) inside irq handler. But I still
don't like the idea of mixing this optimization with bug fixes in a
single patch.
  
   On the third thought, we can't ;)
   Imagine the SMP system where uio_pdrv_genirq_irqcontrol() is being
   executed on CPU0 and irq handler is running concurrently on CPU1. To
   protect from disable_irq counter disbalance we must first check current
   irq status, and in atomic manner. Thus we prevent  double-disable, one
   from
   uio_pdrv_genirq_irqcontrol() running on CPU0 and another form irq handler
   running on CPU1.
   Above consideration justifies current code.
  
   But it seems we have potential concurrency problem here anyway. Here is
   theoretical scenario:
   1) Initial state: irq is enabled, uio_pdrv_genirq_irqcontrol() starts
   being executed on CPU0 with irq_on=1 and at the same time, concurrently,
   irq handler starts being executed on CPU1;
   2) irq handler executes line
  if (!test_and_set_bit(UIO_IRQ_DISABLED, priv-flags))
   as irq was enabled, the condition holds. And now UIO_IRQ_DISABLED is set.
   3) uio_pdrv_genirq_irqcontrol() executes line
  if (test_and_clear_bit(UIO_IRQ_DISABLED, priv-flags))
   as UIO_IRQ_DISABLED was set by CPU1, the condition holds. And now
   UIO_IRQ_DISABLED is cleared.
   4) CPU0 executes enable_irq() . IRQ is enabled. Unbalanced enable for
   IRQ %d\n warning is issued.
   5) irq handler on CPU1 executes disable_irq_nosync(). IRQ is disabled.
  
   And now we are in situation where IRQ is disabled, but UIO_IRQ_DISABLED
   is cleared. Bad.
  
   The above scenario is purely theoretical, I have no means to check it in
   hardware.
   The (theoretical) solution is to guard UIO_IRQ_DISABLED test and actual
   irq disabling inside irq handler by priv-lock.
  
   What do you think about it? Is it worth worrying about?
 
  Hi Vitalii,
  thanks a lot for analyzing the problem so thoroughly. It made me review
  uio_pdrv_genirq.c again, and I noticed several issues and came to the
  following conclusions:
 
  1.) priv-lock is completely unnecessary. It is only used in one function,
  so there's nothing it could possibly protect.
 
  2.) All these test_and_clear_bit and test_and_set_bit calls are also
  unnecessary. We can simply use enable_irq and disable_irq in both the
  irq handler and in uio_pdrv_genirq_irqcontrol.
 
  We should go back to the roots and have a look at how UIO works.
  The workflow it is intended for is like this:
 
  1.) Hardware is in Reset State (e.g. after boot). Any decent hardware
  has its interrupt disabled at that time.
 
  2.) uio_pdrv_genirq is loaded. Kernel enables the irq.
 
  3.) Userspace part of the driver comes up. It will initialize the hardware
  (including setting the bits that enable the interrupt).
 
  4.) Userspace will then issue a blocking read() on /dev/uioX. Typically,
  there'll be a loop or a thread with this blocking read() at the beginning
  (usually using the select() call).
 
  5.) At some time, a hardware interrupt will occur. The irq handler in
  kernel space will be called, only to disable the irq. This will also cause
  the UIO core to make /dev/uioX readable.
 
  6.) Userspace's blocking read returns. Userspace does its work by
  reading/writing device memory.
 
  7.) As the last thing, Userspace writes a 1 to /dev/uioX, which causes
  uio_pdrv_genirq_irqcontrol to be called, re-enabling the interrupt.
 
  8.) Goto 4.)
 
  We should also remember that uio_pdrv_genirq_handler() is NOT a real
  hardware irq handler. The real handler is in the UIO core, which will
  increment the event number and wake up userspace.
 
  So, although your scenario clearly shows a subtle race condition, there is
  none. If userspace does stupid things, no harm will be done to the kernel.
 
 With all due respect, I disagree here. If userspace does stupid things, 
 unintentionally because of poorly written code or intentionally because of a 
 malicious purpose, we could have irq depth counter disbalanced which, in 
 turn, could lead

Re: [PATCH v2] drivers/uio/uio_pdrv_genirq.c: Fix memory freeing issues

2012-12-10 Thread Hans J. Koch
On Mon, Dec 10, 2012 at 12:24:04PM +0200, Vitalii Demianets wrote:
Hi Vitalii,
thanks a lot for analyzing the problem so thoroughly. It made me review
uio_pdrv_genirq.c again, and I noticed several issues and came to the
following conclusions:
   
1.) priv-lock is completely unnecessary. It is only used in one 
   function,
so there's nothing it could possibly protect.
   
2.) All these test_and_clear_bit and test_and_set_bit calls are also
unnecessary. We can simply use enable_irq and disable_irq in both the
irq handler and in uio_pdrv_genirq_irqcontrol.
   
We should go back to the roots and have a look at how UIO works.
The workflow it is intended for is like this:
   
1.) Hardware is in Reset State (e.g. after boot). Any decent hardware
has its interrupt disabled at that time.
   
2.) uio_pdrv_genirq is loaded. Kernel enables the irq.
   
3.) Userspace part of the driver comes up. It will initialize the 
hardware
(including setting the bits that enable the interrupt).
   
4.) Userspace will then issue a blocking read() on /dev/uioX. Typically,
there'll be a loop or a thread with this blocking read() at the 
beginning
(usually using the select() call).
   
5.) At some time, a hardware interrupt will occur. The irq handler in
kernel space will be called, only to disable the irq. This will also 
cause the UIO core to make /dev/uioX readable.
   
6.) Userspace's blocking read returns. Userspace does its work by
reading/writing device memory.
   
7.) As the last thing, Userspace writes a 1 to /dev/uioX, which causes
uio_pdrv_genirq_irqcontrol to be called, re-enabling the interrupt.
   
8.) Goto 4.)
   
We should also remember that uio_pdrv_genirq_handler() is NOT a real
hardware irq handler. The real handler is in the UIO core, which will
increment the event number and wake up userspace.
   
So, although your scenario clearly shows a subtle race condition, there 
is none. If userspace does stupid things, no harm will be done to the 
kernel.
   
   With all due respect, I disagree here. If userspace does stupid things, 
   unintentionally because of poorly written code or intentionally because 
   of 
 a 
   malicious purpose, we could have irq depth counter disbalanced which, in 
   turn, could lead to the interrupt not enabled when it should be.
  
  It's just the interrupt of a broken UIO userspace driver. Note that this is
  also a security mechanism, disabling the irq when it is not handled 
  properly.
  
   In which 
   case the whole system would stop doing useful things which it was 
   designed 
   to do.
  
  If the kernel irq depth counter can't track the irq, I don't really see a
  point in fixing it by adding extra flags in a simple driver.
  
 
 The flag in driver would be needed if we supposed that userspace can do 
 stupid 
 things. For example, userspace can call write() twice with zero data. Which 
 would lead to disabling irq twice. Which means that someone would need to 
 enable irq twice. Which is not in the userspace-kernel interaction scenario 
 you so clearly described above previously.

Indeed. It means that somebody wrote bad userspace code, and it needs to be
fixed there.

 
 Also, without that flag the irq could be disabled twice even when userspace 
 do 
 not do double-disable. It could happen when userspace is writing to the 
 device file AND irq is running at this same moment on another CPU core 
 concurrently.

If that happens, then either userspace is broken or the device cannot be
handled by a UIO driver (e.g. because irq rate is too high which is usually
an indicator for bad hardware design).

 Yes, you are right that such a situation could be avoided if userspace code 
 was written carefully. But how can you assure that every user will write good 
 code?

I don't care at all. I know the quality of code written in industry too well.
They'll write bad code. All we can do is prevent damage to others.

 
   
If userspace is designed the way described above (and in the
documentation), it will always wake up with its interrupt disabled, do 
its work, and then re-enable the interrupt. You can probably think of
a few things userspace could do to screw things up. But that's not our 
problem.
   
   
   Disagree again. I think we can not leave a hole in kernel which opens DOS 
   possibilities and hope userspace will behave well. There are always 
   errors  
   in the code. And security issues, too.
  
  UIO is a risky thing to begin with. There are many more possibilities to
  do bad things. That's why UIO devices are root-only.
  
 
 We can assume that code running under root does not do bad things on purpose.

If that was true, there would be no security problems in the world. Making
UIO devices root-only is only a prerequisite for constructing a safe system.
BTW, there are more safety-critical devices in a typical 

Re: [PATCH v2 1/1] uio.c: solve memory leak

2012-12-10 Thread Hans J. Koch
On Thu, Nov 29, 2012 at 05:40:00PM +, Cong Ding wrote:
 In version 1, I forgot to modify the same bug in the first loop.
 
 we have to call kobject_put() to clean up the kobject after function
 kobject_init(), kobject_add(), or kobject_uevent() is called.
 
 Signed-off-by: Cong Ding ding...@gmail.com

Signed-off-by: Hans J. Koch h...@hansjkoch.de

 ---
  drivers/uio/uio.c |   16 ++--
  1 files changed, 10 insertions(+), 6 deletions(-)
 
 diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
 index 5110f36..79774d3 100644
 --- a/drivers/uio/uio.c
 +++ b/drivers/uio/uio.c
 @@ -291,10 +291,10 @@ static int uio_dev_add_attributes(struct uio_device 
 *idev)
   mem-map = map;
   ret = kobject_add(map-kobj, idev-map_dir, map%d, mi);
   if (ret)
 - goto err_map;
 + goto err_map_kobj;
   ret = kobject_uevent(map-kobj, KOBJ_ADD);
   if (ret)
 - goto err_map;
 + goto err_map_kobj;
   }
  
   for (pi = 0; pi  MAX_UIO_PORT_REGIONS; pi++) {
 @@ -317,23 +317,27 @@ static int uio_dev_add_attributes(struct uio_device 
 *idev)
   ret = kobject_add(portio-kobj, idev-portio_dir,
   port%d, pi);
   if (ret)
 - goto err_portio;
 + goto err_portio_kobj;
   ret = kobject_uevent(portio-kobj, KOBJ_ADD);
   if (ret)
 - goto err_portio;
 + goto err_portio_kobj;
   }
  
   return 0;
  
  err_portio:
 - for (pi--; pi = 0; pi--) {
 + pi--;
 +err_portio_kobj:
 + for (; pi = 0; pi--) {
   port = idev-info-port[pi];
   portio = port-portio;
   kobject_put(portio-kobj);
   }
   kobject_put(idev-portio_dir);
  err_map:
 - for (mi--; mi=0; mi--) {
 + mi--;
 +err_map_kobj:
 + for (; mi = 0; mi--) {
   mem = idev-info-mem[mi];
   map = mem-map;
   kobject_put(map-kobj);
 -- 
 1.7.4.5
 
 
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 1/1] uio.c: solve memory leak

2012-12-07 Thread Hans J. Koch
On Fri, Dec 07, 2012 at 12:02:11AM +0100, Cong Ding wrote:
> ping Hans, did you have any comment on this?

Sounds right what you say. Is your patch v2 your final solution, or would
you like to come up with v3?

Thanks a lot for your patience and your thorough analysis.

Hans

> 
> - cong
> 
> On Fri, Nov 30, 2012 at 12:03 PM, Cong Ding  wrote:
> > Hi Hans, I think the memory allocated with kzalloc is properly freed
> > by calling kobject_put.
> >
> > I can give a simple explanation.
> >
> > 1)  when we call kobject_init, the parameter portio_attr_type is
> > passed in. portio_attr_type includes a function pointer to
> > portio_release, which releases the memory of portio.
> >
> > 2) when we call kobject_put, kref_put is called with the pointer of
> > function kobject_release.
> > 3) kref_put calls kref_sub, with the same pointer of function 
> > kobject_release.
> > 4) and kref_put calls the function kboject_release if
> > atomic_sub_and_test returns true
> >
> > 5) let's look at what kobject_release is. it calls kobject_cleanup,
> > and kobject_cleanup calls t->release(kobj) where t->release is exactly
> > the function we passed in through portio_init at step (1). so function
> > portio_release is called, and the memory allocated with kzalloc is
> > freed.
> >
> > If there are anything wrong in my analysis, please feel free to let me know.
> >
> > Personally, I suggest to add a function to create and release
> > uio_portio, which is similar as kobject_create and kobject_put in file
> > lib/kobject.c. In this way, it avoid other readers thinking the memory
> > is not freed (and we should add some comments here). For example,
> > uio_portio_create call kzalloc and kboject_init, and returns
> > uio_portio, which is similar as function kobject_create; and
> > uio_portio_release calls kobject_put to release the memory. And we do
> > same thing for uio_map.
> >
> > The usage here is quite strange, but it works. If I write this
> > function from zero, I will use a pointer to kobject in uio_portio
> > struct instead of kobject struct itself. In this case I can call
> > kobject_create instead of kobject_init, and then we do both
> > kzalloc(uio_portio) and kfree(uio_portio) in the file uio.c.
> >
> > Best,
> > Cong
> >
> > On Fri, Nov 30, 2012 at 1:13 AM, Hans J. Koch  wrote:
> >> There's still another bug: The memory allocated with kzalloc is
> >> never freed.
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2] drivers/uio/uio_pdrv_genirq.c: Fix memory freeing issues

2012-12-07 Thread Hans J. Koch
On Fri, Dec 07, 2012 at 05:00:54PM +0200, Vitalii Demianets wrote:
> >
> > On second thought, we can't call enable_irq()/disable_irq() unconditionally
> > because of the potential disable counter (irq_desc->depth) disbalance.
> > That's why we need UIO_IRQ_DISABLED flag, and that's why we should check it
> > in uio_pdrv_genirq_irqcontrol().
> > On the other hand, you are right in that we don't need to check it inside
> > irq handler. Inside irq handler we can disable irq and set the flag
> > unconditionally, because:
> > a) We know for sure that irqs are enabled, because we are inside
> > (not-shared) irq handler;
> >  and
> > b) We are guarded from potential race conditions by spin_lock_irqsave()
> > call in uio_pdrv_genirq_irqcontrol().
> >
> > So,yes, we can get rid of costly atomic call to
> > test_and_set_bit(UIO_IRQ_DISABLED,..) inside irq handler. But I still don't
> > like the idea of mixing this optimization with bug fixes in a single patch.
> 
> On the third thought, we can't ;)
> Imagine the SMP system where uio_pdrv_genirq_irqcontrol() is being executed 
> on 
> CPU0 and irq handler is running concurrently on CPU1. To protect from 
> disable_irq counter disbalance we must first check current irq status, and in 
> atomic manner. Thus we prevent  double-disable, one from 
> uio_pdrv_genirq_irqcontrol() running on CPU0 and another form irq handler 
> running on CPU1.
> Above consideration justifies current code.
> 
> But it seems we have potential concurrency problem here anyway. Here is 
> theoretical scenario:
> 1) Initial state: irq is enabled, uio_pdrv_genirq_irqcontrol() starts being 
> executed on CPU0 with irq_on=1 and at the same time, concurrently, irq 
> handler starts being executed on CPU1;
> 2) irq handler executes line
>if (!test_and_set_bit(UIO_IRQ_DISABLED, >flags))
> as irq was enabled, the condition holds. And now UIO_IRQ_DISABLED is set.
> 3) uio_pdrv_genirq_irqcontrol() executes line
>if (test_and_clear_bit(UIO_IRQ_DISABLED, >flags))
> as UIO_IRQ_DISABLED was set by CPU1, the condition holds. And now 
> UIO_IRQ_DISABLED is cleared.
> 4) CPU0 executes enable_irq() . IRQ is enabled. "Unbalanced enable for 
> IRQ %d\n" warning is issued.
> 5) irq handler on CPU1 executes disable_irq_nosync(). IRQ is disabled.
> 
> And now we are in situation where IRQ is disabled, but UIO_IRQ_DISABLED is 
> cleared. Bad.
> 
> The above scenario is purely theoretical, I have no means to check it in 
> hardware.
> The (theoretical) solution is to guard UIO_IRQ_DISABLED test and actual irq 
> disabling inside irq handler by priv->lock.
> 
> What do you think about it? Is it worth worrying about?

Hi Vitalii,
thanks a lot for analyzing the problem so thoroughly. It made me review
uio_pdrv_genirq.c again, and I noticed several issues and came to the
following conclusions:

1.) priv->lock is completely unnecessary. It is only used in one function,
so there's nothing it could possibly protect.

2.) All these "test_and_clear_bit" and "test_and_set_bit" calls are also
unnecessary. We can simply use enable_irq and disable_irq in both the
irq handler and in uio_pdrv_genirq_irqcontrol.

We should go "back to the roots" and have a look at how UIO works.
The workflow it is intended for is like this:

1.) Hardware is in Reset State (e.g. after boot). Any decent hardware
has its interrupt disabled at that time.

2.) uio_pdrv_genirq is loaded. Kernel enables the irq.

3.) Userspace part of the driver comes up. It will initialize the hardware
(including setting the bits that enable the interrupt).

4.) Userspace will then issue a blocking read() on /dev/uioX. Typically,
there'll be a loop or a thread with this blocking read() at the beginning
(usually using the select() call).

5.) At some time, a hardware interrupt will occur. The irq handler in kernel
space will be called, only to disable the irq. This will also cause the UIO
core to make /dev/uioX readable.

6.) Userspace's blocking read returns. Userspace does its work by
reading/writing device memory.

7.) As the last thing, Userspace writes a "1" to /dev/uioX, which causes
uio_pdrv_genirq_irqcontrol to be called, re-enabling the interrupt.

8.) Goto 4.)

We should also remember that uio_pdrv_genirq_handler() is NOT a real hardware
irq handler. The real handler is in the UIO core, which will increment the
event number and wake up userspace.

So, although your scenario clearly shows a subtle race condition, there is
none. If userspace does stupid things, no harm will be done to the kernel.
If userspace is designed the way described above (and in the documentation),
it will always wake up with its interrupt disabled, do its work, and then
re-enable the interrupt. You can probably think of a few things userspace
could do to screw things up. But that's not our problem.

Could you hack up a patch for that? I think it should start with removing
uio_pdrv_genirq_platdata->lock and uio_pdrv_genirq_platdata->flags...

Thanks again for your work. What do you 

Re: [PATCH v2] drivers/uio/uio_pdrv_genirq.c: Fix memory freeing issues

2012-12-07 Thread Hans J. Koch
On Fri, Dec 07, 2012 at 05:00:54PM +0200, Vitalii Demianets wrote:
 
  On second thought, we can't call enable_irq()/disable_irq() unconditionally
  because of the potential disable counter (irq_desc-depth) disbalance.
  That's why we need UIO_IRQ_DISABLED flag, and that's why we should check it
  in uio_pdrv_genirq_irqcontrol().
  On the other hand, you are right in that we don't need to check it inside
  irq handler. Inside irq handler we can disable irq and set the flag
  unconditionally, because:
  a) We know for sure that irqs are enabled, because we are inside
  (not-shared) irq handler;
   and
  b) We are guarded from potential race conditions by spin_lock_irqsave()
  call in uio_pdrv_genirq_irqcontrol().
 
  So,yes, we can get rid of costly atomic call to
  test_and_set_bit(UIO_IRQ_DISABLED,..) inside irq handler. But I still don't
  like the idea of mixing this optimization with bug fixes in a single patch.
 
 On the third thought, we can't ;)
 Imagine the SMP system where uio_pdrv_genirq_irqcontrol() is being executed 
 on 
 CPU0 and irq handler is running concurrently on CPU1. To protect from 
 disable_irq counter disbalance we must first check current irq status, and in 
 atomic manner. Thus we prevent  double-disable, one from 
 uio_pdrv_genirq_irqcontrol() running on CPU0 and another form irq handler 
 running on CPU1.
 Above consideration justifies current code.
 
 But it seems we have potential concurrency problem here anyway. Here is 
 theoretical scenario:
 1) Initial state: irq is enabled, uio_pdrv_genirq_irqcontrol() starts being 
 executed on CPU0 with irq_on=1 and at the same time, concurrently, irq 
 handler starts being executed on CPU1;
 2) irq handler executes line
if (!test_and_set_bit(UIO_IRQ_DISABLED, priv-flags))
 as irq was enabled, the condition holds. And now UIO_IRQ_DISABLED is set.
 3) uio_pdrv_genirq_irqcontrol() executes line
if (test_and_clear_bit(UIO_IRQ_DISABLED, priv-flags))
 as UIO_IRQ_DISABLED was set by CPU1, the condition holds. And now 
 UIO_IRQ_DISABLED is cleared.
 4) CPU0 executes enable_irq() . IRQ is enabled. Unbalanced enable for 
 IRQ %d\n warning is issued.
 5) irq handler on CPU1 executes disable_irq_nosync(). IRQ is disabled.
 
 And now we are in situation where IRQ is disabled, but UIO_IRQ_DISABLED is 
 cleared. Bad.
 
 The above scenario is purely theoretical, I have no means to check it in 
 hardware.
 The (theoretical) solution is to guard UIO_IRQ_DISABLED test and actual irq 
 disabling inside irq handler by priv-lock.
 
 What do you think about it? Is it worth worrying about?

Hi Vitalii,
thanks a lot for analyzing the problem so thoroughly. It made me review
uio_pdrv_genirq.c again, and I noticed several issues and came to the
following conclusions:

1.) priv-lock is completely unnecessary. It is only used in one function,
so there's nothing it could possibly protect.

2.) All these test_and_clear_bit and test_and_set_bit calls are also
unnecessary. We can simply use enable_irq and disable_irq in both the
irq handler and in uio_pdrv_genirq_irqcontrol.

We should go back to the roots and have a look at how UIO works.
The workflow it is intended for is like this:

1.) Hardware is in Reset State (e.g. after boot). Any decent hardware
has its interrupt disabled at that time.

2.) uio_pdrv_genirq is loaded. Kernel enables the irq.

3.) Userspace part of the driver comes up. It will initialize the hardware
(including setting the bits that enable the interrupt).

4.) Userspace will then issue a blocking read() on /dev/uioX. Typically,
there'll be a loop or a thread with this blocking read() at the beginning
(usually using the select() call).

5.) At some time, a hardware interrupt will occur. The irq handler in kernel
space will be called, only to disable the irq. This will also cause the UIO
core to make /dev/uioX readable.

6.) Userspace's blocking read returns. Userspace does its work by
reading/writing device memory.

7.) As the last thing, Userspace writes a 1 to /dev/uioX, which causes
uio_pdrv_genirq_irqcontrol to be called, re-enabling the interrupt.

8.) Goto 4.)

We should also remember that uio_pdrv_genirq_handler() is NOT a real hardware
irq handler. The real handler is in the UIO core, which will increment the
event number and wake up userspace.

So, although your scenario clearly shows a subtle race condition, there is
none. If userspace does stupid things, no harm will be done to the kernel.
If userspace is designed the way described above (and in the documentation),
it will always wake up with its interrupt disabled, do its work, and then
re-enable the interrupt. You can probably think of a few things userspace
could do to screw things up. But that's not our problem.

Could you hack up a patch for that? I think it should start with removing
uio_pdrv_genirq_platdata-lock and uio_pdrv_genirq_platdata-flags...

Thanks again for your work. What do you think about my theory?

Thanks,
Hans

--
To unsubscribe from this list: send the 

Re: [PATCH v2 1/1] uio.c: solve memory leak

2012-12-07 Thread Hans J. Koch
On Fri, Dec 07, 2012 at 12:02:11AM +0100, Cong Ding wrote:
 ping Hans, did you have any comment on this?

Sounds right what you say. Is your patch v2 your final solution, or would
you like to come up with v3?

Thanks a lot for your patience and your thorough analysis.

Hans

 
 - cong
 
 On Fri, Nov 30, 2012 at 12:03 PM, Cong Ding ding...@gmail.com wrote:
  Hi Hans, I think the memory allocated with kzalloc is properly freed
  by calling kobject_put.
 
  I can give a simple explanation.
 
  1)  when we call kobject_init, the parameter portio_attr_type is
  passed in. portio_attr_type includes a function pointer to
  portio_release, which releases the memory of portio.
 
  2) when we call kobject_put, kref_put is called with the pointer of
  function kobject_release.
  3) kref_put calls kref_sub, with the same pointer of function 
  kobject_release.
  4) and kref_put calls the function kboject_release if
  atomic_sub_and_test returns true
 
  5) let's look at what kobject_release is. it calls kobject_cleanup,
  and kobject_cleanup calls t-release(kobj) where t-release is exactly
  the function we passed in through portio_init at step (1). so function
  portio_release is called, and the memory allocated with kzalloc is
  freed.
 
  If there are anything wrong in my analysis, please feel free to let me know.
 
  Personally, I suggest to add a function to create and release
  uio_portio, which is similar as kobject_create and kobject_put in file
  lib/kobject.c. In this way, it avoid other readers thinking the memory
  is not freed (and we should add some comments here). For example,
  uio_portio_create call kzalloc and kboject_init, and returns
  uio_portio, which is similar as function kobject_create; and
  uio_portio_release calls kobject_put to release the memory. And we do
  same thing for uio_map.
 
  The usage here is quite strange, but it works. If I write this
  function from zero, I will use a pointer to kobject in uio_portio
  struct instead of kobject struct itself. In this case I can call
  kobject_create instead of kobject_init, and then we do both
  kzalloc(uio_portio) and kfree(uio_portio) in the file uio.c.
 
  Best,
  Cong
 
  On Fri, Nov 30, 2012 at 1:13 AM, Hans J. Koch h...@hansjkoch.de wrote:
  There's still another bug: The memory allocated with kzalloc is
  never freed.
 
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/2] uio: be aware of open(), mmap(), close()

2012-12-06 Thread Hans J. Koch
On Thu, Dec 06, 2012 at 01:44:56PM +0100, Benedikt Spranger wrote:
> After open(), mmap(), close() the mmaped pointer is valid. Removing the
> underlaying module causes a Oops or other strange effects. Keep all structures
> valid till the last user is gone.
> 
> Signed-off-by: Benedikt Spranger 
> ---
>  drivers/uio/uio.c |   59 
> ++---
>  drivers/uio/uio_pdrv_genirq.c |4 +--
>  include/linux/uio_driver.h|4 +--
>  3 files changed, 48 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
> index 5110f36..b96499a 100644
> --- a/drivers/uio/uio.c
> +++ b/drivers/uio/uio.c
> @@ -433,8 +433,22 @@ static irqreturn_t uio_interrupt(int irq, void *dev_id)
>  struct uio_listener {
>   struct uio_device *dev;
>   s32 event_count;
> + struct kref kref;
>  };
>  
> +static void uio_release_listener(struct kref *kref)
> +{
> + struct uio_listener *listener = container_of(kref, struct uio_listener,
> +  kref);
> + struct uio_device *idev = listener->dev;
> +
> + if (idev->info->release)
> + idev->info->release(idev->info);
> +
> + module_put(idev->owner);
> + kfree(listener);
> +}
> +
>  static int uio_open(struct inode *inode, struct file *filep)
>  {
>   struct uio_device *idev;
> @@ -465,10 +479,13 @@ static int uio_open(struct inode *inode, struct file 
> *filep)
>   filep->private_data = listener;
>  
>   if (idev->info->open) {
> - ret = idev->info->open(idev->info, inode);
> + ret = idev->info->open(idev->info);
>   if (ret)
>   goto err_infoopen;
>   }
> +
> + kref_init(>kref);
> +
>   return 0;
>  
>  err_infoopen:
> @@ -491,16 +508,11 @@ static int uio_fasync(int fd, struct file *filep, int 
> on)
>  
>  static int uio_release(struct inode *inode, struct file *filep)
>  {
> - int ret = 0;
>   struct uio_listener *listener = filep->private_data;
> - struct uio_device *idev = listener->dev;
>  
> - if (idev->info->release)
> - ret = idev->info->release(idev->info, inode);
> + kref_put(>kref, uio_release_listener);
>  
> - module_put(idev->owner);
> - kfree(listener);
> - return ret;
> + return 0;
>  }
>  
>  static unsigned int uio_poll(struct file *filep, poll_table *wait)
> @@ -605,19 +617,22 @@ static int uio_find_mem_index(struct vm_area_struct 
> *vma)
>  
>  static void uio_vma_open(struct vm_area_struct *vma)
>  {
> - struct uio_device *idev = vma->vm_private_data;
> - idev->vma_count++;
> + struct uio_listener *listener = vma->vm_private_data;
> +
> + kref_get(>kref);
>  }
>  
>  static void uio_vma_close(struct vm_area_struct *vma)
>  {
> - struct uio_device *idev = vma->vm_private_data;
> - idev->vma_count--;
> + struct uio_listener *listener = vma->vm_private_data;
> +
> + kref_put(>kref, uio_release_listener);
>  }
>  
>  static int uio_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
>  {
> - struct uio_device *idev = vma->vm_private_data;
> + struct uio_listener *listener = vma->vm_private_data;
> + struct uio_device *idev = listener->dev;
>   struct page *page;
>   unsigned long offset;
>  
> @@ -646,20 +661,34 @@ static const struct vm_operations_struct uio_vm_ops = {
>   .fault = uio_vma_fault,
>  };
>  
> +static const struct vm_operations_struct uio_phys_ops = {
> + .open = uio_vma_open,
> + .close = uio_vma_close,
> +};
> +
>  static int uio_mmap_physical(struct vm_area_struct *vma)
>  {
>   struct uio_device *idev = vma->vm_private_data;
>   int mi = uio_find_mem_index(vma);
> + int ret;
> +
>   if (mi < 0)
>   return -EINVAL;
>  
>   vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
> + vma->vm_ops = _phys_ops;
>  
> - return remap_pfn_range(vma,
> + ret = remap_pfn_range(vma,
>  vma->vm_start,
>  idev->info->mem[mi].addr >> PAGE_SHIFT,
>  vma->vm_end - vma->vm_start,
>  vma->vm_page_prot);
> + if (ret)
> + return ret;
> +
> + uio_vma_open(vma);
> +
> + return 0;
>  }
>  
>  static int uio_mmap_logical(struct vm_area_struct *vma)
> @@ -681,7 +710,7 @@ static int uio_mmap(struct file *filep, struct 
> vm_area_struct *vma)
>   if (vma->vm_end < vma->vm_start)
>   return -EINVAL;
>  
> - vma->vm_private_data = idev;
> + vma->vm_private_data = listener;
>  
>   mi = uio_find_mem_index(vma);
>   if (mi < 0)
> diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c
> index 42202cd..a4e32fa 100644
> --- a/drivers/uio/uio_pdrv_genirq.c
> +++ b/drivers/uio/uio_pdrv_genirq.c
> @@ -37,7 +37,7 @@ struct uio_pdrv_genirq_platdata {
>   struct platform_device *pdev;
>  };
>  
> -static 

Re: [PATCH 2/2] uio: avoid module unloding of in module created UIO devices

2012-12-06 Thread Hans J. Koch
On Thu, Dec 06, 2012 at 01:44:57PM +0100, Benedikt Spranger wrote:
> A kernel module can create a uio device. Get a reference to the module, if the
> UIO device is in use. Otherwise the device can be removed and a uio write or 
> an
> access to am mmaped memory can cause a kernel Oops or other strange effects.
> 
> Signed-off-by: Benedikt Spranger 
> ---
>  drivers/uio/uio.c  |8 
>  include/linux/uio_driver.h |1 +
>  2 files changed, 9 insertions(+)
> 
> diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
> index b96499a..3b62da0 100644
> --- a/drivers/uio/uio.c
> +++ b/drivers/uio/uio.c
> @@ -446,6 +446,7 @@ static void uio_release_listener(struct kref *kref)
>   idev->info->release(idev->info);
>  
>   module_put(idev->owner);
> + module_put(idev->info->owner);
>   kfree(listener);
>  }
>  
> @@ -468,6 +469,11 @@ static int uio_open(struct inode *inode, struct file 
> *filep)
>   goto out;
>   }
>  
> + if (!try_module_get(idev->info->owner)) {
> + ret = -ENODEV;
> + goto err_get_module;
> + }
> +
>   listener = kmalloc(sizeof(*listener), GFP_KERNEL);
>   if (!listener) {
>   ret = -ENOMEM;
> @@ -493,6 +499,8 @@ err_infoopen:
>  
>  err_alloc_listener:
>   module_put(idev->owner);
> +err_get_module:
> + module_put(idev->owner);
>  
>  out:
>   return ret;
> diff --git a/include/linux/uio_driver.h b/include/linux/uio_driver.h
> index 1bc6493..2862de23 100644
> --- a/include/linux/uio_driver.h
> +++ b/include/linux/uio_driver.h
> @@ -95,6 +95,7 @@ struct uio_info {
>   int (*open)(struct uio_info *info);
>   void (*release)(struct uio_info *info);
>   int (*irqcontrol)(struct uio_info *info, s32 irq_on);
> + struct module   *owner;

Where is that needed? I won't add a new element to struct uio_info without
an in-kernel user.

Thanks,
Hans
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2] drivers/uio/uio_pdrv_genirq.c: Fix memory freeing issues

2012-12-06 Thread Hans J. Koch
On Thu, Dec 06, 2012 at 11:11:38AM +0200, Vitalii Demianets wrote:
> On Thursday 06 December 2012 04:41:01 Hans J. Koch wrote:
> > > @@ -63,7 +68,7 @@ static irqreturn_t uio_pdrv_genirq_handler(int irq, 
> struct uio_info *dev_info)
> > >* remember the state so we can allow user space to enable it later.
> > >*/
> > >  
> > > - if (!test_and_set_bit(0, >flags))
> > > + if (!test_and_set_bit(UIO_IRQ_DISABLED, >flags))
> > >   disable_irq_nosync(irq);
> > 
> > That is not safe. That flag can only be changed by userspace, and if the
> > userspace part is not running, the CPU on which the irq is pending will
> > hang. 
> > The handler has to disable the interrupt in any case.
> > (The original version had the same problem, I know...)
> > 
> 
> Perhaps I'm missing something here, but I don't see your point. If userspace 
> is not (implicitly) calling uio_pdrv_genirq_irqcontrol() by writing to the 
> device file, then on the first invocation of interrupt handler that IRQ is 
> disabled by disable_irq_nosync() and that's the end of story - no more irqs, 
> no problems. Until userspace writes non-zero to the device file, of course.

If you run into the irq handler, the interrupt was obviously enabled. Since
irq sharing is not supported by this driver, you ALWAYS have to disable it
because it IS your interrupt. Storing the enabled/disabled status in a
variable is not needed at all here. Or am I missing something?

> 
> > >   priv->uioinfo = uioinfo;
> > >   spin_lock_init(>lock);
> > > - priv->flags = 0; /* interrupt is enabled to begin with */
> > > + /* interrupt is enabled to begin with */
> > > + priv->flags = uioinfo_alloced ? (1 << UIO_INFO_ALLOCED) : 0;
> > 
> > The comment doesn't describe the line it's supposed to comment.
> > 
> 
> The comment draws attention to the fact that UIO_IRQ_DISABLED is not set 
> initially, and this is done on purpose.

And that's right because the interrupt is initially enabled by
uio_register_device().

> Particularly it is done because of 
> the potential problem you noted earlier - if userspace is never setting this 
> flag, the interrupt handler will disable irq on the first invocation thanks 
> to the absence of the flag (if(!test_and_set_bit(UIO_IRQ_DISABLED,...) will 
> succeed).
> So, I think we really need some comment explaining how the things are 
> arranged 
> here; after all even you haven't got the whole picture on the first glance.
> Maybe the current wording of the comment is not the best. I've just left what 
> was there before.

OK, but we humans tend to read a text from top to bottom, so a comment should
describe the code immediately following it. And that is a line that deals with
memory allocation, not with interrupts.

Thanks,
Hans
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2] drivers/uio/uio_pdrv_genirq.c: Fix memory freeing issues

2012-12-06 Thread Hans J. Koch
On Thu, Dec 06, 2012 at 11:11:38AM +0200, Vitalii Demianets wrote:
 On Thursday 06 December 2012 04:41:01 Hans J. Koch wrote:
   @@ -63,7 +68,7 @@ static irqreturn_t uio_pdrv_genirq_handler(int irq, 
 struct uio_info *dev_info)
  * remember the state so we can allow user space to enable it later.
  */

   - if (!test_and_set_bit(0, priv-flags))
   + if (!test_and_set_bit(UIO_IRQ_DISABLED, priv-flags))
 disable_irq_nosync(irq);
  
  That is not safe. That flag can only be changed by userspace, and if the
  userspace part is not running, the CPU on which the irq is pending will
  hang. 
  The handler has to disable the interrupt in any case.
  (The original version had the same problem, I know...)
  
 
 Perhaps I'm missing something here, but I don't see your point. If userspace 
 is not (implicitly) calling uio_pdrv_genirq_irqcontrol() by writing to the 
 device file, then on the first invocation of interrupt handler that IRQ is 
 disabled by disable_irq_nosync() and that's the end of story - no more irqs, 
 no problems. Until userspace writes non-zero to the device file, of course.

If you run into the irq handler, the interrupt was obviously enabled. Since
irq sharing is not supported by this driver, you ALWAYS have to disable it
because it IS your interrupt. Storing the enabled/disabled status in a
variable is not needed at all here. Or am I missing something?

 
 priv-uioinfo = uioinfo;
 spin_lock_init(priv-lock);
   - priv-flags = 0; /* interrupt is enabled to begin with */
   + /* interrupt is enabled to begin with */
   + priv-flags = uioinfo_alloced ? (1  UIO_INFO_ALLOCED) : 0;
  
  The comment doesn't describe the line it's supposed to comment.
  
 
 The comment draws attention to the fact that UIO_IRQ_DISABLED is not set 
 initially, and this is done on purpose.

And that's right because the interrupt is initially enabled by
uio_register_device().

 Particularly it is done because of 
 the potential problem you noted earlier - if userspace is never setting this 
 flag, the interrupt handler will disable irq on the first invocation thanks 
 to the absence of the flag (if(!test_and_set_bit(UIO_IRQ_DISABLED,...) will 
 succeed).
 So, I think we really need some comment explaining how the things are 
 arranged 
 here; after all even you haven't got the whole picture on the first glance.
 Maybe the current wording of the comment is not the best. I've just left what 
 was there before.

OK, but we humans tend to read a text from top to bottom, so a comment should
describe the code immediately following it. And that is a line that deals with
memory allocation, not with interrupts.

Thanks,
Hans
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/2] uio: avoid module unloding of in module created UIO devices

2012-12-06 Thread Hans J. Koch
On Thu, Dec 06, 2012 at 01:44:57PM +0100, Benedikt Spranger wrote:
 A kernel module can create a uio device. Get a reference to the module, if the
 UIO device is in use. Otherwise the device can be removed and a uio write or 
 an
 access to am mmaped memory can cause a kernel Oops or other strange effects.
 
 Signed-off-by: Benedikt Spranger b.spran...@linutronix.de
 ---
  drivers/uio/uio.c  |8 
  include/linux/uio_driver.h |1 +
  2 files changed, 9 insertions(+)
 
 diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
 index b96499a..3b62da0 100644
 --- a/drivers/uio/uio.c
 +++ b/drivers/uio/uio.c
 @@ -446,6 +446,7 @@ static void uio_release_listener(struct kref *kref)
   idev-info-release(idev-info);
  
   module_put(idev-owner);
 + module_put(idev-info-owner);
   kfree(listener);
  }
  
 @@ -468,6 +469,11 @@ static int uio_open(struct inode *inode, struct file 
 *filep)
   goto out;
   }
  
 + if (!try_module_get(idev-info-owner)) {
 + ret = -ENODEV;
 + goto err_get_module;
 + }
 +
   listener = kmalloc(sizeof(*listener), GFP_KERNEL);
   if (!listener) {
   ret = -ENOMEM;
 @@ -493,6 +499,8 @@ err_infoopen:
  
  err_alloc_listener:
   module_put(idev-owner);
 +err_get_module:
 + module_put(idev-owner);
  
  out:
   return ret;
 diff --git a/include/linux/uio_driver.h b/include/linux/uio_driver.h
 index 1bc6493..2862de23 100644
 --- a/include/linux/uio_driver.h
 +++ b/include/linux/uio_driver.h
 @@ -95,6 +95,7 @@ struct uio_info {
   int (*open)(struct uio_info *info);
   void (*release)(struct uio_info *info);
   int (*irqcontrol)(struct uio_info *info, s32 irq_on);
 + struct module   *owner;

Where is that needed? I won't add a new element to struct uio_info without
an in-kernel user.

Thanks,
Hans
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/2] uio: be aware of open(), mmap(), close()

2012-12-06 Thread Hans J. Koch
On Thu, Dec 06, 2012 at 01:44:56PM +0100, Benedikt Spranger wrote:
 After open(), mmap(), close() the mmaped pointer is valid. Removing the
 underlaying module causes a Oops or other strange effects. Keep all structures
 valid till the last user is gone.
 
 Signed-off-by: Benedikt Spranger b.spran...@linutronix.de
 ---
  drivers/uio/uio.c |   59 
 ++---
  drivers/uio/uio_pdrv_genirq.c |4 +--
  include/linux/uio_driver.h|4 +--
  3 files changed, 48 insertions(+), 19 deletions(-)
 
 diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
 index 5110f36..b96499a 100644
 --- a/drivers/uio/uio.c
 +++ b/drivers/uio/uio.c
 @@ -433,8 +433,22 @@ static irqreturn_t uio_interrupt(int irq, void *dev_id)
  struct uio_listener {
   struct uio_device *dev;
   s32 event_count;
 + struct kref kref;
  };
  
 +static void uio_release_listener(struct kref *kref)
 +{
 + struct uio_listener *listener = container_of(kref, struct uio_listener,
 +  kref);
 + struct uio_device *idev = listener-dev;
 +
 + if (idev-info-release)
 + idev-info-release(idev-info);
 +
 + module_put(idev-owner);
 + kfree(listener);
 +}
 +
  static int uio_open(struct inode *inode, struct file *filep)
  {
   struct uio_device *idev;
 @@ -465,10 +479,13 @@ static int uio_open(struct inode *inode, struct file 
 *filep)
   filep-private_data = listener;
  
   if (idev-info-open) {
 - ret = idev-info-open(idev-info, inode);
 + ret = idev-info-open(idev-info);
   if (ret)
   goto err_infoopen;
   }
 +
 + kref_init(listener-kref);
 +
   return 0;
  
  err_infoopen:
 @@ -491,16 +508,11 @@ static int uio_fasync(int fd, struct file *filep, int 
 on)
  
  static int uio_release(struct inode *inode, struct file *filep)
  {
 - int ret = 0;
   struct uio_listener *listener = filep-private_data;
 - struct uio_device *idev = listener-dev;
  
 - if (idev-info-release)
 - ret = idev-info-release(idev-info, inode);
 + kref_put(listener-kref, uio_release_listener);
  
 - module_put(idev-owner);
 - kfree(listener);
 - return ret;
 + return 0;
  }
  
  static unsigned int uio_poll(struct file *filep, poll_table *wait)
 @@ -605,19 +617,22 @@ static int uio_find_mem_index(struct vm_area_struct 
 *vma)
  
  static void uio_vma_open(struct vm_area_struct *vma)
  {
 - struct uio_device *idev = vma-vm_private_data;
 - idev-vma_count++;
 + struct uio_listener *listener = vma-vm_private_data;
 +
 + kref_get(listener-kref);
  }
  
  static void uio_vma_close(struct vm_area_struct *vma)
  {
 - struct uio_device *idev = vma-vm_private_data;
 - idev-vma_count--;
 + struct uio_listener *listener = vma-vm_private_data;
 +
 + kref_put(listener-kref, uio_release_listener);
  }
  
  static int uio_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
  {
 - struct uio_device *idev = vma-vm_private_data;
 + struct uio_listener *listener = vma-vm_private_data;
 + struct uio_device *idev = listener-dev;
   struct page *page;
   unsigned long offset;
  
 @@ -646,20 +661,34 @@ static const struct vm_operations_struct uio_vm_ops = {
   .fault = uio_vma_fault,
  };
  
 +static const struct vm_operations_struct uio_phys_ops = {
 + .open = uio_vma_open,
 + .close = uio_vma_close,
 +};
 +
  static int uio_mmap_physical(struct vm_area_struct *vma)
  {
   struct uio_device *idev = vma-vm_private_data;
   int mi = uio_find_mem_index(vma);
 + int ret;
 +
   if (mi  0)
   return -EINVAL;
  
   vma-vm_page_prot = pgprot_noncached(vma-vm_page_prot);
 + vma-vm_ops = uio_phys_ops;
  
 - return remap_pfn_range(vma,
 + ret = remap_pfn_range(vma,
  vma-vm_start,
  idev-info-mem[mi].addr  PAGE_SHIFT,
  vma-vm_end - vma-vm_start,
  vma-vm_page_prot);
 + if (ret)
 + return ret;
 +
 + uio_vma_open(vma);
 +
 + return 0;
  }
  
  static int uio_mmap_logical(struct vm_area_struct *vma)
 @@ -681,7 +710,7 @@ static int uio_mmap(struct file *filep, struct 
 vm_area_struct *vma)
   if (vma-vm_end  vma-vm_start)
   return -EINVAL;
  
 - vma-vm_private_data = idev;
 + vma-vm_private_data = listener;
  
   mi = uio_find_mem_index(vma);
   if (mi  0)
 diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c
 index 42202cd..a4e32fa 100644
 --- a/drivers/uio/uio_pdrv_genirq.c
 +++ b/drivers/uio/uio_pdrv_genirq.c
 @@ -37,7 +37,7 @@ struct uio_pdrv_genirq_platdata {
   struct platform_device *pdev;
  };
  
 -static int uio_pdrv_genirq_open(struct uio_info *info, struct inode *inode)
 +static int uio_pdrv_genirq_open(struct uio_info *info)
  {
   struct 

Re: [PATCH v2] drivers/uio/uio_pdrv_genirq.c: Fix memory freeing issues

2012-12-05 Thread Hans J. Koch
On Wed, Dec 05, 2012 at 11:22:57AM +0200, Vitalii Demianets wrote:
> 1. uioinfo was kfreed based on the presence of pdev->dev.of_node, which was
> obviously wrong and unrelated to the fact if uioinfo was allocated statically
> or dynamically. This patch introduces new flag which clearly shows if uioinfo
> was allocated dynamically and kfrees uioinfo based on that flag;
> 2. Fix: priv data was not freed in case platform_get_irq() failed. As it was
> caused mainly by improper exit labels naming, labels were renamed too;
> 3. The case of uioinfo AND pdev->dev.of_node both NULL (not initialized
> in platform data) was not treated properly.

I noticed two more issues. See below.

> 
> Signed-off-by: Vitalii Demianets 
> 
> ---
> v2: Constants naming style
> 
> ---
>  drivers/uio/uio_pdrv_genirq.c |   44 
>  1 files changed, 26 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c
> index 42202cd..75aaeee 100644
> --- a/drivers/uio/uio_pdrv_genirq.c
> +++ b/drivers/uio/uio_pdrv_genirq.c
> @@ -30,6 +30,11 @@
>  
>  #define DRIVER_NAME "uio_pdrv_genirq"
>  
> +enum {
> + UIO_IRQ_DISABLED = 0,
> + UIO_INFO_ALLOCED = 1,
> +};
> +
>  struct uio_pdrv_genirq_platdata {
>   struct uio_info *uioinfo;
>   spinlock_t lock;
> @@ -63,7 +68,7 @@ static irqreturn_t uio_pdrv_genirq_handler(int irq, struct 
> uio_info *dev_info)
>* remember the state so we can allow user space to enable it later.
>*/
>  
> - if (!test_and_set_bit(0, >flags))
> + if (!test_and_set_bit(UIO_IRQ_DISABLED, >flags))
>   disable_irq_nosync(irq);

That is not safe. That flag can only be changed by userspace, and if the
userspace part is not running, the CPU on which the irq is pending will hang.
The handler has to disable the interrupt in any case.
(The original version had the same problem, I know...)

>  
>   return IRQ_HANDLED;
> @@ -83,10 +88,10 @@ static int uio_pdrv_genirq_irqcontrol(struct uio_info 
> *dev_info, s32 irq_on)
>  
>   spin_lock_irqsave(>lock, flags);
>   if (irq_on) {
> - if (test_and_clear_bit(0, >flags))
> + if (test_and_clear_bit(UIO_IRQ_DISABLED, >flags))
>   enable_irq(dev_info->irq);
>   } else {
> - if (!test_and_set_bit(0, >flags))
> + if (!test_and_set_bit(UIO_IRQ_DISABLED, >flags))
>   disable_irq(dev_info->irq);
>   }
>   spin_unlock_irqrestore(>lock, flags);
> @@ -101,8 +106,9 @@ static int uio_pdrv_genirq_probe(struct platform_device 
> *pdev)
>   struct uio_mem *uiomem;
>   int ret = -EINVAL;
>   int i;
> + bool uioinfo_alloced = false;
>  
> - if (!uioinfo) {
> + if (!uioinfo && pdev->dev.of_node) {
>   int irq;
>  
>   /* alloc uioinfo for one device */
> @@ -110,10 +116,11 @@ static int uio_pdrv_genirq_probe(struct platform_device 
> *pdev)
>   if (!uioinfo) {
>   ret = -ENOMEM;
>   dev_err(>dev, "unable to kmalloc\n");
> - goto bad2;
> + goto out;
>   }
>   uioinfo->name = pdev->dev.of_node->name;
>   uioinfo->version = "devicetree";
> + uioinfo_alloced = true;
>  
>   /* Multiple IRQs are not supported */
>   irq = platform_get_irq(pdev, 0);
> @@ -125,32 +132,33 @@ static int uio_pdrv_genirq_probe(struct platform_device 
> *pdev)
>  
>   if (!uioinfo || !uioinfo->name || !uioinfo->version) {
>   dev_err(>dev, "missing platform_data\n");
> - goto bad0;
> + goto out_uioinfo;
>   }
>  
>   if (uioinfo->handler || uioinfo->irqcontrol ||
>   uioinfo->irq_flags & IRQF_SHARED) {
>   dev_err(>dev, "interrupt configuration error\n");
> - goto bad0;
> + goto out_uioinfo;
>   }
>  
>   priv = kzalloc(sizeof(*priv), GFP_KERNEL);
>   if (!priv) {
>   ret = -ENOMEM;
>   dev_err(>dev, "unable to kmalloc\n");
> - goto bad0;
> + goto out_uioinfo;
>   }
>  
>   priv->uioinfo = uioinfo;
>   spin_lock_init(>lock);
> - priv->flags = 0; /* interrupt is enabled to begin with */
> + /* interrupt is enabled to begin with */
> + priv->flags = uioinfo_alloced ? (1 << UIO_INFO_ALLOCED) : 0;

The comment doesn't describe the line it's supposed to comment.

>   priv->pdev = pdev;
>  
>   if (!uioinfo->irq) {
>   ret = platform_get_irq(pdev, 0);
>   if (ret < 0) {
>   dev_err(>dev, "failed to get IRQ\n");
> - goto bad0;
> + goto out_priv;
>   }
>   uioinfo->irq = ret;
>   }
> @@ -205,19 +213,19 @@ static int uio_pdrv_genirq_probe(struct platform_device 
> *pdev)
>   ret = 

Re: [PATCH v2] drivers/uio/uio_pdrv_genirq.c: Fix memory freeing issues

2012-12-05 Thread Hans J. Koch
On Wed, Dec 05, 2012 at 11:22:57AM +0200, Vitalii Demianets wrote:
 1. uioinfo was kfreed based on the presence of pdev-dev.of_node, which was
 obviously wrong and unrelated to the fact if uioinfo was allocated statically
 or dynamically. This patch introduces new flag which clearly shows if uioinfo
 was allocated dynamically and kfrees uioinfo based on that flag;
 2. Fix: priv data was not freed in case platform_get_irq() failed. As it was
 caused mainly by improper exit labels naming, labels were renamed too;
 3. The case of uioinfo AND pdev-dev.of_node both NULL (not initialized
 in platform data) was not treated properly.

I noticed two more issues. See below.

 
 Signed-off-by: Vitalii Demianets vi...@nppfactor.kiev.ua
 
 ---
 v2: Constants naming style
 
 ---
  drivers/uio/uio_pdrv_genirq.c |   44 
  1 files changed, 26 insertions(+), 18 deletions(-)
 
 diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c
 index 42202cd..75aaeee 100644
 --- a/drivers/uio/uio_pdrv_genirq.c
 +++ b/drivers/uio/uio_pdrv_genirq.c
 @@ -30,6 +30,11 @@
  
  #define DRIVER_NAME uio_pdrv_genirq
  
 +enum {
 + UIO_IRQ_DISABLED = 0,
 + UIO_INFO_ALLOCED = 1,
 +};
 +
  struct uio_pdrv_genirq_platdata {
   struct uio_info *uioinfo;
   spinlock_t lock;
 @@ -63,7 +68,7 @@ static irqreturn_t uio_pdrv_genirq_handler(int irq, struct 
 uio_info *dev_info)
* remember the state so we can allow user space to enable it later.
*/
  
 - if (!test_and_set_bit(0, priv-flags))
 + if (!test_and_set_bit(UIO_IRQ_DISABLED, priv-flags))
   disable_irq_nosync(irq);

That is not safe. That flag can only be changed by userspace, and if the
userspace part is not running, the CPU on which the irq is pending will hang.
The handler has to disable the interrupt in any case.
(The original version had the same problem, I know...)

  
   return IRQ_HANDLED;
 @@ -83,10 +88,10 @@ static int uio_pdrv_genirq_irqcontrol(struct uio_info 
 *dev_info, s32 irq_on)
  
   spin_lock_irqsave(priv-lock, flags);
   if (irq_on) {
 - if (test_and_clear_bit(0, priv-flags))
 + if (test_and_clear_bit(UIO_IRQ_DISABLED, priv-flags))
   enable_irq(dev_info-irq);
   } else {
 - if (!test_and_set_bit(0, priv-flags))
 + if (!test_and_set_bit(UIO_IRQ_DISABLED, priv-flags))
   disable_irq(dev_info-irq);
   }
   spin_unlock_irqrestore(priv-lock, flags);
 @@ -101,8 +106,9 @@ static int uio_pdrv_genirq_probe(struct platform_device 
 *pdev)
   struct uio_mem *uiomem;
   int ret = -EINVAL;
   int i;
 + bool uioinfo_alloced = false;
  
 - if (!uioinfo) {
 + if (!uioinfo  pdev-dev.of_node) {
   int irq;
  
   /* alloc uioinfo for one device */
 @@ -110,10 +116,11 @@ static int uio_pdrv_genirq_probe(struct platform_device 
 *pdev)
   if (!uioinfo) {
   ret = -ENOMEM;
   dev_err(pdev-dev, unable to kmalloc\n);
 - goto bad2;
 + goto out;
   }
   uioinfo-name = pdev-dev.of_node-name;
   uioinfo-version = devicetree;
 + uioinfo_alloced = true;
  
   /* Multiple IRQs are not supported */
   irq = platform_get_irq(pdev, 0);
 @@ -125,32 +132,33 @@ static int uio_pdrv_genirq_probe(struct platform_device 
 *pdev)
  
   if (!uioinfo || !uioinfo-name || !uioinfo-version) {
   dev_err(pdev-dev, missing platform_data\n);
 - goto bad0;
 + goto out_uioinfo;
   }
  
   if (uioinfo-handler || uioinfo-irqcontrol ||
   uioinfo-irq_flags  IRQF_SHARED) {
   dev_err(pdev-dev, interrupt configuration error\n);
 - goto bad0;
 + goto out_uioinfo;
   }
  
   priv = kzalloc(sizeof(*priv), GFP_KERNEL);
   if (!priv) {
   ret = -ENOMEM;
   dev_err(pdev-dev, unable to kmalloc\n);
 - goto bad0;
 + goto out_uioinfo;
   }
  
   priv-uioinfo = uioinfo;
   spin_lock_init(priv-lock);
 - priv-flags = 0; /* interrupt is enabled to begin with */
 + /* interrupt is enabled to begin with */
 + priv-flags = uioinfo_alloced ? (1  UIO_INFO_ALLOCED) : 0;

The comment doesn't describe the line it's supposed to comment.

   priv-pdev = pdev;
  
   if (!uioinfo-irq) {
   ret = platform_get_irq(pdev, 0);
   if (ret  0) {
   dev_err(pdev-dev, failed to get IRQ\n);
 - goto bad0;
 + goto out_priv;
   }
   uioinfo-irq = ret;
   }
 @@ -205,19 +213,19 @@ static int uio_pdrv_genirq_probe(struct platform_device 
 *pdev)
   ret = uio_register_device(pdev-dev, priv-uioinfo);
   if (ret) {
   dev_err(pdev-dev, 

Re: [PATCH] drivers/uio/uio_pdrv_genirq.c: Fix memory freeing issues

2012-12-04 Thread Hans J. Koch
On Thu, Nov 29, 2012 at 01:47:28PM +0200, Vitalii Demianets wrote:
> 1. uioinfo was kfreed based on the presence of pdev->dev.of_node, which was
> obviously wrong and unrelated to the fact if uioinfo was allocated statically
> or dynamically. This patch introduces new flag which clearly shows if uioinfo
> was allocated dynamically and kfrees uioinfo based on that flag;
> 2. Fix: priv data was not freed in case platform_get_irq() failed. As it was
> caused mainly by improper exit labels naming, labels were renamed too;
> 3. The case of uioinfo AND pdev->dev.of_node both NULL (not initialized
> in platform data) was not treated properly.

Your arguments sound right to me. But there are some minor issues, see below.

Otherwise looks good.
Thanks,
Hans

> 
> Signed-off-by: Vitalii Demianets 
> ---
>  drivers/uio/uio_pdrv_genirq.c |   44 
>  1 files changed, 26 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c
> index 42202cd..45126e3 100644
> --- a/drivers/uio/uio_pdrv_genirq.c
> +++ b/drivers/uio/uio_pdrv_genirq.c
> @@ -30,6 +30,11 @@
>  
>  #define DRIVER_NAME "uio_pdrv_genirq"
>  
> +enum {
> + bitIRQDisabled = 0,
> + bitUioinfoAlloced = 1,

Please do not use CamelCase. This is neither Windows nor C++ or Java.
And you don't need to tell users about the type (like "bit"). That should
be clear by looking at the code. I'd prefer UPPERCASE to make it clear that
these are constants, e.g. IRQ_IS_DISABLED and UIO_INFO_IS_ALLOCATED or
something like that.

> +};
> +
>  struct uio_pdrv_genirq_platdata {
>   struct uio_info *uioinfo;
>   spinlock_t lock;
> @@ -63,7 +68,7 @@ static irqreturn_t uio_pdrv_genirq_handler(int irq, struct 
> uio_info *dev_info)
>* remember the state so we can allow user space to enable it later.
>*/
>  
> - if (!test_and_set_bit(0, >flags))
> + if (!test_and_set_bit(bitIRQDisabled, >flags))
>   disable_irq_nosync(irq);
>  
>   return IRQ_HANDLED;
> @@ -83,10 +88,10 @@ static int uio_pdrv_genirq_irqcontrol(struct uio_info 
> *dev_info, s32 irq_on)
>  
>   spin_lock_irqsave(>lock, flags);
>   if (irq_on) {
> - if (test_and_clear_bit(0, >flags))
> + if (test_and_clear_bit(bitIRQDisabled, >flags))
>   enable_irq(dev_info->irq);
>   } else {
> - if (!test_and_set_bit(0, >flags))
> + if (!test_and_set_bit(bitIRQDisabled, >flags))
>   disable_irq(dev_info->irq);
>   }
>   spin_unlock_irqrestore(>lock, flags);
> @@ -101,8 +106,9 @@ static int uio_pdrv_genirq_probe(struct platform_device 
> *pdev)
>   struct uio_mem *uiomem;
>   int ret = -EINVAL;
>   int i;
> + bool uioinfo_alloced = false;
>  
> - if (!uioinfo) {
> + if (!uioinfo && pdev->dev.of_node) {
>   int irq;
>  
>   /* alloc uioinfo for one device */
> @@ -110,10 +116,11 @@ static int uio_pdrv_genirq_probe(struct platform_device 
> *pdev)
>   if (!uioinfo) {
>   ret = -ENOMEM;
>   dev_err(>dev, "unable to kmalloc\n");
> - goto bad2;
> + goto out;
>   }
>   uioinfo->name = pdev->dev.of_node->name;
>   uioinfo->version = "devicetree";
> + uioinfo_alloced = true;
>  
>   /* Multiple IRQs are not supported */
>   irq = platform_get_irq(pdev, 0);
> @@ -125,32 +132,33 @@ static int uio_pdrv_genirq_probe(struct platform_device 
> *pdev)
>  
>   if (!uioinfo || !uioinfo->name || !uioinfo->version) {
>   dev_err(>dev, "missing platform_data\n");
> - goto bad0;
> + goto out_uioinfo;
>   }
>  
>   if (uioinfo->handler || uioinfo->irqcontrol ||
>   uioinfo->irq_flags & IRQF_SHARED) {
>   dev_err(>dev, "interrupt configuration error\n");
> - goto bad0;
> + goto out_uioinfo;
>   }
>  
>   priv = kzalloc(sizeof(*priv), GFP_KERNEL);
>   if (!priv) {
>   ret = -ENOMEM;
>   dev_err(>dev, "unable to kmalloc\n");
> - goto bad0;
> + goto out_uioinfo;
>   }
>  
>   priv->uioinfo = uioinfo;
>   spin_lock_init(>lock);
> - priv->flags = 0; /* interrupt is enabled to begin with */
> + /* interrupt is enabled to begin with */
> + priv->flags = uioinfo_alloced ? (1 << bitUioinfoAlloced) : 0;
>   priv->pdev = pdev;
>  
>   if (!uioinfo->irq) {
>   ret = platform_get_irq(pdev, 0);
>   if (ret < 0) {
>   dev_err(>dev, "failed to get IRQ\n");
> - goto bad0;
> + goto out_priv;
>   }
>   uioinfo->irq = ret;
>   }
> @@ -205,19 +213,19 @@ static int uio_pdrv_genirq_probe(struct platform_device 
> *pdev)
>   ret 

Re: [PATCH] drivers/uio/uio_pdrv_genirq.c: Fix memory freeing issues

2012-12-04 Thread Hans J. Koch
On Thu, Nov 29, 2012 at 01:47:28PM +0200, Vitalii Demianets wrote:
 1. uioinfo was kfreed based on the presence of pdev-dev.of_node, which was
 obviously wrong and unrelated to the fact if uioinfo was allocated statically
 or dynamically. This patch introduces new flag which clearly shows if uioinfo
 was allocated dynamically and kfrees uioinfo based on that flag;
 2. Fix: priv data was not freed in case platform_get_irq() failed. As it was
 caused mainly by improper exit labels naming, labels were renamed too;
 3. The case of uioinfo AND pdev-dev.of_node both NULL (not initialized
 in platform data) was not treated properly.

Your arguments sound right to me. But there are some minor issues, see below.

Otherwise looks good.
Thanks,
Hans

 
 Signed-off-by: Vitalii Demianets vi...@nppfactor.kiev.ua
 ---
  drivers/uio/uio_pdrv_genirq.c |   44 
  1 files changed, 26 insertions(+), 18 deletions(-)
 
 diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c
 index 42202cd..45126e3 100644
 --- a/drivers/uio/uio_pdrv_genirq.c
 +++ b/drivers/uio/uio_pdrv_genirq.c
 @@ -30,6 +30,11 @@
  
  #define DRIVER_NAME uio_pdrv_genirq
  
 +enum {
 + bitIRQDisabled = 0,
 + bitUioinfoAlloced = 1,

Please do not use CamelCase. This is neither Windows nor C++ or Java.
And you don't need to tell users about the type (like bit). That should
be clear by looking at the code. I'd prefer UPPERCASE to make it clear that
these are constants, e.g. IRQ_IS_DISABLED and UIO_INFO_IS_ALLOCATED or
something like that.

 +};
 +
  struct uio_pdrv_genirq_platdata {
   struct uio_info *uioinfo;
   spinlock_t lock;
 @@ -63,7 +68,7 @@ static irqreturn_t uio_pdrv_genirq_handler(int irq, struct 
 uio_info *dev_info)
* remember the state so we can allow user space to enable it later.
*/
  
 - if (!test_and_set_bit(0, priv-flags))
 + if (!test_and_set_bit(bitIRQDisabled, priv-flags))
   disable_irq_nosync(irq);
  
   return IRQ_HANDLED;
 @@ -83,10 +88,10 @@ static int uio_pdrv_genirq_irqcontrol(struct uio_info 
 *dev_info, s32 irq_on)
  
   spin_lock_irqsave(priv-lock, flags);
   if (irq_on) {
 - if (test_and_clear_bit(0, priv-flags))
 + if (test_and_clear_bit(bitIRQDisabled, priv-flags))
   enable_irq(dev_info-irq);
   } else {
 - if (!test_and_set_bit(0, priv-flags))
 + if (!test_and_set_bit(bitIRQDisabled, priv-flags))
   disable_irq(dev_info-irq);
   }
   spin_unlock_irqrestore(priv-lock, flags);
 @@ -101,8 +106,9 @@ static int uio_pdrv_genirq_probe(struct platform_device 
 *pdev)
   struct uio_mem *uiomem;
   int ret = -EINVAL;
   int i;
 + bool uioinfo_alloced = false;
  
 - if (!uioinfo) {
 + if (!uioinfo  pdev-dev.of_node) {
   int irq;
  
   /* alloc uioinfo for one device */
 @@ -110,10 +116,11 @@ static int uio_pdrv_genirq_probe(struct platform_device 
 *pdev)
   if (!uioinfo) {
   ret = -ENOMEM;
   dev_err(pdev-dev, unable to kmalloc\n);
 - goto bad2;
 + goto out;
   }
   uioinfo-name = pdev-dev.of_node-name;
   uioinfo-version = devicetree;
 + uioinfo_alloced = true;
  
   /* Multiple IRQs are not supported */
   irq = platform_get_irq(pdev, 0);
 @@ -125,32 +132,33 @@ static int uio_pdrv_genirq_probe(struct platform_device 
 *pdev)
  
   if (!uioinfo || !uioinfo-name || !uioinfo-version) {
   dev_err(pdev-dev, missing platform_data\n);
 - goto bad0;
 + goto out_uioinfo;
   }
  
   if (uioinfo-handler || uioinfo-irqcontrol ||
   uioinfo-irq_flags  IRQF_SHARED) {
   dev_err(pdev-dev, interrupt configuration error\n);
 - goto bad0;
 + goto out_uioinfo;
   }
  
   priv = kzalloc(sizeof(*priv), GFP_KERNEL);
   if (!priv) {
   ret = -ENOMEM;
   dev_err(pdev-dev, unable to kmalloc\n);
 - goto bad0;
 + goto out_uioinfo;
   }
  
   priv-uioinfo = uioinfo;
   spin_lock_init(priv-lock);
 - priv-flags = 0; /* interrupt is enabled to begin with */
 + /* interrupt is enabled to begin with */
 + priv-flags = uioinfo_alloced ? (1  bitUioinfoAlloced) : 0;
   priv-pdev = pdev;
  
   if (!uioinfo-irq) {
   ret = platform_get_irq(pdev, 0);
   if (ret  0) {
   dev_err(pdev-dev, failed to get IRQ\n);
 - goto bad0;
 + goto out_priv;
   }
   uioinfo-irq = ret;
   }
 @@ -205,19 +213,19 @@ static int uio_pdrv_genirq_probe(struct platform_device 
 *pdev)
   ret = uio_register_device(pdev-dev, priv-uioinfo);
   if (ret) {
   

Re: [PATCH] uio.c: Fix warning: 'ret' might be used uninitialized

2012-12-03 Thread Hans J. Koch
On Mon, Dec 03, 2012 at 10:53:45AM +0200, Vitalii Demianets wrote:
> > On Friday 30 November 2012 23:39:06 Hans J. Koch wrote:
> > > Thanks a lot for reporting and discussing that problem. I'll add a
> > >
> > > Reported-by: Vitalii Demianets 
> > >
> > > if you have no objections.
> >
> > No objections. Thanks, Hans.
> 
> By the way, what do you think about my revised version of uio_pdrv_genirq.c 
> patch from November 29th?

I hope I find the time to look at that later tonight. I'm a bit busy ATM.

Hans
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] uio.c: Fix warning: 'ret' might be used uninitialized

2012-12-03 Thread Hans J. Koch
On Mon, Dec 03, 2012 at 10:53:45AM +0200, Vitalii Demianets wrote:
  On Friday 30 November 2012 23:39:06 Hans J. Koch wrote:
   Thanks a lot for reporting and discussing that problem. I'll add a
  
   Reported-by: Vitalii Demianets vi...@nppfactor.kiev.ua
  
   if you have no objections.
 
  No objections. Thanks, Hans.
 
 By the way, what do you think about my revised version of uio_pdrv_genirq.c 
 patch from November 29th?

I hope I find the time to look at that later tonight. I'm a bit busy ATM.

Hans
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] uio.c: Fix warning: 'ret' might be used uninitialized

2012-12-02 Thread Hans J. Koch
On Sat, Dec 01, 2012 at 09:58:32AM +, Cong Ding wrote:
> If it is really necessary to save the 4 lines of codes, I would suggest to do 
> in the following style. But you are more senior than me, so I may be wrong in 
> this aspect. 

"Seniority" (whatever you mean by that) has got nothing to do with it.
I'll accept any child's patch if it is good. Discussing code on LKML is
a purely technically thing, only if two patches are technically equivalent,
the maintainer's personal taste will decide. And if it makes you feel better:
My patches (and those of any other developer) are also sometimes rejected
because they are not to some other maintainer's taste.

Thanks,
Hans
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] stable: uio: Fix warning: 'ret' might be used uninitialized

2012-12-02 Thread Hans J. Koch
In two cases, the return value variable "ret" can be undefined.

Signed-off-by: Hans J. Koch 
Reported-by: Vitalii Demianets 

---
 drivers/uio/uio.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index 5110f36..0c80df2 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -273,6 +273,7 @@ static int uio_dev_add_attributes(struct uio_device *idev)
struct uio_portio *portio;
 
for (mi = 0; mi < MAX_UIO_MAPS; mi++) {
+   ret = -ENOMEM;
mem = >info->mem[mi];
if (mem->size == 0)
break;
@@ -298,6 +299,7 @@ static int uio_dev_add_attributes(struct uio_device *idev)
}
 
for (pi = 0; pi < MAX_UIO_PORT_REGIONS; pi++) {
+   ret = -ENOMEM;
port = >info->port[pi];
if (port->size == 0)
break;
-- 
1.7.9

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] stable: uio: Fix warning: 'ret' might be used uninitialized

2012-12-02 Thread Hans J. Koch
In two cases, the return value variable ret can be undefined.

Signed-off-by: Hans J. Koch h...@hansjkoch.de
Reported-by: Vitalii Demianets vi...@nppfactor.kiev.ua

---
 drivers/uio/uio.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index 5110f36..0c80df2 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -273,6 +273,7 @@ static int uio_dev_add_attributes(struct uio_device *idev)
struct uio_portio *portio;
 
for (mi = 0; mi  MAX_UIO_MAPS; mi++) {
+   ret = -ENOMEM;
mem = idev-info-mem[mi];
if (mem-size == 0)
break;
@@ -298,6 +299,7 @@ static int uio_dev_add_attributes(struct uio_device *idev)
}
 
for (pi = 0; pi  MAX_UIO_PORT_REGIONS; pi++) {
+   ret = -ENOMEM;
port = idev-info-port[pi];
if (port-size == 0)
break;
-- 
1.7.9

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] uio.c: Fix warning: 'ret' might be used uninitialized

2012-12-02 Thread Hans J. Koch
On Sat, Dec 01, 2012 at 09:58:32AM +, Cong Ding wrote:
 If it is really necessary to save the 4 lines of codes, I would suggest to do 
 in the following style. But you are more senior than me, so I may be wrong in 
 this aspect. 

Seniority (whatever you mean by that) has got nothing to do with it.
I'll accept any child's patch if it is good. Discussing code on LKML is
a purely technically thing, only if two patches are technically equivalent,
the maintainer's personal taste will decide. And if it makes you feel better:
My patches (and those of any other developer) are also sometimes rejected
because they are not to some other maintainer's taste.

Thanks,
Hans
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] uio.c: Fix warning: 'ret' might be used uninitialized

2012-11-30 Thread Hans J. Koch
On Sat, Dec 01, 2012 at 02:22:44AM +0100, Cong Ding wrote:
> On Fri, Nov 30, 2012 at 10:33 PM, Hans J. Koch  wrote:
> > On Fri, Nov 30, 2012 at 12:12:46PM +0100, Tux9 wrote:
> >> I like Vitalii's solution more. Hans's solution assign the value
> >> -ENOMEM to ret in every round of the loop, which is a kind of wasting
> >> CPU cycles.
> >
> > The difference between
> > 1 files changed, 12 insertions(+), 4 deletions(-) and
> > 1 files changed, 2 insertions(+), 0 deletions(-)
> >
> > is more important. Note that this code is not in a fast path but only
> > called once at device creation.
> Why do you think the size of the patch is so important? I think the
> most important thing is the coding style and efficiency. I agree
> efficiency is not important in this case, but what about coding style?

Most important. Short is beautiful.

> Your code is _not_ very easy to understand.

You think so?

> It's a very natural thing
> to set the return value and then goto the error-handling codes, which
> is exactly same as what Vitalii did, rather than setting an initial
> value in the beginning of each round of the loop as you did.

Setting a default value at the beginning of a block is the most natural
thing. I don't want to repeat the same code in three places.

> There are
> also a bunch of codes in kernel in the same style with Vitalii, but I
> cannot find anything same as your codes.

If you follow LKML closely, you'll notice that simplifying code by
replacing unnecessary repetitions with shorter versions is always welcome.
If we didn't go for that, the kernel source would be a few million lines
bigger by now.

Thanks,
Hans
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] uio.c: Fix warning: 'ret' might be used uninitialized

2012-11-30 Thread Hans J. Koch
On Fri, Nov 30, 2012 at 01:16:19PM +0200, Vitalii Demianets wrote:
> On Friday 30 November 2012 01:58:22 Hans J. Koch wrote:
> > On Thu, Nov 29, 2012 at 06:36:59PM +0200, Vitalii Demianets wrote:
> > > > On Thursday 29 November 2012 18:05:27 Tux9 wrote:
> > > > > Hans, I think there are something wrong in your patch, while
> > > > > Vitalii's is right. The variable "ret" is reused in line 292 and line
> > > > > 295, so the value of "ret" would be overridden (if it goto err_map in
> > > > > line 284 when mi>=1).
> > > >
> > > > Actually, both patches do exactly the same thing. Hans's patch
> > > > establishes default value for the ret for all those "other" cases when
> > > > ret is not explicitly overridden. My patch explicitly enumerates all
> > > > those "other" cases in more wordily manner.
> > >
> > > Oops, disregard this. After looking at it more thoroughly I got your
> > > point. You are right, ret is overridden at first iteration (mi == 0), so
> > > Hans's approach does not work.
> > > I must do more thinking before replying in a hurry.
> >
> > You're right. Initialization of "ret" has to take place at the beginning of
> > the loop.
> >
> > I think this version is right:
> 
> Yes, this looks right for me.

OK, I'll send that patch offically, then. This might also be material for
the stable updates. Greg?

Thanks a lot for reporting and discussing that problem. I'll add a

Reported-by: Vitalii Demianets 

if you have no objections.

Thanks,
Hans

> 
> > >From 00c3c734c0dde67873a628bcb18cee403c95c301 Mon Sep 17 00:00:00 2001
> >
> > From: "Hans J. Koch" 
> > Date: Fri, 30 Nov 2012 00:51:50 +0100
> > Subject: [PATCH] uio: Fix warning: 'ret' might be used uninitialized
> >
> > In two cases, the return value variable "ret" can be undefined.
> >
> > Signed-off-by: Hans J. Koch 
> > ---
> >  drivers/uio/uio.c |2 ++
> >  1 files changed, 2 insertions(+), 0 deletions(-)
> >
> > diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
> > index 5110f36..0c80df2 100644
> > --- a/drivers/uio/uio.c
> > +++ b/drivers/uio/uio.c
> > @@ -273,6 +273,7 @@ static int uio_dev_add_attributes(struct uio_device
> > *idev) struct uio_portio *portio;
> >
> > for (mi = 0; mi < MAX_UIO_MAPS; mi++) {
> > +   ret = -ENOMEM;
> > mem = >info->mem[mi];
> > if (mem->size == 0)
> > break;
> > @@ -298,6 +299,7 @@ static int uio_dev_add_attributes(struct uio_device
> > *idev) }
> >
> > for (pi = 0; pi < MAX_UIO_PORT_REGIONS; pi++) {
> > +   ret = -ENOMEM;
> > port = >info->port[pi];
> > if (port->size == 0)
> > break;
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] uio.c: Fix warning: 'ret' might be used uninitialized

2012-11-30 Thread Hans J. Koch
On Fri, Nov 30, 2012 at 12:12:46PM +0100, Tux9 wrote:
> I like Vitalii's solution more. Hans's solution assign the value
> -ENOMEM to ret in every round of the loop, which is a kind of wasting
> CPU cycles.

The difference between
1 files changed, 12 insertions(+), 4 deletions(-) and
1 files changed, 2 insertions(+), 0 deletions(-)

is more important. Note that this code is not in a fast path but only
called once at device creation.

Thanks,
Hans

> 
> On Fri, Nov 30, 2012 at 12:58 AM, Hans J. Koch  wrote:
> > On Thu, Nov 29, 2012 at 06:36:59PM +0200, Vitalii Demianets wrote:
> >> > On Thursday 29 November 2012 18:05:27 Tux9 wrote:
> >> > > Hans, I think there are something wrong in your patch, while Vitalii's
> >> > > is right. The variable "ret" is reused in line 292 and line 295, so
> >> > > the value of "ret" would be overridden (if it goto err_map in line 284
> >> > > when mi>=1).
> >> >
> >> > Actually, both patches do exactly the same thing. Hans's patch 
> >> > establishes
> >> > default value for the ret for all those "other" cases when ret is not
> >> > explicitly overridden. My patch explicitly enumerates all those "other"
> >> > cases in more wordily manner.
> >> >
> >>
> >> Oops, disregard this. After looking at it more thoroughly I got your point.
> >> You are right, ret is overridden at first iteration (mi == 0), so Hans's
> >> approach does not work.
> >> I must do more thinking before replying in a hurry.
> >
> > You're right. Initialization of "ret" has to take place at the beginning of
> > the loop.
> >
> > I think this version is right:
> >
> >
> > From 00c3c734c0dde67873a628bcb18cee403c95c301 Mon Sep 17 00:00:00 2001
> > From: "Hans J. Koch" 
> > Date: Fri, 30 Nov 2012 00:51:50 +0100
> > Subject: [PATCH] uio: Fix warning: 'ret' might be used uninitialized
> >
> > In two cases, the return value variable "ret" can be undefined.
> >
> > Signed-off-by: Hans J. Koch 
> > ---
> >  drivers/uio/uio.c |2 ++
> >  1 files changed, 2 insertions(+), 0 deletions(-)
> >
> > diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
> > index 5110f36..0c80df2 100644
> > --- a/drivers/uio/uio.c
> > +++ b/drivers/uio/uio.c
> > @@ -273,6 +273,7 @@ static int uio_dev_add_attributes(struct uio_device 
> > *idev)
> > struct uio_portio *portio;
> >
> > for (mi = 0; mi < MAX_UIO_MAPS; mi++) {
> > +   ret = -ENOMEM;
> > mem = >info->mem[mi];
> > if (mem->size == 0)
> > break;
> > @@ -298,6 +299,7 @@ static int uio_dev_add_attributes(struct uio_device 
> > *idev)
> > }
> >
> > for (pi = 0; pi < MAX_UIO_PORT_REGIONS; pi++) {
> > +   ret = -ENOMEM;
> > port = >info->port[pi];
> > if (port->size == 0)
> > break;
> > --
> > 1.7.9
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> > the body of a message to majord...@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> > Please read the FAQ at  http://www.tux.org/lkml/
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] uio.c: Fix warning: 'ret' might be used uninitialized

2012-11-30 Thread Hans J. Koch
On Fri, Nov 30, 2012 at 12:12:46PM +0100, Tux9 wrote:
 I like Vitalii's solution more. Hans's solution assign the value
 -ENOMEM to ret in every round of the loop, which is a kind of wasting
 CPU cycles.

The difference between
1 files changed, 12 insertions(+), 4 deletions(-) and
1 files changed, 2 insertions(+), 0 deletions(-)

is more important. Note that this code is not in a fast path but only
called once at device creation.

Thanks,
Hans

 
 On Fri, Nov 30, 2012 at 12:58 AM, Hans J. Koch h...@hansjkoch.de wrote:
  On Thu, Nov 29, 2012 at 06:36:59PM +0200, Vitalii Demianets wrote:
   On Thursday 29 November 2012 18:05:27 Tux9 wrote:
Hans, I think there are something wrong in your patch, while Vitalii's
is right. The variable ret is reused in line 292 and line 295, so
the value of ret would be overridden (if it goto err_map in line 284
when mi=1).
  
   Actually, both patches do exactly the same thing. Hans's patch 
   establishes
   default value for the ret for all those other cases when ret is not
   explicitly overridden. My patch explicitly enumerates all those other
   cases in more wordily manner.
  
 
  Oops, disregard this. After looking at it more thoroughly I got your point.
  You are right, ret is overridden at first iteration (mi == 0), so Hans's
  approach does not work.
  I must do more thinking before replying in a hurry.
 
  You're right. Initialization of ret has to take place at the beginning of
  the loop.
 
  I think this version is right:
 
 
  From 00c3c734c0dde67873a628bcb18cee403c95c301 Mon Sep 17 00:00:00 2001
  From: Hans J. Koch h...@hansjkoch.de
  Date: Fri, 30 Nov 2012 00:51:50 +0100
  Subject: [PATCH] uio: Fix warning: 'ret' might be used uninitialized
 
  In two cases, the return value variable ret can be undefined.
 
  Signed-off-by: Hans J. Koch h...@hansjkoch.de
  ---
   drivers/uio/uio.c |2 ++
   1 files changed, 2 insertions(+), 0 deletions(-)
 
  diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
  index 5110f36..0c80df2 100644
  --- a/drivers/uio/uio.c
  +++ b/drivers/uio/uio.c
  @@ -273,6 +273,7 @@ static int uio_dev_add_attributes(struct uio_device 
  *idev)
  struct uio_portio *portio;
 
  for (mi = 0; mi  MAX_UIO_MAPS; mi++) {
  +   ret = -ENOMEM;
  mem = idev-info-mem[mi];
  if (mem-size == 0)
  break;
  @@ -298,6 +299,7 @@ static int uio_dev_add_attributes(struct uio_device 
  *idev)
  }
 
  for (pi = 0; pi  MAX_UIO_PORT_REGIONS; pi++) {
  +   ret = -ENOMEM;
  port = idev-info-port[pi];
  if (port-size == 0)
  break;
  --
  1.7.9
 
  --
  To unsubscribe from this list: send the line unsubscribe linux-kernel in
  the body of a message to majord...@vger.kernel.org
  More majordomo info at  http://vger.kernel.org/majordomo-info.html
  Please read the FAQ at  http://www.tux.org/lkml/
 
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] uio.c: Fix warning: 'ret' might be used uninitialized

2012-11-30 Thread Hans J. Koch
On Fri, Nov 30, 2012 at 01:16:19PM +0200, Vitalii Demianets wrote:
 On Friday 30 November 2012 01:58:22 Hans J. Koch wrote:
  On Thu, Nov 29, 2012 at 06:36:59PM +0200, Vitalii Demianets wrote:
On Thursday 29 November 2012 18:05:27 Tux9 wrote:
 Hans, I think there are something wrong in your patch, while
 Vitalii's is right. The variable ret is reused in line 292 and line
 295, so the value of ret would be overridden (if it goto err_map in
 line 284 when mi=1).
   
Actually, both patches do exactly the same thing. Hans's patch
establishes default value for the ret for all those other cases when
ret is not explicitly overridden. My patch explicitly enumerates all
those other cases in more wordily manner.
  
   Oops, disregard this. After looking at it more thoroughly I got your
   point. You are right, ret is overridden at first iteration (mi == 0), so
   Hans's approach does not work.
   I must do more thinking before replying in a hurry.
 
  You're right. Initialization of ret has to take place at the beginning of
  the loop.
 
  I think this version is right:
 
 Yes, this looks right for me.

OK, I'll send that patch offically, then. This might also be material for
the stable updates. Greg?

Thanks a lot for reporting and discussing that problem. I'll add a

Reported-by: Vitalii Demianets vi...@nppfactor.kiev.ua

if you have no objections.

Thanks,
Hans

 
  From 00c3c734c0dde67873a628bcb18cee403c95c301 Mon Sep 17 00:00:00 2001
 
  From: Hans J. Koch h...@hansjkoch.de
  Date: Fri, 30 Nov 2012 00:51:50 +0100
  Subject: [PATCH] uio: Fix warning: 'ret' might be used uninitialized
 
  In two cases, the return value variable ret can be undefined.
 
  Signed-off-by: Hans J. Koch h...@hansjkoch.de
  ---
   drivers/uio/uio.c |2 ++
   1 files changed, 2 insertions(+), 0 deletions(-)
 
  diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
  index 5110f36..0c80df2 100644
  --- a/drivers/uio/uio.c
  +++ b/drivers/uio/uio.c
  @@ -273,6 +273,7 @@ static int uio_dev_add_attributes(struct uio_device
  *idev) struct uio_portio *portio;
 
  for (mi = 0; mi  MAX_UIO_MAPS; mi++) {
  +   ret = -ENOMEM;
  mem = idev-info-mem[mi];
  if (mem-size == 0)
  break;
  @@ -298,6 +299,7 @@ static int uio_dev_add_attributes(struct uio_device
  *idev) }
 
  for (pi = 0; pi  MAX_UIO_PORT_REGIONS; pi++) {
  +   ret = -ENOMEM;
  port = idev-info-port[pi];
  if (port-size == 0)
  break;
 
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] uio.c: Fix warning: 'ret' might be used uninitialized

2012-11-30 Thread Hans J. Koch
On Sat, Dec 01, 2012 at 02:22:44AM +0100, Cong Ding wrote:
 On Fri, Nov 30, 2012 at 10:33 PM, Hans J. Koch h...@hansjkoch.de wrote:
  On Fri, Nov 30, 2012 at 12:12:46PM +0100, Tux9 wrote:
  I like Vitalii's solution more. Hans's solution assign the value
  -ENOMEM to ret in every round of the loop, which is a kind of wasting
  CPU cycles.
 
  The difference between
  1 files changed, 12 insertions(+), 4 deletions(-) and
  1 files changed, 2 insertions(+), 0 deletions(-)
 
  is more important. Note that this code is not in a fast path but only
  called once at device creation.
 Why do you think the size of the patch is so important? I think the
 most important thing is the coding style and efficiency. I agree
 efficiency is not important in this case, but what about coding style?

Most important. Short is beautiful.

 Your code is _not_ very easy to understand.

You think so?

 It's a very natural thing
 to set the return value and then goto the error-handling codes, which
 is exactly same as what Vitalii did, rather than setting an initial
 value in the beginning of each round of the loop as you did.

Setting a default value at the beginning of a block is the most natural
thing. I don't want to repeat the same code in three places.

 There are
 also a bunch of codes in kernel in the same style with Vitalii, but I
 cannot find anything same as your codes.

If you follow LKML closely, you'll notice that simplifying code by
replacing unnecessary repetitions with shorter versions is always welcome.
If we didn't go for that, the kernel source would be a few million lines
bigger by now.

Thanks,
Hans
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 1/1] uio.c: solve memory leak

2012-11-29 Thread Hans J. Koch
On Thu, Nov 29, 2012 at 05:40:00PM +, Cong Ding wrote:
> In version 1, I forgot to modify the same bug in the first loop.
> 
> we have to call kobject_put() to clean up the kobject after function
> kobject_init(), kobject_add(), or kobject_uevent() is called.

Yes, thanks. Incredible how that code looks like...
There's still another bug: The memory allocated with kzalloc is
never freed. More tomorrow, have to go to sleep now.

Thanks,
Hans

> 
> Signed-off-by: Cong Ding 
> ---
>  drivers/uio/uio.c |   16 ++--
>  1 files changed, 10 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
> index 5110f36..79774d3 100644
> --- a/drivers/uio/uio.c
> +++ b/drivers/uio/uio.c
> @@ -291,10 +291,10 @@ static int uio_dev_add_attributes(struct uio_device 
> *idev)
>   mem->map = map;
>   ret = kobject_add(>kobj, idev->map_dir, "map%d", mi);
>   if (ret)
> - goto err_map;
> + goto err_map_kobj;
>   ret = kobject_uevent(>kobj, KOBJ_ADD);
>   if (ret)
> - goto err_map;
> + goto err_map_kobj;
>   }
>  
>   for (pi = 0; pi < MAX_UIO_PORT_REGIONS; pi++) {
> @@ -317,23 +317,27 @@ static int uio_dev_add_attributes(struct uio_device 
> *idev)
>   ret = kobject_add(>kobj, idev->portio_dir,
>   "port%d", pi);
>   if (ret)
> - goto err_portio;
> + goto err_portio_kobj;
>   ret = kobject_uevent(>kobj, KOBJ_ADD);
>   if (ret)
> - goto err_portio;
> + goto err_portio_kobj;
>   }
>  
>   return 0;
>  
>  err_portio:
> - for (pi--; pi >= 0; pi--) {
> + pi--;
> +err_portio_kobj:
> + for (; pi >= 0; pi--) {
>   port = >info->port[pi];
>   portio = port->portio;
>   kobject_put(>kobj);
>   }
>   kobject_put(idev->portio_dir);
>  err_map:
> - for (mi--; mi>=0; mi--) {
> + mi--;
> +err_map_kobj:
> + for (; mi >= 0; mi--) {
>   mem = >info->mem[mi];
>   map = mem->map;
>   kobject_put(>kobj);
> -- 
> 1.7.4.5
> 
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] uio.c: Fix warning: 'ret' might be used uninitialized

2012-11-29 Thread Hans J. Koch
On Thu, Nov 29, 2012 at 06:36:59PM +0200, Vitalii Demianets wrote:
> > On Thursday 29 November 2012 18:05:27 Tux9 wrote:
> > > Hans, I think there are something wrong in your patch, while Vitalii's
> > > is right. The variable "ret" is reused in line 292 and line 295, so
> > > the value of "ret" would be overridden (if it goto err_map in line 284
> > > when mi>=1).
> >
> > Actually, both patches do exactly the same thing. Hans's patch establishes
> > default value for the ret for all those "other" cases when ret is not
> > explicitly overridden. My patch explicitly enumerates all those "other"
> > cases in more wordily manner.
> >
> 
> Oops, disregard this. After looking at it more thoroughly I got your point.
> You are right, ret is overridden at first iteration (mi == 0), so Hans's 
> approach does not work.
> I must do more thinking before replying in a hurry.

You're right. Initialization of "ret" has to take place at the beginning of
the loop.

I think this version is right:


>From 00c3c734c0dde67873a628bcb18cee403c95c301 Mon Sep 17 00:00:00 2001
From: "Hans J. Koch" 
Date: Fri, 30 Nov 2012 00:51:50 +0100
Subject: [PATCH] uio: Fix warning: 'ret' might be used uninitialized

In two cases, the return value variable "ret" can be undefined.

Signed-off-by: Hans J. Koch 
---
 drivers/uio/uio.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index 5110f36..0c80df2 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -273,6 +273,7 @@ static int uio_dev_add_attributes(struct uio_device *idev)
struct uio_portio *portio;
 
for (mi = 0; mi < MAX_UIO_MAPS; mi++) {
+   ret = -ENOMEM;
mem = >info->mem[mi];
if (mem->size == 0)
break;
@@ -298,6 +299,7 @@ static int uio_dev_add_attributes(struct uio_device *idev)
}
 
for (pi = 0; pi < MAX_UIO_PORT_REGIONS; pi++) {
+   ret = -ENOMEM;
port = >info->port[pi];
if (port->size == 0)
break;
-- 
1.7.9

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] uio.c: Fix warning: 'ret' might be used uninitialized

2012-11-29 Thread Hans J. Koch
On Thu, Nov 29, 2012 at 06:36:59PM +0200, Vitalii Demianets wrote:
  On Thursday 29 November 2012 18:05:27 Tux9 wrote:
   Hans, I think there are something wrong in your patch, while Vitalii's
   is right. The variable ret is reused in line 292 and line 295, so
   the value of ret would be overridden (if it goto err_map in line 284
   when mi=1).
 
  Actually, both patches do exactly the same thing. Hans's patch establishes
  default value for the ret for all those other cases when ret is not
  explicitly overridden. My patch explicitly enumerates all those other
  cases in more wordily manner.
 
 
 Oops, disregard this. After looking at it more thoroughly I got your point.
 You are right, ret is overridden at first iteration (mi == 0), so Hans's 
 approach does not work.
 I must do more thinking before replying in a hurry.

You're right. Initialization of ret has to take place at the beginning of
the loop.

I think this version is right:


From 00c3c734c0dde67873a628bcb18cee403c95c301 Mon Sep 17 00:00:00 2001
From: Hans J. Koch h...@hansjkoch.de
Date: Fri, 30 Nov 2012 00:51:50 +0100
Subject: [PATCH] uio: Fix warning: 'ret' might be used uninitialized

In two cases, the return value variable ret can be undefined.

Signed-off-by: Hans J. Koch h...@hansjkoch.de
---
 drivers/uio/uio.c |2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index 5110f36..0c80df2 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -273,6 +273,7 @@ static int uio_dev_add_attributes(struct uio_device *idev)
struct uio_portio *portio;
 
for (mi = 0; mi  MAX_UIO_MAPS; mi++) {
+   ret = -ENOMEM;
mem = idev-info-mem[mi];
if (mem-size == 0)
break;
@@ -298,6 +299,7 @@ static int uio_dev_add_attributes(struct uio_device *idev)
}
 
for (pi = 0; pi  MAX_UIO_PORT_REGIONS; pi++) {
+   ret = -ENOMEM;
port = idev-info-port[pi];
if (port-size == 0)
break;
-- 
1.7.9

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 1/1] uio.c: solve memory leak

2012-11-29 Thread Hans J. Koch
On Thu, Nov 29, 2012 at 05:40:00PM +, Cong Ding wrote:
 In version 1, I forgot to modify the same bug in the first loop.
 
 we have to call kobject_put() to clean up the kobject after function
 kobject_init(), kobject_add(), or kobject_uevent() is called.

Yes, thanks. Incredible how that code looks like...
There's still another bug: The memory allocated with kzalloc is
never freed. More tomorrow, have to go to sleep now.

Thanks,
Hans

 
 Signed-off-by: Cong Ding ding...@gmail.com
 ---
  drivers/uio/uio.c |   16 ++--
  1 files changed, 10 insertions(+), 6 deletions(-)
 
 diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
 index 5110f36..79774d3 100644
 --- a/drivers/uio/uio.c
 +++ b/drivers/uio/uio.c
 @@ -291,10 +291,10 @@ static int uio_dev_add_attributes(struct uio_device 
 *idev)
   mem-map = map;
   ret = kobject_add(map-kobj, idev-map_dir, map%d, mi);
   if (ret)
 - goto err_map;
 + goto err_map_kobj;
   ret = kobject_uevent(map-kobj, KOBJ_ADD);
   if (ret)
 - goto err_map;
 + goto err_map_kobj;
   }
  
   for (pi = 0; pi  MAX_UIO_PORT_REGIONS; pi++) {
 @@ -317,23 +317,27 @@ static int uio_dev_add_attributes(struct uio_device 
 *idev)
   ret = kobject_add(portio-kobj, idev-portio_dir,
   port%d, pi);
   if (ret)
 - goto err_portio;
 + goto err_portio_kobj;
   ret = kobject_uevent(portio-kobj, KOBJ_ADD);
   if (ret)
 - goto err_portio;
 + goto err_portio_kobj;
   }
  
   return 0;
  
  err_portio:
 - for (pi--; pi = 0; pi--) {
 + pi--;
 +err_portio_kobj:
 + for (; pi = 0; pi--) {
   port = idev-info-port[pi];
   portio = port-portio;
   kobject_put(portio-kobj);
   }
   kobject_put(idev-portio_dir);
  err_map:
 - for (mi--; mi=0; mi--) {
 + mi--;
 +err_map_kobj:
 + for (; mi = 0; mi--) {
   mem = idev-info-mem[mi];
   map = mem-map;
   kobject_put(map-kobj);
 -- 
 1.7.4.5
 
 
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] drivers/uio/uio_pdrv_genirq.c: Fix memory leak & confusing labels

2012-11-28 Thread Hans J. Koch
On Wed, Nov 28, 2012 at 11:37:23AM +0200, Vitalii Demianets wrote:
> On Wednesday 28 November 2012 02:37:50 Hans J. Koch wrote:
> >
> > In other words, the case of uioinfo AND pdev->dev.of_node both being NULL
> > is not handled properly and will have ugly results.
> >
> 
> Moreover, the case of (uioinfo != NULL) && (pdev->dev.of_node != NULL) leads 
> to equally ugly results too (freeing uoinfo when it is statically allocated).

You're right. That wants to be fixed as well.

> 
> I think, we should sort out these problems, but in another patch. It is 
> totally unrelated to the problem solved by the original patch (memory leak 
> caused by not freeing priv in case platform_get_irq() fails).

So far, no patch was applied. I don't mind if all fixes for uio_pdrv_genirq
are in one patch as long as only this one file is altered.

Thanks,
Hans
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] drivers/uio/uio_pdrv_genirq.c: Fix memory leak & confusing labels

2012-11-28 Thread Hans J. Koch
On Wed, Nov 28, 2012 at 10:29:29AM +0100, Cong Ding wrote:
> On Wed, Nov 28, 2012 at 1:37 AM, Hans J. Koch  wrote:
> > On Wed, Nov 28, 2012 at 01:07:26AM +0100, Cong Ding wrote:
> >> On Wed, Nov 28, 2012 at 12:07 AM, Hans J. Koch  wrote:
> >> > On Tue, Nov 27, 2012 at 07:29:32PM +0200, Vitalii Demianets wrote:
> >> >> Memory leak was caused by jumping to the wrong exit label. So, it is 
> >> >> good time
> >> >> to improve misleading label names too.
> >> >
> >> > I agree that bad0, bad1, and bad2 are not the best choice for label 
> >> > names...
> >> > I don't have any objections to your renaming.
> >> >
> >> > But there's a more serious bug, maybe you can fix that as well while 
> >> > you're
> >> > at it? (See below)
> >> >
> >> > Thanks,
> >> > Hans
> >> >
> >> >>
> >> >> Signed-off-by: Vitalii Demianets 
> >> >> ---
> >> >>  drivers/uio/uio_pdrv_genirq.c |   21 +++--
> >> >>  1 files changed, 11 insertions(+), 10 deletions(-)
> >> >>
> >> >> diff --git a/drivers/uio/uio_pdrv_genirq.c 
> >> >> b/drivers/uio/uio_pdrv_genirq.c
> >> >> index 42202cd..b88cf7b 100644
> >> >> --- a/drivers/uio/uio_pdrv_genirq.c
> >> >> +++ b/drivers/uio/uio_pdrv_genirq.c
> >> >> @@ -110,7 +110,7 @@ static int uio_pdrv_genirq_probe(struct 
> >> >> platform_device *pdev)
> >> >>   if (!uioinfo) {
> >> >>   ret = -ENOMEM;
> >> >>   dev_err(>dev, "unable to kmalloc\n");
> >> >> - goto bad2;
> >> >> + goto out;
> >> >>   }
> >> >>   uioinfo->name = pdev->dev.of_node->name;
> >> >>   uioinfo->version = "devicetree";
> >> >> @@ -125,20 +125,20 @@ static int uio_pdrv_genirq_probe(struct 
> >> >> platform_device *pdev)
> >> >>
> >> >>   if (!uioinfo || !uioinfo->name || !uioinfo->version) {
> >> >>   dev_err(>dev, "missing platform_data\n");
> >> >> - goto bad0;
> >> >> + goto out_uioinfo;
> >> >>   }
> >> >>
> >> >>   if (uioinfo->handler || uioinfo->irqcontrol ||
> >> >>   uioinfo->irq_flags & IRQF_SHARED) {
> >> >>   dev_err(>dev, "interrupt configuration error\n");
> >> >> - goto bad0;
> >> >> + goto out_uioinfo;
> >> >>   }
> >> >>
> >> >>   priv = kzalloc(sizeof(*priv), GFP_KERNEL);
> >> >>   if (!priv) {
> >> >>   ret = -ENOMEM;
> >> >>   dev_err(>dev, "unable to kmalloc\n");
> >> >> - goto bad0;
> >> >> + goto out_uioinfo;
> >> >>   }
> >> >>
> >> >>   priv->uioinfo = uioinfo;
> >> >> @@ -150,7 +150,7 @@ static int uio_pdrv_genirq_probe(struct 
> >> >> platform_device *pdev)
> >> >>   ret = platform_get_irq(pdev, 0);
> >> >>   if (ret < 0) {
> >> >>   dev_err(>dev, "failed to get IRQ\n");
> >> >> - goto bad0;
> >> >> + goto out_priv;
> >> >>   }
> >> >>   uioinfo->irq = ret;
> >> >>   }
> >> >> @@ -205,19 +205,20 @@ static int uio_pdrv_genirq_probe(struct 
> >> >> platform_device *pdev)
> >> >>   ret = uio_register_device(>dev, priv->uioinfo);
> >> >>   if (ret) {
> >> >>   dev_err(>dev, "unable to register uio device\n");
> >> >> - goto bad1;
> >> >> + goto out_pm;
> >> >>   }
> >> >>
> >> >>   platform_set_drvdata(pdev, priv);
> >> >>   return 0;
> >> >> - bad1:
> >> >> - kfree(priv);
> >> >> +out_pm:
> >> >>   pm_runtime_disable(>dev);
> >> >&g

Re: [PATCH] uio.c: Fix warning: 'ret' might be used uninitialized

2012-11-28 Thread Hans J. Koch
On Wed, Nov 28, 2012 at 10:58:32AM +0200, Vitalii Demianets wrote:
> On Wednesday 28 November 2012 00:43:41 Hans J. Koch wrote:
> > 
> > Thanks, good catch, but why don't you simply do this:
> > 
> 
> Just a matter of personal preference.

Your patch: 1 files changed, 12 insertions(+), 4 deletions(-)
My patch: 1 files changed, 1 insertions(+), 1 deletions(-)

Both achieve exactly the same. That's not a matter of personal
preference, that's the difference between a working solution and
a good solution. In the kernel, we want the latter.

> As a maintainer you can apply either 
> patch you want. I guess you would prefer your approach and I have no 
> objections to that :)

That's not the right kind of comment. Don't make it a habit.

Thanks,
Hans

> 
> > 
> > >From 228445996bb75a44d16b6237eca6a0916d9b2d7e Mon Sep 17 00:00:00 2001
> > From: "Hans J. Koch" 
> > Date: Tue, 27 Nov 2012 23:38:00 +0100
> > Subject: [PATCH] uio: Fix warning: 'ret' might be used uninitialized
> > 
> > In two cases, the return value variable "ret" can be undefined.
> > 
> > Signed-off-by: Hans J. Koch 
> > ---
> >  drivers/uio/uio.c |2 +-
> >  1 files changed, 1 insertions(+), 1 deletions(-)
> > 
> > diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
> > index 5110f36..fc60e35 100644
> > --- a/drivers/uio/uio.c
> > +++ b/drivers/uio/uio.c
> > @@ -263,7 +263,7 @@ static struct class uio_class = {
> >   */
> >  static int uio_dev_add_attributes(struct uio_device *idev)
> >  {
> > -   int ret;
> > +   int ret = -ENOMEM;
> > int mi, pi;
> > int map_found = 0;
> > int portio_found = 0;
> 
> 
> 
> -- 
> With Best Regards,
> Vitalii Demianets
> 
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] uio.c: Fix warning: 'ret' might be used uninitialized

2012-11-28 Thread Hans J. Koch
On Wed, Nov 28, 2012 at 10:58:32AM +0200, Vitalii Demianets wrote:
 On Wednesday 28 November 2012 00:43:41 Hans J. Koch wrote:
  
  Thanks, good catch, but why don't you simply do this:
  
 
 Just a matter of personal preference.

Your patch: 1 files changed, 12 insertions(+), 4 deletions(-)
My patch: 1 files changed, 1 insertions(+), 1 deletions(-)

Both achieve exactly the same. That's not a matter of personal
preference, that's the difference between a working solution and
a good solution. In the kernel, we want the latter.

 As a maintainer you can apply either 
 patch you want. I guess you would prefer your approach and I have no 
 objections to that :)

That's not the right kind of comment. Don't make it a habit.

Thanks,
Hans

 
  
  From 228445996bb75a44d16b6237eca6a0916d9b2d7e Mon Sep 17 00:00:00 2001
  From: Hans J. Koch h...@hansjkoch.de
  Date: Tue, 27 Nov 2012 23:38:00 +0100
  Subject: [PATCH] uio: Fix warning: 'ret' might be used uninitialized
  
  In two cases, the return value variable ret can be undefined.
  
  Signed-off-by: Hans J. Koch h...@hansjkoch.de
  ---
   drivers/uio/uio.c |2 +-
   1 files changed, 1 insertions(+), 1 deletions(-)
  
  diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
  index 5110f36..fc60e35 100644
  --- a/drivers/uio/uio.c
  +++ b/drivers/uio/uio.c
  @@ -263,7 +263,7 @@ static struct class uio_class = {
*/
   static int uio_dev_add_attributes(struct uio_device *idev)
   {
  -   int ret;
  +   int ret = -ENOMEM;
  int mi, pi;
  int map_found = 0;
  int portio_found = 0;
 
 
 
 -- 
 With Best Regards,
 Vitalii Demianets
 
 
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] drivers/uio/uio_pdrv_genirq.c: Fix memory leak confusing labels

2012-11-28 Thread Hans J. Koch
On Wed, Nov 28, 2012 at 10:29:29AM +0100, Cong Ding wrote:
 On Wed, Nov 28, 2012 at 1:37 AM, Hans J. Koch h...@hansjkoch.de wrote:
  On Wed, Nov 28, 2012 at 01:07:26AM +0100, Cong Ding wrote:
  On Wed, Nov 28, 2012 at 12:07 AM, Hans J. Koch h...@hansjkoch.de wrote:
   On Tue, Nov 27, 2012 at 07:29:32PM +0200, Vitalii Demianets wrote:
   Memory leak was caused by jumping to the wrong exit label. So, it is 
   good time
   to improve misleading label names too.
  
   I agree that bad0, bad1, and bad2 are not the best choice for label 
   names...
   I don't have any objections to your renaming.
  
   But there's a more serious bug, maybe you can fix that as well while 
   you're
   at it? (See below)
  
   Thanks,
   Hans
  
  
   Signed-off-by: Vitalii Demianets vi...@nppfactor.kiev.ua
   ---
drivers/uio/uio_pdrv_genirq.c |   21 +++--
1 files changed, 11 insertions(+), 10 deletions(-)
  
   diff --git a/drivers/uio/uio_pdrv_genirq.c 
   b/drivers/uio/uio_pdrv_genirq.c
   index 42202cd..b88cf7b 100644
   --- a/drivers/uio/uio_pdrv_genirq.c
   +++ b/drivers/uio/uio_pdrv_genirq.c
   @@ -110,7 +110,7 @@ static int uio_pdrv_genirq_probe(struct 
   platform_device *pdev)
 if (!uioinfo) {
 ret = -ENOMEM;
 dev_err(pdev-dev, unable to kmalloc\n);
   - goto bad2;
   + goto out;
 }
 uioinfo-name = pdev-dev.of_node-name;
 uioinfo-version = devicetree;
   @@ -125,20 +125,20 @@ static int uio_pdrv_genirq_probe(struct 
   platform_device *pdev)
  
 if (!uioinfo || !uioinfo-name || !uioinfo-version) {
 dev_err(pdev-dev, missing platform_data\n);
   - goto bad0;
   + goto out_uioinfo;
 }
  
 if (uioinfo-handler || uioinfo-irqcontrol ||
 uioinfo-irq_flags  IRQF_SHARED) {
 dev_err(pdev-dev, interrupt configuration error\n);
   - goto bad0;
   + goto out_uioinfo;
 }
  
 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
 if (!priv) {
 ret = -ENOMEM;
 dev_err(pdev-dev, unable to kmalloc\n);
   - goto bad0;
   + goto out_uioinfo;
 }
  
 priv-uioinfo = uioinfo;
   @@ -150,7 +150,7 @@ static int uio_pdrv_genirq_probe(struct 
   platform_device *pdev)
 ret = platform_get_irq(pdev, 0);
 if (ret  0) {
 dev_err(pdev-dev, failed to get IRQ\n);
   - goto bad0;
   + goto out_priv;
 }
 uioinfo-irq = ret;
 }
   @@ -205,19 +205,20 @@ static int uio_pdrv_genirq_probe(struct 
   platform_device *pdev)
 ret = uio_register_device(pdev-dev, priv-uioinfo);
 if (ret) {
 dev_err(pdev-dev, unable to register uio device\n);
   - goto bad1;
   + goto out_pm;
 }
  
 platform_set_drvdata(pdev, priv);
 return 0;
   - bad1:
   - kfree(priv);
   +out_pm:
 pm_runtime_disable(pdev-dev);
   - bad0:
   +out_priv:
   + kfree(priv);
   +out_uioinfo:
 /* kfree uioinfo for OF */
 if (pdev-dev.of_node)
 kfree(uioinfo);
  
   The free() depends on pdev-dev.of_node, while the allocation doesn't
   That's another source of memory leaks.
  I don't agree. In line 99, it is
  struct uio_info *uioinfo = pdev-dev.platform_data;
  if uioinfo doesn't equal to NULL, it will run to line 126,
  if (!uioinfo || !uioinfo-name || !uioinfo-version) {
  and then if uioinfo-name equals to NULL, it runs to line 127 and 128,
  and then goto bad0. If in this flow, we have to check
  pdev-dev.of_node before free(uioinfo), right?
 
  Hmmm. The idea is that uioinfo==NULL means OF. In that case,
  a struct uio_info is allocated and filled with the necessary values (name,
  version, irq). It is assumed (without check...) that pdev-dev.of_node
  is not NULL. If it were NULL we would crash here when dereferencing
   pdev-dev.of_node-name, leaving a memory leak.
 
  After bad0 it is also assumed that pdev-dev.of_node is an indicator for
  OF or not OF.
 
  In other words, the case of uioinfo AND pdev-dev.of_node both being NULL
  is not handled properly and will have ugly results.
 You are correct, we have to ensure they are valid before line 115 (or
 109). Sorry for misunderstanding your idea in the former email.
 
 
  btw, I think in line 126 it is not necessary to check (!uioinfo),
  because if uioinfo equals to NULL, it will go to line 109, and if the
  alloc fails, it will go to bad2. uioinfo has no chance to be NULL when
  runs to line 126. So I'd like to suggest a patch to avoid unnecessary
  check like this
 
  diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c
   index 42202cd..3eb4fa2 100644
   --- a/drivers/uio

Re: [PATCH] drivers/uio/uio_pdrv_genirq.c: Fix memory leak confusing labels

2012-11-28 Thread Hans J. Koch
On Wed, Nov 28, 2012 at 11:37:23AM +0200, Vitalii Demianets wrote:
 On Wednesday 28 November 2012 02:37:50 Hans J. Koch wrote:
 
  In other words, the case of uioinfo AND pdev-dev.of_node both being NULL
  is not handled properly and will have ugly results.
 
 
 Moreover, the case of (uioinfo != NULL)  (pdev-dev.of_node != NULL) leads 
 to equally ugly results too (freeing uoinfo when it is statically allocated).

You're right. That wants to be fixed as well.

 
 I think, we should sort out these problems, but in another patch. It is 
 totally unrelated to the problem solved by the original patch (memory leak 
 caused by not freeing priv in case platform_get_irq() fails).

So far, no patch was applied. I don't mind if all fixes for uio_pdrv_genirq
are in one patch as long as only this one file is altered.

Thanks,
Hans
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] drivers/uio/uio_pdrv_genirq.c: Fix memory leak & confusing labels

2012-11-27 Thread Hans J. Koch
On Wed, Nov 28, 2012 at 01:07:26AM +0100, Cong Ding wrote:
> On Wed, Nov 28, 2012 at 12:07 AM, Hans J. Koch  wrote:
> > On Tue, Nov 27, 2012 at 07:29:32PM +0200, Vitalii Demianets wrote:
> >> Memory leak was caused by jumping to the wrong exit label. So, it is good 
> >> time
> >> to improve misleading label names too.
> >
> > I agree that bad0, bad1, and bad2 are not the best choice for label names...
> > I don't have any objections to your renaming.
> >
> > But there's a more serious bug, maybe you can fix that as well while you're
> > at it? (See below)
> >
> > Thanks,
> > Hans
> >
> >>
> >> Signed-off-by: Vitalii Demianets 
> >> ---
> >>  drivers/uio/uio_pdrv_genirq.c |   21 +++--
> >>  1 files changed, 11 insertions(+), 10 deletions(-)
> >>
> >> diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c
> >> index 42202cd..b88cf7b 100644
> >> --- a/drivers/uio/uio_pdrv_genirq.c
> >> +++ b/drivers/uio/uio_pdrv_genirq.c
> >> @@ -110,7 +110,7 @@ static int uio_pdrv_genirq_probe(struct 
> >> platform_device *pdev)
> >>   if (!uioinfo) {
> >>   ret = -ENOMEM;
> >>   dev_err(>dev, "unable to kmalloc\n");
> >> - goto bad2;
> >> + goto out;
> >>   }
> >>   uioinfo->name = pdev->dev.of_node->name;
> >>   uioinfo->version = "devicetree";
> >> @@ -125,20 +125,20 @@ static int uio_pdrv_genirq_probe(struct 
> >> platform_device *pdev)
> >>
> >>   if (!uioinfo || !uioinfo->name || !uioinfo->version) {
> >>   dev_err(>dev, "missing platform_data\n");
> >> - goto bad0;
> >> + goto out_uioinfo;
> >>   }
> >>
> >>   if (uioinfo->handler || uioinfo->irqcontrol ||
> >>   uioinfo->irq_flags & IRQF_SHARED) {
> >>   dev_err(>dev, "interrupt configuration error\n");
> >> - goto bad0;
> >> + goto out_uioinfo;
> >>   }
> >>
> >>   priv = kzalloc(sizeof(*priv), GFP_KERNEL);
> >>   if (!priv) {
> >>   ret = -ENOMEM;
> >>   dev_err(>dev, "unable to kmalloc\n");
> >> - goto bad0;
> >> + goto out_uioinfo;
> >>   }
> >>
> >>   priv->uioinfo = uioinfo;
> >> @@ -150,7 +150,7 @@ static int uio_pdrv_genirq_probe(struct 
> >> platform_device *pdev)
> >>   ret = platform_get_irq(pdev, 0);
> >>   if (ret < 0) {
> >>   dev_err(>dev, "failed to get IRQ\n");
> >> - goto bad0;
> >> + goto out_priv;
> >>   }
> >>   uioinfo->irq = ret;
> >>   }
> >> @@ -205,19 +205,20 @@ static int uio_pdrv_genirq_probe(struct 
> >> platform_device *pdev)
> >>   ret = uio_register_device(>dev, priv->uioinfo);
> >>   if (ret) {
> >>   dev_err(>dev, "unable to register uio device\n");
> >> - goto bad1;
> >> + goto out_pm;
> >>   }
> >>
> >>   platform_set_drvdata(pdev, priv);
> >>   return 0;
> >> - bad1:
> >> - kfree(priv);
> >> +out_pm:
> >>   pm_runtime_disable(>dev);
> >> - bad0:
> >> +out_priv:
> >> + kfree(priv);
> >> +out_uioinfo:
> >>   /* kfree uioinfo for OF */
> >>   if (pdev->dev.of_node)
> >>   kfree(uioinfo);
> >
> > The free() depends on pdev->dev.of_node, while the allocation doesn't
> > That's another source of memory leaks.
> I don't agree. In line 99, it is
> struct uio_info *uioinfo = pdev->dev.platform_data;
> if uioinfo doesn't equal to NULL, it will run to line 126,
> if (!uioinfo || !uioinfo->name || !uioinfo->version) {
> and then if uioinfo->name equals to NULL, it runs to line 127 and 128,
> and then goto bad0. If in this flow, we have to check
> pdev->dev.of_node before free(uioinfo), right?

Hmmm. The idea is that uioinfo==NULL means OF. In that case,
a struct uio_info is allocated and filled with the necessary values (name,
version, irq). It is assu

Re: [PATCH] drivers/uio/uio_pdrv_genirq.c: Fix memory leak & confusing labels

2012-11-27 Thread Hans J. Koch
On Tue, Nov 27, 2012 at 07:29:32PM +0200, Vitalii Demianets wrote:
> Memory leak was caused by jumping to the wrong exit label. So, it is good time
> to improve misleading label names too.

I agree that bad0, bad1, and bad2 are not the best choice for label names...
I don't have any objections to your renaming.

But there's a more serious bug, maybe you can fix that as well while you're
at it? (See below)

Thanks,
Hans

> 
> Signed-off-by: Vitalii Demianets 
> ---
>  drivers/uio/uio_pdrv_genirq.c |   21 +++--
>  1 files changed, 11 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c
> index 42202cd..b88cf7b 100644
> --- a/drivers/uio/uio_pdrv_genirq.c
> +++ b/drivers/uio/uio_pdrv_genirq.c
> @@ -110,7 +110,7 @@ static int uio_pdrv_genirq_probe(struct platform_device 
> *pdev)
>   if (!uioinfo) {
>   ret = -ENOMEM;
>   dev_err(>dev, "unable to kmalloc\n");
> - goto bad2;
> + goto out;
>   }
>   uioinfo->name = pdev->dev.of_node->name;
>   uioinfo->version = "devicetree";
> @@ -125,20 +125,20 @@ static int uio_pdrv_genirq_probe(struct platform_device 
> *pdev)
>  
>   if (!uioinfo || !uioinfo->name || !uioinfo->version) {
>   dev_err(>dev, "missing platform_data\n");
> - goto bad0;
> + goto out_uioinfo;
>   }
>  
>   if (uioinfo->handler || uioinfo->irqcontrol ||
>   uioinfo->irq_flags & IRQF_SHARED) {
>   dev_err(>dev, "interrupt configuration error\n");
> - goto bad0;
> + goto out_uioinfo;
>   }
>  
>   priv = kzalloc(sizeof(*priv), GFP_KERNEL);
>   if (!priv) {
>   ret = -ENOMEM;
>   dev_err(>dev, "unable to kmalloc\n");
> - goto bad0;
> + goto out_uioinfo;
>   }
>  
>   priv->uioinfo = uioinfo;
> @@ -150,7 +150,7 @@ static int uio_pdrv_genirq_probe(struct platform_device 
> *pdev)
>   ret = platform_get_irq(pdev, 0);
>   if (ret < 0) {
>   dev_err(>dev, "failed to get IRQ\n");
> - goto bad0;
> + goto out_priv;
>   }
>   uioinfo->irq = ret;
>   }
> @@ -205,19 +205,20 @@ static int uio_pdrv_genirq_probe(struct platform_device 
> *pdev)
>   ret = uio_register_device(>dev, priv->uioinfo);
>   if (ret) {
>   dev_err(>dev, "unable to register uio device\n");
> - goto bad1;
> + goto out_pm;
>   }
>  
>   platform_set_drvdata(pdev, priv);
>   return 0;
> - bad1:
> - kfree(priv);
> +out_pm:
>   pm_runtime_disable(>dev);
> - bad0:
> +out_priv:
> + kfree(priv);
> +out_uioinfo:
>   /* kfree uioinfo for OF */
>   if (pdev->dev.of_node)
>   kfree(uioinfo);

The free() depends on pdev->dev.of_node, while the allocation doesn't
That's another source of memory leaks.

> - bad2:
> +out:
>   return ret;
>  }
>  
> -- 
> 1.7.8.6
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] uio.c: Fix warning: 'ret' might be used uninitialized

2012-11-27 Thread Hans J. Koch
On Tue, Nov 27, 2012 at 01:48:14PM +0200, Vitalii Demianets wrote:
> Fix warning: 'ret' might be used uninitialized
> 
> Signed-off-by: Vitalii Demianets 
> ---
>  drivers/uio/uio.c |   16 
>  1 files changed, 12 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
> index 5110f36..c33fd18 100644
> --- a/drivers/uio/uio.c
> +++ b/drivers/uio/uio.c
> @@ -280,12 +280,16 @@ static int uio_dev_add_attributes(struct uio_device 
> *idev)
>   map_found = 1;
>   idev->map_dir = kobject_create_and_add("maps",
>   >dev->kobj);
> - if (!idev->map_dir)
> + if (!idev->map_dir) {
> + ret = -ENOMEM;
>   goto err_map;
> + }
>   }
>   map = kzalloc(sizeof(*map), GFP_KERNEL);
> - if (!map)
> + if (!map) {
> + ret = -ENOMEM;
>   goto err_map;
> + }
>   kobject_init(>kobj, _attr_type);
>   map->mem = mem;
>   mem->map = map;
> @@ -305,12 +309,16 @@ static int uio_dev_add_attributes(struct uio_device 
> *idev)
>   portio_found = 1;
>   idev->portio_dir = kobject_create_and_add("portio",
>   >dev->kobj);
> - if (!idev->portio_dir)
> + if (!idev->portio_dir) {
> + ret = -ENOMEM;
>   goto err_portio;
> + }
>   }
>   portio = kzalloc(sizeof(*portio), GFP_KERNEL);
> - if (!portio)
> + if (!portio) {
> + ret = -ENOMEM;
>   goto err_portio;
> + }
>   kobject_init(>kobj, _attr_type);
>   portio->port = port;
>   port->portio = portio;
> -- 
> 1.7.8.6
> 

Thanks, good catch, but why don't you simply do this:


>From 228445996bb75a44d16b6237eca6a0916d9b2d7e Mon Sep 17 00:00:00 2001
From: "Hans J. Koch" 
Date: Tue, 27 Nov 2012 23:38:00 +0100
Subject: [PATCH] uio: Fix warning: 'ret' might be used uninitialized

In two cases, the return value variable "ret" can be undefined.

Signed-off-by: Hans J. Koch 
---
 drivers/uio/uio.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index 5110f36..fc60e35 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -263,7 +263,7 @@ static struct class uio_class = {
  */
 static int uio_dev_add_attributes(struct uio_device *idev)
 {
-   int ret;
+   int ret = -ENOMEM;
int mi, pi;
int map_found = 0;
int portio_found = 0;
-- 
1.7.9

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] uio.c: Fix warning: 'ret' might be used uninitialized

2012-11-27 Thread Hans J. Koch
On Tue, Nov 27, 2012 at 01:48:14PM +0200, Vitalii Demianets wrote:
 Fix warning: 'ret' might be used uninitialized
 
 Signed-off-by: Vitalii Demianets vi...@nppfactor.kiev.ua
 ---
  drivers/uio/uio.c |   16 
  1 files changed, 12 insertions(+), 4 deletions(-)
 
 diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
 index 5110f36..c33fd18 100644
 --- a/drivers/uio/uio.c
 +++ b/drivers/uio/uio.c
 @@ -280,12 +280,16 @@ static int uio_dev_add_attributes(struct uio_device 
 *idev)
   map_found = 1;
   idev-map_dir = kobject_create_and_add(maps,
   idev-dev-kobj);
 - if (!idev-map_dir)
 + if (!idev-map_dir) {
 + ret = -ENOMEM;
   goto err_map;
 + }
   }
   map = kzalloc(sizeof(*map), GFP_KERNEL);
 - if (!map)
 + if (!map) {
 + ret = -ENOMEM;
   goto err_map;
 + }
   kobject_init(map-kobj, map_attr_type);
   map-mem = mem;
   mem-map = map;
 @@ -305,12 +309,16 @@ static int uio_dev_add_attributes(struct uio_device 
 *idev)
   portio_found = 1;
   idev-portio_dir = kobject_create_and_add(portio,
   idev-dev-kobj);
 - if (!idev-portio_dir)
 + if (!idev-portio_dir) {
 + ret = -ENOMEM;
   goto err_portio;
 + }
   }
   portio = kzalloc(sizeof(*portio), GFP_KERNEL);
 - if (!portio)
 + if (!portio) {
 + ret = -ENOMEM;
   goto err_portio;
 + }
   kobject_init(portio-kobj, portio_attr_type);
   portio-port = port;
   port-portio = portio;
 -- 
 1.7.8.6
 

Thanks, good catch, but why don't you simply do this:


From 228445996bb75a44d16b6237eca6a0916d9b2d7e Mon Sep 17 00:00:00 2001
From: Hans J. Koch h...@hansjkoch.de
Date: Tue, 27 Nov 2012 23:38:00 +0100
Subject: [PATCH] uio: Fix warning: 'ret' might be used uninitialized

In two cases, the return value variable ret can be undefined.

Signed-off-by: Hans J. Koch h...@hansjkoch.de
---
 drivers/uio/uio.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index 5110f36..fc60e35 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -263,7 +263,7 @@ static struct class uio_class = {
  */
 static int uio_dev_add_attributes(struct uio_device *idev)
 {
-   int ret;
+   int ret = -ENOMEM;
int mi, pi;
int map_found = 0;
int portio_found = 0;
-- 
1.7.9

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] drivers/uio/uio_pdrv_genirq.c: Fix memory leak confusing labels

2012-11-27 Thread Hans J. Koch
On Tue, Nov 27, 2012 at 07:29:32PM +0200, Vitalii Demianets wrote:
 Memory leak was caused by jumping to the wrong exit label. So, it is good time
 to improve misleading label names too.

I agree that bad0, bad1, and bad2 are not the best choice for label names...
I don't have any objections to your renaming.

But there's a more serious bug, maybe you can fix that as well while you're
at it? (See below)

Thanks,
Hans

 
 Signed-off-by: Vitalii Demianets vi...@nppfactor.kiev.ua
 ---
  drivers/uio/uio_pdrv_genirq.c |   21 +++--
  1 files changed, 11 insertions(+), 10 deletions(-)
 
 diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c
 index 42202cd..b88cf7b 100644
 --- a/drivers/uio/uio_pdrv_genirq.c
 +++ b/drivers/uio/uio_pdrv_genirq.c
 @@ -110,7 +110,7 @@ static int uio_pdrv_genirq_probe(struct platform_device 
 *pdev)
   if (!uioinfo) {
   ret = -ENOMEM;
   dev_err(pdev-dev, unable to kmalloc\n);
 - goto bad2;
 + goto out;
   }
   uioinfo-name = pdev-dev.of_node-name;
   uioinfo-version = devicetree;
 @@ -125,20 +125,20 @@ static int uio_pdrv_genirq_probe(struct platform_device 
 *pdev)
  
   if (!uioinfo || !uioinfo-name || !uioinfo-version) {
   dev_err(pdev-dev, missing platform_data\n);
 - goto bad0;
 + goto out_uioinfo;
   }
  
   if (uioinfo-handler || uioinfo-irqcontrol ||
   uioinfo-irq_flags  IRQF_SHARED) {
   dev_err(pdev-dev, interrupt configuration error\n);
 - goto bad0;
 + goto out_uioinfo;
   }
  
   priv = kzalloc(sizeof(*priv), GFP_KERNEL);
   if (!priv) {
   ret = -ENOMEM;
   dev_err(pdev-dev, unable to kmalloc\n);
 - goto bad0;
 + goto out_uioinfo;
   }
  
   priv-uioinfo = uioinfo;
 @@ -150,7 +150,7 @@ static int uio_pdrv_genirq_probe(struct platform_device 
 *pdev)
   ret = platform_get_irq(pdev, 0);
   if (ret  0) {
   dev_err(pdev-dev, failed to get IRQ\n);
 - goto bad0;
 + goto out_priv;
   }
   uioinfo-irq = ret;
   }
 @@ -205,19 +205,20 @@ static int uio_pdrv_genirq_probe(struct platform_device 
 *pdev)
   ret = uio_register_device(pdev-dev, priv-uioinfo);
   if (ret) {
   dev_err(pdev-dev, unable to register uio device\n);
 - goto bad1;
 + goto out_pm;
   }
  
   platform_set_drvdata(pdev, priv);
   return 0;
 - bad1:
 - kfree(priv);
 +out_pm:
   pm_runtime_disable(pdev-dev);
 - bad0:
 +out_priv:
 + kfree(priv);
 +out_uioinfo:
   /* kfree uioinfo for OF */
   if (pdev-dev.of_node)
   kfree(uioinfo);

The free() depends on pdev-dev.of_node, while the allocation doesn't
That's another source of memory leaks.

 - bad2:
 +out:
   return ret;
  }
  
 -- 
 1.7.8.6
 
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] drivers/uio/uio_pdrv_genirq.c: Fix memory leak confusing labels

2012-11-27 Thread Hans J. Koch
On Wed, Nov 28, 2012 at 01:07:26AM +0100, Cong Ding wrote:
 On Wed, Nov 28, 2012 at 12:07 AM, Hans J. Koch h...@hansjkoch.de wrote:
  On Tue, Nov 27, 2012 at 07:29:32PM +0200, Vitalii Demianets wrote:
  Memory leak was caused by jumping to the wrong exit label. So, it is good 
  time
  to improve misleading label names too.
 
  I agree that bad0, bad1, and bad2 are not the best choice for label names...
  I don't have any objections to your renaming.
 
  But there's a more serious bug, maybe you can fix that as well while you're
  at it? (See below)
 
  Thanks,
  Hans
 
 
  Signed-off-by: Vitalii Demianets vi...@nppfactor.kiev.ua
  ---
   drivers/uio/uio_pdrv_genirq.c |   21 +++--
   1 files changed, 11 insertions(+), 10 deletions(-)
 
  diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c
  index 42202cd..b88cf7b 100644
  --- a/drivers/uio/uio_pdrv_genirq.c
  +++ b/drivers/uio/uio_pdrv_genirq.c
  @@ -110,7 +110,7 @@ static int uio_pdrv_genirq_probe(struct 
  platform_device *pdev)
if (!uioinfo) {
ret = -ENOMEM;
dev_err(pdev-dev, unable to kmalloc\n);
  - goto bad2;
  + goto out;
}
uioinfo-name = pdev-dev.of_node-name;
uioinfo-version = devicetree;
  @@ -125,20 +125,20 @@ static int uio_pdrv_genirq_probe(struct 
  platform_device *pdev)
 
if (!uioinfo || !uioinfo-name || !uioinfo-version) {
dev_err(pdev-dev, missing platform_data\n);
  - goto bad0;
  + goto out_uioinfo;
}
 
if (uioinfo-handler || uioinfo-irqcontrol ||
uioinfo-irq_flags  IRQF_SHARED) {
dev_err(pdev-dev, interrupt configuration error\n);
  - goto bad0;
  + goto out_uioinfo;
}
 
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv) {
ret = -ENOMEM;
dev_err(pdev-dev, unable to kmalloc\n);
  - goto bad0;
  + goto out_uioinfo;
}
 
priv-uioinfo = uioinfo;
  @@ -150,7 +150,7 @@ static int uio_pdrv_genirq_probe(struct 
  platform_device *pdev)
ret = platform_get_irq(pdev, 0);
if (ret  0) {
dev_err(pdev-dev, failed to get IRQ\n);
  - goto bad0;
  + goto out_priv;
}
uioinfo-irq = ret;
}
  @@ -205,19 +205,20 @@ static int uio_pdrv_genirq_probe(struct 
  platform_device *pdev)
ret = uio_register_device(pdev-dev, priv-uioinfo);
if (ret) {
dev_err(pdev-dev, unable to register uio device\n);
  - goto bad1;
  + goto out_pm;
}
 
platform_set_drvdata(pdev, priv);
return 0;
  - bad1:
  - kfree(priv);
  +out_pm:
pm_runtime_disable(pdev-dev);
  - bad0:
  +out_priv:
  + kfree(priv);
  +out_uioinfo:
/* kfree uioinfo for OF */
if (pdev-dev.of_node)
kfree(uioinfo);
 
  The free() depends on pdev-dev.of_node, while the allocation doesn't
  That's another source of memory leaks.
 I don't agree. In line 99, it is
 struct uio_info *uioinfo = pdev-dev.platform_data;
 if uioinfo doesn't equal to NULL, it will run to line 126,
 if (!uioinfo || !uioinfo-name || !uioinfo-version) {
 and then if uioinfo-name equals to NULL, it runs to line 127 and 128,
 and then goto bad0. If in this flow, we have to check
 pdev-dev.of_node before free(uioinfo), right?

Hmmm. The idea is that uioinfo==NULL means OF. In that case,
a struct uio_info is allocated and filled with the necessary values (name,
version, irq). It is assumed (without check...) that pdev-dev.of_node
is not NULL. If it were NULL we would crash here when dereferencing
 pdev-dev.of_node-name, leaving a memory leak.

After bad0 it is also assumed that pdev-dev.of_node is an indicator for
OF or not OF.

In other words, the case of uioinfo AND pdev-dev.of_node both being NULL
is not handled properly and will have ugly results.

 
 btw, I think in line 126 it is not necessary to check (!uioinfo),
 because if uioinfo equals to NULL, it will go to line 109, and if the
 alloc fails, it will go to bad2. uioinfo has no chance to be NULL when
 runs to line 126. So I'd like to suggest a patch to avoid unnecessary
 check like this
 
 diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c
  index 42202cd..3eb4fa2 100644
  --- a/drivers/uio/uio_pdrv_genirq.c
  +++ b/drivers/uio/uio_pdrv_genirq.c
  @@ -123,7 +123,7 @@ static int uio_pdrv_genirq_probe(struct
 platform_device *pdev)
  uioinfo-irq = irq;
  }
 
  -   if (!uioinfo || !uioinfo-name || !uioinfo-version) {
  +   if (!uioinfo-name || !uioinfo-version) {

That's wrong. We need a valid uioinfo at this point.

  dev_err(pdev-dev, missing platform_data\n);
  goto bad0

Re: [PATCH] uio_pdrv: set memory mapping name

2012-11-11 Thread Hans J. Koch
On Fri, Nov 09, 2012 at 07:06:40AM +0100, Manuel Traut wrote:
> If uio_pdrv[_genirq] is used, the uio maps have currently no name set.
> This patch sets the uio_mem name to the name of the memory resource.

Looks fine to me. I added the driver's authors to Cc.

Signed-off-by: "Hans J. Koch" 

>  
> Signed-off-by: Manuel Traut 
> Reported-by: Stefan Staedtler 
> Tested-by: Stefan Staedtler 
> 
> diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c
> index 42202cd..ac988ce 100644
> --- a/drivers/uio/uio_pdrv_genirq.c
> +++ b/drivers/uio/uio_pdrv_genirq.c
> @@ -172,6 +172,7 @@ static int uio_pdrv_genirq_probe(struct platform_device 
> *pdev)
>   uiomem->memtype = UIO_MEM_PHYS;
>   uiomem->addr = r->start;
>   uiomem->size = resource_size(r);
> + uiomem->name = r->name;
>   ++uiomem;
>   }
>  
> diff --git a/drivers/uio/uio_pdrv.c b/drivers/uio/uio_pdrv.c
> index 72d3646..39be9e0 100644
> --- a/drivers/uio/uio_pdrv.c
> +++ b/drivers/uio/uio_pdrv.c
> @@ -60,6 +60,7 @@ static int uio_pdrv_probe(struct platform_device *pdev)
>   uiomem->memtype = UIO_MEM_PHYS;
>   uiomem->addr = r->start;
>   uiomem->size = resource_size(r);
> + uiomem->name = r->name;
>   ++uiomem;
>   }
>  
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] uio_pdrv: set memory mapping name

2012-11-11 Thread Hans J. Koch
On Fri, Nov 09, 2012 at 07:06:40AM +0100, Manuel Traut wrote:
 If uio_pdrv[_genirq] is used, the uio maps have currently no name set.
 This patch sets the uio_mem name to the name of the memory resource.

Looks fine to me. I added the driver's authors to Cc.

Signed-off-by: Hans J. Koch h...@hansjkoch.de

  
 Signed-off-by: Manuel Traut ma...@linutronix.de
 Reported-by: Stefan Staedtler stefan.staedt...@siemens.com
 Tested-by: Stefan Staedtler stefan.staedt...@siemens.com
 
 diff --git a/drivers/uio/uio_pdrv_genirq.c b/drivers/uio/uio_pdrv_genirq.c
 index 42202cd..ac988ce 100644
 --- a/drivers/uio/uio_pdrv_genirq.c
 +++ b/drivers/uio/uio_pdrv_genirq.c
 @@ -172,6 +172,7 @@ static int uio_pdrv_genirq_probe(struct platform_device 
 *pdev)
   uiomem-memtype = UIO_MEM_PHYS;
   uiomem-addr = r-start;
   uiomem-size = resource_size(r);
 + uiomem-name = r-name;
   ++uiomem;
   }
  
 diff --git a/drivers/uio/uio_pdrv.c b/drivers/uio/uio_pdrv.c
 index 72d3646..39be9e0 100644
 --- a/drivers/uio/uio_pdrv.c
 +++ b/drivers/uio/uio_pdrv.c
 @@ -60,6 +60,7 @@ static int uio_pdrv_probe(struct platform_device *pdev)
   uiomem-memtype = UIO_MEM_PHYS;
   uiomem-addr = r-start;
   uiomem-size = resource_size(r);
 + uiomem-name = r-name;
   ++uiomem;
   }
  
 
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v4 1/7] uio: uio_pruss: replace private SRAM API with genalloc

2012-10-21 Thread Hans J. Koch
On Thu, Oct 18, 2012 at 10:53:38AM -0400, Matt Porter wrote:
> On Fri, Oct 05, 2012 at 01:04:40PM -0400, Matt Porter wrote:
> > Remove the use of the private DaVinci SRAM API in favor
> > of genalloc. The pool to be used is provided by platform
> > data.
> > 
> > Signed-off-by: Matt Porter 
> 
> Hans,
> 
> Any additional concerns on this patch?

Not from my side. I was waiting for your discussion to calm down.

> Sekhar is holding off on applying
> parts 4,5,7 for davinci until this is accepted.

You can add my

Signed-off-by: "Hans J. Koch" 

Thanks,
Hans

> 
> Thanks,
> Matt
> 
> > ---
> >  drivers/uio/Kconfig |1 +
> >  drivers/uio/uio_pruss.c |   24 +---
> >  include/linux/platform_data/uio_pruss.h |3 ++-
> >  3 files changed, 20 insertions(+), 8 deletions(-)
> > 
> > diff --git a/drivers/uio/Kconfig b/drivers/uio/Kconfig
> > index 6f3ea9b..c48b938 100644
> > --- a/drivers/uio/Kconfig
> > +++ b/drivers/uio/Kconfig
> > @@ -97,6 +97,7 @@ config UIO_NETX
> >  config UIO_PRUSS
> > tristate "Texas Instruments PRUSS driver"
> > depends on ARCH_DAVINCI_DA850
> > +   select GENERIC_ALLOCATOR
> > help
> >   PRUSS driver for OMAPL138/DA850/AM18XX devices
> >   PRUSS driver requires user space components, examples and user space
> > diff --git a/drivers/uio/uio_pruss.c b/drivers/uio/uio_pruss.c
> > index 33a7a27..f8738de 100644
> > --- a/drivers/uio/uio_pruss.c
> > +++ b/drivers/uio/uio_pruss.c
> > @@ -25,7 +25,7 @@
> >  #include 
> >  #include 
> >  #include 
> > -#include 
> > +#include 
> >  
> >  #define DRV_NAME "pruss_uio"
> >  #define DRV_VERSION "1.0"
> > @@ -65,10 +65,11 @@ struct uio_pruss_dev {
> > dma_addr_t sram_paddr;
> > dma_addr_t ddr_paddr;
> > void __iomem *prussio_vaddr;
> > -   void *sram_vaddr;
> > +   unsigned long sram_vaddr;
> > void *ddr_vaddr;
> > unsigned int hostirq_start;
> > unsigned int pintc_base;
> > +   struct gen_pool *sram_pool;
> >  };
> >  
> >  static irqreturn_t pruss_handler(int irq, struct uio_info *info)
> > @@ -106,7 +107,9 @@ static void pruss_cleanup(struct platform_device *dev,
> > gdev->ddr_paddr);
> > }
> > if (gdev->sram_vaddr)
> > -   sram_free(gdev->sram_vaddr, sram_pool_sz);
> > +   gen_pool_free(gdev->sram_pool,
> > + gdev->sram_vaddr,
> > + sram_pool_sz);
> > kfree(gdev->info);
> > clk_put(gdev->pruss_clk);
> > kfree(gdev);
> > @@ -152,10 +155,17 @@ static int __devinit pruss_probe(struct 
> > platform_device *dev)
> > goto out_free;
> > }
> >  
> > -   gdev->sram_vaddr = sram_alloc(sram_pool_sz, &(gdev->sram_paddr));
> > -   if (!gdev->sram_vaddr) {
> > -   dev_err(>dev, "Could not allocate SRAM pool\n");
> > -   goto out_free;
> > +   if (pdata->sram_pool) {
> > +   gdev->sram_pool = pdata->sram_pool;
> > +   gdev->sram_vaddr =
> > +   gen_pool_alloc(gdev->sram_pool, sram_pool_sz);
> > +   if (!gdev->sram_vaddr) {
> > +   dev_err(>dev, "Could not allocate SRAM pool\n");
> > +   goto out_free;
> > +   }
> > +   gdev->sram_paddr =
> > +   gen_pool_virt_to_phys(gdev->sram_pool,
> > + gdev->sram_vaddr);
> > }
> >  
> > gdev->ddr_vaddr = dma_alloc_coherent(>dev, extram_pool_sz,
> > diff --git a/include/linux/platform_data/uio_pruss.h 
> > b/include/linux/platform_data/uio_pruss.h
> > index f39140a..3d47d21 100644
> > --- a/include/linux/platform_data/uio_pruss.h
> > +++ b/include/linux/platform_data/uio_pruss.h
> > @@ -20,6 +20,7 @@
> >  
> >  /* To configure the PRUSS INTC base offset for UIO driver */
> >  struct uio_pruss_pdata {
> > -   u32 pintc_base;
> > +   u32 pintc_base;
> > +   struct gen_pool *sram_pool;
> >  };
> >  #endif /* _UIO_PRUSS_H_ */
> > -- 
> > 1.7.9.5
> > 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v4 1/7] uio: uio_pruss: replace private SRAM API with genalloc

2012-10-21 Thread Hans J. Koch
On Thu, Oct 18, 2012 at 10:53:38AM -0400, Matt Porter wrote:
 On Fri, Oct 05, 2012 at 01:04:40PM -0400, Matt Porter wrote:
  Remove the use of the private DaVinci SRAM API in favor
  of genalloc. The pool to be used is provided by platform
  data.
  
  Signed-off-by: Matt Porter mpor...@ti.com
 
 Hans,
 
 Any additional concerns on this patch?

Not from my side. I was waiting for your discussion to calm down.

 Sekhar is holding off on applying
 parts 4,5,7 for davinci until this is accepted.

You can add my

Signed-off-by: Hans J. Koch h...@hansjkoch.de

Thanks,
Hans

 
 Thanks,
 Matt
 
  ---
   drivers/uio/Kconfig |1 +
   drivers/uio/uio_pruss.c |   24 +---
   include/linux/platform_data/uio_pruss.h |3 ++-
   3 files changed, 20 insertions(+), 8 deletions(-)
  
  diff --git a/drivers/uio/Kconfig b/drivers/uio/Kconfig
  index 6f3ea9b..c48b938 100644
  --- a/drivers/uio/Kconfig
  +++ b/drivers/uio/Kconfig
  @@ -97,6 +97,7 @@ config UIO_NETX
   config UIO_PRUSS
  tristate Texas Instruments PRUSS driver
  depends on ARCH_DAVINCI_DA850
  +   select GENERIC_ALLOCATOR
  help
PRUSS driver for OMAPL138/DA850/AM18XX devices
PRUSS driver requires user space components, examples and user space
  diff --git a/drivers/uio/uio_pruss.c b/drivers/uio/uio_pruss.c
  index 33a7a27..f8738de 100644
  --- a/drivers/uio/uio_pruss.c
  +++ b/drivers/uio/uio_pruss.c
  @@ -25,7 +25,7 @@
   #include linux/clk.h
   #include linux/dma-mapping.h
   #include linux/slab.h
  -#include mach/sram.h
  +#include linux/genalloc.h
   
   #define DRV_NAME pruss_uio
   #define DRV_VERSION 1.0
  @@ -65,10 +65,11 @@ struct uio_pruss_dev {
  dma_addr_t sram_paddr;
  dma_addr_t ddr_paddr;
  void __iomem *prussio_vaddr;
  -   void *sram_vaddr;
  +   unsigned long sram_vaddr;
  void *ddr_vaddr;
  unsigned int hostirq_start;
  unsigned int pintc_base;
  +   struct gen_pool *sram_pool;
   };
   
   static irqreturn_t pruss_handler(int irq, struct uio_info *info)
  @@ -106,7 +107,9 @@ static void pruss_cleanup(struct platform_device *dev,
  gdev-ddr_paddr);
  }
  if (gdev-sram_vaddr)
  -   sram_free(gdev-sram_vaddr, sram_pool_sz);
  +   gen_pool_free(gdev-sram_pool,
  + gdev-sram_vaddr,
  + sram_pool_sz);
  kfree(gdev-info);
  clk_put(gdev-pruss_clk);
  kfree(gdev);
  @@ -152,10 +155,17 @@ static int __devinit pruss_probe(struct 
  platform_device *dev)
  goto out_free;
  }
   
  -   gdev-sram_vaddr = sram_alloc(sram_pool_sz, (gdev-sram_paddr));
  -   if (!gdev-sram_vaddr) {
  -   dev_err(dev-dev, Could not allocate SRAM pool\n);
  -   goto out_free;
  +   if (pdata-sram_pool) {
  +   gdev-sram_pool = pdata-sram_pool;
  +   gdev-sram_vaddr =
  +   gen_pool_alloc(gdev-sram_pool, sram_pool_sz);
  +   if (!gdev-sram_vaddr) {
  +   dev_err(dev-dev, Could not allocate SRAM pool\n);
  +   goto out_free;
  +   }
  +   gdev-sram_paddr =
  +   gen_pool_virt_to_phys(gdev-sram_pool,
  + gdev-sram_vaddr);
  }
   
  gdev-ddr_vaddr = dma_alloc_coherent(dev-dev, extram_pool_sz,
  diff --git a/include/linux/platform_data/uio_pruss.h 
  b/include/linux/platform_data/uio_pruss.h
  index f39140a..3d47d21 100644
  --- a/include/linux/platform_data/uio_pruss.h
  +++ b/include/linux/platform_data/uio_pruss.h
  @@ -20,6 +20,7 @@
   
   /* To configure the PRUSS INTC base offset for UIO driver */
   struct uio_pruss_pdata {
  -   u32 pintc_base;
  +   u32 pintc_base;
  +   struct gen_pool *sram_pool;
   };
   #endif /* _UIO_PRUSS_H_ */
  -- 
  1.7.9.5
  
 --
 To unsubscribe from this list: send the line unsubscribe linux-kernel in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html
 Please read the FAQ at  http://www.tux.org/lkml/
 
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC PATCH 1/3] uio: uio_pruss: port to AM33xx

2012-09-26 Thread Hans J. Koch
On Wed, Sep 26, 2012 at 09:44:29AM -0400, Matt Porter wrote:
> Add ifdefery hacks to only use SRAM on Davinci. This
> needs to be cleaned up with a sane generic SRAM allocator
> (like the DT based driver available that can't be used on
> Davinci which is just starting DT conversion) before it
> can go upstream.

I agree with that ;-)
Needing lots of ifdefs in *.c files is usually a bad sign...

Thanks anyway for posting, it's good to have things like that in the archives.

And please make driver code and documentation updates separate patches in the
future.

Hans

> 
> Adds DT, pinctrl, and runtime PM support for use on
> AM33xx.
> 
> Signed-off-by: Matt Porter 
> ---
>  Documentation/devicetree/bindings/uio/pruss.txt|   17 ++
>  .../devicetree/bindings/uio/uio_pruss.txt  |   17 ++
>  drivers/uio/Kconfig|4 +-
>  drivers/uio/uio_pruss.c|   63 
> +++-
>  4 files changed, 98 insertions(+), 3 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/uio/pruss.txt
>  create mode 100644 Documentation/devicetree/bindings/uio/uio_pruss.txt
> 
> diff --git a/Documentation/devicetree/bindings/uio/pruss.txt 
> b/Documentation/devicetree/bindings/uio/pruss.txt
> new file mode 100644
> index 000..2ac45c5
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/uio/pruss.txt
> @@ -0,0 +1,17 @@
> +TI PRUSS device
> +
> +Required properties:
> +- compatible :
> +  - "ti,pruss-v1" for AM18xx/OMAP-L138/DA850
> +  - "ti,pruss-v2" for AM33xx.
> +- ti,pintc-offset : Offset of the PINTC from the PRUSS address base
> +- ti,hwmods: Name of the hwmod associated to the PRUSS
> +
> +Example:
> +
> +pruss: pruss@4a30 {
> + compatible = "ti,pruss-v2";
> + ti,hwmods = "pruss";
> + reg = <0x4a30 0x08>;
> + ti,pintc-offset = <0x2>;
> +};
> diff --git a/Documentation/devicetree/bindings/uio/uio_pruss.txt 
> b/Documentation/devicetree/bindings/uio/uio_pruss.txt
> new file mode 100644
> index 000..2ac45c5
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/uio/uio_pruss.txt
> @@ -0,0 +1,17 @@
> +TI PRUSS device
> +
> +Required properties:
> +- compatible :
> +  - "ti,pruss-v1" for AM18xx/OMAP-L138/DA850
> +  - "ti,pruss-v2" for AM33xx.
> +- ti,pintc-offset : Offset of the PINTC from the PRUSS address base
> +- ti,hwmods: Name of the hwmod associated to the PRUSS
> +
> +Example:
> +
> +pruss: pruss@4a30 {
> + compatible = "ti,pruss-v2";
> + ti,hwmods = "pruss";
> + reg = <0x4a30 0x08>;
> + ti,pintc-offset = <0x2>;
> +};
> diff --git a/drivers/uio/Kconfig b/drivers/uio/Kconfig
> index 6f3ea9b..8da7d9b 100644
> --- a/drivers/uio/Kconfig
> +++ b/drivers/uio/Kconfig
> @@ -96,9 +96,9 @@ config UIO_NETX
>  
>  config UIO_PRUSS
>   tristate "Texas Instruments PRUSS driver"
> - depends on ARCH_DAVINCI_DA850
> + depends on ARCH_DAVINCI_DA850 || SOC_AM33XX
>   help
> -   PRUSS driver for OMAPL138/DA850/AM18XX devices
> +   PRUSS driver for OMAPL138/DA850/AM18XX and AM33XX devices
> PRUSS driver requires user space components, examples and user space
> driver is available from below SVN repo - you may use anonymous login
>  
> diff --git a/drivers/uio/uio_pruss.c b/drivers/uio/uio_pruss.c
> index 33a7a27..326ce40 100644
> --- a/drivers/uio/uio_pruss.c
> +++ b/drivers/uio/uio_pruss.c
> @@ -25,7 +25,15 @@
>  #include 
>  #include 
>  #include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#ifdef CONFIG_ARCH_DAVINCI_DA850
>  #include 
> +#endif
>  
>  #define DRV_NAME "pruss_uio"
>  #define DRV_VERSION "1.0"
> @@ -105,8 +113,10 @@ static void pruss_cleanup(struct platform_device *dev,
>   dma_free_coherent(>dev, extram_pool_sz, gdev->ddr_vaddr,
>   gdev->ddr_paddr);
>   }
> +#ifdef CONFIG_ARCH_DAVINCI_DA850
>   if (gdev->sram_vaddr)
>   sram_free(gdev->sram_vaddr, sram_pool_sz);
> +#endif
>   kfree(gdev->info);
>   clk_put(gdev->pruss_clk);
>   kfree(gdev);
> @@ -117,8 +127,10 @@ static int __devinit pruss_probe(struct platform_device 
> *dev)
>   struct uio_info *p;
>   struct uio_pruss_dev *gdev;
>   struct resource *regs_prussio;
> + struct resource res;
>   int ret = -ENODEV, cnt = 0, len;
>   struct uio_pruss_pdata *pdata = dev->dev.platform_data;
> + struct pinctrl *pinctrl;
>  
>   gdev = kzalloc(sizeof(struct uio_pruss_dev), GFP_KERNEL);
>   if (!gdev)
> @@ -129,6 +141,7 @@ static int __devinit pruss_probe(struct platform_device 
> *dev)
>   kfree(gdev);
>   return -ENOMEM;
>   }
> +#ifdef CONFIG_ARCH_DAVINCI_DA850
>   /* Power on PRU in case its not done as part of boot-loader */
>   gdev->pruss_clk = clk_get(>dev, "pruss");
>   if (IS_ERR(gdev->pruss_clk)) {
> @@ -140,6 +153,28 @@ static int __devinit pruss_probe(struct platform_device 
> *dev)
>   } 

Re: [v2 PATCH 2/2] Add uio_dmem_genirq description to UIO documentation

2012-09-26 Thread Hans J. Koch
On Tue, Sep 25, 2012 at 03:09:12PM +0900, Damian Hobson-Garcia wrote:
> Signed-off-by: Damian Hobson-Garcia 

Signed-off-by: "Hans J. Koch" 

> ---
>  Documentation/DocBook/uio-howto.tmpl |   56 
> ++
>  1 files changed, 56 insertions(+), 0 deletions(-)
> 
> diff --git a/Documentation/DocBook/uio-howto.tmpl 
> b/Documentation/DocBook/uio-howto.tmpl
> index ac3d001..db08c1a 100644
> --- a/Documentation/DocBook/uio-howto.tmpl
> +++ b/Documentation/DocBook/uio-howto.tmpl
> @@ -719,6 +719,62 @@ framework to set up sysfs files for this region. Simply 
> leave it alone.
>   
>  
>  
> +
> +Using uio_dmem_genirq for platform devices
> + 
> + In addition to statically allocated memory ranges, they may also be
> + a desire to use dynamically allocated regions in a user space driver.
> + In particular, being able to access memory made available through the
> + dma-mapping API, may be particularly useful.  The
> + uio_dmem_genirq driver provides a way to accomplish
> + this.
> + 
> + 
> + This driver is used in a similar manner to the
> + "uio_pdrv_genirq" driver with respect to interrupt
> + configuration and handling.
> + 
> + 
> + Set the .name element of
> + struct platform_device to
> + "uio_dmem_genirq" to use this driver.
> + 
> + 
> + When using this driver, fill in the .platform_data
> + element of struct platform_device, which is of type
> + struct uio_dmem_genirq_pdata and which contains the
> + following elements:
> + 
> + 
> + struct uio_info uioinfo: The same
> + structure used as the  uio_pdrv_genirq platform
> + data
> + unsigned int *dynamic_region_sizes:
> + Pointer to list of sizes of dynamic memory regions to be mapped into
> + user space.
> + 
> + unsigned int num_dynamic_regions:
> + Number of elements in dynamic_region_sizes array.
> + 
> + 
> + 
> + The dynamic regions defined in the platform data will be appended to
> + the  mem[]  array after the platform device
> + resources, which implies that the total number of static and dynamic
> + memory regions cannot exceed MAX_UIO_MAPS.
> + 
> + 
> + The dynamic memory regions will be allocated when the UIO device file,
> + /dev/uioX is opened.
> + Simiar to static memory resources, the memory region information for
> + dynamic regions is then visible via sysfs at
> + /sys/class/uio/uioX/maps/mapY/*.
> + The dynmaic memory regions will be freed when the UIO device file is
> + closed. When no processes are holding the device file open, the address
> + returned to userspace is DMA_ERROR_CODE.
> + 
> +
> +
>  
>  
>  
> -- 
> 1.7.5.4
> 
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [v2 PATCH 1/2] Add new uio device for dynamic memory allocation

2012-09-26 Thread Hans J. Koch
On Tue, Sep 25, 2012 at 03:09:11PM +0900, Damian Hobson-Garcia wrote:
> This device extends the uio_pdrv_genirq driver to provide limited
> dynamic memory allocation for UIO devices.  This allows UIO devices
> to use CMA and IOMMU allocated memory regions. This driver is based
> on the uio_pdrv_genirq driver and provides the same generic interrupt
> handling capabilities.  Like uio_prdv_genirq,
> a fixed number of memory regions, defined in the platform device's
> .resources field are exported to userpace. This driver adds the ability
> to export additional regions whose number and size are known at boot time,
> but whose memory is not allocated until the uio device file is opened for
> the first time.  When the device file is closed, the allocated memory block
> is freed.  Physical (DMA) addresses for the dynamic regions are provided to
> the userspace via /sys/class/uio/uioX/maps/mapY/addr in the same way as
> static addresses are when the uio device file is open, when no processes
> are holding the device file open, the address returned to userspace is
> DMA_ERROR_CODE.
> 
> Signed-off-by: Damian Hobson-Garcia 

Thanks for your contribution!

Signed-off-by: "Hans J. Koch" 

> ---
>  drivers/uio/Kconfig   |   16 ++
>  drivers/uio/Makefile  |1 +
>  drivers/uio/uio_dmem_genirq.c |  354 
> +
>  include/linux/platform_data/uio_dmem_genirq.h |   26 ++
>  4 files changed, 397 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/uio/uio_dmem_genirq.c
>  create mode 100644 include/linux/platform_data/uio_dmem_genirq.h
> 
> diff --git a/drivers/uio/Kconfig b/drivers/uio/Kconfig
> index 6f3ea9b..82e2b89 100644
> --- a/drivers/uio/Kconfig
> +++ b/drivers/uio/Kconfig
> @@ -44,6 +44,22 @@ config UIO_PDRV_GENIRQ
>  
> If you don't know what to do here, say N.
>  
> +config UIO_DMEM_GENIRQ
> + tristate "Userspace platform driver with generic irq and dynamic memory"
> + help
> +   Platform driver for Userspace I/O devices, including generic
> +   interrupt handling code. Shared interrupts are not supported.
> +
> +   Memory regions can be specified with the same platform device
> +   resources as the UIO_PDRV drivers, but dynamic regions can also
> +   be specified.
> +   The number and size of these regions is static,
> +   but the memory allocation is not performed until
> +   the associated device file is opened. The
> +   memory is freed once the uio device is closed.
> +
> +   If you don't know what to do here, say N.
> +
>  config UIO_AEC
>   tristate "AEC video timestamp device"
>   depends on PCI
> diff --git a/drivers/uio/Makefile b/drivers/uio/Makefile
> index d4dd9a5..b354c53 100644
> --- a/drivers/uio/Makefile
> +++ b/drivers/uio/Makefile
> @@ -2,6 +2,7 @@ obj-$(CONFIG_UIO) += uio.o
>  obj-$(CONFIG_UIO_CIF)+= uio_cif.o
>  obj-$(CONFIG_UIO_PDRV)   += uio_pdrv.o
>  obj-$(CONFIG_UIO_PDRV_GENIRQ)+= uio_pdrv_genirq.o
> +obj-$(CONFIG_UIO_DMEM_GENIRQ)+= uio_dmem_genirq.o
>  obj-$(CONFIG_UIO_AEC)+= uio_aec.o
>  obj-$(CONFIG_UIO_SERCOS3)+= uio_sercos3.o
>  obj-$(CONFIG_UIO_PCI_GENERIC)+= uio_pci_generic.o
> diff --git a/drivers/uio/uio_dmem_genirq.c b/drivers/uio/uio_dmem_genirq.c
> new file mode 100644
> index 000..4d4dd00
> --- /dev/null
> +++ b/drivers/uio/uio_dmem_genirq.c
> @@ -0,0 +1,354 @@
> +/*
> + * drivers/uio/uio_dmem_genirq.c
> + *
> + * Userspace I/O platform driver with generic IRQ handling code.
> + *
> + * Copyright (C) 2012 Damian Hobson-Garcia
> + *
> + * Based on uio_pdrv_genirq.c by Magnus Damm
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License version 2 as published 
> by
> + * the Free Software Foundation.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +#include 
> +#include 
> +
> +#define DRIVER_NAME "uio_dmem_genirq"
> +
> +struct uio_dmem_genirq_platdata {
> + struct uio_info *uioinfo;
> + spinlock_t lock;
> + unsigned long flags;
> + struct platform_device *pdev;
> + unsigned int dmem_region_start;
> + unsigned int num_dmem_regions;
> + struct mutex alloc_lock;
> + unsigned int refcnt;
> +};
> +
> +static int uio_dmem_genirq_open(struct uio_info *info, struct inode *inode)
> +{
> + struct uio_dmem_genirq_platdata *priv = in

Re: [v2 PATCH 1/2] Add new uio device for dynamic memory allocation

2012-09-26 Thread Hans J. Koch
On Tue, Sep 25, 2012 at 03:09:11PM +0900, Damian Hobson-Garcia wrote:
 This device extends the uio_pdrv_genirq driver to provide limited
 dynamic memory allocation for UIO devices.  This allows UIO devices
 to use CMA and IOMMU allocated memory regions. This driver is based
 on the uio_pdrv_genirq driver and provides the same generic interrupt
 handling capabilities.  Like uio_prdv_genirq,
 a fixed number of memory regions, defined in the platform device's
 .resources field are exported to userpace. This driver adds the ability
 to export additional regions whose number and size are known at boot time,
 but whose memory is not allocated until the uio device file is opened for
 the first time.  When the device file is closed, the allocated memory block
 is freed.  Physical (DMA) addresses for the dynamic regions are provided to
 the userspace via /sys/class/uio/uioX/maps/mapY/addr in the same way as
 static addresses are when the uio device file is open, when no processes
 are holding the device file open, the address returned to userspace is
 DMA_ERROR_CODE.
 
 Signed-off-by: Damian Hobson-Garcia dhobs...@igel.co.jp

Thanks for your contribution!

Signed-off-by: Hans J. Koch h...@hansjkoch.de

 ---
  drivers/uio/Kconfig   |   16 ++
  drivers/uio/Makefile  |1 +
  drivers/uio/uio_dmem_genirq.c |  354 
 +
  include/linux/platform_data/uio_dmem_genirq.h |   26 ++
  4 files changed, 397 insertions(+), 0 deletions(-)
  create mode 100644 drivers/uio/uio_dmem_genirq.c
  create mode 100644 include/linux/platform_data/uio_dmem_genirq.h
 
 diff --git a/drivers/uio/Kconfig b/drivers/uio/Kconfig
 index 6f3ea9b..82e2b89 100644
 --- a/drivers/uio/Kconfig
 +++ b/drivers/uio/Kconfig
 @@ -44,6 +44,22 @@ config UIO_PDRV_GENIRQ
  
 If you don't know what to do here, say N.
  
 +config UIO_DMEM_GENIRQ
 + tristate Userspace platform driver with generic irq and dynamic memory
 + help
 +   Platform driver for Userspace I/O devices, including generic
 +   interrupt handling code. Shared interrupts are not supported.
 +
 +   Memory regions can be specified with the same platform device
 +   resources as the UIO_PDRV drivers, but dynamic regions can also
 +   be specified.
 +   The number and size of these regions is static,
 +   but the memory allocation is not performed until
 +   the associated device file is opened. The
 +   memory is freed once the uio device is closed.
 +
 +   If you don't know what to do here, say N.
 +
  config UIO_AEC
   tristate AEC video timestamp device
   depends on PCI
 diff --git a/drivers/uio/Makefile b/drivers/uio/Makefile
 index d4dd9a5..b354c53 100644
 --- a/drivers/uio/Makefile
 +++ b/drivers/uio/Makefile
 @@ -2,6 +2,7 @@ obj-$(CONFIG_UIO) += uio.o
  obj-$(CONFIG_UIO_CIF)+= uio_cif.o
  obj-$(CONFIG_UIO_PDRV)   += uio_pdrv.o
  obj-$(CONFIG_UIO_PDRV_GENIRQ)+= uio_pdrv_genirq.o
 +obj-$(CONFIG_UIO_DMEM_GENIRQ)+= uio_dmem_genirq.o
  obj-$(CONFIG_UIO_AEC)+= uio_aec.o
  obj-$(CONFIG_UIO_SERCOS3)+= uio_sercos3.o
  obj-$(CONFIG_UIO_PCI_GENERIC)+= uio_pci_generic.o
 diff --git a/drivers/uio/uio_dmem_genirq.c b/drivers/uio/uio_dmem_genirq.c
 new file mode 100644
 index 000..4d4dd00
 --- /dev/null
 +++ b/drivers/uio/uio_dmem_genirq.c
 @@ -0,0 +1,354 @@
 +/*
 + * drivers/uio/uio_dmem_genirq.c
 + *
 + * Userspace I/O platform driver with generic IRQ handling code.
 + *
 + * Copyright (C) 2012 Damian Hobson-Garcia
 + *
 + * Based on uio_pdrv_genirq.c by Magnus Damm
 + *
 + * This program is free software; you can redistribute it and/or modify it
 + * under the terms of the GNU General Public License version 2 as published 
 by
 + * the Free Software Foundation.
 + */
 +
 +#include linux/platform_device.h
 +#include linux/uio_driver.h
 +#include linux/spinlock.h
 +#include linux/bitops.h
 +#include linux/module.h
 +#include linux/interrupt.h
 +#include linux/platform_data/uio_dmem_genirq.h
 +#include linux/stringify.h
 +#include linux/pm_runtime.h
 +#include linux/dma-mapping.h
 +#include linux/slab.h
 +
 +#include linux/of.h
 +#include linux/of_platform.h
 +#include linux/of_address.h
 +
 +#define DRIVER_NAME uio_dmem_genirq
 +
 +struct uio_dmem_genirq_platdata {
 + struct uio_info *uioinfo;
 + spinlock_t lock;
 + unsigned long flags;
 + struct platform_device *pdev;
 + unsigned int dmem_region_start;
 + unsigned int num_dmem_regions;
 + struct mutex alloc_lock;
 + unsigned int refcnt;
 +};
 +
 +static int uio_dmem_genirq_open(struct uio_info *info, struct inode *inode)
 +{
 + struct uio_dmem_genirq_platdata *priv = info-priv;
 + struct uio_mem *uiomem;
 + int ret = 0;
 +
 + uiomem = priv-uioinfo-mem[priv-dmem_region_start];
 +
 + mutex_lock(priv-alloc_lock);
 + while (!priv-refcnt  uiomem  priv-uioinfo-mem[MAX_UIO_MAPS]) {
 + void

Re: [v2 PATCH 2/2] Add uio_dmem_genirq description to UIO documentation

2012-09-26 Thread Hans J. Koch
On Tue, Sep 25, 2012 at 03:09:12PM +0900, Damian Hobson-Garcia wrote:
 Signed-off-by: Damian Hobson-Garcia dhobs...@igel.co.jp

Signed-off-by: Hans J. Koch h...@hansjkoch.de

 ---
  Documentation/DocBook/uio-howto.tmpl |   56 
 ++
  1 files changed, 56 insertions(+), 0 deletions(-)
 
 diff --git a/Documentation/DocBook/uio-howto.tmpl 
 b/Documentation/DocBook/uio-howto.tmpl
 index ac3d001..db08c1a 100644
 --- a/Documentation/DocBook/uio-howto.tmpl
 +++ b/Documentation/DocBook/uio-howto.tmpl
 @@ -719,6 +719,62 @@ framework to set up sysfs files for this region. Simply 
 leave it alone.
   /para
  /sect1
  
 +sect1 id=using uio_dmem_genirq
 +titleUsing uio_dmem_genirq for platform devices/title
 + para
 + In addition to statically allocated memory ranges, they may also be
 + a desire to use dynamically allocated regions in a user space driver.
 + In particular, being able to access memory made available through the
 + dma-mapping API, may be particularly useful.  The
 + varnameuio_dmem_genirq/varname driver provides a way to accomplish
 + this.
 + /para
 + para
 + This driver is used in a similar manner to the
 + varnameuio_pdrv_genirq/varname driver with respect to interrupt
 + configuration and handling.
 + /para
 + para
 + Set the varname.name/varname element of
 + varnamestruct platform_device/varname to
 + varnameuio_dmem_genirq/varname to use this driver.
 + /para
 + para
 + When using this driver, fill in the varname.platform_data/varname
 + element of varnamestruct platform_device/varname, which is of type
 + varnamestruct uio_dmem_genirq_pdata/varname and which contains the
 + following elements:
 + /para
 + itemizedlist
 + listitemvarnamestruct uio_info uioinfo/varname: The same
 + structure used as the  varnameuio_pdrv_genirq/varname platform
 + data/listitem
 + listitemvarnameunsigned int *dynamic_region_sizes/varname:
 + Pointer to list of sizes of dynamic memory regions to be mapped into
 + user space.
 + /listitem
 + listitemvarnameunsigned int num_dynamic_regions/varname:
 + Number of elements in varnamedynamic_region_sizes/varname array.
 + /listitem
 + /itemizedlist
 + para
 + The dynamic regions defined in the platform data will be appended to
 + the varname mem[] /varname array after the platform device
 + resources, which implies that the total number of static and dynamic
 + memory regions cannot exceed varnameMAX_UIO_MAPS/varname.
 + /para
 + para
 + The dynamic memory regions will be allocated when the UIO device file,
 + varname/dev/uioX/varname is opened.
 + Simiar to static memory resources, the memory region information for
 + dynamic regions is then visible via sysfs at
 + varname/sys/class/uio/uioX/maps/mapY/*/varname.
 + The dynmaic memory regions will be freed when the UIO device file is
 + closed. When no processes are holding the device file open, the address
 + returned to userspace is DMA_ERROR_CODE.
 + /para
 +/sect1
 +
  /chapter
  
  chapter id=userspace_driver xreflabel=Writing a driver in user space
 -- 
 1.7.5.4
 
 
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC PATCH 1/3] uio: uio_pruss: port to AM33xx

2012-09-26 Thread Hans J. Koch
On Wed, Sep 26, 2012 at 09:44:29AM -0400, Matt Porter wrote:
 Add ifdefery hacks to only use SRAM on Davinci. This
 needs to be cleaned up with a sane generic SRAM allocator
 (like the DT based driver available that can't be used on
 Davinci which is just starting DT conversion) before it
 can go upstream.

I agree with that ;-)
Needing lots of ifdefs in *.c files is usually a bad sign...

Thanks anyway for posting, it's good to have things like that in the archives.

And please make driver code and documentation updates separate patches in the
future.

Hans

 
 Adds DT, pinctrl, and runtime PM support for use on
 AM33xx.
 
 Signed-off-by: Matt Porter mpor...@ti.com
 ---
  Documentation/devicetree/bindings/uio/pruss.txt|   17 ++
  .../devicetree/bindings/uio/uio_pruss.txt  |   17 ++
  drivers/uio/Kconfig|4 +-
  drivers/uio/uio_pruss.c|   63 
 +++-
  4 files changed, 98 insertions(+), 3 deletions(-)
  create mode 100644 Documentation/devicetree/bindings/uio/pruss.txt
  create mode 100644 Documentation/devicetree/bindings/uio/uio_pruss.txt
 
 diff --git a/Documentation/devicetree/bindings/uio/pruss.txt 
 b/Documentation/devicetree/bindings/uio/pruss.txt
 new file mode 100644
 index 000..2ac45c5
 --- /dev/null
 +++ b/Documentation/devicetree/bindings/uio/pruss.txt
 @@ -0,0 +1,17 @@
 +TI PRUSS device
 +
 +Required properties:
 +- compatible :
 +  - ti,pruss-v1 for AM18xx/OMAP-L138/DA850
 +  - ti,pruss-v2 for AM33xx.
 +- ti,pintc-offset : Offset of the PINTC from the PRUSS address base
 +- ti,hwmods: Name of the hwmod associated to the PRUSS
 +
 +Example:
 +
 +pruss: pruss@4a30 {
 + compatible = ti,pruss-v2;
 + ti,hwmods = pruss;
 + reg = 0x4a30 0x08;
 + ti,pintc-offset = 0x2;
 +};
 diff --git a/Documentation/devicetree/bindings/uio/uio_pruss.txt 
 b/Documentation/devicetree/bindings/uio/uio_pruss.txt
 new file mode 100644
 index 000..2ac45c5
 --- /dev/null
 +++ b/Documentation/devicetree/bindings/uio/uio_pruss.txt
 @@ -0,0 +1,17 @@
 +TI PRUSS device
 +
 +Required properties:
 +- compatible :
 +  - ti,pruss-v1 for AM18xx/OMAP-L138/DA850
 +  - ti,pruss-v2 for AM33xx.
 +- ti,pintc-offset : Offset of the PINTC from the PRUSS address base
 +- ti,hwmods: Name of the hwmod associated to the PRUSS
 +
 +Example:
 +
 +pruss: pruss@4a30 {
 + compatible = ti,pruss-v2;
 + ti,hwmods = pruss;
 + reg = 0x4a30 0x08;
 + ti,pintc-offset = 0x2;
 +};
 diff --git a/drivers/uio/Kconfig b/drivers/uio/Kconfig
 index 6f3ea9b..8da7d9b 100644
 --- a/drivers/uio/Kconfig
 +++ b/drivers/uio/Kconfig
 @@ -96,9 +96,9 @@ config UIO_NETX
  
  config UIO_PRUSS
   tristate Texas Instruments PRUSS driver
 - depends on ARCH_DAVINCI_DA850
 + depends on ARCH_DAVINCI_DA850 || SOC_AM33XX
   help
 -   PRUSS driver for OMAPL138/DA850/AM18XX devices
 +   PRUSS driver for OMAPL138/DA850/AM18XX and AM33XX devices
 PRUSS driver requires user space components, examples and user space
 driver is available from below SVN repo - you may use anonymous login
  
 diff --git a/drivers/uio/uio_pruss.c b/drivers/uio/uio_pruss.c
 index 33a7a27..326ce40 100644
 --- a/drivers/uio/uio_pruss.c
 +++ b/drivers/uio/uio_pruss.c
 @@ -25,7 +25,15 @@
  #include linux/clk.h
  #include linux/dma-mapping.h
  #include linux/slab.h
 +#include linux/of_address.h
 +#include linux/of_device.h
 +#include linux/pinctrl/consumer.h
 +#include linux/err.h
 +#include linux/pm_runtime.h
 +
 +#ifdef CONFIG_ARCH_DAVINCI_DA850
  #include mach/sram.h
 +#endif
  
  #define DRV_NAME pruss_uio
  #define DRV_VERSION 1.0
 @@ -105,8 +113,10 @@ static void pruss_cleanup(struct platform_device *dev,
   dma_free_coherent(dev-dev, extram_pool_sz, gdev-ddr_vaddr,
   gdev-ddr_paddr);
   }
 +#ifdef CONFIG_ARCH_DAVINCI_DA850
   if (gdev-sram_vaddr)
   sram_free(gdev-sram_vaddr, sram_pool_sz);
 +#endif
   kfree(gdev-info);
   clk_put(gdev-pruss_clk);
   kfree(gdev);
 @@ -117,8 +127,10 @@ static int __devinit pruss_probe(struct platform_device 
 *dev)
   struct uio_info *p;
   struct uio_pruss_dev *gdev;
   struct resource *regs_prussio;
 + struct resource res;
   int ret = -ENODEV, cnt = 0, len;
   struct uio_pruss_pdata *pdata = dev-dev.platform_data;
 + struct pinctrl *pinctrl;
  
   gdev = kzalloc(sizeof(struct uio_pruss_dev), GFP_KERNEL);
   if (!gdev)
 @@ -129,6 +141,7 @@ static int __devinit pruss_probe(struct platform_device 
 *dev)
   kfree(gdev);
   return -ENOMEM;
   }
 +#ifdef CONFIG_ARCH_DAVINCI_DA850
   /* Power on PRU in case its not done as part of boot-loader */
   gdev-pruss_clk = clk_get(dev-dev, pruss);
   if (IS_ERR(gdev-pruss_clk)) {
 @@ -140,6 +153,28 @@ static int __devinit pruss_probe(struct platform_device 
 *dev)
   } else {
  

Re: [RFC PATCH 0/2] Add UIO device supporting dynamic memory allocation

2012-09-12 Thread Hans J. Koch
On Wed, Sep 12, 2012 at 02:29:43PM +0900, Damian Hobson-Garcia wrote:
> Reposting: I realized that this series should have gone out to a broader list.

You forgot GregKH, I added him.

> My apologies to those who those who will recieve a duplicate post. 
> 
> Hello all,
> 
> I've been using this UIO driver for allocation/deallocation
> of memory regions through an IOMMU via the dma-mapping API, but
> it seems that it would be more generally useful for userspace drivers
> to access CMA memory regions. I don't know if it's useful to try to add
> this functionality into the core uio driver or not, so for now I've kept
> all dynamic memory handling in the specific device driver.
> 
> The number and size of the dynamically allocatable regions is defined
> statically in the device platform data, and the actually memory is
> allocated and deallocated when the device is opened/closed.
> 
> Details of the dynamically allocated regions are available from sysfs in
> exactly the same was as for static regions. The total number of
> dynamic and static regions combined cannot exceed MAX_UIO_MAPS.
> 
> Any comments, especially with regard to exposing the dma-mapping API to
> userspace in this way, would be greatly appreciated.
> 
> Damian Hobson-Garcia (2):
>   Add new uio device for dynamic memory allocation
>   ARM: shmobile: sh7372: Change VPU UIO to uio_dmem_genirq
> 
>  arch/arm/mach-shmobile/setup-sh7372.c |   19 +-
>  drivers/uio/Kconfig   |   16 ++
>  drivers/uio/Makefile  |1 +
>  drivers/uio/uio_dmem_genirq.c |  356 
> +
>  include/linux/platform_data/uio_dmem_genirq.h |   26 ++
>  5 files changed, 413 insertions(+), 5 deletions(-)
>  create mode 100644 drivers/uio/uio_dmem_genirq.c
>  create mode 100644 include/linux/platform_data/uio_dmem_genirq.h

Please add a third patch with a few words for 
Documentation/DocBook/uio-howto.tmpl
since this driver could be useful for other people, too.

Otherwise, looks good to me.

Thanks,
Hans
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [RFC PATCH 0/2] Add UIO device supporting dynamic memory allocation

2012-09-12 Thread Hans J. Koch
On Wed, Sep 12, 2012 at 02:29:43PM +0900, Damian Hobson-Garcia wrote:
 Reposting: I realized that this series should have gone out to a broader list.

You forgot GregKH, I added him.

 My apologies to those who those who will recieve a duplicate post. 
 
 Hello all,
 
 I've been using this UIO driver for allocation/deallocation
 of memory regions through an IOMMU via the dma-mapping API, but
 it seems that it would be more generally useful for userspace drivers
 to access CMA memory regions. I don't know if it's useful to try to add
 this functionality into the core uio driver or not, so for now I've kept
 all dynamic memory handling in the specific device driver.
 
 The number and size of the dynamically allocatable regions is defined
 statically in the device platform data, and the actually memory is
 allocated and deallocated when the device is opened/closed.
 
 Details of the dynamically allocated regions are available from sysfs in
 exactly the same was as for static regions. The total number of
 dynamic and static regions combined cannot exceed MAX_UIO_MAPS.
 
 Any comments, especially with regard to exposing the dma-mapping API to
 userspace in this way, would be greatly appreciated.
 
 Damian Hobson-Garcia (2):
   Add new uio device for dynamic memory allocation
   ARM: shmobile: sh7372: Change VPU UIO to uio_dmem_genirq
 
  arch/arm/mach-shmobile/setup-sh7372.c |   19 +-
  drivers/uio/Kconfig   |   16 ++
  drivers/uio/Makefile  |1 +
  drivers/uio/uio_dmem_genirq.c |  356 
 +
  include/linux/platform_data/uio_dmem_genirq.h |   26 ++
  5 files changed, 413 insertions(+), 5 deletions(-)
  create mode 100644 drivers/uio/uio_dmem_genirq.c
  create mode 100644 include/linux/platform_data/uio_dmem_genirq.h

Please add a third patch with a few words for 
Documentation/DocBook/uio-howto.tmpl
since this driver could be useful for other people, too.

Otherwise, looks good to me.

Thanks,
Hans
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Using uio_pdrv to create an platform device for an FPGA, mmap() fails

2012-08-31 Thread Hans J. Koch
On Thu, Aug 30, 2012 at 11:03:04PM +, Worth, Kevin wrote:
> >
> >>  but the code seems like
> >> possibly useful sample/example code.
> >
> >That is another good argument.
> 
> Perhaps this could be genericized to be a generic "Memory Map Userspace
> IO Device" that takes a base address and a length in config (since those
> are really the only things that are particular to my device/usage).

I don't see a point in making it more generic than it already is. Other
people's devices generate interrupts or have several mappings. Since these
drivers are so small, especially when using uio_pdrv, it doesn't make sense
to make it more generic.

> Could be enhanced to allow for additional maps, etc. or just serve as a
> working example. Docs could then also simply refer to this as an example
> of a device that uses the uio_pdrv driver.

Just make your driver clean and simple, then refer to it in the docs as one
possible example.

Thanks,
Hans

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Using uio_pdrv to create an platform device for an FPGA, mmap() fails

2012-08-31 Thread Hans J. Koch
On Thu, Aug 30, 2012 at 11:03:04PM +, Worth, Kevin wrote:
 
   but the code seems like
  possibly useful sample/example code.
 
 That is another good argument.
 
 Perhaps this could be genericized to be a generic Memory Map Userspace
 IO Device that takes a base address and a length in config (since those
 are really the only things that are particular to my device/usage).

I don't see a point in making it more generic than it already is. Other
people's devices generate interrupts or have several mappings. Since these
drivers are so small, especially when using uio_pdrv, it doesn't make sense
to make it more generic.

 Could be enhanced to allow for additional maps, etc. or just serve as a
 working example. Docs could then also simply refer to this as an example
 of a device that uses the uio_pdrv driver.

Just make your driver clean and simple, then refer to it in the docs as one
possible example.

Thanks,
Hans

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Using uio_pdrv to create an platform device for an FPGA, mmap() fails

2012-08-30 Thread Hans J. Koch
[Added Greg Kroah-Hartman to Cc:]

On Thu, Aug 30, 2012 at 08:10:11PM +, Worth, Kevin wrote:
> >> Thanks for the reply, Hans. Your question about opening /dev/uio0 O_RDWR
> >> prompted me to check out how I was creating /dev/uio0 ... my system
> >> isn't using udev, and I was accidentally creating it with major/minor
> >> number 254/0 instead of the correct 253/0 (found by looking at
> >> /proc/devices). Fixed that and the mmap() call started working.
> >
> >Good.
> >
> >> 
> >> Verified that if /dev/uio0 has permissions 0644, root can open it O_RDWR
> >> and mmap PROT_READ | PROT_WRITE using the below code and write to an
> >> address within my memory map. Of course this contradicts the statement
> >> "/dev/uioX is a read-only file" in the UIO howto.
> >
> >You're right. That wants to be fixed...
> >
> >> 
> >> Including my updated, tested code for completeness.
> >> Note I also cleaned up the device registration a little by
> >> using a different platform_device_register_ call and removing fields
> >> in the struct uio_info that get filled in by uio_pdrv automatically.
> >
> >If you want to have that included in the mainline, please choose a more
> >descriptive name than "myfpga" and send a proper patch.
> 
> I wasn't sure about submitting as a patch since it's for a custom FPGA
> that I don't expect the community will be using,

That doesn't matter. If it helps YOU that the code is maintained in mainline,
post it.

>  but the code seems like
> possibly useful sample/example code.

That is another good argument.

> Perhaps patching the HOWTO like
> http://www.kernel.org/doc/htmldocs/uio-howto.html#uio_pci_generic_example
> is the right approach?

Oh, if you could hack up a patch for the documentation, that would be great.
But please make it a second patch, don't mix it with your driver code.

Thanks,
Hans

> 
> >
> >Thanks,
> >Hans
> >
> >> 
> >> -Kevin
> >> 
> >> # lsuio -m -v
> >> uio0: name=uio_myfpga, version=0.1, events=0
> >> map[0]: addr=0xD000, size=262144, mmap test: OK
> >> Device attributes:
> >> uevent=DRIVER=uio_pdrv
> >> modalias=platform:uio_pdrv
> >> 
> >> --Kernelspace--
> >> #include 
> >> #include 
> >> #include 
> >> 
> >> #define MYFPGA_BASE 0xd000 // 3G
> >> #define MYFPGA_SIZE 0x0004 // 256k
> >> 
> >> static struct resource myfpga_resources[] = {
> >> {
> >> .start = MYFPGA_BASE,
> >> .end   = MYFPGA_BASE + MYFPGA_SIZE - 1,
> >> .name  = "myfpga",
> >> .flags = IORESOURCE_MEM
> >> }
> >> };
> >> 
> >> static struct uio_info myfpga_uio_info = {
> >>.name = "uio_myfpga",
> >>.version = "0.1",
> >> };
> >> 
> >> static struct platform_device *myfpga_uio_pdev;
> >> 
> >> static int __init myfpga_init(void)
> >> {
> >> myfpga_uio_pdev = platform_device_register_resndata (NULL,
> >>  "uio_pdrv",
> >>  -1,
> >>  myfpga_resources,
> >>  1,
> >>  _uio_info,
> >>  sizeof(struct 
> >> uio_info)
> >> );
> >> if (IS_ERR(myfpga_uio_pdev)) {
> >> return PTR_ERR(myfpga_uio_pdev);
> >> }
> >> 
> >> return 0;
> >> }
> >> 
> >> static void __exit myfpga_exit(void)
> >> {
> >> platform_device_unregister(myfpga_uio_pdev);
> >> }
> >> 
> >> module_init(myfpga_init);
> >> module_exit(myfpga_exit);
> >> 
> >> --Userspace---
> >> #include 
> >> #include 
> >> #include 
> >> 
> >> #include 
> >> #include 
> >> #include 
> >> #include 
> >> #include 
> >> #include 
> >> #include 
> >> 
> >> #define MYFPGA_BASE 0xd000 // 3G
> >> #define MYFPGA_SIZE 0x0004 // 256k
> >> #define MYFPGA_MAP_NUM  0 // First and only defined map
> >> 
> >> #define BIT32(n) (1 << (n))
> >> 
> >> /* Use mmap()'ped address "iomem", not physical MYFPGA address */
> >> #define MYFPGA_REG(iomem) (volatile uint32_t*)(iomem + 0x8) // Third 
> >> 32-bit reg
> >> 
> >> int main (int argc, char *argv[])
> >> {
> >> int fd;
> >> void *iomem;
> >> fd = open("/dev/uio0", O_RDWR|O_SYNC);
> >> if (fd < 0) {
> >> printf("failed to open /dev/uio0, quitting\n");
> >> return -1;
> >> }
> >> /* Note offset has a special meaning with uio devices */
> >> iomem = mmap(NULL, MYFPGA_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
> >>  MYFPGA_MAP_NUM * getpagesize());
> >> if (iomem == MAP_FAILED) {
> >> printf("mmap failed, quitting\n");
> >> close(fd);
> >> return -2;
> >> }
> >> 
> >> /* Set bit 5 of MYFPGA_REG register */
> >> *MYFPGA_REG(iomem) |= BIT32(5);
> >> 
> >> munmap(iomem, MYFPGA_SIZE);
> >> 

Re: Using uio_pdrv to create an platform device for an FPGA, mmap() fails

2012-08-30 Thread Hans J. Koch
On Thu, Aug 30, 2012 at 06:36:53PM +, Worth, Kevin wrote:
> Thanks for the reply, Hans. Your question about opening /dev/uio0 O_RDWR
> prompted me to check out how I was creating /dev/uio0 ... my system
> isn't using udev, and I was accidentally creating it with major/minor
> number 254/0 instead of the correct 253/0 (found by looking at
> /proc/devices). Fixed that and the mmap() call started working.

Good.

> 
> Verified that if /dev/uio0 has permissions 0644, root can open it O_RDWR
> and mmap PROT_READ | PROT_WRITE using the below code and write to an
> address within my memory map. Of course this contradicts the statement
> "/dev/uioX is a read-only file" in the UIO howto.

You're right. That wants to be fixed...

> 
> Including my updated, tested code for completeness.
> Note I also cleaned up the device registration a little by
> using a different platform_device_register_ call and removing fields
> in the struct uio_info that get filled in by uio_pdrv automatically.

If you want to have that included in the mainline, please choose a more
descriptive name than "myfpga" and send a proper patch.

Thanks,
Hans

> 
> -Kevin
> 
> # lsuio -m -v
> uio0: name=uio_myfpga, version=0.1, events=0
> map[0]: addr=0xD000, size=262144, mmap test: OK
> Device attributes:
> uevent=DRIVER=uio_pdrv
> modalias=platform:uio_pdrv
> 
> --Kernelspace--
> #include 
> #include 
> #include 
> 
> #define MYFPGA_BASE 0xd000 // 3G
> #define MYFPGA_SIZE 0x0004 // 256k
> 
> static struct resource myfpga_resources[] = {
> {
> .start = MYFPGA_BASE,
> .end   = MYFPGA_BASE + MYFPGA_SIZE - 1,
> .name  = "myfpga",
> .flags = IORESOURCE_MEM
> }
> };
> 
> static struct uio_info myfpga_uio_info = {
>.name = "uio_myfpga",
>.version = "0.1",
> };
> 
> static struct platform_device *myfpga_uio_pdev;
> 
> static int __init myfpga_init(void)
> {
> myfpga_uio_pdev = platform_device_register_resndata (NULL,
>  "uio_pdrv",
>  -1,
>  myfpga_resources,
>  1,
>  _uio_info,
>  sizeof(struct 
> uio_info)
> );
> if (IS_ERR(myfpga_uio_pdev)) {
> return PTR_ERR(myfpga_uio_pdev);
> }
> 
> return 0;
> }
> 
> static void __exit myfpga_exit(void)
> {
> platform_device_unregister(myfpga_uio_pdev);
> }
> 
> module_init(myfpga_init);
> module_exit(myfpga_exit);
> 
> --Userspace---
> #include 
> #include 
> #include 
> 
> #include 
> #include 
> #include 
> #include 
> #include 
> #include 
> #include 
> 
> #define MYFPGA_BASE 0xd000 // 3G
> #define MYFPGA_SIZE 0x0004 // 256k
> #define MYFPGA_MAP_NUM  0 // First and only defined map
> 
> #define BIT32(n) (1 << (n))
> 
> /* Use mmap()'ped address "iomem", not physical MYFPGA address */
> #define MYFPGA_REG(iomem) (volatile uint32_t*)(iomem + 0x8) // Third 32-bit 
> reg
> 
> int main (int argc, char *argv[])
> {
> int fd;
> void *iomem;
> fd = open("/dev/uio0", O_RDWR|O_SYNC);
> if (fd < 0) {
> printf("failed to open /dev/uio0, quitting\n");
> return -1;
> }
> /* Note offset has a special meaning with uio devices */
> iomem = mmap(NULL, MYFPGA_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
>  MYFPGA_MAP_NUM * getpagesize());
> if (iomem == MAP_FAILED) {
> printf("mmap failed, quitting\n");
> close(fd);
> return -2;
> }
> 
> /* Set bit 5 of MYFPGA_REG register */
> *MYFPGA_REG(iomem) |= BIT32(5);
> 
> munmap(iomem, MYFPGA_SIZE);
> close(fd);
> return 0;
> }
>  
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Using uio_pdrv to create an platform device for an FPGA, mmap() fails

2012-08-30 Thread Hans J. Koch
On Thu, Aug 30, 2012 at 06:36:53PM +, Worth, Kevin wrote:
 Thanks for the reply, Hans. Your question about opening /dev/uio0 O_RDWR
 prompted me to check out how I was creating /dev/uio0 ... my system
 isn't using udev, and I was accidentally creating it with major/minor
 number 254/0 instead of the correct 253/0 (found by looking at
 /proc/devices). Fixed that and the mmap() call started working.

Good.

 
 Verified that if /dev/uio0 has permissions 0644, root can open it O_RDWR
 and mmap PROT_READ | PROT_WRITE using the below code and write to an
 address within my memory map. Of course this contradicts the statement
 /dev/uioX is a read-only file in the UIO howto.

You're right. That wants to be fixed...

 
 Including my updated, tested code for completeness.
 Note I also cleaned up the device registration a little by
 using a different platform_device_register_ call and removing fields
 in the struct uio_info that get filled in by uio_pdrv automatically.

If you want to have that included in the mainline, please choose a more
descriptive name than myfpga and send a proper patch.

Thanks,
Hans

 
 -Kevin
 
 # lsuio -m -v
 uio0: name=uio_myfpga, version=0.1, events=0
 map[0]: addr=0xD000, size=262144, mmap test: OK
 Device attributes:
 uevent=DRIVER=uio_pdrv
 modalias=platform:uio_pdrv
 
 --Kernelspace--
 #include linux/platform_device.h
 #include linux/uio_driver.h
 #include linux/module.h
 
 #define MYFPGA_BASE 0xd000 // 3G
 #define MYFPGA_SIZE 0x0004 // 256k
 
 static struct resource myfpga_resources[] = {
 {
 .start = MYFPGA_BASE,
 .end   = MYFPGA_BASE + MYFPGA_SIZE - 1,
 .name  = myfpga,
 .flags = IORESOURCE_MEM
 }
 };
 
 static struct uio_info myfpga_uio_info = {
.name = uio_myfpga,
.version = 0.1,
 };
 
 static struct platform_device *myfpga_uio_pdev;
 
 static int __init myfpga_init(void)
 {
 myfpga_uio_pdev = platform_device_register_resndata (NULL,
  uio_pdrv,
  -1,
  myfpga_resources,
  1,
  myfpga_uio_info,
  sizeof(struct 
 uio_info)
 );
 if (IS_ERR(myfpga_uio_pdev)) {
 return PTR_ERR(myfpga_uio_pdev);
 }
 
 return 0;
 }
 
 static void __exit myfpga_exit(void)
 {
 platform_device_unregister(myfpga_uio_pdev);
 }
 
 module_init(myfpga_init);
 module_exit(myfpga_exit);
 
 --Userspace---
 #include sys/types.h
 #include sys/mman.h
 #include sys/stat.h
 
 #include dirent.h
 #include string.h
 #include stdlib.h
 #include stdio.h
 #include fcntl.h
 #include unistd.h
 #include stdint.h
 
 #define MYFPGA_BASE 0xd000 // 3G
 #define MYFPGA_SIZE 0x0004 // 256k
 #define MYFPGA_MAP_NUM  0 // First and only defined map
 
 #define BIT32(n) (1  (n))
 
 /* Use mmap()'ped address iomem, not physical MYFPGA address */
 #define MYFPGA_REG(iomem) (volatile uint32_t*)(iomem + 0x8) // Third 32-bit 
 reg
 
 int main (int argc, char *argv[])
 {
 int fd;
 void *iomem;
 fd = open(/dev/uio0, O_RDWR|O_SYNC);
 if (fd  0) {
 printf(failed to open /dev/uio0, quitting\n);
 return -1;
 }
 /* Note offset has a special meaning with uio devices */
 iomem = mmap(NULL, MYFPGA_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
  MYFPGA_MAP_NUM * getpagesize());
 if (iomem == MAP_FAILED) {
 printf(mmap failed, quitting\n);
 close(fd);
 return -2;
 }
 
 /* Set bit 5 of MYFPGA_REG register */
 *MYFPGA_REG(iomem) |= BIT32(5);
 
 munmap(iomem, MYFPGA_SIZE);
 close(fd);
 return 0;
 }
  
 
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Using uio_pdrv to create an platform device for an FPGA, mmap() fails

2012-08-30 Thread Hans J. Koch
[Added Greg Kroah-Hartman to Cc:]

On Thu, Aug 30, 2012 at 08:10:11PM +, Worth, Kevin wrote:
  Thanks for the reply, Hans. Your question about opening /dev/uio0 O_RDWR
  prompted me to check out how I was creating /dev/uio0 ... my system
  isn't using udev, and I was accidentally creating it with major/minor
  number 254/0 instead of the correct 253/0 (found by looking at
  /proc/devices). Fixed that and the mmap() call started working.
 
 Good.
 
  
  Verified that if /dev/uio0 has permissions 0644, root can open it O_RDWR
  and mmap PROT_READ | PROT_WRITE using the below code and write to an
  address within my memory map. Of course this contradicts the statement
  /dev/uioX is a read-only file in the UIO howto.
 
 You're right. That wants to be fixed...
 
  
  Including my updated, tested code for completeness.
  Note I also cleaned up the device registration a little by
  using a different platform_device_register_ call and removing fields
  in the struct uio_info that get filled in by uio_pdrv automatically.
 
 If you want to have that included in the mainline, please choose a more
 descriptive name than myfpga and send a proper patch.
 
 I wasn't sure about submitting as a patch since it's for a custom FPGA
 that I don't expect the community will be using,

That doesn't matter. If it helps YOU that the code is maintained in mainline,
post it.

  but the code seems like
 possibly useful sample/example code.

That is another good argument.

 Perhaps patching the HOWTO like
 http://www.kernel.org/doc/htmldocs/uio-howto.html#uio_pci_generic_example
 is the right approach?

Oh, if you could hack up a patch for the documentation, that would be great.
But please make it a second patch, don't mix it with your driver code.

Thanks,
Hans

 
 
 Thanks,
 Hans
 
  
  -Kevin
  
  # lsuio -m -v
  uio0: name=uio_myfpga, version=0.1, events=0
  map[0]: addr=0xD000, size=262144, mmap test: OK
  Device attributes:
  uevent=DRIVER=uio_pdrv
  modalias=platform:uio_pdrv
  
  --Kernelspace--
  #include linux/platform_device.h
  #include linux/uio_driver.h
  #include linux/module.h
  
  #define MYFPGA_BASE 0xd000 // 3G
  #define MYFPGA_SIZE 0x0004 // 256k
  
  static struct resource myfpga_resources[] = {
  {
  .start = MYFPGA_BASE,
  .end   = MYFPGA_BASE + MYFPGA_SIZE - 1,
  .name  = myfpga,
  .flags = IORESOURCE_MEM
  }
  };
  
  static struct uio_info myfpga_uio_info = {
 .name = uio_myfpga,
 .version = 0.1,
  };
  
  static struct platform_device *myfpga_uio_pdev;
  
  static int __init myfpga_init(void)
  {
  myfpga_uio_pdev = platform_device_register_resndata (NULL,
   uio_pdrv,
   -1,
   myfpga_resources,
   1,
   myfpga_uio_info,
   sizeof(struct 
  uio_info)
  );
  if (IS_ERR(myfpga_uio_pdev)) {
  return PTR_ERR(myfpga_uio_pdev);
  }
  
  return 0;
  }
  
  static void __exit myfpga_exit(void)
  {
  platform_device_unregister(myfpga_uio_pdev);
  }
  
  module_init(myfpga_init);
  module_exit(myfpga_exit);
  
  --Userspace---
  #include sys/types.h
  #include sys/mman.h
  #include sys/stat.h
  
  #include dirent.h
  #include string.h
  #include stdlib.h
  #include stdio.h
  #include fcntl.h
  #include unistd.h
  #include stdint.h
  
  #define MYFPGA_BASE 0xd000 // 3G
  #define MYFPGA_SIZE 0x0004 // 256k
  #define MYFPGA_MAP_NUM  0 // First and only defined map
  
  #define BIT32(n) (1  (n))
  
  /* Use mmap()'ped address iomem, not physical MYFPGA address */
  #define MYFPGA_REG(iomem) (volatile uint32_t*)(iomem + 0x8) // Third 
  32-bit reg
  
  int main (int argc, char *argv[])
  {
  int fd;
  void *iomem;
  fd = open(/dev/uio0, O_RDWR|O_SYNC);
  if (fd  0) {
  printf(failed to open /dev/uio0, quitting\n);
  return -1;
  }
  /* Note offset has a special meaning with uio devices */
  iomem = mmap(NULL, MYFPGA_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
   MYFPGA_MAP_NUM * getpagesize());
  if (iomem == MAP_FAILED) {
  printf(mmap failed, quitting\n);
  close(fd);
  return -2;
  }
  
  /* Set bit 5 of MYFPGA_REG register */
  *MYFPGA_REG(iomem) |= BIT32(5);
  
  munmap(iomem, MYFPGA_SIZE);
  close(fd);
  return 0;
  }
   
   
 
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  

Re: Using uio_pdrv to create an platform device for an FPGA, mmap() fails

2012-08-29 Thread Hans J. Koch
[Added driver author to Cc:]

On Wed, Aug 29, 2012 at 11:19:00PM +, Worth, Kevin wrote:
> I have below what appears to be a mostly-functional device using the UIO 
> Platform Driver. The /sys entries I'd expect appear,  /proc/iomem contains " 
> d000-dfff : myfpga", and lsuio sees the properties that I've set. 
> However an mmap() from userspace (either my test program below or lsuio) 
> fails. So close! (at least it would seem)
> 
> Finding a good example for this did not come easily (which is why I'm hitting 
> LKML, since I know it'll get a lot of eyeballs and be archived). Maybe there 
> was something obvious I missed, but the only "official" documentation I could 
> locate was http://www.kernel.org/doc/htmldocs/uio-howto.html#using_uio_pdrv , 
> and most everything else was snippets from presentations, papers, and forums 
> that lacked completeness.
> 
> Thanks for the help any might be able to offer.
> Please CC me on replies as I'm not ready to drink from the fire hose that is 
> an LKML subscription.
> 
> # lsuio -v -m
> uio0: name=uio_myfpga, version=0.1, events=0
> map[0]: addr=0xD000, size=4096, mmap test: FAILED
> Device attributes:
> uevent=DRIVER=uio_pdrv
> modalias=platform:uio_pdrv
> 
> --Kernelspace portion---
> 
> #include 
> #include 
> #include 
> 
> #define MYFPGA_BASE 0xd000 // 3G
> #define MYFPGA_SIZE 0x0004 // 256k
> 
> static struct resource myfpga_resources[] = {
> {
> .start  = MYFPGA_BASE,
> .end= MYFPGA_BASE + MYFPGA_SIZE - 1,
> .name   = "myfpga",
> .flags  = IORESOURCE_MEM
> }
> };
> 
> static struct uio_info myfpga_uio_info = {
>.name = "uio_myfpga",
>.version = "0.1",
>.irq = UIO_IRQ_CUSTOM,
>.mem = {
> {
> .name = "myfpga",
> .memtype = UIO_MEM_PHYS,
> .addr = MYFPGA_BASE,
> .size = MYFPGA_SIZE
> }
> }
> };
> 
> static struct platform_device_info myfpga_uio_pdevinfo = {
> .name = "uio_pdrv",
> .id = -1,
> .res = myfpga_resources,
> .num_res = 1,
> .data = _uio_info,
> .size_data = sizeof(struct uio_info)
> };
> 
> static struct platform_device *myfpga_uio_pdev;
> 
> static int __init myfpga_init(void)
> {
> myfpga_uio_pdev = platform_device_register_full(_uio_pdevinfo);
> if (IS_ERR(myfpga_uio_pdev)) {
> return PTR_ERR(myfpga_uio_pdev);
> }
> 
> return 0;
> }
> 
> static void __exit myfpga_exit(void)
> {
> platform_device_unregister(myfpga_uio_pdev);
> }
> 
> module_init(myfpga_init);
> module_exit(myfpga_exit);
> 
> --Userspace portion---
> 
> #include 
> #include 
> #include 
> 
> #include 
> #include 
> #include 
> #include 
> #include 
> #include 
> 
> #define MYFPGA_BASE 0xd000 // 3G
> #define MYFPGA_SIZE 0x0004 // 256k
> #define MYFPGA_UIO_NUM  0  // uio0

That's misleading regarding its use below. The factor you need for mmap
is the number of the mapping, not uio0, uio1...

> 
> int main (int argc, char *argv[])
> {
> int fd;
> void *iomem;
> fd = open("/dev/uio0", O_RDWR|O_SYNC);

Does it work with O_RDWR ?

Thanks,
Hans

> if (fd < 0) {
> printf("failed to open /dev/uio0, quitting\n");
> return -1;
> }
> /* Note offset has a special meaning with uio devices */
> iomem = mmap(NULL, MYFPGA_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
>  MYFPGA_UIO_NUM * getpagesize());
> if (iomem == MAP_FAILED) {
> printf("mmap failed, quitting\n");
> close(fd);
> return -2;
> }
> printf("mmap successful!\n");
> munmap(iomem, MYFPGA_SIZE);
> close(fd);
> return 0;
> }
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: Using uio_pdrv to create an platform device for an FPGA, mmap() fails

2012-08-29 Thread Hans J. Koch
[Added driver author to Cc:]

On Wed, Aug 29, 2012 at 11:19:00PM +, Worth, Kevin wrote:
 I have below what appears to be a mostly-functional device using the UIO 
 Platform Driver. The /sys entries I'd expect appear,  /proc/iomem contains  
 d000-dfff : myfpga, and lsuio sees the properties that I've set. 
 However an mmap() from userspace (either my test program below or lsuio) 
 fails. So close! (at least it would seem)
 
 Finding a good example for this did not come easily (which is why I'm hitting 
 LKML, since I know it'll get a lot of eyeballs and be archived). Maybe there 
 was something obvious I missed, but the only official documentation I could 
 locate was http://www.kernel.org/doc/htmldocs/uio-howto.html#using_uio_pdrv , 
 and most everything else was snippets from presentations, papers, and forums 
 that lacked completeness.
 
 Thanks for the help any might be able to offer.
 Please CC me on replies as I'm not ready to drink from the fire hose that is 
 an LKML subscription.
 
 # lsuio -v -m
 uio0: name=uio_myfpga, version=0.1, events=0
 map[0]: addr=0xD000, size=4096, mmap test: FAILED
 Device attributes:
 uevent=DRIVER=uio_pdrv
 modalias=platform:uio_pdrv
 
 --Kernelspace portion---
 
 #include linux/platform_device.h
 #include linux/uio_driver.h
 #include linux/module.h
 
 #define MYFPGA_BASE 0xd000 // 3G
 #define MYFPGA_SIZE 0x0004 // 256k
 
 static struct resource myfpga_resources[] = {
 {
 .start  = MYFPGA_BASE,
 .end= MYFPGA_BASE + MYFPGA_SIZE - 1,
 .name   = myfpga,
 .flags  = IORESOURCE_MEM
 }
 };
 
 static struct uio_info myfpga_uio_info = {
.name = uio_myfpga,
.version = 0.1,
.irq = UIO_IRQ_CUSTOM,
.mem = {
 {
 .name = myfpga,
 .memtype = UIO_MEM_PHYS,
 .addr = MYFPGA_BASE,
 .size = MYFPGA_SIZE
 }
 }
 };
 
 static struct platform_device_info myfpga_uio_pdevinfo = {
 .name = uio_pdrv,
 .id = -1,
 .res = myfpga_resources,
 .num_res = 1,
 .data = myfpga_uio_info,
 .size_data = sizeof(struct uio_info)
 };
 
 static struct platform_device *myfpga_uio_pdev;
 
 static int __init myfpga_init(void)
 {
 myfpga_uio_pdev = platform_device_register_full(myfpga_uio_pdevinfo);
 if (IS_ERR(myfpga_uio_pdev)) {
 return PTR_ERR(myfpga_uio_pdev);
 }
 
 return 0;
 }
 
 static void __exit myfpga_exit(void)
 {
 platform_device_unregister(myfpga_uio_pdev);
 }
 
 module_init(myfpga_init);
 module_exit(myfpga_exit);
 
 --Userspace portion---
 
 #include sys/types.h
 #include sys/mman.h
 #include sys/stat.h
 
 #include dirent.h
 #include string.h
 #include stdlib.h
 #include stdio.h
 #include fcntl.h
 #include unistd.h
 
 #define MYFPGA_BASE 0xd000 // 3G
 #define MYFPGA_SIZE 0x0004 // 256k
 #define MYFPGA_UIO_NUM  0  // uio0

That's misleading regarding its use below. The factor you need for mmap
is the number of the mapping, not uio0, uio1...

 
 int main (int argc, char *argv[])
 {
 int fd;
 void *iomem;
 fd = open(/dev/uio0, O_RDWR|O_SYNC);

Does it work with O_RDWR ?

Thanks,
Hans

 if (fd  0) {
 printf(failed to open /dev/uio0, quitting\n);
 return -1;
 }
 /* Note offset has a special meaning with uio devices */
 iomem = mmap(NULL, MYFPGA_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
  MYFPGA_UIO_NUM * getpagesize());
 if (iomem == MAP_FAILED) {
 printf(mmap failed, quitting\n);
 close(fd);
 return -2;
 }
 printf(mmap successful!\n);
 munmap(iomem, MYFPGA_SIZE);
 close(fd);
 return 0;
 }
 --
 To unsubscribe from this list: send the line unsubscribe linux-kernel in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html
 Please read the FAQ at  http://www.tux.org/lkml/
 
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: UIO: missing resource mapping

2012-08-08 Thread Hans J. Koch
On Wed, Jul 18, 2012 at 12:40:47PM +0200, Dominic Eschweiler wrote:
> Am Montag, den 16.07.2012, 23:58 +0200 schrieb Hans J. Koch:
> > Try to hack up a patch to add generic BAR mapping to uio_pci_generic.c
> > and post it for review.
> > 
> 
> Here we go ...

Thank you very much for your work. I'm really sorry for the long delay,
but I was busy finishing a project because I go to vacation tomorrow.
Sorry, that might cause further delay since I don't know yet how often
I can read my mail...
Greg, can you review the next one?

Here's a first review.

Thanks,
Hans

> > 
> Signed-off-by: Dominic Eschweiler 
> diff --git a/drivers/uio/uio_pci_generic.c
> b/drivers/uio/uio_pci_generic.c
> index 0bd08ef..e25991e 100644
> --- a/drivers/uio/uio_pci_generic.c
> +++ b/drivers/uio/uio_pci_generic.c
> @@ -25,10 +25,12 @@
>  #include 
>  #include 
>  
> -#define DRIVER_VERSION   "0.01.0"
> +#define DRIVER_VERSION   "0.02.0"
>  #define DRIVER_AUTHOR"Michael S. Tsirkin "
>  #define DRIVER_DESC  "Generic UIO driver for PCI 2.3 devices"
>  
> +#define DRV_NAME "uio_pci_generic"
> +
>  struct uio_pci_generic_dev {
>   struct uio_info info;
>   struct pci_dev *pdev;
> @@ -58,6 +60,7 @@ static int __devinit probe(struct pci_dev *pdev,
>  {
>   struct uio_pci_generic_dev *gdev;
>   int err;
> + int i;
>  
>   err = pci_enable_device(pdev);
>   if (err) {
> @@ -67,8 +70,7 @@ static int __devinit probe(struct pci_dev *pdev,
>   }
>  
>   if (!pdev->irq) {
> - dev_warn(>dev, "No IRQ assigned to device: "
> -  "no support for interrupts?\n");
> + dev_warn(>dev, "No IRQ assigned to device: no support for
> interrupts?\n");

Please configure your mail client not to break lines when sending a patch.
It can't be applied like this.

Why did you make that change anyway? If it's just coding style, please send
another patch, don't mix functional changes with coding style fixes.

>   pci_disable_device(pdev);
>   return -ENODEV;
>   }
> @@ -91,10 +93,31 @@ static int __devinit probe(struct pci_dev *pdev,
>   gdev->info.handler = irqhandler;
>   gdev->pdev = pdev;
>  
> + /* request regions */
> + err = pci_request_regions(pdev, DRV_NAME);
> + if (err) {
> + dev_err(>dev, "Couldn't get PCI resources, aborting\n");
> + return err;
> + }
> +
> + /* create attributes for BAR mappings */
> + for (i = 0; i < PCI_NUM_RESOURCES; i++) {
> + if (pdev->resource[i].flags &&
> + (pdev->resource[i].flags & IORESOURCE_MEM)) {
> + gdev->info.mem[i].addr = pci_resource_start(pdev, i);
> + gdev->info.mem[i].size = pci_resource_len(pdev, i);
> + gdev->info.mem[i].internal_addr = NULL;
> + gdev->info.mem[i].memtype = UIO_MEM_PHYS;
> + }
> + }
> +
>   if (uio_register_device(>dev, >info))
>   goto err_register;
>   pci_set_drvdata(pdev, gdev);
>  
> + pr_info("UIO_PCI_GENERIC : initialized new device (%x %x)\n",

Please use dev_info()

> + pdev->vendor, pdev->device);
> +
>   return 0;
>  err_register:
>   kfree(gdev);
> @@ -107,17 +130,21 @@ err_verify:
>  static void remove(struct pci_dev *pdev)
>  {
>   struct uio_pci_generic_dev *gdev = pci_get_drvdata(pdev);
> -
>   uio_unregister_device(>info);
> +
> + pci_release_regions(pdev);
>   pci_disable_device(pdev);
>   kfree(gdev);
> +
> + pr_info("UIO_PCI_GENERIC : removed device (%x %x)\n",

ditto

> + pdev->vendor, pdev->device);
>  }
>  
>  static struct pci_driver driver = {
> - .name = "uio_pci_generic",
> + .name = DRV_NAME,
>   .id_table = NULL, /* only dynamic id's */
> - .probe = probe,
> - .remove = remove,
> + .probe= probe,
> + .remove   = remove,

As above: Please put coding style fixes in an extra patch (if you really
insist on tabs instead of spaces...)

>  };
>  
>  static int __init init(void)
> 
> -- 
> Gruß
>   Dominic
> 
> Frankfurt Institute for Advanced Studies (FIAS)
> Ruth-Moufang-Straße 1
> D-60438 Frankfurt am Main
> Germany
> 
> Phone:  +49 69 79844114
> 
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: UIO: missing resource mapping

2012-08-08 Thread Hans J. Koch
On Wed, Jul 18, 2012 at 12:40:47PM +0200, Dominic Eschweiler wrote:
 Am Montag, den 16.07.2012, 23:58 +0200 schrieb Hans J. Koch:
  Try to hack up a patch to add generic BAR mapping to uio_pci_generic.c
  and post it for review.
  
 
 Here we go ...

Thank you very much for your work. I'm really sorry for the long delay,
but I was busy finishing a project because I go to vacation tomorrow.
Sorry, that might cause further delay since I don't know yet how often
I can read my mail...
Greg, can you review the next one?

Here's a first review.

Thanks,
Hans

  
 Signed-off-by: Dominic Eschweiler eschwei...@fias.uni-frankfurt.de
 diff --git a/drivers/uio/uio_pci_generic.c
 b/drivers/uio/uio_pci_generic.c
 index 0bd08ef..e25991e 100644
 --- a/drivers/uio/uio_pci_generic.c
 +++ b/drivers/uio/uio_pci_generic.c
 @@ -25,10 +25,12 @@
  #include linux/slab.h
  #include linux/uio_driver.h
  
 -#define DRIVER_VERSION   0.01.0
 +#define DRIVER_VERSION   0.02.0
  #define DRIVER_AUTHORMichael S. Tsirkin m...@redhat.com
  #define DRIVER_DESC  Generic UIO driver for PCI 2.3 devices
  
 +#define DRV_NAME uio_pci_generic
 +
  struct uio_pci_generic_dev {
   struct uio_info info;
   struct pci_dev *pdev;
 @@ -58,6 +60,7 @@ static int __devinit probe(struct pci_dev *pdev,
  {
   struct uio_pci_generic_dev *gdev;
   int err;
 + int i;
  
   err = pci_enable_device(pdev);
   if (err) {
 @@ -67,8 +70,7 @@ static int __devinit probe(struct pci_dev *pdev,
   }
  
   if (!pdev-irq) {
 - dev_warn(pdev-dev, No IRQ assigned to device: 
 -  no support for interrupts?\n);
 + dev_warn(pdev-dev, No IRQ assigned to device: no support for
 interrupts?\n);

Please configure your mail client not to break lines when sending a patch.
It can't be applied like this.

Why did you make that change anyway? If it's just coding style, please send
another patch, don't mix functional changes with coding style fixes.

   pci_disable_device(pdev);
   return -ENODEV;
   }
 @@ -91,10 +93,31 @@ static int __devinit probe(struct pci_dev *pdev,
   gdev-info.handler = irqhandler;
   gdev-pdev = pdev;
  
 + /* request regions */
 + err = pci_request_regions(pdev, DRV_NAME);
 + if (err) {
 + dev_err(pdev-dev, Couldn't get PCI resources, aborting\n);
 + return err;
 + }
 +
 + /* create attributes for BAR mappings */
 + for (i = 0; i  PCI_NUM_RESOURCES; i++) {
 + if (pdev-resource[i].flags 
 + (pdev-resource[i].flags  IORESOURCE_MEM)) {
 + gdev-info.mem[i].addr = pci_resource_start(pdev, i);
 + gdev-info.mem[i].size = pci_resource_len(pdev, i);
 + gdev-info.mem[i].internal_addr = NULL;
 + gdev-info.mem[i].memtype = UIO_MEM_PHYS;
 + }
 + }
 +
   if (uio_register_device(pdev-dev, gdev-info))
   goto err_register;
   pci_set_drvdata(pdev, gdev);
  
 + pr_info(UIO_PCI_GENERIC : initialized new device (%x %x)\n,

Please use dev_info()

 + pdev-vendor, pdev-device);
 +
   return 0;
  err_register:
   kfree(gdev);
 @@ -107,17 +130,21 @@ err_verify:
  static void remove(struct pci_dev *pdev)
  {
   struct uio_pci_generic_dev *gdev = pci_get_drvdata(pdev);
 -
   uio_unregister_device(gdev-info);
 +
 + pci_release_regions(pdev);
   pci_disable_device(pdev);
   kfree(gdev);
 +
 + pr_info(UIO_PCI_GENERIC : removed device (%x %x)\n,

ditto

 + pdev-vendor, pdev-device);
  }
  
  static struct pci_driver driver = {
 - .name = uio_pci_generic,
 + .name = DRV_NAME,
   .id_table = NULL, /* only dynamic id's */
 - .probe = probe,
 - .remove = remove,
 + .probe= probe,
 + .remove   = remove,

As above: Please put coding style fixes in an extra patch (if you really
insist on tabs instead of spaces...)

  };
  
  static int __init init(void)
 
 -- 
 Gruß
   Dominic
 
 Frankfurt Institute for Advanced Studies (FIAS)
 Ruth-Moufang-Straße 1
 D-60438 Frankfurt am Main
 Germany
 
 Phone:  +49 69 79844114
 
 
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: UIO: missing resource mapping

2012-07-18 Thread Hans J. Koch
On Wed, Jul 18, 2012 at 12:40:47PM +0200, Dominic Eschweiler wrote:
> Am Montag, den 16.07.2012, 23:58 +0200 schrieb Hans J. Koch:
> > Try to hack up a patch to add generic BAR mapping to uio_pci_generic.c
> > and post it for review.
> > 
> 
> Here we go ...

Great! I'm a bit under time pressure with my current work ATM. A call to
open("/dev/hansjkoch", O_NONBLOCK) only returns -EBUSY. So it'll take me one or
two days to review it thoroughly. But at first sight, it is what I had in mind.

You'll hear from me soon, thanks for your work! Comments and reviews from
others are welcome...

Hans

> > 
> Signed-off-by: Dominic Eschweiler 
> diff --git a/drivers/uio/uio_pci_generic.c
> b/drivers/uio/uio_pci_generic.c
> index 0bd08ef..e25991e 100644
> --- a/drivers/uio/uio_pci_generic.c
> +++ b/drivers/uio/uio_pci_generic.c
> @@ -25,10 +25,12 @@
>  #include 
>  #include 
>  
> -#define DRIVER_VERSION   "0.01.0"
> +#define DRIVER_VERSION   "0.02.0"
>  #define DRIVER_AUTHOR"Michael S. Tsirkin "
>  #define DRIVER_DESC  "Generic UIO driver for PCI 2.3 devices"
>  
> +#define DRV_NAME "uio_pci_generic"
> +
>  struct uio_pci_generic_dev {
>   struct uio_info info;
>   struct pci_dev *pdev;
> @@ -58,6 +60,7 @@ static int __devinit probe(struct pci_dev *pdev,
>  {
>   struct uio_pci_generic_dev *gdev;
>   int err;
> + int i;
>  
>   err = pci_enable_device(pdev);
>   if (err) {
> @@ -67,8 +70,7 @@ static int __devinit probe(struct pci_dev *pdev,
>   }
>  
>   if (!pdev->irq) {
> - dev_warn(>dev, "No IRQ assigned to device: "
> -  "no support for interrupts?\n");
> + dev_warn(>dev, "No IRQ assigned to device: no support for
> interrupts?\n");
>   pci_disable_device(pdev);
>   return -ENODEV;
>   }
> @@ -91,10 +93,31 @@ static int __devinit probe(struct pci_dev *pdev,
>   gdev->info.handler = irqhandler;
>   gdev->pdev = pdev;
>  
> + /* request regions */
> + err = pci_request_regions(pdev, DRV_NAME);
> + if (err) {
> + dev_err(>dev, "Couldn't get PCI resources, aborting\n");
> + return err;
> + }
> +
> + /* create attributes for BAR mappings */
> + for (i = 0; i < PCI_NUM_RESOURCES; i++) {
> + if (pdev->resource[i].flags &&
> + (pdev->resource[i].flags & IORESOURCE_MEM)) {
> + gdev->info.mem[i].addr = pci_resource_start(pdev, i);
> + gdev->info.mem[i].size = pci_resource_len(pdev, i);
> + gdev->info.mem[i].internal_addr = NULL;
> + gdev->info.mem[i].memtype = UIO_MEM_PHYS;
> + }
> + }
> +
>   if (uio_register_device(>dev, >info))
>   goto err_register;
>   pci_set_drvdata(pdev, gdev);
>  
> + pr_info("UIO_PCI_GENERIC : initialized new device (%x %x)\n",
> + pdev->vendor, pdev->device);
> +
>   return 0;
>  err_register:
>   kfree(gdev);
> @@ -107,17 +130,21 @@ err_verify:
>  static void remove(struct pci_dev *pdev)
>  {
>   struct uio_pci_generic_dev *gdev = pci_get_drvdata(pdev);
> -
>   uio_unregister_device(>info);
> +
> + pci_release_regions(pdev);
>   pci_disable_device(pdev);
>   kfree(gdev);
> +
> + pr_info("UIO_PCI_GENERIC : removed device (%x %x)\n",
> + pdev->vendor, pdev->device);
>  }
>  
>  static struct pci_driver driver = {
> - .name = "uio_pci_generic",
> + .name = DRV_NAME,
>   .id_table = NULL, /* only dynamic id's */
> - .probe = probe,
> - .remove = remove,
> + .probe= probe,
> + .remove   = remove,
>  };
>  
>  static int __init init(void)
> 
> -- 
> Gruß
>   Dominic
> 
> Frankfurt Institute for Advanced Studies (FIAS)
> Ruth-Moufang-Straße 1
> D-60438 Frankfurt am Main
> Germany
> 
> Phone:  +49 69 79844114
> 
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: UIO: missing resource mapping

2012-07-18 Thread Hans J. Koch
On Wed, Jul 18, 2012 at 12:40:47PM +0200, Dominic Eschweiler wrote:
 Am Montag, den 16.07.2012, 23:58 +0200 schrieb Hans J. Koch:
  Try to hack up a patch to add generic BAR mapping to uio_pci_generic.c
  and post it for review.
  
 
 Here we go ...

Great! I'm a bit under time pressure with my current work ATM. A call to
open(/dev/hansjkoch, O_NONBLOCK) only returns -EBUSY. So it'll take me one or
two days to review it thoroughly. But at first sight, it is what I had in mind.

You'll hear from me soon, thanks for your work! Comments and reviews from
others are welcome...

Hans

  
 Signed-off-by: Dominic Eschweiler eschwei...@fias.uni-frankfurt.de
 diff --git a/drivers/uio/uio_pci_generic.c
 b/drivers/uio/uio_pci_generic.c
 index 0bd08ef..e25991e 100644
 --- a/drivers/uio/uio_pci_generic.c
 +++ b/drivers/uio/uio_pci_generic.c
 @@ -25,10 +25,12 @@
  #include linux/slab.h
  #include linux/uio_driver.h
  
 -#define DRIVER_VERSION   0.01.0
 +#define DRIVER_VERSION   0.02.0
  #define DRIVER_AUTHORMichael S. Tsirkin m...@redhat.com
  #define DRIVER_DESC  Generic UIO driver for PCI 2.3 devices
  
 +#define DRV_NAME uio_pci_generic
 +
  struct uio_pci_generic_dev {
   struct uio_info info;
   struct pci_dev *pdev;
 @@ -58,6 +60,7 @@ static int __devinit probe(struct pci_dev *pdev,
  {
   struct uio_pci_generic_dev *gdev;
   int err;
 + int i;
  
   err = pci_enable_device(pdev);
   if (err) {
 @@ -67,8 +70,7 @@ static int __devinit probe(struct pci_dev *pdev,
   }
  
   if (!pdev-irq) {
 - dev_warn(pdev-dev, No IRQ assigned to device: 
 -  no support for interrupts?\n);
 + dev_warn(pdev-dev, No IRQ assigned to device: no support for
 interrupts?\n);
   pci_disable_device(pdev);
   return -ENODEV;
   }
 @@ -91,10 +93,31 @@ static int __devinit probe(struct pci_dev *pdev,
   gdev-info.handler = irqhandler;
   gdev-pdev = pdev;
  
 + /* request regions */
 + err = pci_request_regions(pdev, DRV_NAME);
 + if (err) {
 + dev_err(pdev-dev, Couldn't get PCI resources, aborting\n);
 + return err;
 + }
 +
 + /* create attributes for BAR mappings */
 + for (i = 0; i  PCI_NUM_RESOURCES; i++) {
 + if (pdev-resource[i].flags 
 + (pdev-resource[i].flags  IORESOURCE_MEM)) {
 + gdev-info.mem[i].addr = pci_resource_start(pdev, i);
 + gdev-info.mem[i].size = pci_resource_len(pdev, i);
 + gdev-info.mem[i].internal_addr = NULL;
 + gdev-info.mem[i].memtype = UIO_MEM_PHYS;
 + }
 + }
 +
   if (uio_register_device(pdev-dev, gdev-info))
   goto err_register;
   pci_set_drvdata(pdev, gdev);
  
 + pr_info(UIO_PCI_GENERIC : initialized new device (%x %x)\n,
 + pdev-vendor, pdev-device);
 +
   return 0;
  err_register:
   kfree(gdev);
 @@ -107,17 +130,21 @@ err_verify:
  static void remove(struct pci_dev *pdev)
  {
   struct uio_pci_generic_dev *gdev = pci_get_drvdata(pdev);
 -
   uio_unregister_device(gdev-info);
 +
 + pci_release_regions(pdev);
   pci_disable_device(pdev);
   kfree(gdev);
 +
 + pr_info(UIO_PCI_GENERIC : removed device (%x %x)\n,
 + pdev-vendor, pdev-device);
  }
  
  static struct pci_driver driver = {
 - .name = uio_pci_generic,
 + .name = DRV_NAME,
   .id_table = NULL, /* only dynamic id's */
 - .probe = probe,
 - .remove = remove,
 + .probe= probe,
 + .remove   = remove,
  };
  
  static int __init init(void)
 
 -- 
 Gruß
   Dominic
 
 Frankfurt Institute for Advanced Studies (FIAS)
 Ruth-Moufang-Straße 1
 D-60438 Frankfurt am Main
 Germany
 
 Phone:  +49 69 79844114
 
 
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: UIO: missing resource mapping

2012-07-16 Thread Hans J. Koch
On Mon, Jul 16, 2012 at 08:16:12PM +0200, Dominic Eschweiler wrote:
> Am Freitag, den 13.07.2012, 21:19 +0300 schrieb Michael S. Tsirkin:
> > 
> > UIO has the same property, doesn't it? Multiple users can
> > access device memory through sysfs. 
> 
> 
> Indeed, that's a similar problem. I haven't tried it (yet), but this
> particular problem can maybe circumvented by using mmap with the
> MAP_PRIVATE flag. Doing so is the responsibility of the driver
> programmer (like Hans already said). Even if that mmap trick does not
> work, it is pretty much sure that a BAR is already used by another
> program, if a related kernel driver is loaded. In that case the kernel
> has a chance to avoid such BAR race conditions by not giving the
> possibility to map them to the userspace.

Don't make it more complicated than it is. I see no general problem in
mapping BARs in uio_pci_generic like in any other UIO PCI driver.

> 
> Nevertheless, I'm pretty sure that the possibility via sysfs to access
> BARs, which are already managed by a kernel driver, opens the door for
> denial of service attacks.

There are also a few other possible attack scenarios, depending on the
hardware.
That's a general problem of all userspace drivers (e.g. X graphics drivers).
You have to make sure access rights are correct. Making a UIO device node
available to all normal users is foolishly dangerous.

> 
> On the other hand, I'm quite a newbie on this topic and maybe I don't
> see the big picture here. Therefore it is up to you guys to make the
> right decision (if needed).

Try to hack up a patch to add generic BAR mapping to uio_pci_generic.c
and post it for review.

Thanks,
Hans
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: UIO: missing resource mapping

2012-07-16 Thread Hans J. Koch
On Mon, Jul 16, 2012 at 08:16:12PM +0200, Dominic Eschweiler wrote:
 Am Freitag, den 13.07.2012, 21:19 +0300 schrieb Michael S. Tsirkin:
  
  UIO has the same property, doesn't it? Multiple users can
  access device memory through sysfs. 
 
 
 Indeed, that's a similar problem. I haven't tried it (yet), but this
 particular problem can maybe circumvented by using mmap with the
 MAP_PRIVATE flag. Doing so is the responsibility of the driver
 programmer (like Hans already said). Even if that mmap trick does not
 work, it is pretty much sure that a BAR is already used by another
 program, if a related kernel driver is loaded. In that case the kernel
 has a chance to avoid such BAR race conditions by not giving the
 possibility to map them to the userspace.

Don't make it more complicated than it is. I see no general problem in
mapping BARs in uio_pci_generic like in any other UIO PCI driver.

 
 Nevertheless, I'm pretty sure that the possibility via sysfs to access
 BARs, which are already managed by a kernel driver, opens the door for
 denial of service attacks.

There are also a few other possible attack scenarios, depending on the
hardware.
That's a general problem of all userspace drivers (e.g. X graphics drivers).
You have to make sure access rights are correct. Making a UIO device node
available to all normal users is foolishly dangerous.

 
 On the other hand, I'm quite a newbie on this topic and maybe I don't
 see the big picture here. Therefore it is up to you guys to make the
 right decision (if needed).

Try to hack up a patch to add generic BAR mapping to uio_pci_generic.c
and post it for review.

Thanks,
Hans
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


  1   2   >