Re: [PATCH v2] input: don't call input_dev_release_keys() in resume

2013-12-06 Thread Oskar Andero
Hi Dmitry,

On 03:14 Tue 26 Nov , Dmitry Torokhov wrote:
> Hi Oskar,
> 
> On Fri, Nov 22, 2013 at 02:27:04PM +0100, Oskar Andero wrote:
> > From: Aleksej Makarov 
> > 
> > When waking up the platform by pressing a specific key, sending a
> > release on that key makes it impossible to react on the event in
> > user-space. This is fixed by moving the input_reset_device() call to
> > resume instead.
> > 
> > Cc: Dmitry Torokhov 
> > Reviewed-by: Radovan Lekanovic 
> > Signed-off-by: Aleksej Makarov 
> > Signed-off-by: Oskar Andero 
> > ---
> >  drivers/input/input.c | 11 +--
> >  1 file changed, 1 insertion(+), 10 deletions(-)
> > 
> > diff --git a/drivers/input/input.c b/drivers/input/input.c
> > index 846ccdd..511d490 100644
> > --- a/drivers/input/input.c
> > +++ b/drivers/input/input.c
> > @@ -1676,22 +1676,13 @@ static int input_dev_suspend(struct device *dev)
> >  {
> > struct input_dev *input_dev = to_input_dev(dev);
> >  
> > -   mutex_lock(_dev->mutex);
> > -
> > -   if (input_dev->users)
> > -   input_dev_toggle(input_dev, false);
> > -
> > -   mutex_unlock(_dev->mutex);
> > +   input_reset_device(input_dev);
> >  
> > return 0;
> >  }
> >  
> >  static int input_dev_resume(struct device *dev)
> >  {
> > -   struct input_dev *input_dev = to_input_dev(dev);
> > -
> > -   input_reset_device(input_dev);
> 
> We still need to restore LED state after resume. Does the patch below
> work for you?

Finally found some time to test the patch! Not much left of the initial
one though. :)

The patch works for our use-case, i.e. wake-up the phone by pressing a
key and then be able to retrieve what key was pressed.
Please note that I haven't tested the LED/sound and hibernation parts
of the patch.

Thanks,
 Oskar

> 
> Input: don't call input_dev_release_keys() in resume
> 
> From: Aleksej Makarov 
> 
> When waking up the platform by pressing a specific key, sending a
> release on that key makes it impossible to react on the event in
> user-space. This is fixed by moving the input_reset_device() call to
> resume instead.
> 
> [dmitry.torok...@gmail.com: make sure we still restore LED/sound state
> after resume, handle hibernation properly]
> 
> Signed-off-by: Aleksej Makarov 
> Signed-off-by: Oskar Andero 
> Signed-off-by: Dmitry Torokhov 
> ---
>  drivers/input/input.c |   76 
> +
>  1 file changed, 57 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/input/input.c b/drivers/input/input.c
> index 846ccdd..692435a 100644
> --- a/drivers/input/input.c
> +++ b/drivers/input/input.c
> @@ -1653,35 +1653,36 @@ static void input_dev_toggle(struct input_dev *dev, 
> bool activate)
>   */
>  void input_reset_device(struct input_dev *dev)
>  {
> - mutex_lock(>mutex);
> + unsigned long flags;
>  
> - if (dev->users) {
> - input_dev_toggle(dev, true);
> + mutex_lock(>mutex);
> + spin_lock_irqsave(>event_lock, flags);
>  
> - /*
> -  * Keys that have been pressed at suspend time are unlikely
> -  * to be still pressed when we resume.
> -  */
> - spin_lock_irq(>event_lock);
> - input_dev_release_keys(dev);
> - spin_unlock_irq(>event_lock);
> - }
> + input_dev_toggle(dev, true);
> + input_dev_release_keys(dev);
>  
> + spin_unlock_irqrestore(>event_lock, flags);
>   mutex_unlock(>mutex);
>  }
>  EXPORT_SYMBOL(input_reset_device);
>  
> -#ifdef CONFIG_PM
> +#ifdef CONFIG_PM_SLEEP
>  static int input_dev_suspend(struct device *dev)
>  {
>   struct input_dev *input_dev = to_input_dev(dev);
>  
> - mutex_lock(_dev->mutex);
> + spin_lock_irq(_dev->event_lock);
>  
> - if (input_dev->users)
> - input_dev_toggle(input_dev, false);
> + /*
> +  * Keys that are pressed now are unlikely to be
> +  * still pressed when we resume.
> +  */
> + input_dev_release_keys(input_dev);
>  
> - mutex_unlock(_dev->mutex);
> + /* Turn off LEDs and sounds, if any are active. */
> + input_dev_toggle(input_dev, false);
> +
> + spin_unlock_irq(_dev->event_lock);
>  
>   return 0;
>  }
> @@ -1690,7 +1691,43 @@ static int input_dev_resume(struct device *dev)
>  {
>   struct input_dev *input_dev = to_input_dev(dev);
>  
> - input_reset_device(input_dev);
> + spin_lock_irq(_dev->event_lock);
> +
> + /* Restor

Re: [PATCH v2] input: don't call input_dev_release_keys() in resume

2013-12-06 Thread Oskar Andero
Hi Dmitry,

On 03:14 Tue 26 Nov , Dmitry Torokhov wrote:
 Hi Oskar,
 
 On Fri, Nov 22, 2013 at 02:27:04PM +0100, Oskar Andero wrote:
  From: Aleksej Makarov aleksej.maka...@sonymobile.com
  
  When waking up the platform by pressing a specific key, sending a
  release on that key makes it impossible to react on the event in
  user-space. This is fixed by moving the input_reset_device() call to
  resume instead.
  
  Cc: Dmitry Torokhov dmitry.torok...@gmail.com
  Reviewed-by: Radovan Lekanovic radovan.lekano...@sonymobile.com
  Signed-off-by: Aleksej Makarov aleksej.maka...@sonymobile.com
  Signed-off-by: Oskar Andero oskar.and...@sonymobile.com
  ---
   drivers/input/input.c | 11 +--
   1 file changed, 1 insertion(+), 10 deletions(-)
  
  diff --git a/drivers/input/input.c b/drivers/input/input.c
  index 846ccdd..511d490 100644
  --- a/drivers/input/input.c
  +++ b/drivers/input/input.c
  @@ -1676,22 +1676,13 @@ static int input_dev_suspend(struct device *dev)
   {
  struct input_dev *input_dev = to_input_dev(dev);
   
  -   mutex_lock(input_dev-mutex);
  -
  -   if (input_dev-users)
  -   input_dev_toggle(input_dev, false);
  -
  -   mutex_unlock(input_dev-mutex);
  +   input_reset_device(input_dev);
   
  return 0;
   }
   
   static int input_dev_resume(struct device *dev)
   {
  -   struct input_dev *input_dev = to_input_dev(dev);
  -
  -   input_reset_device(input_dev);
 
 We still need to restore LED state after resume. Does the patch below
 work for you?

Finally found some time to test the patch! Not much left of the initial
one though. :)

The patch works for our use-case, i.e. wake-up the phone by pressing a
key and then be able to retrieve what key was pressed.
Please note that I haven't tested the LED/sound and hibernation parts
of the patch.

Thanks,
 Oskar

 
 Input: don't call input_dev_release_keys() in resume
 
 From: Aleksej Makarov aleksej.maka...@sonymobile.com
 
 When waking up the platform by pressing a specific key, sending a
 release on that key makes it impossible to react on the event in
 user-space. This is fixed by moving the input_reset_device() call to
 resume instead.
 
 [dmitry.torok...@gmail.com: make sure we still restore LED/sound state
 after resume, handle hibernation properly]
 
 Signed-off-by: Aleksej Makarov aleksej.maka...@sonymobile.com
 Signed-off-by: Oskar Andero oskar.and...@sonymobile.com
 Signed-off-by: Dmitry Torokhov dmitry.torok...@gmail.com
 ---
  drivers/input/input.c |   76 
 +
  1 file changed, 57 insertions(+), 19 deletions(-)
 
 diff --git a/drivers/input/input.c b/drivers/input/input.c
 index 846ccdd..692435a 100644
 --- a/drivers/input/input.c
 +++ b/drivers/input/input.c
 @@ -1653,35 +1653,36 @@ static void input_dev_toggle(struct input_dev *dev, 
 bool activate)
   */
  void input_reset_device(struct input_dev *dev)
  {
 - mutex_lock(dev-mutex);
 + unsigned long flags;
  
 - if (dev-users) {
 - input_dev_toggle(dev, true);
 + mutex_lock(dev-mutex);
 + spin_lock_irqsave(dev-event_lock, flags);
  
 - /*
 -  * Keys that have been pressed at suspend time are unlikely
 -  * to be still pressed when we resume.
 -  */
 - spin_lock_irq(dev-event_lock);
 - input_dev_release_keys(dev);
 - spin_unlock_irq(dev-event_lock);
 - }
 + input_dev_toggle(dev, true);
 + input_dev_release_keys(dev);
  
 + spin_unlock_irqrestore(dev-event_lock, flags);
   mutex_unlock(dev-mutex);
  }
  EXPORT_SYMBOL(input_reset_device);
  
 -#ifdef CONFIG_PM
 +#ifdef CONFIG_PM_SLEEP
  static int input_dev_suspend(struct device *dev)
  {
   struct input_dev *input_dev = to_input_dev(dev);
  
 - mutex_lock(input_dev-mutex);
 + spin_lock_irq(input_dev-event_lock);
  
 - if (input_dev-users)
 - input_dev_toggle(input_dev, false);
 + /*
 +  * Keys that are pressed now are unlikely to be
 +  * still pressed when we resume.
 +  */
 + input_dev_release_keys(input_dev);
  
 - mutex_unlock(input_dev-mutex);
 + /* Turn off LEDs and sounds, if any are active. */
 + input_dev_toggle(input_dev, false);
 +
 + spin_unlock_irq(input_dev-event_lock);
  
   return 0;
  }
 @@ -1690,7 +1691,43 @@ static int input_dev_resume(struct device *dev)
  {
   struct input_dev *input_dev = to_input_dev(dev);
  
 - input_reset_device(input_dev);
 + spin_lock_irq(input_dev-event_lock);
 +
 + /* Restore state of LEDs and sounds, if any were active. */
 + input_dev_toggle(input_dev, true);
 +
 + spin_unlock_irq(input_dev-event_lock);
 +
 + return 0;
 +}
 +
 +static int input_dev_freeze(struct device *dev)
 +{
 + struct input_dev *input_dev = to_input_dev(dev);
 +
 + spin_lock_irq(input_dev-event_lock);
 +
 + /*
 +  * Keys that are pressed now are unlikely to be
 +  * still pressed when we resume

[PATCH v2] input: don't call input_dev_release_keys() in resume

2013-11-22 Thread Oskar Andero
From: Aleksej Makarov 

When waking up the platform by pressing a specific key, sending a
release on that key makes it impossible to react on the event in
user-space. This is fixed by moving the input_reset_device() call to
resume instead.

Cc: Dmitry Torokhov 
Reviewed-by: Radovan Lekanovic 
Signed-off-by: Aleksej Makarov 
Signed-off-by: Oskar Andero 
---
 drivers/input/input.c | 11 +--
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/drivers/input/input.c b/drivers/input/input.c
index 846ccdd..511d490 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -1676,22 +1676,13 @@ static int input_dev_suspend(struct device *dev)
 {
struct input_dev *input_dev = to_input_dev(dev);
 
-   mutex_lock(_dev->mutex);
-
-   if (input_dev->users)
-   input_dev_toggle(input_dev, false);
-
-   mutex_unlock(_dev->mutex);
+   input_reset_device(input_dev);
 
return 0;
 }
 
 static int input_dev_resume(struct device *dev)
 {
-   struct input_dev *input_dev = to_input_dev(dev);
-
-   input_reset_device(input_dev);
-
return 0;
 }
 
-- 
1.8.1.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/


[PATCH v2] input: don't call input_dev_release_keys() in resume

2013-11-22 Thread Oskar Andero
From: Aleksej Makarov aleksej.maka...@sonymobile.com

When waking up the platform by pressing a specific key, sending a
release on that key makes it impossible to react on the event in
user-space. This is fixed by moving the input_reset_device() call to
resume instead.

Cc: Dmitry Torokhov dmitry.torok...@gmail.com
Reviewed-by: Radovan Lekanovic radovan.lekano...@sonymobile.com
Signed-off-by: Aleksej Makarov aleksej.maka...@sonymobile.com
Signed-off-by: Oskar Andero oskar.and...@sonymobile.com
---
 drivers/input/input.c | 11 +--
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/drivers/input/input.c b/drivers/input/input.c
index 846ccdd..511d490 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -1676,22 +1676,13 @@ static int input_dev_suspend(struct device *dev)
 {
struct input_dev *input_dev = to_input_dev(dev);
 
-   mutex_lock(input_dev-mutex);
-
-   if (input_dev-users)
-   input_dev_toggle(input_dev, false);
-
-   mutex_unlock(input_dev-mutex);
+   input_reset_device(input_dev);
 
return 0;
 }
 
 static int input_dev_resume(struct device *dev)
 {
-   struct input_dev *input_dev = to_input_dev(dev);
-
-   input_reset_device(input_dev);
-
return 0;
 }
 
-- 
1.8.1.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 1/1] MMC: Detect execution mode errors after r/w command

2013-11-07 Thread Oskar Andero
Hi Ulf,

On 18:50 Tue 22 Oct , Ulf Hansson wrote:
> > And this is after the patch has been applied:
> >   KB  reclen   write rewritereadreread
> >51200   4 251 990 3280 3244
> >51200   8 4601545 4460 4463
> >51200  16 8782633 7023 7028
> >51200  3213804394 9802 9832
> >51200  64245762161231412314
> >51200 128366778941408714088
> >51200 256642259161508515086
> >51200 5125536   109941257115659
> >512001024911294991620316205
> >512002048   10197   105021636316368
> >512004096   10524   10238 885016309
> >5120081929615   104561652816529
> >51200   16384   10553   104281680316803
> 
> Hi Oskar,
> 
> The numbers were not that impressing from the beginning, so that could
> be why you don't see any impact.
> What kind of card are you using, eMMC/SD? In what speed mode are the
> card operating in?

The test was run on an Beagleboard with sdcard. I will try to find another 
board with
eMMC support and rerun the tests.

> >> > +   /*
> >> > +* Try to get card status which indicates the card state after
> >> > +* command execution. If the first attempt fails, we can't be
> >> > +* sure the returned status is for the r/w command.
> >> > +*/
> >> > +   for (retries = 2; retries >= 0; retries--) {
> >> > +   err = get_card_status(card, , 0);
> >> > +   if (!err)
> >> > +   break;
> >> > +
> >> > +   status_valid = false;
> >> > +   pr_err("%s: error %d sending status command, %sing\n",
> >> > +  req->rq_disk->disk_name, err,
> >> > +  retries ? "retry" : "abort");
> >> > +   }
> >>
> >> Do we have to issue a CMD13 (get_card_status), even if we are using
> >> the open-ended transmission sequence? In other words, could we make
> >> use of the response from CMD12 (stop transmission) instead?
> >
> > That's probably a good idea. Do you know of a way to check if CMD12 has been
> > sent or not?
> 
> Have a look for "mmc_host_cmd23", which gets translated into
> "MMC_BLK_CMD23" for the mmc block layer. This will give you some hints
> of were to look.

Thanks! We will revise the patch according to your comments.

-Oskar
--
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/1] MMC: Detect execution mode errors after r/w command

2013-11-07 Thread Oskar Andero
Hi Ulf,

On 18:50 Tue 22 Oct , Ulf Hansson wrote:
  And this is after the patch has been applied:
KB  reclen   write rewritereadreread
 51200   4 251 990 3280 3244
 51200   8 4601545 4460 4463
 51200  16 8782633 7023 7028
 51200  3213804394 9802 9832
 51200  64245762161231412314
 51200 128366778941408714088
 51200 256642259161508515086
 51200 5125536   109941257115659
 512001024911294991620316205
 512002048   10197   105021636316368
 512004096   10524   10238 885016309
 5120081929615   104561652816529
 51200   16384   10553   104281680316803
 
 Hi Oskar,
 
 The numbers were not that impressing from the beginning, so that could
 be why you don't see any impact.
 What kind of card are you using, eMMC/SD? In what speed mode are the
 card operating in?

The test was run on an Beagleboard with sdcard. I will try to find another 
board with
eMMC support and rerun the tests.

   +   /*
   +* Try to get card status which indicates the card state after
   +* command execution. If the first attempt fails, we can't be
   +* sure the returned status is for the r/w command.
   +*/
   +   for (retries = 2; retries = 0; retries--) {
   +   err = get_card_status(card, status, 0);
   +   if (!err)
   +   break;
   +
   +   status_valid = false;
   +   pr_err(%s: error %d sending status command, %sing\n,
   +  req-rq_disk-disk_name, err,
   +  retries ? retry : abort);
   +   }
 
  Do we have to issue a CMD13 (get_card_status), even if we are using
  the open-ended transmission sequence? In other words, could we make
  use of the response from CMD12 (stop transmission) instead?
 
  That's probably a good idea. Do you know of a way to check if CMD12 has been
  sent or not?
 
 Have a look for mmc_host_cmd23, which gets translated into
 MMC_BLK_CMD23 for the mmc block layer. This will give you some hints
 of were to look.

Thanks! We will revise the patch according to your comments.

-Oskar
--
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/1] MMC: Detect execution mode errors after r/w command

2013-10-22 Thread Oskar Andero
Hi Ulf,

On 17:01 Wed 16 Oct , Ulf Hansson wrote:
> Hi Oskar / Lars,
> 
> Sorry for the delayed response!
> 
> On 10 October 2013 15:28, Oskar Andero  wrote:
> > From: Lars Svensson 
> >
> > Some error bits in the status field of R1/R1b response are only set
> > by the device in response to the command following the failing
> > command. The status is only read and checked after a r/w command if
> > an error is detected during the initial command or the following data
> > transfer. In some situations this causes errors passing undetected.
> >
> > The solution is to read the status and check for these errors after
> > each r/w operation.
> 
> I am a bit concerned about performance, especially when operating on
> small packets.
> 
> Previously we already sent a CMD13 after each write, thus this change
> will have no effect on write performance. But for read, this will add
> a CMD13 check after each request. Have you made any performance
> measurement - how big is the impact? It is certainly interested to
> know before proceeding.

I just ran some iozone tests and I don't see any dramatic degrade in
performance.

This is before applying the patch:
Command line used: ./iozone_arm -az -i0 -i1 -s 50m -I
Output is in Kbytes/sec
Time Resolution = 0.30 seconds.
Processor cache size set to 1024 Kbytes.
Processor cache line size set to 32 bytes.
File stride size set to 17 * record size.

  KB  reclen   write rewritereadreread
   51200   4 240 970 3294 3299
   51200   8 4571575 4648 4549
   51200  16 8622366 6487 6332
   51200  3214894181 8642 8661
   51200  64250959281085210855
   51200 128371378561273812742
   51200 256616790041440414410
   51200 5128299   104481541615414
   512001024933794581607916082
   512002048922297291636116365
   5120040968926   105261648516477
   512008192   10035   10179 855016455
   51200   16384   10286   107261683416835

And this is after the patch has been applied:
  KB  reclen   write rewritereadreread
   51200   4 251 990 3280 3244
   51200   8 4601545 4460 4463
   51200  16 8782633 7023 7028
   51200  3213804394 9802 9832
   51200  64245762161231412314
   51200 128366778941408714088
   51200 256642259161508515086
   51200 5125536   109941257115659
   512001024911294991620316205
   512002048   10197   105021636316368
   512004096   10524   10238 885016309
   5120081929615   104561652816529
   51200   16384   10553   104281680316803

> >
> > Signed-off-by: Lars Svensson 
> > Signed-off-by: Oskar Andero 
> > Cc: linux-...@vger.kernel.org
> > ---
> >  drivers/mmc/card/block.c | 105 
> > +--
> >  1 file changed, 57 insertions(+), 48 deletions(-)
> >
> > diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
> > index 1a3163f..05de087 100644
> > --- a/drivers/mmc/card/block.c
> > +++ b/drivers/mmc/card/block.c
> > @@ -797,10 +797,9 @@ static int mmc_blk_cmd_error(struct request *req, 
> > const char *name, int error,
> >   * Initial r/w and stop cmd error recovery.
> >   * We don't know whether the card received the r/w cmd or not, so try to
> >   * restore things back to a sane state.  Essentially, we do this as 
> > follows:
> > - * - Obtain card status.  If the first attempt to obtain card status fails,
> > - *   the status word will reflect the failed status cmd, not the failed
> > - *   r/w cmd.  If we fail to obtain card status, it suggests we can no
> > - *   longer communicate with the card.
> > + * - Check card status. If the status_valid argument is false, the first 
> > attempt
> > + *   to obtain card status failed and the status argument will not reflect 
> > the
> > + *   failed r/w cmd.
> >   * - Check the card state.  If the card received the cmd but there was a
> >   *   transient problem with the response, it might still be in a data 
> > transfer
> >   *   mode.  Try to send it a stop command.  If this fails, we can't 
> > recover.
> > @@ -812,38 +811,15 @

Re: [PATCH 1/1] MMC: Detect execution mode errors after r/w command

2013-10-22 Thread Oskar Andero
Hi Ulf,

On 17:01 Wed 16 Oct , Ulf Hansson wrote:
 Hi Oskar / Lars,
 
 Sorry for the delayed response!
 
 On 10 October 2013 15:28, Oskar Andero oskar.and...@sonymobile.com wrote:
  From: Lars Svensson lars1.svens...@sonymobile.com
 
  Some error bits in the status field of R1/R1b response are only set
  by the device in response to the command following the failing
  command. The status is only read and checked after a r/w command if
  an error is detected during the initial command or the following data
  transfer. In some situations this causes errors passing undetected.
 
  The solution is to read the status and check for these errors after
  each r/w operation.
 
 I am a bit concerned about performance, especially when operating on
 small packets.
 
 Previously we already sent a CMD13 after each write, thus this change
 will have no effect on write performance. But for read, this will add
 a CMD13 check after each request. Have you made any performance
 measurement - how big is the impact? It is certainly interested to
 know before proceeding.

I just ran some iozone tests and I don't see any dramatic degrade in
performance.

This is before applying the patch:
Command line used: ./iozone_arm -az -i0 -i1 -s 50m -I
Output is in Kbytes/sec
Time Resolution = 0.30 seconds.
Processor cache size set to 1024 Kbytes.
Processor cache line size set to 32 bytes.
File stride size set to 17 * record size.

  KB  reclen   write rewritereadreread
   51200   4 240 970 3294 3299
   51200   8 4571575 4648 4549
   51200  16 8622366 6487 6332
   51200  3214894181 8642 8661
   51200  64250959281085210855
   51200 128371378561273812742
   51200 256616790041440414410
   51200 5128299   104481541615414
   512001024933794581607916082
   512002048922297291636116365
   5120040968926   105261648516477
   512008192   10035   10179 855016455
   51200   16384   10286   107261683416835

And this is after the patch has been applied:
  KB  reclen   write rewritereadreread
   51200   4 251 990 3280 3244
   51200   8 4601545 4460 4463
   51200  16 8782633 7023 7028
   51200  3213804394 9802 9832
   51200  64245762161231412314
   51200 128366778941408714088
   51200 256642259161508515086
   51200 5125536   109941257115659
   512001024911294991620316205
   512002048   10197   105021636316368
   512004096   10524   10238 885016309
   5120081929615   104561652816529
   51200   16384   10553   104281680316803

 
  Signed-off-by: Lars Svensson lars1.svens...@sonymobile.com
  Signed-off-by: Oskar Andero oskar.and...@sonymobile.com
  Cc: linux-...@vger.kernel.org
  ---
   drivers/mmc/card/block.c | 105 
  +--
   1 file changed, 57 insertions(+), 48 deletions(-)
 
  diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
  index 1a3163f..05de087 100644
  --- a/drivers/mmc/card/block.c
  +++ b/drivers/mmc/card/block.c
  @@ -797,10 +797,9 @@ static int mmc_blk_cmd_error(struct request *req, 
  const char *name, int error,
* Initial r/w and stop cmd error recovery.
* We don't know whether the card received the r/w cmd or not, so try to
* restore things back to a sane state.  Essentially, we do this as 
  follows:
  - * - Obtain card status.  If the first attempt to obtain card status fails,
  - *   the status word will reflect the failed status cmd, not the failed
  - *   r/w cmd.  If we fail to obtain card status, it suggests we can no
  - *   longer communicate with the card.
  + * - Check card status. If the status_valid argument is false, the first 
  attempt
  + *   to obtain card status failed and the status argument will not reflect 
  the
  + *   failed r/w cmd.
* - Check the card state.  If the card received the cmd but there was a
*   transient problem with the response, it might still be in a data 
  transfer
*   mode.  Try to send it a stop command.  If this fails, we can't 
  recover.
  @@ -812,38 +811,15 @@ static int mmc_blk_cmd_error(struct request *req, 
  const char *name, int error,
* Otherwise we don't understand what happened, so abort.
*/
   static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req,
  -   struct mmc_blk_request *brq, int *ecc_err, int *gen_err)
  +   struct

[PATCH 1/1] MMC: Detect execution mode errors after r/w command

2013-10-10 Thread Oskar Andero
From: Lars Svensson 

Some error bits in the status field of R1/R1b response are only set
by the device in response to the command following the failing
command. The status is only read and checked after a r/w command if
an error is detected during the initial command or the following data
transfer. In some situations this causes errors passing undetected.

The solution is to read the status and check for these errors after
each r/w operation.

Signed-off-by: Lars Svensson 
Signed-off-by: Oskar Andero 
Cc: linux-...@vger.kernel.org
---
 drivers/mmc/card/block.c | 105 +--
 1 file changed, 57 insertions(+), 48 deletions(-)

diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 1a3163f..05de087 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -797,10 +797,9 @@ static int mmc_blk_cmd_error(struct request *req, const 
char *name, int error,
  * Initial r/w and stop cmd error recovery.
  * We don't know whether the card received the r/w cmd or not, so try to
  * restore things back to a sane state.  Essentially, we do this as follows:
- * - Obtain card status.  If the first attempt to obtain card status fails,
- *   the status word will reflect the failed status cmd, not the failed
- *   r/w cmd.  If we fail to obtain card status, it suggests we can no
- *   longer communicate with the card.
+ * - Check card status. If the status_valid argument is false, the first 
attempt
+ *   to obtain card status failed and the status argument will not reflect the
+ *   failed r/w cmd.
  * - Check the card state.  If the card received the cmd but there was a
  *   transient problem with the response, it might still be in a data transfer
  *   mode.  Try to send it a stop command.  If this fails, we can't recover.
@@ -812,38 +811,15 @@ static int mmc_blk_cmd_error(struct request *req, const 
char *name, int error,
  * Otherwise we don't understand what happened, so abort.
  */
 static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req,
-   struct mmc_blk_request *brq, int *ecc_err, int *gen_err)
+   struct mmc_blk_request *brq, int *ecc_err, int *gen_err,
+   bool status_valid, int status)
 {
-   bool prev_cmd_status_valid = true;
-   u32 status, stop_status = 0;
-   int err, retry;
+   u32 stop_status = 0;
+   int err;
 
if (mmc_card_removed(card))
return ERR_NOMEDIUM;
 
-   /*
-* Try to get card status which indicates both the card state
-* and why there was no response.  If the first attempt fails,
-* we can't be sure the returned status is for the r/w command.
-*/
-   for (retry = 2; retry >= 0; retry--) {
-   err = get_card_status(card, , 0);
-   if (!err)
-   break;
-
-   prev_cmd_status_valid = false;
-   pr_err("%s: error %d sending status command, %sing\n",
-  req->rq_disk->disk_name, err, retry ? "retry" : "abort");
-   }
-
-   /* We couldn't get a response from the card.  Give up. */
-   if (err) {
-   /* Check if the card is removed */
-   if (mmc_detect_card_removed(card->host))
-   return ERR_NOMEDIUM;
-   return ERR_ABORT;
-   }
-
/* Flag ECC errors */
if ((status & R1_CARD_ECC_FAILED) ||
(brq->stop.resp[0] & R1_CARD_ECC_FAILED) ||
@@ -891,12 +867,12 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, 
struct request *req,
/* Check for set block count errors */
if (brq->sbc.error)
return mmc_blk_cmd_error(req, "SET_BLOCK_COUNT", brq->sbc.error,
-   prev_cmd_status_valid, status);
+   status_valid, status);
 
/* Check for r/w command errors */
if (brq->cmd.error)
return mmc_blk_cmd_error(req, "r/w cmd", brq->cmd.error,
-   prev_cmd_status_valid, status);
+   status_valid, status);
 
/* Data errors */
if (!brq->stop.error)
@@ -1107,6 +1083,12 @@ static inline void mmc_apply_rel_rw(struct 
mmc_blk_request *brq,
 R1_CC_ERROR |  /* Card controller error */ \
 R1_ERROR)  /* General/unknown error */
 
+#define EXE_ERRORS \
+   (R1_OUT_OF_RANGE |  /* Command argument out of range */ \
+R1_ADDRESS_ERROR | /* Misaligned address */\
+R1_WP_VIOLATION |  /* Tried to write to protected block */ \
+R1_ERROR)  /* General/unknown error */
+
 static int mmc_blk_err_check(struct mmc_card *card,
 struct mmc_async_req *areq)
 {
@@ -1114,7 +1096,33 @@ static int mmc_blk_err_che

[PATCH 1/1] MMC: Detect execution mode errors after r/w command

2013-10-10 Thread Oskar Andero
From: Lars Svensson lars1.svens...@sonymobile.com

Some error bits in the status field of R1/R1b response are only set
by the device in response to the command following the failing
command. The status is only read and checked after a r/w command if
an error is detected during the initial command or the following data
transfer. In some situations this causes errors passing undetected.

The solution is to read the status and check for these errors after
each r/w operation.

Signed-off-by: Lars Svensson lars1.svens...@sonymobile.com
Signed-off-by: Oskar Andero oskar.and...@sonymobile.com
Cc: linux-...@vger.kernel.org
---
 drivers/mmc/card/block.c | 105 +--
 1 file changed, 57 insertions(+), 48 deletions(-)

diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 1a3163f..05de087 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -797,10 +797,9 @@ static int mmc_blk_cmd_error(struct request *req, const 
char *name, int error,
  * Initial r/w and stop cmd error recovery.
  * We don't know whether the card received the r/w cmd or not, so try to
  * restore things back to a sane state.  Essentially, we do this as follows:
- * - Obtain card status.  If the first attempt to obtain card status fails,
- *   the status word will reflect the failed status cmd, not the failed
- *   r/w cmd.  If we fail to obtain card status, it suggests we can no
- *   longer communicate with the card.
+ * - Check card status. If the status_valid argument is false, the first 
attempt
+ *   to obtain card status failed and the status argument will not reflect the
+ *   failed r/w cmd.
  * - Check the card state.  If the card received the cmd but there was a
  *   transient problem with the response, it might still be in a data transfer
  *   mode.  Try to send it a stop command.  If this fails, we can't recover.
@@ -812,38 +811,15 @@ static int mmc_blk_cmd_error(struct request *req, const 
char *name, int error,
  * Otherwise we don't understand what happened, so abort.
  */
 static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req,
-   struct mmc_blk_request *brq, int *ecc_err, int *gen_err)
+   struct mmc_blk_request *brq, int *ecc_err, int *gen_err,
+   bool status_valid, int status)
 {
-   bool prev_cmd_status_valid = true;
-   u32 status, stop_status = 0;
-   int err, retry;
+   u32 stop_status = 0;
+   int err;
 
if (mmc_card_removed(card))
return ERR_NOMEDIUM;
 
-   /*
-* Try to get card status which indicates both the card state
-* and why there was no response.  If the first attempt fails,
-* we can't be sure the returned status is for the r/w command.
-*/
-   for (retry = 2; retry = 0; retry--) {
-   err = get_card_status(card, status, 0);
-   if (!err)
-   break;
-
-   prev_cmd_status_valid = false;
-   pr_err(%s: error %d sending status command, %sing\n,
-  req-rq_disk-disk_name, err, retry ? retry : abort);
-   }
-
-   /* We couldn't get a response from the card.  Give up. */
-   if (err) {
-   /* Check if the card is removed */
-   if (mmc_detect_card_removed(card-host))
-   return ERR_NOMEDIUM;
-   return ERR_ABORT;
-   }
-
/* Flag ECC errors */
if ((status  R1_CARD_ECC_FAILED) ||
(brq-stop.resp[0]  R1_CARD_ECC_FAILED) ||
@@ -891,12 +867,12 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, 
struct request *req,
/* Check for set block count errors */
if (brq-sbc.error)
return mmc_blk_cmd_error(req, SET_BLOCK_COUNT, brq-sbc.error,
-   prev_cmd_status_valid, status);
+   status_valid, status);
 
/* Check for r/w command errors */
if (brq-cmd.error)
return mmc_blk_cmd_error(req, r/w cmd, brq-cmd.error,
-   prev_cmd_status_valid, status);
+   status_valid, status);
 
/* Data errors */
if (!brq-stop.error)
@@ -1107,6 +1083,12 @@ static inline void mmc_apply_rel_rw(struct 
mmc_blk_request *brq,
 R1_CC_ERROR |  /* Card controller error */ \
 R1_ERROR)  /* General/unknown error */
 
+#define EXE_ERRORS \
+   (R1_OUT_OF_RANGE |  /* Command argument out of range */ \
+R1_ADDRESS_ERROR | /* Misaligned address */\
+R1_WP_VIOLATION |  /* Tried to write to protected block */ \
+R1_ERROR)  /* General/unknown error */
+
 static int mmc_blk_err_check(struct mmc_card *card,
 struct mmc_async_req *areq)
 {
@@ -1114,7 +1096,33 @@ static int mmc_blk_err_check(struct mmc_card

Re: [PATCH v2] input: don't call input_dev_release_keys() in resume

2013-09-18 Thread Oskar Andero
Hii Dmitry,

On 14:09 Thu 25 Jul , Oskar Andero wrote:
> From: Aleksej Makarov 
> 
> When waking up the platform by pressing a specific key, sending a
> release on that key makes it impossible to react on the event in
> user-space. This is fixed by moving the input_reset_device() call to
> resume instead.
> 
> Cc: Dmitry Torokhov 
> Reviewed-by: Radovan Lekanovic 
> Signed-off-by: Aleksej Makarov 
> Signed-off-by: Oskar Andero 
> ---
>  drivers/input/input.c | 11 +--
>  1 file changed, 1 insertion(+), 10 deletions(-)
> 
> diff --git a/drivers/input/input.c b/drivers/input/input.c
> index c044699..ee3ff16 100644
> --- a/drivers/input/input.c
> +++ b/drivers/input/input.c
> @@ -1676,22 +1676,13 @@ static int input_dev_suspend(struct device *dev)
>  {
>   struct input_dev *input_dev = to_input_dev(dev);
>  
> - mutex_lock(_dev->mutex);
> -
> - if (input_dev->users)
> - input_dev_toggle(input_dev, false);
> -
> - mutex_unlock(_dev->mutex);
> + input_reset_device(input_dev);
>  
>   return 0;
>  }
>  
>  static int input_dev_resume(struct device *dev)
>  {
> - struct input_dev *input_dev = to_input_dev(dev);
> -
> - input_reset_device(input_dev);
> -
>   return 0;
>  }

Sorry for bugging you with this patch again! I realize that changes to
input.c is sensitive since it's a central part of the subsystem.
However, the problem of reading input events after wake-up remains.

Does the patch make sense or do you see any potential risks with it?

Thanks,
 Oskar
--
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] input: don't call input_dev_release_keys() in resume

2013-09-18 Thread Oskar Andero
Hii Dmitry,

On 14:09 Thu 25 Jul , Oskar Andero wrote:
 From: Aleksej Makarov aleksej.maka...@sonymobile.com
 
 When waking up the platform by pressing a specific key, sending a
 release on that key makes it impossible to react on the event in
 user-space. This is fixed by moving the input_reset_device() call to
 resume instead.
 
 Cc: Dmitry Torokhov dmitry.torok...@gmail.com
 Reviewed-by: Radovan Lekanovic radovan.lekano...@sonymobile.com
 Signed-off-by: Aleksej Makarov aleksej.maka...@sonymobile.com
 Signed-off-by: Oskar Andero oskar.and...@sonymobile.com
 ---
  drivers/input/input.c | 11 +--
  1 file changed, 1 insertion(+), 10 deletions(-)
 
 diff --git a/drivers/input/input.c b/drivers/input/input.c
 index c044699..ee3ff16 100644
 --- a/drivers/input/input.c
 +++ b/drivers/input/input.c
 @@ -1676,22 +1676,13 @@ static int input_dev_suspend(struct device *dev)
  {
   struct input_dev *input_dev = to_input_dev(dev);
  
 - mutex_lock(input_dev-mutex);
 -
 - if (input_dev-users)
 - input_dev_toggle(input_dev, false);
 -
 - mutex_unlock(input_dev-mutex);
 + input_reset_device(input_dev);
  
   return 0;
  }
  
  static int input_dev_resume(struct device *dev)
  {
 - struct input_dev *input_dev = to_input_dev(dev);
 -
 - input_reset_device(input_dev);
 -
   return 0;
  }

Sorry for bugging you with this patch again! I realize that changes to
input.c is sensitive since it's a central part of the subsystem.
However, the problem of reading input events after wake-up remains.

Does the patch make sense or do you see any potential risks with it?

Thanks,
 Oskar
--
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 v2] input: don't call input_dev_release_keys() in resume

2013-07-25 Thread Oskar Andero
From: Aleksej Makarov 

When waking up the platform by pressing a specific key, sending a
release on that key makes it impossible to react on the event in
user-space. This is fixed by moving the input_reset_device() call to
resume instead.

Cc: Dmitry Torokhov 
Reviewed-by: Radovan Lekanovic 
Signed-off-by: Aleksej Makarov 
Signed-off-by: Oskar Andero 
---
 drivers/input/input.c | 11 +--
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/drivers/input/input.c b/drivers/input/input.c
index c044699..ee3ff16 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -1676,22 +1676,13 @@ static int input_dev_suspend(struct device *dev)
 {
struct input_dev *input_dev = to_input_dev(dev);
 
-   mutex_lock(_dev->mutex);
-
-   if (input_dev->users)
-   input_dev_toggle(input_dev, false);
-
-   mutex_unlock(_dev->mutex);
+   input_reset_device(input_dev);
 
return 0;
 }
 
 static int input_dev_resume(struct device *dev)
 {
-   struct input_dev *input_dev = to_input_dev(dev);
-
-   input_reset_device(input_dev);
-
return 0;
 }
 
-- 
1.8.1.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] MMC: Detect execution mode errors after r/w command

2013-07-25 Thread Oskar Andero
Hi,

On 14:47 Tue 09 Jul , Oskar Andero wrote:
> From: Lars Svensson 
> 
> Some error bits in the status field of R1/R1b response are only set
> by the device in response to the command following the failing
> command. The status is only read and checked after a r/w command if
> an error is detected during the initial command or the following data
> transfer. In some situations this causes errors passing undetected.
> 
> The solution is to read the status and check for these errors after
> each r/w operation.
> 
> Signed-off-by: Lars Svensson 
> Signed-off-by: Oskar Andero 
> Cc: linux-...@vger.kernel.org
> ---
>  drivers/mmc/card/block.c | 105 
> +--
>  1 file changed, 57 insertions(+), 48 deletions(-)
> 
> diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
> index dd27b07..b2664d7 100644
> --- a/drivers/mmc/card/block.c
> +++ b/drivers/mmc/card/block.c
> @@ -754,10 +754,9 @@ static int mmc_blk_cmd_error(struct request *req, const 
> char *name, int error,
>   * Initial r/w and stop cmd error recovery.
>   * We don't know whether the card received the r/w cmd or not, so try to
>   * restore things back to a sane state.  Essentially, we do this as follows:
> - * - Obtain card status.  If the first attempt to obtain card status fails,
> - *   the status word will reflect the failed status cmd, not the failed
> - *   r/w cmd.  If we fail to obtain card status, it suggests we can no
> - *   longer communicate with the card.
> + * - Check card status. If the status_valid argument is false, the first 
> attempt
> + *   to obtain card status failed and the status argument will not reflect 
> the
> + *   failed r/w cmd.
>   * - Check the card state.  If the card received the cmd but there was a
>   *   transient problem with the response, it might still be in a data 
> transfer
>   *   mode.  Try to send it a stop command.  If this fails, we can't recover.
> @@ -769,38 +768,15 @@ static int mmc_blk_cmd_error(struct request *req, const 
> char *name, int error,
>   * Otherwise we don't understand what happened, so abort.
>   */
>  static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req,
> - struct mmc_blk_request *brq, int *ecc_err)
> + struct mmc_blk_request *brq, int *ecc_err, u32 status,
> + bool status_valid)
>  {
> - bool prev_cmd_status_valid = true;
> - u32 status, stop_status = 0;
> - int err, retry;
> + u32 stop_status = 0;
> + int err;
>  
>   if (mmc_card_removed(card))
>   return ERR_NOMEDIUM;
>  
> - /*
> -  * Try to get card status which indicates both the card state
> -  * and why there was no response.  If the first attempt fails,
> -  * we can't be sure the returned status is for the r/w command.
> -  */
> - for (retry = 2; retry >= 0; retry--) {
> - err = get_card_status(card, , 0);
> - if (!err)
> - break;
> -
> - prev_cmd_status_valid = false;
> - pr_err("%s: error %d sending status command, %sing\n",
> -req->rq_disk->disk_name, err, retry ? "retry" : "abort");
> - }
> -
> - /* We couldn't get a response from the card.  Give up. */
> - if (err) {
> - /* Check if the card is removed */
> - if (mmc_detect_card_removed(card->host))
> - return ERR_NOMEDIUM;
> - return ERR_ABORT;
> - }
> -
>   /* Flag ECC errors */
>   if ((status & R1_CARD_ECC_FAILED) ||
>   (brq->stop.resp[0] & R1_CARD_ECC_FAILED) ||
> @@ -831,12 +807,12 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, 
> struct request *req,
>   /* Check for set block count errors */
>   if (brq->sbc.error)
>   return mmc_blk_cmd_error(req, "SET_BLOCK_COUNT", brq->sbc.error,
> - prev_cmd_status_valid, status);
> + status_valid, status);
>  
>   /* Check for r/w command errors */
>   if (brq->cmd.error)
>   return mmc_blk_cmd_error(req, "r/w cmd", brq->cmd.error,
> - prev_cmd_status_valid, status);
> + status_valid, status);
>  
>   /* Data errors */
>   if (!brq->stop.error)
> @@ -1062,6 +1038,12 @@ static inline void mmc_apply_rel_rw(struct 
> mmc_blk_request *brq,
>R1_CC_ERROR |  /* Card controller error */ \
>R1_ERROR)  /* General/unknown error */
>  
> +#define EXE_ERRORS  

Re: [PATCH] MMC: Detect execution mode errors after r/w command

2013-07-25 Thread Oskar Andero
Hi,

On 14:47 Tue 09 Jul , Oskar Andero wrote:
 From: Lars Svensson lars1.svens...@sonymobile.com
 
 Some error bits in the status field of R1/R1b response are only set
 by the device in response to the command following the failing
 command. The status is only read and checked after a r/w command if
 an error is detected during the initial command or the following data
 transfer. In some situations this causes errors passing undetected.
 
 The solution is to read the status and check for these errors after
 each r/w operation.
 
 Signed-off-by: Lars Svensson lars1.svens...@sonymobile.com
 Signed-off-by: Oskar Andero oskar.and...@sonymobile.com
 Cc: linux-...@vger.kernel.org
 ---
  drivers/mmc/card/block.c | 105 
 +--
  1 file changed, 57 insertions(+), 48 deletions(-)
 
 diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
 index dd27b07..b2664d7 100644
 --- a/drivers/mmc/card/block.c
 +++ b/drivers/mmc/card/block.c
 @@ -754,10 +754,9 @@ static int mmc_blk_cmd_error(struct request *req, const 
 char *name, int error,
   * Initial r/w and stop cmd error recovery.
   * We don't know whether the card received the r/w cmd or not, so try to
   * restore things back to a sane state.  Essentially, we do this as follows:
 - * - Obtain card status.  If the first attempt to obtain card status fails,
 - *   the status word will reflect the failed status cmd, not the failed
 - *   r/w cmd.  If we fail to obtain card status, it suggests we can no
 - *   longer communicate with the card.
 + * - Check card status. If the status_valid argument is false, the first 
 attempt
 + *   to obtain card status failed and the status argument will not reflect 
 the
 + *   failed r/w cmd.
   * - Check the card state.  If the card received the cmd but there was a
   *   transient problem with the response, it might still be in a data 
 transfer
   *   mode.  Try to send it a stop command.  If this fails, we can't recover.
 @@ -769,38 +768,15 @@ static int mmc_blk_cmd_error(struct request *req, const 
 char *name, int error,
   * Otherwise we don't understand what happened, so abort.
   */
  static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req,
 - struct mmc_blk_request *brq, int *ecc_err)
 + struct mmc_blk_request *brq, int *ecc_err, u32 status,
 + bool status_valid)
  {
 - bool prev_cmd_status_valid = true;
 - u32 status, stop_status = 0;
 - int err, retry;
 + u32 stop_status = 0;
 + int err;
  
   if (mmc_card_removed(card))
   return ERR_NOMEDIUM;
  
 - /*
 -  * Try to get card status which indicates both the card state
 -  * and why there was no response.  If the first attempt fails,
 -  * we can't be sure the returned status is for the r/w command.
 -  */
 - for (retry = 2; retry = 0; retry--) {
 - err = get_card_status(card, status, 0);
 - if (!err)
 - break;
 -
 - prev_cmd_status_valid = false;
 - pr_err(%s: error %d sending status command, %sing\n,
 -req-rq_disk-disk_name, err, retry ? retry : abort);
 - }
 -
 - /* We couldn't get a response from the card.  Give up. */
 - if (err) {
 - /* Check if the card is removed */
 - if (mmc_detect_card_removed(card-host))
 - return ERR_NOMEDIUM;
 - return ERR_ABORT;
 - }
 -
   /* Flag ECC errors */
   if ((status  R1_CARD_ECC_FAILED) ||
   (brq-stop.resp[0]  R1_CARD_ECC_FAILED) ||
 @@ -831,12 +807,12 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, 
 struct request *req,
   /* Check for set block count errors */
   if (brq-sbc.error)
   return mmc_blk_cmd_error(req, SET_BLOCK_COUNT, brq-sbc.error,
 - prev_cmd_status_valid, status);
 + status_valid, status);
  
   /* Check for r/w command errors */
   if (brq-cmd.error)
   return mmc_blk_cmd_error(req, r/w cmd, brq-cmd.error,
 - prev_cmd_status_valid, status);
 + status_valid, status);
  
   /* Data errors */
   if (!brq-stop.error)
 @@ -1062,6 +1038,12 @@ static inline void mmc_apply_rel_rw(struct 
 mmc_blk_request *brq,
R1_CC_ERROR |  /* Card controller error */ \
R1_ERROR)  /* General/unknown error */
  
 +#define EXE_ERRORS   \
 + (R1_OUT_OF_RANGE |  /* Command argument out of range */ \
 +  R1_ADDRESS_ERROR | /* Misaligned address */\
 +  R1_WP_VIOLATION |  /* Tried to write to protected block */ \
 +  R1_ERROR)  /* General/unknown error */
 +
  static int mmc_blk_err_check(struct mmc_card *card,
struct mmc_async_req *areq)
  {
 @@ -1069,7 +1051,33 @@ static

[PATCH v2] input: don't call input_dev_release_keys() in resume

2013-07-25 Thread Oskar Andero
From: Aleksej Makarov aleksej.maka...@sonymobile.com

When waking up the platform by pressing a specific key, sending a
release on that key makes it impossible to react on the event in
user-space. This is fixed by moving the input_reset_device() call to
resume instead.

Cc: Dmitry Torokhov dmitry.torok...@gmail.com
Reviewed-by: Radovan Lekanovic radovan.lekano...@sonymobile.com
Signed-off-by: Aleksej Makarov aleksej.maka...@sonymobile.com
Signed-off-by: Oskar Andero oskar.and...@sonymobile.com
---
 drivers/input/input.c | 11 +--
 1 file changed, 1 insertion(+), 10 deletions(-)

diff --git a/drivers/input/input.c b/drivers/input/input.c
index c044699..ee3ff16 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -1676,22 +1676,13 @@ static int input_dev_suspend(struct device *dev)
 {
struct input_dev *input_dev = to_input_dev(dev);
 
-   mutex_lock(input_dev-mutex);
-
-   if (input_dev-users)
-   input_dev_toggle(input_dev, false);
-
-   mutex_unlock(input_dev-mutex);
+   input_reset_device(input_dev);
 
return 0;
 }
 
 static int input_dev_resume(struct device *dev)
 {
-   struct input_dev *input_dev = to_input_dev(dev);
-
-   input_reset_device(input_dev);
-
return 0;
 }
 
-- 
1.8.1.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] input: don't call input_dev_release_keys() in resume

2013-07-12 Thread Oskar Andero
On 09:46 Fri 05 Jul , Oskar Andero wrote:
> Hi Dmitry,
> 
> On 18:33 Thu 04 Apr , Dmitry Torokhov wrote:
> > Hi Oskar,
> > 
> > On Thu, Mar 07, 2013 at 03:01:22PM +0100, oskar.and...@sonymobile.com wrote:
> > > From: Aleksej Makarov 
> > >
> > > When waking up the platform by pressing a specific key, sending a
> > > release on that key makes it impossible to react on the event in
> > > user-space.
> > >
> > 
> > No, we can not simply not release keys after resume from suspend, as
> > this leads to keys being stuck. Consider you are holding an 'I' key on
> > your external USB keyboard and close your laptop's lid. Then you release
> > the key and leave. Later you come back, open the lid waking the laptop
> > and observe endless stream of 'I' in your open terminal.
> > 
> > Maybe we should release the keys during suspend time? I am not sure how
> > Android infrastructure will react to this though...
> 
> I finally got the time to try this out. Releasing the keys in suspend
> also solves our problem. Would such patch work for the USB keyboard
> case you described? Theoretically, I think it should, right?
> 
> So, basically:
> 
> static int input_dev_suspend(struct device *dev)
>  {
> struct input_dev *input_dev = to_input_dev(dev);
>  
> -   mutex_lock(_dev->mutex);
> -
> -   if (input_dev->users)
> -   input_dev_toggle(input_dev, false);
> -
> -   mutex_unlock(_dev->mutex);
> +   input_reset_device(input_dev);
>  
> return 0;
>  }
>  
>  static int input_dev_resume(struct device *dev)
>  {
> -   struct input_dev *input_dev = to_input_dev(dev);
> -
> -   input_reset_device(input_dev);
> -
> return 0;
>  }
> 
> Should I send the patch?

Ping. Any thoughts on this?

Thanks!

-Oskar

--
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] input: don't call input_dev_release_keys() in resume

2013-07-12 Thread Oskar Andero
On 09:46 Fri 05 Jul , Oskar Andero wrote:
 Hi Dmitry,
 
 On 18:33 Thu 04 Apr , Dmitry Torokhov wrote:
  Hi Oskar,
  
  On Thu, Mar 07, 2013 at 03:01:22PM +0100, oskar.and...@sonymobile.com wrote:
   From: Aleksej Makarov aleksej.maka...@sonymobile.com
  
   When waking up the platform by pressing a specific key, sending a
   release on that key makes it impossible to react on the event in
   user-space.
  
  
  No, we can not simply not release keys after resume from suspend, as
  this leads to keys being stuck. Consider you are holding an 'I' key on
  your external USB keyboard and close your laptop's lid. Then you release
  the key and leave. Later you come back, open the lid waking the laptop
  and observe endless stream of 'I' in your open terminal.
  
  Maybe we should release the keys during suspend time? I am not sure how
  Android infrastructure will react to this though...
 
 I finally got the time to try this out. Releasing the keys in suspend
 also solves our problem. Would such patch work for the USB keyboard
 case you described? Theoretically, I think it should, right?
 
 So, basically:
 
 static int input_dev_suspend(struct device *dev)
  {
 struct input_dev *input_dev = to_input_dev(dev);
  
 -   mutex_lock(input_dev-mutex);
 -
 -   if (input_dev-users)
 -   input_dev_toggle(input_dev, false);
 -
 -   mutex_unlock(input_dev-mutex);
 +   input_reset_device(input_dev);
  
 return 0;
  }
  
  static int input_dev_resume(struct device *dev)
  {
 -   struct input_dev *input_dev = to_input_dev(dev);
 -
 -   input_reset_device(input_dev);
 -
 return 0;
  }
 
 Should I send the patch?

Ping. Any thoughts on this?

Thanks!

-Oskar

--
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] MMC: Detect execution mode errors after r/w command

2013-07-09 Thread Oskar Andero
From: Lars Svensson 

Some error bits in the status field of R1/R1b response are only set
by the device in response to the command following the failing
command. The status is only read and checked after a r/w command if
an error is detected during the initial command or the following data
transfer. In some situations this causes errors passing undetected.

The solution is to read the status and check for these errors after
each r/w operation.

Signed-off-by: Lars Svensson 
Signed-off-by: Oskar Andero 
Cc: linux-...@vger.kernel.org
---
 drivers/mmc/card/block.c | 105 +--
 1 file changed, 57 insertions(+), 48 deletions(-)

diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index dd27b07..b2664d7 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -754,10 +754,9 @@ static int mmc_blk_cmd_error(struct request *req, const 
char *name, int error,
  * Initial r/w and stop cmd error recovery.
  * We don't know whether the card received the r/w cmd or not, so try to
  * restore things back to a sane state.  Essentially, we do this as follows:
- * - Obtain card status.  If the first attempt to obtain card status fails,
- *   the status word will reflect the failed status cmd, not the failed
- *   r/w cmd.  If we fail to obtain card status, it suggests we can no
- *   longer communicate with the card.
+ * - Check card status. If the status_valid argument is false, the first 
attempt
+ *   to obtain card status failed and the status argument will not reflect the
+ *   failed r/w cmd.
  * - Check the card state.  If the card received the cmd but there was a
  *   transient problem with the response, it might still be in a data transfer
  *   mode.  Try to send it a stop command.  If this fails, we can't recover.
@@ -769,38 +768,15 @@ static int mmc_blk_cmd_error(struct request *req, const 
char *name, int error,
  * Otherwise we don't understand what happened, so abort.
  */
 static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req,
-   struct mmc_blk_request *brq, int *ecc_err)
+   struct mmc_blk_request *brq, int *ecc_err, u32 status,
+   bool status_valid)
 {
-   bool prev_cmd_status_valid = true;
-   u32 status, stop_status = 0;
-   int err, retry;
+   u32 stop_status = 0;
+   int err;
 
if (mmc_card_removed(card))
return ERR_NOMEDIUM;
 
-   /*
-* Try to get card status which indicates both the card state
-* and why there was no response.  If the first attempt fails,
-* we can't be sure the returned status is for the r/w command.
-*/
-   for (retry = 2; retry >= 0; retry--) {
-   err = get_card_status(card, , 0);
-   if (!err)
-   break;
-
-   prev_cmd_status_valid = false;
-   pr_err("%s: error %d sending status command, %sing\n",
-  req->rq_disk->disk_name, err, retry ? "retry" : "abort");
-   }
-
-   /* We couldn't get a response from the card.  Give up. */
-   if (err) {
-   /* Check if the card is removed */
-   if (mmc_detect_card_removed(card->host))
-   return ERR_NOMEDIUM;
-   return ERR_ABORT;
-   }
-
/* Flag ECC errors */
if ((status & R1_CARD_ECC_FAILED) ||
(brq->stop.resp[0] & R1_CARD_ECC_FAILED) ||
@@ -831,12 +807,12 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, 
struct request *req,
/* Check for set block count errors */
if (brq->sbc.error)
return mmc_blk_cmd_error(req, "SET_BLOCK_COUNT", brq->sbc.error,
-   prev_cmd_status_valid, status);
+   status_valid, status);
 
/* Check for r/w command errors */
if (brq->cmd.error)
return mmc_blk_cmd_error(req, "r/w cmd", brq->cmd.error,
-   prev_cmd_status_valid, status);
+   status_valid, status);
 
/* Data errors */
if (!brq->stop.error)
@@ -1062,6 +1038,12 @@ static inline void mmc_apply_rel_rw(struct 
mmc_blk_request *brq,
 R1_CC_ERROR |  /* Card controller error */ \
 R1_ERROR)  /* General/unknown error */
 
+#define EXE_ERRORS \
+   (R1_OUT_OF_RANGE |  /* Command argument out of range */ \
+R1_ADDRESS_ERROR | /* Misaligned address */\
+R1_WP_VIOLATION |  /* Tried to write to protected block */ \
+R1_ERROR)  /* General/unknown error */
+
 static int mmc_blk_err_check(struct mmc_card *card,
 struct mmc_async_req *areq)
 {
@@ -1069,7 +1051,33 @@ static int mmc_blk_err_check(struct mmc_car

[PATCH] MMC: Detect execution mode errors after r/w command

2013-07-09 Thread Oskar Andero
From: Lars Svensson lars1.svens...@sonymobile.com

Some error bits in the status field of R1/R1b response are only set
by the device in response to the command following the failing
command. The status is only read and checked after a r/w command if
an error is detected during the initial command or the following data
transfer. In some situations this causes errors passing undetected.

The solution is to read the status and check for these errors after
each r/w operation.

Signed-off-by: Lars Svensson lars1.svens...@sonymobile.com
Signed-off-by: Oskar Andero oskar.and...@sonymobile.com
Cc: linux-...@vger.kernel.org
---
 drivers/mmc/card/block.c | 105 +--
 1 file changed, 57 insertions(+), 48 deletions(-)

diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index dd27b07..b2664d7 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -754,10 +754,9 @@ static int mmc_blk_cmd_error(struct request *req, const 
char *name, int error,
  * Initial r/w and stop cmd error recovery.
  * We don't know whether the card received the r/w cmd or not, so try to
  * restore things back to a sane state.  Essentially, we do this as follows:
- * - Obtain card status.  If the first attempt to obtain card status fails,
- *   the status word will reflect the failed status cmd, not the failed
- *   r/w cmd.  If we fail to obtain card status, it suggests we can no
- *   longer communicate with the card.
+ * - Check card status. If the status_valid argument is false, the first 
attempt
+ *   to obtain card status failed and the status argument will not reflect the
+ *   failed r/w cmd.
  * - Check the card state.  If the card received the cmd but there was a
  *   transient problem with the response, it might still be in a data transfer
  *   mode.  Try to send it a stop command.  If this fails, we can't recover.
@@ -769,38 +768,15 @@ static int mmc_blk_cmd_error(struct request *req, const 
char *name, int error,
  * Otherwise we don't understand what happened, so abort.
  */
 static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req,
-   struct mmc_blk_request *brq, int *ecc_err)
+   struct mmc_blk_request *brq, int *ecc_err, u32 status,
+   bool status_valid)
 {
-   bool prev_cmd_status_valid = true;
-   u32 status, stop_status = 0;
-   int err, retry;
+   u32 stop_status = 0;
+   int err;
 
if (mmc_card_removed(card))
return ERR_NOMEDIUM;
 
-   /*
-* Try to get card status which indicates both the card state
-* and why there was no response.  If the first attempt fails,
-* we can't be sure the returned status is for the r/w command.
-*/
-   for (retry = 2; retry = 0; retry--) {
-   err = get_card_status(card, status, 0);
-   if (!err)
-   break;
-
-   prev_cmd_status_valid = false;
-   pr_err(%s: error %d sending status command, %sing\n,
-  req-rq_disk-disk_name, err, retry ? retry : abort);
-   }
-
-   /* We couldn't get a response from the card.  Give up. */
-   if (err) {
-   /* Check if the card is removed */
-   if (mmc_detect_card_removed(card-host))
-   return ERR_NOMEDIUM;
-   return ERR_ABORT;
-   }
-
/* Flag ECC errors */
if ((status  R1_CARD_ECC_FAILED) ||
(brq-stop.resp[0]  R1_CARD_ECC_FAILED) ||
@@ -831,12 +807,12 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, 
struct request *req,
/* Check for set block count errors */
if (brq-sbc.error)
return mmc_blk_cmd_error(req, SET_BLOCK_COUNT, brq-sbc.error,
-   prev_cmd_status_valid, status);
+   status_valid, status);
 
/* Check for r/w command errors */
if (brq-cmd.error)
return mmc_blk_cmd_error(req, r/w cmd, brq-cmd.error,
-   prev_cmd_status_valid, status);
+   status_valid, status);
 
/* Data errors */
if (!brq-stop.error)
@@ -1062,6 +1038,12 @@ static inline void mmc_apply_rel_rw(struct 
mmc_blk_request *brq,
 R1_CC_ERROR |  /* Card controller error */ \
 R1_ERROR)  /* General/unknown error */
 
+#define EXE_ERRORS \
+   (R1_OUT_OF_RANGE |  /* Command argument out of range */ \
+R1_ADDRESS_ERROR | /* Misaligned address */\
+R1_WP_VIOLATION |  /* Tried to write to protected block */ \
+R1_ERROR)  /* General/unknown error */
+
 static int mmc_blk_err_check(struct mmc_card *card,
 struct mmc_async_req *areq)
 {
@@ -1069,7 +1051,33 @@ static int mmc_blk_err_check(struct mmc_card *card

Re: [PATCH] input: don't call input_dev_release_keys() in resume

2013-07-05 Thread Oskar Andero
Hi Dmitry,

On 18:33 Thu 04 Apr , Dmitry Torokhov wrote:
> Hi Oskar,
> 
> On Thu, Mar 07, 2013 at 03:01:22PM +0100, oskar.and...@sonymobile.com wrote:
> > From: Aleksej Makarov 
> >
> > When waking up the platform by pressing a specific key, sending a
> > release on that key makes it impossible to react on the event in
> > user-space.
> >
> 
> No, we can not simply not release keys after resume from suspend, as
> this leads to keys being stuck. Consider you are holding an 'I' key on
> your external USB keyboard and close your laptop's lid. Then you release
> the key and leave. Later you come back, open the lid waking the laptop
> and observe endless stream of 'I' in your open terminal.
> 
> Maybe we should release the keys during suspend time? I am not sure how
> Android infrastructure will react to this though...

I finally got the time to try this out. Releasing the keys in suspend
also solves our problem. Would such patch work for the USB keyboard
case you described? Theoretically, I think it should, right?

So, basically:

static int input_dev_suspend(struct device *dev)
 {
struct input_dev *input_dev = to_input_dev(dev);
 
-   mutex_lock(_dev->mutex);
-
-   if (input_dev->users)
-   input_dev_toggle(input_dev, false);
-
-   mutex_unlock(_dev->mutex);
+   input_reset_device(input_dev);
 
return 0;
 }
 
 static int input_dev_resume(struct device *dev)
 {
-   struct input_dev *input_dev = to_input_dev(dev);
-
-   input_reset_device(input_dev);
-
return 0;
 }

Should I send the patch?

-Oskar
--
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] input: don't call input_dev_release_keys() in resume

2013-07-05 Thread Oskar Andero
Hi Dmitry,

On 18:33 Thu 04 Apr , Dmitry Torokhov wrote:
 Hi Oskar,
 
 On Thu, Mar 07, 2013 at 03:01:22PM +0100, oskar.and...@sonymobile.com wrote:
  From: Aleksej Makarov aleksej.maka...@sonymobile.com
 
  When waking up the platform by pressing a specific key, sending a
  release on that key makes it impossible to react on the event in
  user-space.
 
 
 No, we can not simply not release keys after resume from suspend, as
 this leads to keys being stuck. Consider you are holding an 'I' key on
 your external USB keyboard and close your laptop's lid. Then you release
 the key and leave. Later you come back, open the lid waking the laptop
 and observe endless stream of 'I' in your open terminal.
 
 Maybe we should release the keys during suspend time? I am not sure how
 Android infrastructure will react to this though...

I finally got the time to try this out. Releasing the keys in suspend
also solves our problem. Would such patch work for the USB keyboard
case you described? Theoretically, I think it should, right?

So, basically:

static int input_dev_suspend(struct device *dev)
 {
struct input_dev *input_dev = to_input_dev(dev);
 
-   mutex_lock(input_dev-mutex);
-
-   if (input_dev-users)
-   input_dev_toggle(input_dev, false);
-
-   mutex_unlock(input_dev-mutex);
+   input_reset_device(input_dev);
 
return 0;
 }
 
 static int input_dev_resume(struct device *dev)
 {
-   struct input_dev *input_dev = to_input_dev(dev);
-
-   input_reset_device(input_dev);
-
return 0;
 }

Should I send the patch?

-Oskar
--
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] backlight: lp855x: set zero brightness at FBBLANK

2013-07-02 Thread Oskar Andero
From: Shingo Nakao 

When backlight turns on early from display, a white line can be
seen on the screen. Therefore make sure backlight is off when we
are under an fb blank event.

Signed-off-by: Shingo Nakao 
Cc: Milo Kim 
Cc: Richard Purdie 
Signed-off-by: Oskar Andero 
---
 drivers/video/backlight/lp855x_bl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/backlight/lp855x_bl.c 
b/drivers/video/backlight/lp855x_bl.c
index a0e1e02..c0b41f1 100644
--- a/drivers/video/backlight/lp855x_bl.c
+++ b/drivers/video/backlight/lp855x_bl.c
@@ -246,7 +246,7 @@ static int lp855x_bl_update_status(struct backlight_device 
*bl)
 {
struct lp855x *lp = bl_get_data(bl);
 
-   if (bl->props.state & BL_CORE_SUSPENDED)
+   if (bl->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK))
bl->props.brightness = 0;
 
if (lp->mode == PWM_BASED) {
-- 
1.8.1.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/


[PATCH] USB: storage: Add MicroVault Flash Drive to unusual_devs

2013-07-02 Thread Oskar Andero
From: Ren Bigcren 

The device report an error capacity when read_capacity_16().
Using read_capacity_10() can get the correct capacity.

Signed-off-by: Ren Bigcren 
Cc: Matthew Dharm 
Signed-off-by: Oskar Andero 
---
 drivers/usb/storage/unusual_devs.h | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/usb/storage/unusual_devs.h 
b/drivers/usb/storage/unusual_devs.h
index 179933528..c015f2c 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -665,6 +665,13 @@ UNUSUAL_DEV(  0x054c, 0x016a, 0x, 0x,
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_FIX_INQUIRY ),
 
+/* Submitted by Ren Bigcren  */
+UNUSUAL_DEV(  0x054c, 0x02a5, 0x0100, 0x0100,
+   "Sony Corp.",
+   "MicroVault Flash Drive",
+   USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+   US_FL_NO_READ_CAPACITY_16 ),
+
 /* floppy reports multiple luns */
 UNUSUAL_DEV(  0x055d, 0x2020, 0x, 0x0210,
"SAMSUNG",
-- 
1.8.1.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/


[PATCH] USB: storage: Add MicroVault Flash Drive to unusual_devs

2013-07-02 Thread Oskar Andero
From: Ren Bigcren bigcren@sonymobile.com

The device report an error capacity when read_capacity_16().
Using read_capacity_10() can get the correct capacity.

Signed-off-by: Ren Bigcren bigcren@sonymobile.com
Cc: Matthew Dharm mdharm-...@one-eyed-alien.net
Signed-off-by: Oskar Andero oskar.and...@sonymobile.com
---
 drivers/usb/storage/unusual_devs.h | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/usb/storage/unusual_devs.h 
b/drivers/usb/storage/unusual_devs.h
index 179933528..c015f2c 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -665,6 +665,13 @@ UNUSUAL_DEV(  0x054c, 0x016a, 0x, 0x,
USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_FIX_INQUIRY ),
 
+/* Submitted by Ren Bigcren bigcren@sonymobile.com */
+UNUSUAL_DEV(  0x054c, 0x02a5, 0x0100, 0x0100,
+   Sony Corp.,
+   MicroVault Flash Drive,
+   USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+   US_FL_NO_READ_CAPACITY_16 ),
+
 /* floppy reports multiple luns */
 UNUSUAL_DEV(  0x055d, 0x2020, 0x, 0x0210,
SAMSUNG,
-- 
1.8.1.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/


[PATCH] backlight: lp855x: set zero brightness at FBBLANK

2013-07-02 Thread Oskar Andero
From: Shingo Nakao shingo.x.na...@sonymobile.com

When backlight turns on early from display, a white line can be
seen on the screen. Therefore make sure backlight is off when we
are under an fb blank event.

Signed-off-by: Shingo Nakao shingo.x.na...@sonymobile.com
Cc: Milo Kim milo@ti.com
Cc: Richard Purdie rpur...@rpsys.net
Signed-off-by: Oskar Andero oskar.and...@sonymobile.com
---
 drivers/video/backlight/lp855x_bl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/backlight/lp855x_bl.c 
b/drivers/video/backlight/lp855x_bl.c
index a0e1e02..c0b41f1 100644
--- a/drivers/video/backlight/lp855x_bl.c
+++ b/drivers/video/backlight/lp855x_bl.c
@@ -246,7 +246,7 @@ static int lp855x_bl_update_status(struct backlight_device 
*bl)
 {
struct lp855x *lp = bl_get_data(bl);
 
-   if (bl-props.state  BL_CORE_SUSPENDED)
+   if (bl-props.state  (BL_CORE_SUSPENDED | BL_CORE_FBBLANK))
bl-props.brightness = 0;
 
if (lp-mode == PWM_BASED) {
-- 
1.8.1.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/


[PATCH v2] mm: vmscan: add VM_BUG_ON on illegal return values from scan_objects

2013-05-21 Thread Oskar Andero
Add a VM_BUG_ON to catch any illegal value from the shrinkers. It's a
potential bug if scan_objects returns a negative other than -1 and
would lead to undefined behaviour.

Cc: Glauber Costa 
Cc: Dave Chinner 
Cc: Andrew Morton 
Cc: Hugh Dickins 
Cc: Greg Kroah-Hartman 
Signed-off-by: Oskar Andero 
---
 mm/vmscan.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/mm/vmscan.c b/mm/vmscan.c
index 6bac41e..63fec86 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -293,6 +293,7 @@ shrink_slab_one(struct shrinker *shrinker, struct 
shrink_control *shrinkctl,
ret = shrinker->scan_objects(shrinker, shrinkctl);
if (ret == -1)
break;
+   VM_BUG_ON(ret < -1);
freed += ret;
 
count_vm_events(SLABS_SCANNED, nr_to_scan);
-- 
1.8.1.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/


[PATCH v2] mm: vmscan: add VM_BUG_ON on illegal return values from scan_objects

2013-05-21 Thread Oskar Andero
Add a VM_BUG_ON to catch any illegal value from the shrinkers. It's a
potential bug if scan_objects returns a negative other than -1 and
would lead to undefined behaviour.

Cc: Glauber Costa glom...@openvz.org
Cc: Dave Chinner dchin...@redhat.com
Cc: Andrew Morton a...@linux-foundation.org
Cc: Hugh Dickins hu...@google.com
Cc: Greg Kroah-Hartman gre...@linuxfoundation.org
Signed-off-by: Oskar Andero oskar.and...@sonymobile.com
---
 mm/vmscan.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/mm/vmscan.c b/mm/vmscan.c
index 6bac41e..63fec86 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -293,6 +293,7 @@ shrink_slab_one(struct shrinker *shrinker, struct 
shrink_control *shrinkctl,
ret = shrinker-scan_objects(shrinker, shrinkctl);
if (ret == -1)
break;
+   VM_BUG_ON(ret  -1);
freed += ret;
 
count_vm_events(SLABS_SCANNED, nr_to_scan);
-- 
1.8.1.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/


[PATCH] mm: vmscan: add BUG_ON on illegal return values from scan_objects

2013-05-20 Thread Oskar Andero
Add a BUG_ON to catch any illegal value from the shrinkers. This fixes a
potential bug if scan_objects returns a negative other than -1, which
would lead to undefined behaviour.

Cc: Glauber Costa 
Cc: Dave Chinner 
Cc: Andrew Morton 
Cc: Hugh Dickins 
Cc: Greg Kroah-Hartman 
Signed-off-by: Oskar Andero 
---
 mm/vmscan.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/mm/vmscan.c b/mm/vmscan.c
index 6bac41e..fbe6742 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -293,6 +293,7 @@ shrink_slab_one(struct shrinker *shrinker, struct 
shrink_control *shrinkctl,
ret = shrinker->scan_objects(shrinker, shrinkctl);
if (ret == -1)
break;
+   BUG_ON(ret < -1);
freed += ret;
 
count_vm_events(SLABS_SCANNED, nr_to_scan);
-- 
1.8.1.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/


[PATCH] mm: vmscan: add BUG_ON on illegal return values from scan_objects

2013-05-20 Thread Oskar Andero
Add a BUG_ON to catch any illegal value from the shrinkers. This fixes a
potential bug if scan_objects returns a negative other than -1, which
would lead to undefined behaviour.

Cc: Glauber Costa glom...@openvz.org
Cc: Dave Chinner dchin...@redhat.com
Cc: Andrew Morton a...@linux-foundation.org
Cc: Hugh Dickins hu...@google.com
Cc: Greg Kroah-Hartman gre...@linuxfoundation.org
Signed-off-by: Oskar Andero oskar.and...@sonymobile.com
---
 mm/vmscan.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/mm/vmscan.c b/mm/vmscan.c
index 6bac41e..fbe6742 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -293,6 +293,7 @@ shrink_slab_one(struct shrinker *shrinker, struct 
shrink_control *shrinkctl,
ret = shrinker-scan_objects(shrinker, shrinkctl);
if (ret == -1)
break;
+   BUG_ON(ret  -1);
freed += ret;
 
count_vm_events(SLABS_SCANNED, nr_to_scan);
-- 
1.8.1.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] mm: vmscan: handle any negative return value from scan_objects

2013-05-17 Thread Oskar Andero
On 08:33 Fri 17 May , Dave Chinner wrote:
> On Thu, May 16, 2013 at 02:27:52PM +0200, Oskar Andero wrote:
> > On 13:52 Thu 16 May , Dave Chinner wrote:
> > > On Thu, May 16, 2013 at 10:42:16AM +0200, Oskar Andero wrote:
> > > > The shrinkers must return -1 to indicate that it is busy. Instead, treat
> > > > any negative value as busy.
> > > 
> > > Why? The API defines return condition for aborting a scan and gives
> > > a specific value for doing that. i.e. explain why should change the
> > > API to over-specify the 'abort scan" return value like this.
> > 
> > As I pointed out earlier, looking in to the code (from master):
> > if (shrink_ret == -1)
> > break;
> > if (shrink_ret < nr_before)
> > ret += nr_before - shrink_ret;
> > 
> > This piece of code lacks a sanity check and will only function if shrink_ret
> > is either greater than zero or exactly -1. If shrink_ret is e.g. -2 this 
> > will
> > lead to undefined behaviour.
> 
> If a shrinker is returning -2 then the shrinker is broken and needs
> fixing.

The point is: returning -2 is just as magical and meaningful as returning -1.

Usually, returning a negative means "failure" (Chapter 16 CodingStyle), not
a perfectly valid "abort scan" as in this piece of code.

> > > FWIW, using "any" negative number for "abort scan" is a bad API
> > > design decision. It means that in future we can't introduce
> > > different negative return values in the API if we have a new to.
> > > i.e. each specific negative return value needs to have the potential
> > > for defining a different behaviour. 
> > 
> > An alternative to my patch would be to add:
> > if (shrink_ret < -1)
> >/* handle illegal return code in some way */
> 
> How? We have one valid negative return code. WTF are we supposed to
> do if a shrinker is passing undefined return values? IOWs, the only
> sane thing to do is:
> 
>   BUG_ON(shrink_ret < -1);

Yes, of course! BUG_ON() is the proper way to handle an illegal value.
Now we are getting somewhere!

> > > So if any change needs to be made, it is to change the -1 return
> > > value to an enum and have the shrinkers return that enum when they
> > > want an abort.
> > 
> > I am all for an enum, but I still believe we should handle the case where
> > the shrinkers return something wicked.
> 
> Which bit of "broken shrinkers need to be fixed" don't you
> understand? A BUG_ON() will make sure they get fixed - anything else
> that allows broken shrinkers to continue functioning is a completely
> unacceptible solution.

BUG_ON() is perfect IMO and if everyone is ok with that I will send
version 2 of my patch.

Now there is just the matter of returning hardcoded -1. Would an enum in
shrinker.h add any value? I have gotten different feedback on this - some
say yea, others nay.
I think I have motivated it enough in this thread, so I am not going to
repeat myself.

-Oskar
--
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] mm: vmscan: handle any negative return value from scan_objects

2013-05-17 Thread Oskar Andero
On 08:33 Fri 17 May , Dave Chinner wrote:
 On Thu, May 16, 2013 at 02:27:52PM +0200, Oskar Andero wrote:
  On 13:52 Thu 16 May , Dave Chinner wrote:
   On Thu, May 16, 2013 at 10:42:16AM +0200, Oskar Andero wrote:
The shrinkers must return -1 to indicate that it is busy. Instead, treat
any negative value as busy.
   
   Why? The API defines return condition for aborting a scan and gives
   a specific value for doing that. i.e. explain why should change the
   API to over-specify the 'abort scan return value like this.
  
  As I pointed out earlier, looking in to the code (from master):
  if (shrink_ret == -1)
  break;
  if (shrink_ret  nr_before)
  ret += nr_before - shrink_ret;
  
  This piece of code lacks a sanity check and will only function if shrink_ret
  is either greater than zero or exactly -1. If shrink_ret is e.g. -2 this 
  will
  lead to undefined behaviour.
 
 If a shrinker is returning -2 then the shrinker is broken and needs
 fixing.

The point is: returning -2 is just as magical and meaningful as returning -1.

Usually, returning a negative means failure (Chapter 16 CodingStyle), not
a perfectly valid abort scan as in this piece of code.

   FWIW, using any negative number for abort scan is a bad API
   design decision. It means that in future we can't introduce
   different negative return values in the API if we have a new to.
   i.e. each specific negative return value needs to have the potential
   for defining a different behaviour. 
  
  An alternative to my patch would be to add:
  if (shrink_ret  -1)
 /* handle illegal return code in some way */
 
 How? We have one valid negative return code. WTF are we supposed to
 do if a shrinker is passing undefined return values? IOWs, the only
 sane thing to do is:
 
   BUG_ON(shrink_ret  -1);

Yes, of course! BUG_ON() is the proper way to handle an illegal value.
Now we are getting somewhere!

   So if any change needs to be made, it is to change the -1 return
   value to an enum and have the shrinkers return that enum when they
   want an abort.
  
  I am all for an enum, but I still believe we should handle the case where
  the shrinkers return something wicked.
 
 Which bit of broken shrinkers need to be fixed don't you
 understand? A BUG_ON() will make sure they get fixed - anything else
 that allows broken shrinkers to continue functioning is a completely
 unacceptible solution.

BUG_ON() is perfect IMO and if everyone is ok with that I will send
version 2 of my patch.

Now there is just the matter of returning hardcoded -1. Would an enum in
shrinker.h add any value? I have gotten different feedback on this - some
say yea, others nay.
I think I have motivated it enough in this thread, so I am not going to
repeat myself.

-Oskar
--
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] mm: vmscan: handle any negative return value from scan_objects

2013-05-16 Thread Oskar Andero
On 13:52 Thu 16 May , Dave Chinner wrote:
> On Thu, May 16, 2013 at 10:42:16AM +0200, Oskar Andero wrote:
> > The shrinkers must return -1 to indicate that it is busy. Instead, treat
> > any negative value as busy.
> 
> Why? The API defines return condition for aborting a scan and gives
> a specific value for doing that. i.e. explain why should change the
> API to over-specify the 'abort scan" return value like this.

As I pointed out earlier, looking in to the code (from master):
if (shrink_ret == -1)
break;
if (shrink_ret < nr_before)
ret += nr_before - shrink_ret;

This piece of code lacks a sanity check and will only function if shrink_ret
is either greater than zero or exactly -1. If shrink_ret is e.g. -2 this will
lead to undefined behaviour.

> FWIW, using "any" negative number for "abort scan" is a bad API
> design decision. It means that in future we can't introduce
> different negative return values in the API if we have a new to.
> i.e. each specific negative return value needs to have the potential
> for defining a different behaviour. 

An alternative to my patch would be to add:
if (shrink_ret < -1)
   /* handle illegal return code in some way */

> So if any change needs to be made, it is to change the -1 return
> value to an enum and have the shrinkers return that enum when they
> want an abort.

I am all for an enum, but I still believe we should handle the case where
the shrinkers return something wicked.

-Oskar
--
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] mm: vmscan: handle any negative return value from scan_objects

2013-05-16 Thread Oskar Andero
The shrinkers must return -1 to indicate that it is busy. Instead, treat
any negative value as busy.
This fixes a potential bug if scan_objects returns a negative other than -1.

Cc: Glauber Costa 
Cc: Dave Chinner 
Cc: Andrew Morton 
Cc: Hugh Dickins 
Cc: Greg Kroah-Hartman 
Signed-off-by: Oskar Andero 
---
 include/linux/shrinker.h | 7 ---
 mm/vmscan.c  | 2 +-
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/include/linux/shrinker.h b/include/linux/shrinker.h
index 3b08869..ced0e91 100644
--- a/include/linux/shrinker.h
+++ b/include/linux/shrinker.h
@@ -38,9 +38,10 @@ struct shrink_control {
  * @scan_objects will only be called if @count_objects returned a positive
  * value for the number of freeable objects. The callout should scan the cache
  * and attempt to free items from the cache. It should then return the number 
of
- * objects freed during the scan, or -1 if progress cannot be made due to
- * potential deadlocks. If -1 is returned, then no further attempts to call the
- * @scan_objects will be made from the current reclaim context.
+ * objects freed during the scan, or a negative value if progress cannot be 
made
+ * due to potential deadlocks. If a negative value is returned, then no further
+ * attempts to call the @scan_objects will be made from the current reclaim
+ * context.
  */
 struct shrinker {
long (*count_objects)(struct shrinker *, struct shrink_control *sc);
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 6bac41e..acb4aef 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -291,7 +291,7 @@ shrink_slab_one(struct shrinker *shrinker, struct 
shrink_control *shrinkctl,
 
shrinkctl->nr_to_scan = nr_to_scan;
ret = shrinker->scan_objects(shrinker, shrinkctl);
-   if (ret == -1)
+   if (ret < 0)
break;
freed += ret;
 
-- 
1.8.1.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: [RFC PATCH 0/2] return value from shrinkers

2013-05-16 Thread Oskar Andero
On 16:49 Wed 15 May , Glauber Costa wrote:
> On 05/15/2013 06:47 PM, Oskar Andero wrote:
> > On 16:18 Wed 15 May , Glauber Costa wrote:
> >> On 05/15/2013 06:10 PM, Oskar Andero wrote:
> >>> On 17:03 Tue 14 May , Glauber Costa wrote:
> >>>> On 05/13/2013 06:16 PM, Oskar Andero wrote:
> >>>>> Hi,
> >>>>>
> >>>>> In a previous discussion on lkml it was noted that the shrinkers use the
> >>>>> magic value "-1" to signal that something went wrong.
> >>>>>
> >>>>> This patch-set implements the suggestion of instead using errno.h values
> >>>>> to return something more meaningful.
> >>>>>
> >>>>> The first patch simply changes the check from -1 to any negative value 
> >>>>> and
> >>>>> updates the comment accordingly.
> >>>>>
> >>>>> The second patch updates the shrinkers to return an errno.h value 
> >>>>> instead
> >>>>> of -1. Since this one spans over many different areas I need input on 
> >>>>> what is
> >>>>> a meaningful return value. Right now I used -EBUSY on everything for 
> >>>>> consitency.
> >>>>>
> >>>>> What do you say? Is this a good idea or does it make no sense at all?
> >>>>>
> >>>>> Thanks!
> >>>>>
> >>>>
> >>>> Right now me and Dave are completely reworking the way shrinkers
> >>>> operate. I suggest, first of all, that you take a look at that 
> >>>> cautiously.
> >>>
> >>> Sounds good. Where can one find the code for that?
> >>>
> >> linux-mm, linux-fsdevel
> >>
> >> Subject is "kmemcg shrinkers", but only the second part is memcg related.
> >>
> >>>> On the specifics of what you are doing here, what would be the benefit
> >>>> of returning something other than -1 ? Is there anything we would do
> >>>> differently for a return value lesser than 1?
> >>>
> >>> Firstly, what bugs me is the magic and unintuitiveness of using -1 rather 
> >>> than a
> >>> more descriptive error code. IMO, even a #define SHRINK_ERROR -1 in some 
> >>> header
> >>> file would be better.
> >>>
> >>> Expanding the test to <0 will open up for more granular error checks,
> >>> like -EAGAIN, -EBUSY and so on. Currently, they would all be treated the 
> >>> same,
> >>> but maybe in the future we would like to handle them differently?
> >>>
> >>
> >> Then in the future we change it.
> >> This is not a user visible API, we are free to change it at any time,
> >> under any conditions. There is only value in supporting different error
> >> codes if we intend to do something different about it. Otherwise, it is
> >> just churn.
> >>
> >> Moreover, -1 does not necessarily mean error. It means "stop shrinking".
> >> There are many non-error conditions in which it could happen.
> >>
> > 
> > Sure, maybe errno.h is not the right way to go. So, why not add the #define
> > instead? E.g. STOP_SHRINKING or something better than -1.
> > 
> >>> Finally, looking at the code:
> >>> if (shrink_ret == -1)
> >>> break;
> >>> if (shrink_ret < nr_before)
> >>> ret += nr_before - shrink_ret;
> >>>
> >>> This piece of code will only function if shrink_ret is either greater 
> >>> than zero
> >>> or -1. If shrink_ret is -2 this will lead to undefined behaviour.
> >>>
> >> Except it never is. But since we are touching this code anyway, I see no
> >> problems in expanding the test. What I don't see the point for, is the
> >> other patch in your series in which you return error codes.
> >>
> >>>> So far, shrink_slab behaves the same, you are just expanding the test.
> >>>> If you really want to push this through, I would suggest coming up with
> >>>> a more concrete reason for why this is wanted.
> >>>
> >>> I don't know how well this patch is aligned with your current rework, but
> >>> based on my comments above, I don't see a reason for not taking it.
> >>>
>

Re: [RFC PATCH 0/2] return value from shrinkers

2013-05-16 Thread Oskar Andero
On 01:05 Thu 16 May , Andrew Morton wrote:
> On Mon, 13 May 2013 16:16:33 +0200 Oskar Andero  
> wrote:
> 
> > In a previous discussion on lkml it was noted that the shrinkers use the
> > magic value "-1" to signal that something went wrong.
> > 
> > This patch-set implements the suggestion of instead using errno.h values
> > to return something more meaningful.
> > 
> > The first patch simply changes the check from -1 to any negative value and
> > updates the comment accordingly.
> > 
> > The second patch updates the shrinkers to return an errno.h value instead
> > of -1. Since this one spans over many different areas I need input on what 
> > is
> > a meaningful return value. Right now I used -EBUSY on everything for 
> > consitency.
> > 
> > What do you say? Is this a good idea or does it make no sense at all?
> 
> I don't see much point in it, really.  Returning an errno implies that
> the errno will eventually be returned to userspace.  But that isn't the
> case, so such a change is somewhat misleading.

Yes. Glauber Costa pointed that out and I agree - errno.h is probably not
the right way to go.

> If we want the capability to return more than a binary yes/no message
> to callers then yes, we could/should enumerate the shrinker return
> values.  But as that is a different concept from errnos, it should be
> done with a different and shrinker-specific namespace.

Agreed, but even if there right now is only a binary return message, is a
hardcoded -1 considered to be acceptable for an interface? IMHO, it is not
very readable nor intuitive for the users of the interface. Why not, as you
mention, add a define or enum in shrinker.h instead, e.g. SHRINKER_STOP or
something.

-Oskar
--
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] return value from shrinkers

2013-05-16 Thread Oskar Andero
On 01:05 Thu 16 May , Andrew Morton wrote:
 On Mon, 13 May 2013 16:16:33 +0200 Oskar Andero oskar.and...@sonymobile.com 
 wrote:
 
  In a previous discussion on lkml it was noted that the shrinkers use the
  magic value -1 to signal that something went wrong.
  
  This patch-set implements the suggestion of instead using errno.h values
  to return something more meaningful.
  
  The first patch simply changes the check from -1 to any negative value and
  updates the comment accordingly.
  
  The second patch updates the shrinkers to return an errno.h value instead
  of -1. Since this one spans over many different areas I need input on what 
  is
  a meaningful return value. Right now I used -EBUSY on everything for 
  consitency.
  
  What do you say? Is this a good idea or does it make no sense at all?
 
 I don't see much point in it, really.  Returning an errno implies that
 the errno will eventually be returned to userspace.  But that isn't the
 case, so such a change is somewhat misleading.

Yes. Glauber Costa pointed that out and I agree - errno.h is probably not
the right way to go.

 If we want the capability to return more than a binary yes/no message
 to callers then yes, we could/should enumerate the shrinker return
 values.  But as that is a different concept from errnos, it should be
 done with a different and shrinker-specific namespace.

Agreed, but even if there right now is only a binary return message, is a
hardcoded -1 considered to be acceptable for an interface? IMHO, it is not
very readable nor intuitive for the users of the interface. Why not, as you
mention, add a define or enum in shrinker.h instead, e.g. SHRINKER_STOP or
something.

-Oskar
--
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] return value from shrinkers

2013-05-16 Thread Oskar Andero
On 16:49 Wed 15 May , Glauber Costa wrote:
 On 05/15/2013 06:47 PM, Oskar Andero wrote:
  On 16:18 Wed 15 May , Glauber Costa wrote:
  On 05/15/2013 06:10 PM, Oskar Andero wrote:
  On 17:03 Tue 14 May , Glauber Costa wrote:
  On 05/13/2013 06:16 PM, Oskar Andero wrote:
  Hi,
 
  In a previous discussion on lkml it was noted that the shrinkers use the
  magic value -1 to signal that something went wrong.
 
  This patch-set implements the suggestion of instead using errno.h values
  to return something more meaningful.
 
  The first patch simply changes the check from -1 to any negative value 
  and
  updates the comment accordingly.
 
  The second patch updates the shrinkers to return an errno.h value 
  instead
  of -1. Since this one spans over many different areas I need input on 
  what is
  a meaningful return value. Right now I used -EBUSY on everything for 
  consitency.
 
  What do you say? Is this a good idea or does it make no sense at all?
 
  Thanks!
 
 
  Right now me and Dave are completely reworking the way shrinkers
  operate. I suggest, first of all, that you take a look at that 
  cautiously.
 
  Sounds good. Where can one find the code for that?
 
  linux-mm, linux-fsdevel
 
  Subject is kmemcg shrinkers, but only the second part is memcg related.
 
  On the specifics of what you are doing here, what would be the benefit
  of returning something other than -1 ? Is there anything we would do
  differently for a return value lesser than 1?
 
  Firstly, what bugs me is the magic and unintuitiveness of using -1 rather 
  than a
  more descriptive error code. IMO, even a #define SHRINK_ERROR -1 in some 
  header
  file would be better.
 
  Expanding the test to 0 will open up for more granular error checks,
  like -EAGAIN, -EBUSY and so on. Currently, they would all be treated the 
  same,
  but maybe in the future we would like to handle them differently?
 
 
  Then in the future we change it.
  This is not a user visible API, we are free to change it at any time,
  under any conditions. There is only value in supporting different error
  codes if we intend to do something different about it. Otherwise, it is
  just churn.
 
  Moreover, -1 does not necessarily mean error. It means stop shrinking.
  There are many non-error conditions in which it could happen.
 
  
  Sure, maybe errno.h is not the right way to go. So, why not add the #define
  instead? E.g. STOP_SHRINKING or something better than -1.
  
  Finally, looking at the code:
  if (shrink_ret == -1)
  break;
  if (shrink_ret  nr_before)
  ret += nr_before - shrink_ret;
 
  This piece of code will only function if shrink_ret is either greater 
  than zero
  or -1. If shrink_ret is -2 this will lead to undefined behaviour.
 
  Except it never is. But since we are touching this code anyway, I see no
  problems in expanding the test. What I don't see the point for, is the
  other patch in your series in which you return error codes.
 
  So far, shrink_slab behaves the same, you are just expanding the test.
  If you really want to push this through, I would suggest coming up with
  a more concrete reason for why this is wanted.
 
  I don't know how well this patch is aligned with your current rework, but
  based on my comments above, I don't see a reason for not taking it.
 
  I see no objections for PATCH #1 that expands the check, as a cautionary
  measure. But I will oppose returning error codes from shrinkers without
  a solid reason for doing so (meaning a use case in which we really
  threat one of the errors differently)
  
  Sorry for being over-zealous about the return codes and I understand
  that it is really a minor thing and possibly also a philosophical
  question. My only solid reasons are unintuiveness and readability.
  That is how I came across it in the first place.
  
  If no-one backs me up on this I will drop the second patch and resend
  the first patch without RFC prefix.
  
 If you are willing to wait a bit until it finally gets merged, please
 send it against my memcg.git in kernel.org (branch
 kmemcg-lru-shrinkers). I can carry your patch in our series.

Alright. I will apply PATCH 1/2 ontop of your kmemcg-lru-shrinker branch
and send it to you offline.

Thanks!

-Oskar
--
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] mm: vmscan: handle any negative return value from scan_objects

2013-05-16 Thread Oskar Andero
The shrinkers must return -1 to indicate that it is busy. Instead, treat
any negative value as busy.
This fixes a potential bug if scan_objects returns a negative other than -1.

Cc: Glauber Costa glom...@openvz.org
Cc: Dave Chinner dchin...@redhat.com
Cc: Andrew Morton a...@linux-foundation.org
Cc: Hugh Dickins hu...@google.com
Cc: Greg Kroah-Hartman gre...@linuxfoundation.org
Signed-off-by: Oskar Andero oskar.and...@sonymobile.com
---
 include/linux/shrinker.h | 7 ---
 mm/vmscan.c  | 2 +-
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/include/linux/shrinker.h b/include/linux/shrinker.h
index 3b08869..ced0e91 100644
--- a/include/linux/shrinker.h
+++ b/include/linux/shrinker.h
@@ -38,9 +38,10 @@ struct shrink_control {
  * @scan_objects will only be called if @count_objects returned a positive
  * value for the number of freeable objects. The callout should scan the cache
  * and attempt to free items from the cache. It should then return the number 
of
- * objects freed during the scan, or -1 if progress cannot be made due to
- * potential deadlocks. If -1 is returned, then no further attempts to call the
- * @scan_objects will be made from the current reclaim context.
+ * objects freed during the scan, or a negative value if progress cannot be 
made
+ * due to potential deadlocks. If a negative value is returned, then no further
+ * attempts to call the @scan_objects will be made from the current reclaim
+ * context.
  */
 struct shrinker {
long (*count_objects)(struct shrinker *, struct shrink_control *sc);
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 6bac41e..acb4aef 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -291,7 +291,7 @@ shrink_slab_one(struct shrinker *shrinker, struct 
shrink_control *shrinkctl,
 
shrinkctl-nr_to_scan = nr_to_scan;
ret = shrinker-scan_objects(shrinker, shrinkctl);
-   if (ret == -1)
+   if (ret  0)
break;
freed += ret;
 
-- 
1.8.1.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] mm: vmscan: handle any negative return value from scan_objects

2013-05-16 Thread Oskar Andero
On 13:52 Thu 16 May , Dave Chinner wrote:
 On Thu, May 16, 2013 at 10:42:16AM +0200, Oskar Andero wrote:
  The shrinkers must return -1 to indicate that it is busy. Instead, treat
  any negative value as busy.
 
 Why? The API defines return condition for aborting a scan and gives
 a specific value for doing that. i.e. explain why should change the
 API to over-specify the 'abort scan return value like this.

As I pointed out earlier, looking in to the code (from master):
if (shrink_ret == -1)
break;
if (shrink_ret  nr_before)
ret += nr_before - shrink_ret;

This piece of code lacks a sanity check and will only function if shrink_ret
is either greater than zero or exactly -1. If shrink_ret is e.g. -2 this will
lead to undefined behaviour.

 FWIW, using any negative number for abort scan is a bad API
 design decision. It means that in future we can't introduce
 different negative return values in the API if we have a new to.
 i.e. each specific negative return value needs to have the potential
 for defining a different behaviour. 

An alternative to my patch would be to add:
if (shrink_ret  -1)
   /* handle illegal return code in some way */

 So if any change needs to be made, it is to change the -1 return
 value to an enum and have the shrinkers return that enum when they
 want an abort.

I am all for an enum, but I still believe we should handle the case where
the shrinkers return something wicked.

-Oskar
--
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] return value from shrinkers

2013-05-15 Thread Oskar Andero
On 16:18 Wed 15 May , Glauber Costa wrote:
> On 05/15/2013 06:10 PM, Oskar Andero wrote:
> > On 17:03 Tue 14 May , Glauber Costa wrote:
> >> On 05/13/2013 06:16 PM, Oskar Andero wrote:
> >>> Hi,
> >>>
> >>> In a previous discussion on lkml it was noted that the shrinkers use the
> >>> magic value "-1" to signal that something went wrong.
> >>>
> >>> This patch-set implements the suggestion of instead using errno.h values
> >>> to return something more meaningful.
> >>>
> >>> The first patch simply changes the check from -1 to any negative value and
> >>> updates the comment accordingly.
> >>>
> >>> The second patch updates the shrinkers to return an errno.h value instead
> >>> of -1. Since this one spans over many different areas I need input on 
> >>> what is
> >>> a meaningful return value. Right now I used -EBUSY on everything for 
> >>> consitency.
> >>>
> >>> What do you say? Is this a good idea or does it make no sense at all?
> >>>
> >>> Thanks!
> >>>
> >>
> >> Right now me and Dave are completely reworking the way shrinkers
> >> operate. I suggest, first of all, that you take a look at that cautiously.
> > 
> > Sounds good. Where can one find the code for that?
> > 
> linux-mm, linux-fsdevel
> 
> Subject is "kmemcg shrinkers", but only the second part is memcg related.
> 
> >> On the specifics of what you are doing here, what would be the benefit
> >> of returning something other than -1 ? Is there anything we would do
> >> differently for a return value lesser than 1?
> > 
> > Firstly, what bugs me is the magic and unintuitiveness of using -1 rather 
> > than a
> > more descriptive error code. IMO, even a #define SHRINK_ERROR -1 in some 
> > header
> > file would be better.
> > 
> > Expanding the test to <0 will open up for more granular error checks,
> > like -EAGAIN, -EBUSY and so on. Currently, they would all be treated the 
> > same,
> > but maybe in the future we would like to handle them differently?
> > 
> 
> Then in the future we change it.
> This is not a user visible API, we are free to change it at any time,
> under any conditions. There is only value in supporting different error
> codes if we intend to do something different about it. Otherwise, it is
> just churn.
> 
> Moreover, -1 does not necessarily mean error. It means "stop shrinking".
> There are many non-error conditions in which it could happen.
> 

Sure, maybe errno.h is not the right way to go. So, why not add the #define
instead? E.g. STOP_SHRINKING or something better than -1.

> > Finally, looking at the code:
> > if (shrink_ret == -1)
> > break;
> > if (shrink_ret < nr_before)
> > ret += nr_before - shrink_ret;
> > 
> > This piece of code will only function if shrink_ret is either greater than 
> > zero
> > or -1. If shrink_ret is -2 this will lead to undefined behaviour.
> > 
> Except it never is. But since we are touching this code anyway, I see no
> problems in expanding the test. What I don't see the point for, is the
> other patch in your series in which you return error codes.
> 
> >> So far, shrink_slab behaves the same, you are just expanding the test.
> >> If you really want to push this through, I would suggest coming up with
> >> a more concrete reason for why this is wanted.
> > 
> > I don't know how well this patch is aligned with your current rework, but
> > based on my comments above, I don't see a reason for not taking it.
> > 
> I see no objections for PATCH #1 that expands the check, as a cautionary
> measure. But I will oppose returning error codes from shrinkers without
> a solid reason for doing so (meaning a use case in which we really
> threat one of the errors differently)

Sorry for being over-zealous about the return codes and I understand
that it is really a minor thing and possibly also a philosophical
question. My only "solid" reasons are unintuiveness and readability.
That is how I came across it in the first place.

If no-one backs me up on this I will drop the second patch and resend
the first patch without RFC prefix.

-Oskar

--
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] return value from shrinkers

2013-05-15 Thread Oskar Andero
On 17:03 Tue 14 May , Glauber Costa wrote:
> On 05/13/2013 06:16 PM, Oskar Andero wrote:
> > Hi,
> > 
> > In a previous discussion on lkml it was noted that the shrinkers use the
> > magic value "-1" to signal that something went wrong.
> > 
> > This patch-set implements the suggestion of instead using errno.h values
> > to return something more meaningful.
> > 
> > The first patch simply changes the check from -1 to any negative value and
> > updates the comment accordingly.
> > 
> > The second patch updates the shrinkers to return an errno.h value instead
> > of -1. Since this one spans over many different areas I need input on what 
> > is
> > a meaningful return value. Right now I used -EBUSY on everything for 
> > consitency.
> > 
> > What do you say? Is this a good idea or does it make no sense at all?
> > 
> > Thanks!
> > 
> 
> Right now me and Dave are completely reworking the way shrinkers
> operate. I suggest, first of all, that you take a look at that cautiously.

Sounds good. Where can one find the code for that?

> On the specifics of what you are doing here, what would be the benefit
> of returning something other than -1 ? Is there anything we would do
> differently for a return value lesser than 1?

Firstly, what bugs me is the magic and unintuitiveness of using -1 rather than a
more descriptive error code. IMO, even a #define SHRINK_ERROR -1 in some header
file would be better.

Expanding the test to <0 will open up for more granular error checks,
like -EAGAIN, -EBUSY and so on. Currently, they would all be treated the same,
but maybe in the future we would like to handle them differently?

Finally, looking at the code:
if (shrink_ret == -1)
break;
if (shrink_ret < nr_before)
ret += nr_before - shrink_ret;

This piece of code will only function if shrink_ret is either greater than zero
or -1. If shrink_ret is -2 this will lead to undefined behaviour.

> So far, shrink_slab behaves the same, you are just expanding the test.
> If you really want to push this through, I would suggest coming up with
> a more concrete reason for why this is wanted.

I don't know how well this patch is aligned with your current rework, but
based on my comments above, I don't see a reason for not taking it.

-Oskar
--
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] return value from shrinkers

2013-05-15 Thread Oskar Andero
On 17:03 Tue 14 May , Glauber Costa wrote:
 On 05/13/2013 06:16 PM, Oskar Andero wrote:
  Hi,
  
  In a previous discussion on lkml it was noted that the shrinkers use the
  magic value -1 to signal that something went wrong.
  
  This patch-set implements the suggestion of instead using errno.h values
  to return something more meaningful.
  
  The first patch simply changes the check from -1 to any negative value and
  updates the comment accordingly.
  
  The second patch updates the shrinkers to return an errno.h value instead
  of -1. Since this one spans over many different areas I need input on what 
  is
  a meaningful return value. Right now I used -EBUSY on everything for 
  consitency.
  
  What do you say? Is this a good idea or does it make no sense at all?
  
  Thanks!
  
 
 Right now me and Dave are completely reworking the way shrinkers
 operate. I suggest, first of all, that you take a look at that cautiously.

Sounds good. Where can one find the code for that?

 On the specifics of what you are doing here, what would be the benefit
 of returning something other than -1 ? Is there anything we would do
 differently for a return value lesser than 1?

Firstly, what bugs me is the magic and unintuitiveness of using -1 rather than a
more descriptive error code. IMO, even a #define SHRINK_ERROR -1 in some header
file would be better.

Expanding the test to 0 will open up for more granular error checks,
like -EAGAIN, -EBUSY and so on. Currently, they would all be treated the same,
but maybe in the future we would like to handle them differently?

Finally, looking at the code:
if (shrink_ret == -1)
break;
if (shrink_ret  nr_before)
ret += nr_before - shrink_ret;

This piece of code will only function if shrink_ret is either greater than zero
or -1. If shrink_ret is -2 this will lead to undefined behaviour.

 So far, shrink_slab behaves the same, you are just expanding the test.
 If you really want to push this through, I would suggest coming up with
 a more concrete reason for why this is wanted.

I don't know how well this patch is aligned with your current rework, but
based on my comments above, I don't see a reason for not taking it.

-Oskar
--
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] return value from shrinkers

2013-05-15 Thread Oskar Andero
On 16:18 Wed 15 May , Glauber Costa wrote:
 On 05/15/2013 06:10 PM, Oskar Andero wrote:
  On 17:03 Tue 14 May , Glauber Costa wrote:
  On 05/13/2013 06:16 PM, Oskar Andero wrote:
  Hi,
 
  In a previous discussion on lkml it was noted that the shrinkers use the
  magic value -1 to signal that something went wrong.
 
  This patch-set implements the suggestion of instead using errno.h values
  to return something more meaningful.
 
  The first patch simply changes the check from -1 to any negative value and
  updates the comment accordingly.
 
  The second patch updates the shrinkers to return an errno.h value instead
  of -1. Since this one spans over many different areas I need input on 
  what is
  a meaningful return value. Right now I used -EBUSY on everything for 
  consitency.
 
  What do you say? Is this a good idea or does it make no sense at all?
 
  Thanks!
 
 
  Right now me and Dave are completely reworking the way shrinkers
  operate. I suggest, first of all, that you take a look at that cautiously.
  
  Sounds good. Where can one find the code for that?
  
 linux-mm, linux-fsdevel
 
 Subject is kmemcg shrinkers, but only the second part is memcg related.
 
  On the specifics of what you are doing here, what would be the benefit
  of returning something other than -1 ? Is there anything we would do
  differently for a return value lesser than 1?
  
  Firstly, what bugs me is the magic and unintuitiveness of using -1 rather 
  than a
  more descriptive error code. IMO, even a #define SHRINK_ERROR -1 in some 
  header
  file would be better.
  
  Expanding the test to 0 will open up for more granular error checks,
  like -EAGAIN, -EBUSY and so on. Currently, they would all be treated the 
  same,
  but maybe in the future we would like to handle them differently?
  
 
 Then in the future we change it.
 This is not a user visible API, we are free to change it at any time,
 under any conditions. There is only value in supporting different error
 codes if we intend to do something different about it. Otherwise, it is
 just churn.
 
 Moreover, -1 does not necessarily mean error. It means stop shrinking.
 There are many non-error conditions in which it could happen.
 

Sure, maybe errno.h is not the right way to go. So, why not add the #define
instead? E.g. STOP_SHRINKING or something better than -1.

  Finally, looking at the code:
  if (shrink_ret == -1)
  break;
  if (shrink_ret  nr_before)
  ret += nr_before - shrink_ret;
  
  This piece of code will only function if shrink_ret is either greater than 
  zero
  or -1. If shrink_ret is -2 this will lead to undefined behaviour.
  
 Except it never is. But since we are touching this code anyway, I see no
 problems in expanding the test. What I don't see the point for, is the
 other patch in your series in which you return error codes.
 
  So far, shrink_slab behaves the same, you are just expanding the test.
  If you really want to push this through, I would suggest coming up with
  a more concrete reason for why this is wanted.
  
  I don't know how well this patch is aligned with your current rework, but
  based on my comments above, I don't see a reason for not taking it.
  
 I see no objections for PATCH #1 that expands the check, as a cautionary
 measure. But I will oppose returning error codes from shrinkers without
 a solid reason for doing so (meaning a use case in which we really
 threat one of the errors differently)

Sorry for being over-zealous about the return codes and I understand
that it is really a minor thing and possibly also a philosophical
question. My only solid reasons are unintuiveness and readability.
That is how I came across it in the first place.

If no-one backs me up on this I will drop the second patch and resend
the first patch without RFC prefix.

-Oskar

--
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/


[RFC PATCH 0/2] return value from shrinkers

2013-05-13 Thread Oskar Andero
Hi,

In a previous discussion on lkml it was noted that the shrinkers use the
magic value "-1" to signal that something went wrong.

This patch-set implements the suggestion of instead using errno.h values
to return something more meaningful.

The first patch simply changes the check from -1 to any negative value and
updates the comment accordingly.

The second patch updates the shrinkers to return an errno.h value instead
of -1. Since this one spans over many different areas I need input on what is
a meaningful return value. Right now I used -EBUSY on everything for consitency.

What do you say? Is this a good idea or does it make no sense at all?

Thanks!

-Oskar

Oskar Andero (2):
  mm: vmscan: let any negative return value from shrinker mean error
  Clean-up shrinker return values

 drivers/staging/android/ashmem.c | 2 +-
 drivers/staging/zcache/zcache-main.c | 2 +-
 fs/gfs2/glock.c  | 2 +-
 fs/gfs2/quota.c  | 2 +-
 fs/nfs/dir.c | 2 +-
 fs/ubifs/shrinker.c  | 2 +-
 include/linux/shrinker.h | 5 +++--
 mm/vmscan.c  | 2 +-
 net/sunrpc/auth.c| 2 +-
 9 files changed, 11 insertions(+), 10 deletions(-)

-- 
1.8.1.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/


[RFC PATCH 1/2] mm: vmscan: let any negative return value from shrinker mean error

2013-05-13 Thread Oskar Andero
The shrinkers must return -1 to indicate that it is busy. Instead of
relaying on magical numbers, let any negative value indicate error. This
opens up for using the errno.h error codes in the shrinker
implementations.

Cc: Hugh Dickins 
Cc: Greg Kroah-Hartman 
Signed-off-by: Oskar Andero 
---
 include/linux/shrinker.h | 5 +++--
 mm/vmscan.c  | 2 +-
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/include/linux/shrinker.h b/include/linux/shrinker.h
index ac6b8ee..31e9406 100644
--- a/include/linux/shrinker.h
+++ b/include/linux/shrinker.h
@@ -18,8 +18,9 @@ struct shrink_control {
  * 'sc' is passed shrink_control which includes a count 'nr_to_scan'
  * and a 'gfpmask'.  It should look through the least-recently-used
  * 'nr_to_scan' entries and attempt to free them up.  It should return
- * the number of objects which remain in the cache.  If it returns -1, it means
- * it cannot do any scanning at this time (eg. there is a risk of deadlock).
+ * the number of objects which remain in the cache.  If it returns a
+ * negative error code, it means it cannot do any scanning at this time
+ * (eg. there is a risk of deadlock).
  *
  * The 'gfpmask' refers to the allocation we are currently trying to
  * fulfil.
diff --git a/mm/vmscan.c b/mm/vmscan.c
index fa6a853..d6ac9a8 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -287,7 +287,7 @@ unsigned long shrink_slab(struct shrink_control *shrink,
nr_before = do_shrinker_shrink(shrinker, shrink, 0);
shrink_ret = do_shrinker_shrink(shrinker, shrink,
batch_size);
-   if (shrink_ret == -1)
+   if (shrink_ret < 0)
break;
if (shrink_ret < nr_before)
ret += nr_before - shrink_ret;
-- 
1.8.1.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/


[RFC PATCH 2/2] Clean-up shrinker return values

2013-05-13 Thread Oskar Andero
Shrinkers return hardcoded -1 on error. Use errno.h values instead
to add more meaning to the errors.

Cc: Hugh Dickins 
Cc: Greg Kroah-Hartman 
Signed-off-by: Oskar Andero 
---
 drivers/staging/android/ashmem.c | 2 +-
 drivers/staging/zcache/zcache-main.c | 2 +-
 fs/gfs2/glock.c  | 2 +-
 fs/gfs2/quota.c  | 2 +-
 fs/nfs/dir.c | 2 +-
 fs/ubifs/shrinker.c  | 2 +-
 net/sunrpc/auth.c| 2 +-
 7 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c
index e681bdd..1968d2f 100644
--- a/drivers/staging/android/ashmem.c
+++ b/drivers/staging/android/ashmem.c
@@ -359,7 +359,7 @@ static int ashmem_shrink(struct shrinker *s, struct 
shrink_control *sc)
 
/* We might recurse into filesystem code, so bail out if necessary */
if (sc->nr_to_scan && !(sc->gfp_mask & __GFP_FS))
-   return -1;
+   return -EBUSY;
if (!sc->nr_to_scan)
return lru_count;
 
diff --git a/drivers/staging/zcache/zcache-main.c 
b/drivers/staging/zcache/zcache-main.c
index 522cb8e..a38532c 100644
--- a/drivers/staging/zcache/zcache-main.c
+++ b/drivers/staging/zcache/zcache-main.c
@@ -1144,7 +1144,7 @@ static int shrink_zcache_memory(struct shrinker *shrink,
struct shrink_control *sc)
 {
static bool in_progress;
-   int ret = -1;
+   int ret = -EBUSY;
int nr = sc->nr_to_scan;
int nr_evict = 0;
int nr_writeback = 0;
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 9435384..401b089 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -1459,7 +1459,7 @@ static int gfs2_shrink_glock_memory(struct shrinker 
*shrink,
 {
if (sc->nr_to_scan) {
if (!(sc->gfp_mask & __GFP_FS))
-   return -1;
+   return -EBUSY;
gfs2_scan_glock_lru(sc->nr_to_scan);
}
 
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index c7c840e..14acbb2 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -85,7 +85,7 @@ int gfs2_shrink_qd_memory(struct shrinker *shrink, struct 
shrink_control *sc)
goto out;
 
if (!(sc->gfp_mask & __GFP_FS))
-   return -1;
+   return -EBUSY;
 
spin_lock(_lru_lock);
while (nr_to_scan && !list_empty(_lru_list)) {
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index e093e73..9fee9bc 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1968,7 +1968,7 @@ int nfs_access_cache_shrinker(struct shrinker *shrink,
gfp_t gfp_mask = sc->gfp_mask;
 
if ((gfp_mask & GFP_KERNEL) != GFP_KERNEL)
-   return (nr_to_scan == 0) ? 0 : -1;
+   return (nr_to_scan == 0) ? nr_to_scan : -EBUSY;
 
spin_lock(_access_lru_lock);
list_for_each_entry_safe(nfsi, next, _access_lru_list, 
access_cache_inode_lru) {
diff --git a/fs/ubifs/shrinker.c b/fs/ubifs/shrinker.c
index 9e1d056..294e685 100644
--- a/fs/ubifs/shrinker.c
+++ b/fs/ubifs/shrinker.c
@@ -316,7 +316,7 @@ int ubifs_shrinker(struct shrinker *shrink, struct 
shrink_control *sc)
 
if (!freed && contention) {
dbg_tnc("freed nothing, but contention");
-   return -1;
+   return -EBUSY;
}
 
 out:
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
index ed2fdd2..45faea0 100644
--- a/net/sunrpc/auth.c
+++ b/net/sunrpc/auth.c
@@ -461,7 +461,7 @@ rpcauth_cache_shrinker(struct shrinker *shrink, struct 
shrink_control *sc)
gfp_t gfp_mask = sc->gfp_mask;
 
if ((gfp_mask & GFP_KERNEL) != GFP_KERNEL)
-   return (nr_to_scan == 0) ? 0 : -1;
+   return (nr_to_scan == 0) ? nr_to_scan : -EBUSY;
if (list_empty(_unused))
return 0;
spin_lock(_credcache_lock);
-- 
1.8.1.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/


[RFC PATCH 2/2] Clean-up shrinker return values

2013-05-13 Thread Oskar Andero
Shrinkers return hardcoded -1 on error. Use errno.h values instead
to add more meaning to the errors.

Cc: Hugh Dickins hu...@google.com
Cc: Greg Kroah-Hartman gre...@linuxfoundation.org
Signed-off-by: Oskar Andero oskar.and...@sonymobile.com
---
 drivers/staging/android/ashmem.c | 2 +-
 drivers/staging/zcache/zcache-main.c | 2 +-
 fs/gfs2/glock.c  | 2 +-
 fs/gfs2/quota.c  | 2 +-
 fs/nfs/dir.c | 2 +-
 fs/ubifs/shrinker.c  | 2 +-
 net/sunrpc/auth.c| 2 +-
 7 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c
index e681bdd..1968d2f 100644
--- a/drivers/staging/android/ashmem.c
+++ b/drivers/staging/android/ashmem.c
@@ -359,7 +359,7 @@ static int ashmem_shrink(struct shrinker *s, struct 
shrink_control *sc)
 
/* We might recurse into filesystem code, so bail out if necessary */
if (sc-nr_to_scan  !(sc-gfp_mask  __GFP_FS))
-   return -1;
+   return -EBUSY;
if (!sc-nr_to_scan)
return lru_count;
 
diff --git a/drivers/staging/zcache/zcache-main.c 
b/drivers/staging/zcache/zcache-main.c
index 522cb8e..a38532c 100644
--- a/drivers/staging/zcache/zcache-main.c
+++ b/drivers/staging/zcache/zcache-main.c
@@ -1144,7 +1144,7 @@ static int shrink_zcache_memory(struct shrinker *shrink,
struct shrink_control *sc)
 {
static bool in_progress;
-   int ret = -1;
+   int ret = -EBUSY;
int nr = sc-nr_to_scan;
int nr_evict = 0;
int nr_writeback = 0;
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 9435384..401b089 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -1459,7 +1459,7 @@ static int gfs2_shrink_glock_memory(struct shrinker 
*shrink,
 {
if (sc-nr_to_scan) {
if (!(sc-gfp_mask  __GFP_FS))
-   return -1;
+   return -EBUSY;
gfs2_scan_glock_lru(sc-nr_to_scan);
}
 
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index c7c840e..14acbb2 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -85,7 +85,7 @@ int gfs2_shrink_qd_memory(struct shrinker *shrink, struct 
shrink_control *sc)
goto out;
 
if (!(sc-gfp_mask  __GFP_FS))
-   return -1;
+   return -EBUSY;
 
spin_lock(qd_lru_lock);
while (nr_to_scan  !list_empty(qd_lru_list)) {
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index e093e73..9fee9bc 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1968,7 +1968,7 @@ int nfs_access_cache_shrinker(struct shrinker *shrink,
gfp_t gfp_mask = sc-gfp_mask;
 
if ((gfp_mask  GFP_KERNEL) != GFP_KERNEL)
-   return (nr_to_scan == 0) ? 0 : -1;
+   return (nr_to_scan == 0) ? nr_to_scan : -EBUSY;
 
spin_lock(nfs_access_lru_lock);
list_for_each_entry_safe(nfsi, next, nfs_access_lru_list, 
access_cache_inode_lru) {
diff --git a/fs/ubifs/shrinker.c b/fs/ubifs/shrinker.c
index 9e1d056..294e685 100644
--- a/fs/ubifs/shrinker.c
+++ b/fs/ubifs/shrinker.c
@@ -316,7 +316,7 @@ int ubifs_shrinker(struct shrinker *shrink, struct 
shrink_control *sc)
 
if (!freed  contention) {
dbg_tnc(freed nothing, but contention);
-   return -1;
+   return -EBUSY;
}
 
 out:
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
index ed2fdd2..45faea0 100644
--- a/net/sunrpc/auth.c
+++ b/net/sunrpc/auth.c
@@ -461,7 +461,7 @@ rpcauth_cache_shrinker(struct shrinker *shrink, struct 
shrink_control *sc)
gfp_t gfp_mask = sc-gfp_mask;
 
if ((gfp_mask  GFP_KERNEL) != GFP_KERNEL)
-   return (nr_to_scan == 0) ? 0 : -1;
+   return (nr_to_scan == 0) ? nr_to_scan : -EBUSY;
if (list_empty(cred_unused))
return 0;
spin_lock(rpc_credcache_lock);
-- 
1.8.1.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/


[RFC PATCH 0/2] return value from shrinkers

2013-05-13 Thread Oskar Andero
Hi,

In a previous discussion on lkml it was noted that the shrinkers use the
magic value -1 to signal that something went wrong.

This patch-set implements the suggestion of instead using errno.h values
to return something more meaningful.

The first patch simply changes the check from -1 to any negative value and
updates the comment accordingly.

The second patch updates the shrinkers to return an errno.h value instead
of -1. Since this one spans over many different areas I need input on what is
a meaningful return value. Right now I used -EBUSY on everything for consitency.

What do you say? Is this a good idea or does it make no sense at all?

Thanks!

-Oskar

Oskar Andero (2):
  mm: vmscan: let any negative return value from shrinker mean error
  Clean-up shrinker return values

 drivers/staging/android/ashmem.c | 2 +-
 drivers/staging/zcache/zcache-main.c | 2 +-
 fs/gfs2/glock.c  | 2 +-
 fs/gfs2/quota.c  | 2 +-
 fs/nfs/dir.c | 2 +-
 fs/ubifs/shrinker.c  | 2 +-
 include/linux/shrinker.h | 5 +++--
 mm/vmscan.c  | 2 +-
 net/sunrpc/auth.c| 2 +-
 9 files changed, 11 insertions(+), 10 deletions(-)

-- 
1.8.1.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/


[RFC PATCH 1/2] mm: vmscan: let any negative return value from shrinker mean error

2013-05-13 Thread Oskar Andero
The shrinkers must return -1 to indicate that it is busy. Instead of
relaying on magical numbers, let any negative value indicate error. This
opens up for using the errno.h error codes in the shrinker
implementations.

Cc: Hugh Dickins hu...@google.com
Cc: Greg Kroah-Hartman gre...@linuxfoundation.org
Signed-off-by: Oskar Andero oskar.and...@sonymobile.com
---
 include/linux/shrinker.h | 5 +++--
 mm/vmscan.c  | 2 +-
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/include/linux/shrinker.h b/include/linux/shrinker.h
index ac6b8ee..31e9406 100644
--- a/include/linux/shrinker.h
+++ b/include/linux/shrinker.h
@@ -18,8 +18,9 @@ struct shrink_control {
  * 'sc' is passed shrink_control which includes a count 'nr_to_scan'
  * and a 'gfpmask'.  It should look through the least-recently-used
  * 'nr_to_scan' entries and attempt to free them up.  It should return
- * the number of objects which remain in the cache.  If it returns -1, it means
- * it cannot do any scanning at this time (eg. there is a risk of deadlock).
+ * the number of objects which remain in the cache.  If it returns a
+ * negative error code, it means it cannot do any scanning at this time
+ * (eg. there is a risk of deadlock).
  *
  * The 'gfpmask' refers to the allocation we are currently trying to
  * fulfil.
diff --git a/mm/vmscan.c b/mm/vmscan.c
index fa6a853..d6ac9a8 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -287,7 +287,7 @@ unsigned long shrink_slab(struct shrink_control *shrink,
nr_before = do_shrinker_shrink(shrinker, shrink, 0);
shrink_ret = do_shrinker_shrink(shrinker, shrink,
batch_size);
-   if (shrink_ret == -1)
+   if (shrink_ret  0)
break;
if (shrink_ret  nr_before)
ret += nr_before - shrink_ret;
-- 
1.8.1.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/


[PATCHv4] iio: adc: add driver for MCP3204/08 12-bit ADC

2013-05-03 Thread Oskar Andero
This adds support for Microchip's 12 bit AD converters MCP3204 and
MCP3208. These chips communicates over SPI and supports single-ended
and pseudo-differential configurations.

Cc: Jonathan Cameron 
Cc: Lars-Peter Clausen 
Signed-off-by: Oskar Andero 
---
 drivers/iio/adc/Kconfig   |  10 ++
 drivers/iio/adc/Makefile  |   1 +
 drivers/iio/adc/mcp320x.c | 257 ++
 3 files changed, 268 insertions(+)
 create mode 100644 drivers/iio/adc/mcp320x.c

diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index ab0767e6..93129ec 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -133,6 +133,16 @@ config MAX1363
  max11646, max11647) Provides direct access via sysfs and buffered
  data via the iio dev interface.
 
+config MCP320X
+   tristate "Microchip Technology MCP3204/08"
+   depends on SPI
+   help
+ Say yes here to build support for Microchip Technology's MCP3204 or
+ MCP3208 analog to digital converter.
+
+ This driver can also be built as a module. If so, the module will be
+ called mcp320x.
+
 config TI_ADC081C
tristate "Texas Instruments ADC081C021/027"
depends on I2C
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 0a825be..8f475d3 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_AT91_ADC) += at91_adc.o
 obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o
 obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
 obj-$(CONFIG_MAX1363) += max1363.o
+obj-$(CONFIG_MCP320X) += mcp320x.o
 obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
 obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
 obj-$(CONFIG_VIPERBOARD_ADC) += viperboard_adc.o
diff --git a/drivers/iio/adc/mcp320x.c b/drivers/iio/adc/mcp320x.c
new file mode 100644
index 000..ebc0159
--- /dev/null
+++ b/drivers/iio/adc/mcp320x.c
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2013 Oskar Andero 
+ *
+ * Driver for Microchip Technology's MCP3204 and MCP3208 ADC chips.
+ * Datasheet can be found here:
+ * http://ww1.microchip.com/downloads/en/devicedoc/21298c.pdf
+ *
+ * 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 
+
+#define MCP_SINGLE_ENDED   (1 << 3)
+#define MCP_START_BIT  (1 << 4)
+
+enum {
+   mcp3204,
+   mcp3208,
+};
+
+struct mcp320x {
+   struct spi_device *spi;
+   struct spi_message msg;
+   struct spi_transfer transfer[2];
+
+   u8 tx_buf;
+   u8 rx_buf[2];
+
+   struct regulator *reg;
+   struct mutex lock;
+};
+
+static int mcp320x_adc_conversion(struct mcp320x *adc, u8 msg)
+{
+   int ret;
+
+   adc->tx_buf = msg;
+   ret = spi_sync(adc->spi, >msg);
+   if (ret < 0)
+   return ret;
+
+   return ((adc->rx_buf[0] & 0x3f) << 6)  |
+   (adc->rx_buf[1] >> 2);
+}
+
+static int mcp320x_read_raw(struct iio_dev *indio_dev,
+   struct iio_chan_spec const *channel, int *val,
+   int *val2, long mask)
+{
+   struct mcp320x *adc = iio_priv(indio_dev);
+   int ret = -EINVAL;
+
+   mutex_lock(>lock);
+
+   switch (mask) {
+   case IIO_CHAN_INFO_RAW:
+   if (channel->differential)
+   ret = mcp320x_adc_conversion(adc,
+   MCP_START_BIT | channel->address);
+   else
+   ret = mcp320x_adc_conversion(adc,
+   MCP_START_BIT | MCP_SINGLE_ENDED |
+   channel->address);
+   if (ret < 0)
+   goto out;
+
+   *val = ret;
+   ret = IIO_VAL_INT;
+   break;
+
+   case IIO_CHAN_INFO_SCALE:
+   /* Digital output code = (4096 * Vin) / Vref */
+   ret = regulator_get_voltage(adc->reg);
+   if (ret < 0)
+   goto out;
+
+   *val = ret / 1000;
+   *val2 = 12;
+   ret = IIO_VAL_FRACTIONAL_LOG2;
+   break;
+
+   default:
+   break;
+   }
+
+out:
+   mutex_unlock(>lock);
+
+   return ret;
+}
+
+#define MCP320X_VOLTAGE_CHANNEL(num)   \
+   {   \
+   .type = IIO_VOLTAGE,\
+   .indexed = 1,   \
+   .channel = (num),   \
+   .address = (num),   \
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),   \
+   .info_mask_shared_

[PATCHv3] iio: adc: add driver for MCP3204/08 12-bit ADC

2013-05-03 Thread Oskar Andero
This adds support for Microchip's 12 bit AD converters MCP3204 and
MCP3208. These chips communicates over SPI and supports single-ended
and pseudo-differential configurations.

Cc: Jonathan Cameron 
Cc: Lars-Peter Clausen 
Signed-off-by: Oskar Andero 
---
 drivers/iio/adc/Kconfig   |  10 ++
 drivers/iio/adc/Makefile  |   1 +
 drivers/iio/adc/mcp320x.c | 258 ++
 3 files changed, 269 insertions(+)
 create mode 100644 drivers/iio/adc/mcp320x.c

diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index ab0767e6..93129ec 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -133,6 +133,16 @@ config MAX1363
  max11646, max11647) Provides direct access via sysfs and buffered
  data via the iio dev interface.
 
+config MCP320X
+   tristate "Microchip Technology MCP3204/08"
+   depends on SPI
+   help
+ Say yes here to build support for Microchip Technology's MCP3204 or
+ MCP3208 analog to digital converter.
+
+ This driver can also be built as a module. If so, the module will be
+ called mcp320x.
+
 config TI_ADC081C
tristate "Texas Instruments ADC081C021/027"
depends on I2C
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 0a825be..8f475d3 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_AT91_ADC) += at91_adc.o
 obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o
 obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
 obj-$(CONFIG_MAX1363) += max1363.o
+obj-$(CONFIG_MCP320X) += mcp320x.o
 obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
 obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
 obj-$(CONFIG_VIPERBOARD_ADC) += viperboard_adc.o
diff --git a/drivers/iio/adc/mcp320x.c b/drivers/iio/adc/mcp320x.c
new file mode 100644
index 000..b38bf87
--- /dev/null
+++ b/drivers/iio/adc/mcp320x.c
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2013 Oskar Andero 
+ *
+ * Driver for Microchip Technology's MCP3204 and MCP3208 ADC chips.
+ * Datasheet can be found here:
+ * http://ww1.microchip.com/downloads/en/devicedoc/21298c.pdf
+ *
+ * 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 
+
+#define MCP_SINGLE_ENDED   (1 << 3)
+#define MCP_START_BIT  (1 << 4)
+
+enum {
+   mcp3204,
+   mcp3208,
+};
+
+struct mcp320x {
+   struct spi_device *spi;
+   struct spi_message msg;
+   struct spi_transfer transfer[2];
+
+   u8 tx_buf;
+   u8 rx_buf[2];
+
+   struct regulator *reg;
+   unsigned int ref_mv;
+
+   struct mutex lock;
+};
+
+static int mcp320x_adc_conversion(struct mcp320x *adc, u8 msg)
+{
+   int ret;
+
+   adc->tx_buf = msg;
+   ret = spi_sync(adc->spi, >msg);
+   if (ret < 0)
+   return ret;
+
+   return ((adc->rx_buf[0] & 0x3f) << 6)  |
+   (adc->rx_buf[1] >> 2);
+}
+
+static int mcp320x_read_raw(struct iio_dev *indio_dev,
+   struct iio_chan_spec const *channel, int *val,
+   int *val2, long mask)
+{
+   struct mcp320x *adc = iio_priv(indio_dev);
+   int ret = -EINVAL;
+
+   mutex_lock(>lock);
+
+   switch (mask) {
+   case IIO_CHAN_INFO_RAW:
+   if (channel->differential)
+   ret = mcp320x_adc_conversion(adc,
+   MCP_START_BIT | channel->address);
+   else
+   ret = mcp320x_adc_conversion(adc,
+   MCP_START_BIT | MCP_SINGLE_ENDED |
+   channel->address);
+   if (ret < 0)
+   goto out;
+
+   *val = ret;
+   ret = IIO_VAL_INT;
+   break;
+
+   case IIO_CHAN_INFO_SCALE:
+   /* Digital output code = (4096 * Vin) / Vref */
+   ret = regulator_get_voltage(adc->reg);
+   if (ret < 0)
+   goto out;
+
+   *val = ret / 1000;
+   *val2 = 12;
+   ret = IIO_VAL_FRACTIONAL_LOG2;
+   break;
+
+   default:
+   break;
+   }
+
+out:
+   mutex_unlock(>lock);
+
+   return ret;
+}
+
+#define MCP320X_VOLTAGE_CHANNEL(num)   \
+   {   \
+   .type = IIO_VOLTAGE,\
+   .indexed = 1,   \
+   .channel = (num),   \
+   .address = (num),   \
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),   \
+   .info_mask_shared_

[PATCHv3] iio: adc: add driver for MCP3204/08 12-bit ADC

2013-05-03 Thread Oskar Andero
This adds support for Microchip's 12 bit AD converters MCP3204 and
MCP3208. These chips communicates over SPI and supports single-ended
and pseudo-differential configurations.

Cc: Jonathan Cameron ji...@cam.ac.uk
Cc: Lars-Peter Clausen l...@metafoo.de
Signed-off-by: Oskar Andero oskar.and...@gmail.com
---
 drivers/iio/adc/Kconfig   |  10 ++
 drivers/iio/adc/Makefile  |   1 +
 drivers/iio/adc/mcp320x.c | 258 ++
 3 files changed, 269 insertions(+)
 create mode 100644 drivers/iio/adc/mcp320x.c

diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index ab0767e6..93129ec 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -133,6 +133,16 @@ config MAX1363
  max11646, max11647) Provides direct access via sysfs and buffered
  data via the iio dev interface.
 
+config MCP320X
+   tristate Microchip Technology MCP3204/08
+   depends on SPI
+   help
+ Say yes here to build support for Microchip Technology's MCP3204 or
+ MCP3208 analog to digital converter.
+
+ This driver can also be built as a module. If so, the module will be
+ called mcp320x.
+
 config TI_ADC081C
tristate Texas Instruments ADC081C021/027
depends on I2C
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 0a825be..8f475d3 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_AT91_ADC) += at91_adc.o
 obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o
 obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
 obj-$(CONFIG_MAX1363) += max1363.o
+obj-$(CONFIG_MCP320X) += mcp320x.o
 obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
 obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
 obj-$(CONFIG_VIPERBOARD_ADC) += viperboard_adc.o
diff --git a/drivers/iio/adc/mcp320x.c b/drivers/iio/adc/mcp320x.c
new file mode 100644
index 000..b38bf87
--- /dev/null
+++ b/drivers/iio/adc/mcp320x.c
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2013 Oskar Andero oskar.and...@gmail.com
+ *
+ * Driver for Microchip Technology's MCP3204 and MCP3208 ADC chips.
+ * Datasheet can be found here:
+ * http://ww1.microchip.com/downloads/en/devicedoc/21298c.pdf
+ *
+ * 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/err.h
+#include linux/spi/spi.h
+#include linux/module.h
+#include linux/iio/iio.h
+#include linux/regulator/consumer.h
+
+#define MCP_SINGLE_ENDED   (1  3)
+#define MCP_START_BIT  (1  4)
+
+enum {
+   mcp3204,
+   mcp3208,
+};
+
+struct mcp320x {
+   struct spi_device *spi;
+   struct spi_message msg;
+   struct spi_transfer transfer[2];
+
+   u8 tx_buf;
+   u8 rx_buf[2];
+
+   struct regulator *reg;
+   unsigned int ref_mv;
+
+   struct mutex lock;
+};
+
+static int mcp320x_adc_conversion(struct mcp320x *adc, u8 msg)
+{
+   int ret;
+
+   adc-tx_buf = msg;
+   ret = spi_sync(adc-spi, adc-msg);
+   if (ret  0)
+   return ret;
+
+   return ((adc-rx_buf[0]  0x3f)  6)  |
+   (adc-rx_buf[1]  2);
+}
+
+static int mcp320x_read_raw(struct iio_dev *indio_dev,
+   struct iio_chan_spec const *channel, int *val,
+   int *val2, long mask)
+{
+   struct mcp320x *adc = iio_priv(indio_dev);
+   int ret = -EINVAL;
+
+   mutex_lock(adc-lock);
+
+   switch (mask) {
+   case IIO_CHAN_INFO_RAW:
+   if (channel-differential)
+   ret = mcp320x_adc_conversion(adc,
+   MCP_START_BIT | channel-address);
+   else
+   ret = mcp320x_adc_conversion(adc,
+   MCP_START_BIT | MCP_SINGLE_ENDED |
+   channel-address);
+   if (ret  0)
+   goto out;
+
+   *val = ret;
+   ret = IIO_VAL_INT;
+   break;
+
+   case IIO_CHAN_INFO_SCALE:
+   /* Digital output code = (4096 * Vin) / Vref */
+   ret = regulator_get_voltage(adc-reg);
+   if (ret  0)
+   goto out;
+
+   *val = ret / 1000;
+   *val2 = 12;
+   ret = IIO_VAL_FRACTIONAL_LOG2;
+   break;
+
+   default:
+   break;
+   }
+
+out:
+   mutex_unlock(adc-lock);
+
+   return ret;
+}
+
+#define MCP320X_VOLTAGE_CHANNEL(num)   \
+   {   \
+   .type = IIO_VOLTAGE,\
+   .indexed = 1,   \
+   .channel = (num),   \
+   .address = (num),   \
+   .info_mask_separate = BIT

[PATCHv4] iio: adc: add driver for MCP3204/08 12-bit ADC

2013-05-03 Thread Oskar Andero
This adds support for Microchip's 12 bit AD converters MCP3204 and
MCP3208. These chips communicates over SPI and supports single-ended
and pseudo-differential configurations.

Cc: Jonathan Cameron ji...@cam.ac.uk
Cc: Lars-Peter Clausen l...@metafoo.de
Signed-off-by: Oskar Andero oskar.and...@gmail.com
---
 drivers/iio/adc/Kconfig   |  10 ++
 drivers/iio/adc/Makefile  |   1 +
 drivers/iio/adc/mcp320x.c | 257 ++
 3 files changed, 268 insertions(+)
 create mode 100644 drivers/iio/adc/mcp320x.c

diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index ab0767e6..93129ec 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -133,6 +133,16 @@ config MAX1363
  max11646, max11647) Provides direct access via sysfs and buffered
  data via the iio dev interface.
 
+config MCP320X
+   tristate Microchip Technology MCP3204/08
+   depends on SPI
+   help
+ Say yes here to build support for Microchip Technology's MCP3204 or
+ MCP3208 analog to digital converter.
+
+ This driver can also be built as a module. If so, the module will be
+ called mcp320x.
+
 config TI_ADC081C
tristate Texas Instruments ADC081C021/027
depends on I2C
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 0a825be..8f475d3 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_AT91_ADC) += at91_adc.o
 obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o
 obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
 obj-$(CONFIG_MAX1363) += max1363.o
+obj-$(CONFIG_MCP320X) += mcp320x.o
 obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
 obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
 obj-$(CONFIG_VIPERBOARD_ADC) += viperboard_adc.o
diff --git a/drivers/iio/adc/mcp320x.c b/drivers/iio/adc/mcp320x.c
new file mode 100644
index 000..ebc0159
--- /dev/null
+++ b/drivers/iio/adc/mcp320x.c
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2013 Oskar Andero oskar.and...@gmail.com
+ *
+ * Driver for Microchip Technology's MCP3204 and MCP3208 ADC chips.
+ * Datasheet can be found here:
+ * http://ww1.microchip.com/downloads/en/devicedoc/21298c.pdf
+ *
+ * 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/err.h
+#include linux/spi/spi.h
+#include linux/module.h
+#include linux/iio/iio.h
+#include linux/regulator/consumer.h
+
+#define MCP_SINGLE_ENDED   (1  3)
+#define MCP_START_BIT  (1  4)
+
+enum {
+   mcp3204,
+   mcp3208,
+};
+
+struct mcp320x {
+   struct spi_device *spi;
+   struct spi_message msg;
+   struct spi_transfer transfer[2];
+
+   u8 tx_buf;
+   u8 rx_buf[2];
+
+   struct regulator *reg;
+   struct mutex lock;
+};
+
+static int mcp320x_adc_conversion(struct mcp320x *adc, u8 msg)
+{
+   int ret;
+
+   adc-tx_buf = msg;
+   ret = spi_sync(adc-spi, adc-msg);
+   if (ret  0)
+   return ret;
+
+   return ((adc-rx_buf[0]  0x3f)  6)  |
+   (adc-rx_buf[1]  2);
+}
+
+static int mcp320x_read_raw(struct iio_dev *indio_dev,
+   struct iio_chan_spec const *channel, int *val,
+   int *val2, long mask)
+{
+   struct mcp320x *adc = iio_priv(indio_dev);
+   int ret = -EINVAL;
+
+   mutex_lock(adc-lock);
+
+   switch (mask) {
+   case IIO_CHAN_INFO_RAW:
+   if (channel-differential)
+   ret = mcp320x_adc_conversion(adc,
+   MCP_START_BIT | channel-address);
+   else
+   ret = mcp320x_adc_conversion(adc,
+   MCP_START_BIT | MCP_SINGLE_ENDED |
+   channel-address);
+   if (ret  0)
+   goto out;
+
+   *val = ret;
+   ret = IIO_VAL_INT;
+   break;
+
+   case IIO_CHAN_INFO_SCALE:
+   /* Digital output code = (4096 * Vin) / Vref */
+   ret = regulator_get_voltage(adc-reg);
+   if (ret  0)
+   goto out;
+
+   *val = ret / 1000;
+   *val2 = 12;
+   ret = IIO_VAL_FRACTIONAL_LOG2;
+   break;
+
+   default:
+   break;
+   }
+
+out:
+   mutex_unlock(adc-lock);
+
+   return ret;
+}
+
+#define MCP320X_VOLTAGE_CHANNEL(num)   \
+   {   \
+   .type = IIO_VOLTAGE,\
+   .indexed = 1,   \
+   .channel = (num),   \
+   .address = (num),   \
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW

[PATCHv2] iio: adc: add driver for MCP3204/08 12-bit ADC

2013-05-02 Thread Oskar Andero
This adds support for Microchip's 12 bit AD converters MCP3204 and
MCP3208. These chips communicates over SPI and supports single-ended
and pseudo-differential configurations.

Cc: Jonathan Cameron 
Cc: Lars-Peter Clausen 
Signed-off-by: Oskar Andero 
---
 drivers/iio/adc/Kconfig   |  10 ++
 drivers/iio/adc/Makefile  |   1 +
 drivers/iio/adc/mcp320x.c | 255 ++
 3 files changed, 266 insertions(+)
 create mode 100644 drivers/iio/adc/mcp320x.c

diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index ab0767e6..93129ec 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -133,6 +133,16 @@ config MAX1363
  max11646, max11647) Provides direct access via sysfs and buffered
  data via the iio dev interface.
 
+config MCP320X
+   tristate "Microchip Technology MCP3204/08"
+   depends on SPI
+   help
+ Say yes here to build support for Microchip Technology's MCP3204 or
+ MCP3208 analog to digital converter.
+
+ This driver can also be built as a module. If so, the module will be
+ called mcp320x.
+
 config TI_ADC081C
tristate "Texas Instruments ADC081C021/027"
depends on I2C
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 0a825be..8f475d3 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_AT91_ADC) += at91_adc.o
 obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o
 obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
 obj-$(CONFIG_MAX1363) += max1363.o
+obj-$(CONFIG_MCP320X) += mcp320x.o
 obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
 obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
 obj-$(CONFIG_VIPERBOARD_ADC) += viperboard_adc.o
diff --git a/drivers/iio/adc/mcp320x.c b/drivers/iio/adc/mcp320x.c
new file mode 100644
index 000..7dc32c3
--- /dev/null
+++ b/drivers/iio/adc/mcp320x.c
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2013 Oskar Andero 
+ *
+ * Driver for Microchip Technology's MCP3204 and MCP3208 ADC chips.
+ * Datasheet can be found here:
+ * http://ww1.microchip.com/downloads/en/devicedoc/21298c.pdf
+ *
+ * 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 
+
+#define MCP_SINGLE_ENDED   (1 << 3)
+#define MCP_START_BIT  (1 << 4)
+
+enum {
+   mcp3204,
+   mcp3208,
+};
+
+struct mcp320x {
+   struct spi_device *spi;
+   struct spi_message msg;
+   struct spi_transfer transfer[2];
+
+   u8 tx_buf;
+   u8 rx_buf[2];
+
+   struct regulator *reg;
+   unsigned int ref_mv;
+
+   struct mutex lock;
+};
+
+static int mcp320x_adc_conversion(struct mcp320x *adc, u8 msg)
+{
+   int ret;
+
+   adc->tx_buf = msg;
+   ret = spi_sync(adc->spi, >msg);
+   if (ret < 0)
+   return ret;
+
+   return ((adc->rx_buf[0] & 0x3f) << 6)  |
+   (adc->rx_buf[1] >> 2);
+}
+
+static int mcp320x_read_raw(struct iio_dev *indio_dev,
+   struct iio_chan_spec const *channel, int *val,
+   int *val2, long mask)
+{
+   struct mcp320x *adc = iio_priv(indio_dev);
+   int ret = -EINVAL;
+
+   mutex_lock(>lock);
+
+   switch (mask) {
+   case IIO_CHAN_INFO_RAW:
+   if (channel->differential)
+   ret = mcp320x_adc_conversion(adc,
+   MCP_START_BIT | channel->address);
+   else
+   ret = mcp320x_adc_conversion(adc,
+   MCP_START_BIT | MCP_SINGLE_ENDED |
+   channel->address);
+   if (ret < 0)
+   goto out;
+
+   *val = ret;
+   ret = IIO_VAL_INT;
+   break;
+
+   case IIO_CHAN_INFO_SCALE:
+   /* Digital output code = (4096 * Vin) / Vref */
+   ret = regulator_get_voltage(adc->reg);
+   if (ret < 0)
+   goto out;
+
+   *val = ret / 1000;
+   *val2 = 4096;
+   ret = IIO_VAL_FRACTIONAL;
+   break;
+
+   default:
+   break;
+   }
+
+out:
+   mutex_unlock(>lock);
+
+   return ret;
+}
+
+#define MCP320X_VOLTAGE_CHANNEL(num)   \
+   {   \
+   .type = IIO_VOLTAGE,\
+   .indexed = 1,   \
+   .channel = (num),   \
+   .address = (num),   \
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),   \
+   .info_mask_shared_

[PATCHv2] iio: adc: add driver for MCP3204/08 12-bit ADC

2013-05-02 Thread Oskar Andero
This adds support for Microchip's 12 bit AD converters MCP3204 and
MCP3208. These chips communicates over SPI and supports single-ended
and pseudo-differential configurations.

Cc: Jonathan Cameron ji...@cam.ac.uk
Cc: Lars-Peter Clausen l...@metafoo.de
Signed-off-by: Oskar Andero oskar.and...@gmail.com
---
 drivers/iio/adc/Kconfig   |  10 ++
 drivers/iio/adc/Makefile  |   1 +
 drivers/iio/adc/mcp320x.c | 255 ++
 3 files changed, 266 insertions(+)
 create mode 100644 drivers/iio/adc/mcp320x.c

diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index ab0767e6..93129ec 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -133,6 +133,16 @@ config MAX1363
  max11646, max11647) Provides direct access via sysfs and buffered
  data via the iio dev interface.
 
+config MCP320X
+   tristate Microchip Technology MCP3204/08
+   depends on SPI
+   help
+ Say yes here to build support for Microchip Technology's MCP3204 or
+ MCP3208 analog to digital converter.
+
+ This driver can also be built as a module. If so, the module will be
+ called mcp320x.
+
 config TI_ADC081C
tristate Texas Instruments ADC081C021/027
depends on I2C
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 0a825be..8f475d3 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_AT91_ADC) += at91_adc.o
 obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o
 obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
 obj-$(CONFIG_MAX1363) += max1363.o
+obj-$(CONFIG_MCP320X) += mcp320x.o
 obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
 obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
 obj-$(CONFIG_VIPERBOARD_ADC) += viperboard_adc.o
diff --git a/drivers/iio/adc/mcp320x.c b/drivers/iio/adc/mcp320x.c
new file mode 100644
index 000..7dc32c3
--- /dev/null
+++ b/drivers/iio/adc/mcp320x.c
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2013 Oskar Andero oskar.and...@gmail.com
+ *
+ * Driver for Microchip Technology's MCP3204 and MCP3208 ADC chips.
+ * Datasheet can be found here:
+ * http://ww1.microchip.com/downloads/en/devicedoc/21298c.pdf
+ *
+ * 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/err.h
+#include linux/spi/spi.h
+#include linux/module.h
+#include linux/iio/iio.h
+#include linux/regulator/consumer.h
+
+#define MCP_SINGLE_ENDED   (1  3)
+#define MCP_START_BIT  (1  4)
+
+enum {
+   mcp3204,
+   mcp3208,
+};
+
+struct mcp320x {
+   struct spi_device *spi;
+   struct spi_message msg;
+   struct spi_transfer transfer[2];
+
+   u8 tx_buf;
+   u8 rx_buf[2];
+
+   struct regulator *reg;
+   unsigned int ref_mv;
+
+   struct mutex lock;
+};
+
+static int mcp320x_adc_conversion(struct mcp320x *adc, u8 msg)
+{
+   int ret;
+
+   adc-tx_buf = msg;
+   ret = spi_sync(adc-spi, adc-msg);
+   if (ret  0)
+   return ret;
+
+   return ((adc-rx_buf[0]  0x3f)  6)  |
+   (adc-rx_buf[1]  2);
+}
+
+static int mcp320x_read_raw(struct iio_dev *indio_dev,
+   struct iio_chan_spec const *channel, int *val,
+   int *val2, long mask)
+{
+   struct mcp320x *adc = iio_priv(indio_dev);
+   int ret = -EINVAL;
+
+   mutex_lock(adc-lock);
+
+   switch (mask) {
+   case IIO_CHAN_INFO_RAW:
+   if (channel-differential)
+   ret = mcp320x_adc_conversion(adc,
+   MCP_START_BIT | channel-address);
+   else
+   ret = mcp320x_adc_conversion(adc,
+   MCP_START_BIT | MCP_SINGLE_ENDED |
+   channel-address);
+   if (ret  0)
+   goto out;
+
+   *val = ret;
+   ret = IIO_VAL_INT;
+   break;
+
+   case IIO_CHAN_INFO_SCALE:
+   /* Digital output code = (4096 * Vin) / Vref */
+   ret = regulator_get_voltage(adc-reg);
+   if (ret  0)
+   goto out;
+
+   *val = ret / 1000;
+   *val2 = 4096;
+   ret = IIO_VAL_FRACTIONAL;
+   break;
+
+   default:
+   break;
+   }
+
+out:
+   mutex_unlock(adc-lock);
+
+   return ret;
+}
+
+#define MCP320X_VOLTAGE_CHANNEL(num)   \
+   {   \
+   .type = IIO_VOLTAGE,\
+   .indexed = 1,   \
+   .channel = (num),   \
+   .address = (num),   \
+   .info_mask_separate = BIT

Re: [PATCH] iio: adc: add driver for MCP3204/08 12-bit ADC

2013-05-01 Thread Oskar Andero
Hi,

On 16:07 Wed 01 May , Lars-Peter Clausen wrote:
> On 05/01/2013 12:21 AM, Oskar Andero wrote:
> > This adds support for Microchip's 12 bit AD converters MCP3204 and
> > MCP3208. These chips communicates over SPI and supports single-ended
> > and pseudo-differential configurations.
> > 
> > Cc: Jonathan Cameron 
> > Cc: Lars-Peter Clausen 
> > Signed-off-by: Oskar Andero 
> 
> Hi,
> 
> Looks very good in general. A few minor things, mostly related to the 
> regulator
> handling and a couple of nitpicks inline.

Thanks for reviewing! I will prepare version 2 shortly.

> > +
> > +   ret = regulator_enable(adc->reg);
> > +   if (ret < 0)
> > +   goto reg_free;
> > +   } else {
> > +   adc->ref_mv = pdata->ref_mv;
> 
> I'd like to see this fallback path go away. For supplies with a const voltage
> the fixed-voltage-regulator can be used.
> 

Ok. I added this since the voltage I use for reference is behind a 
level-shifter,
meaning there is actually no regulator on the board providing that exact
voltage level. Not sure what you mean with "the fixed-voltage-regulator", but
maybe that is what I am looking for in my case?

Thanks!

-Oskar
--
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] iio: adc: add driver for MCP3204/08 12-bit ADC

2013-05-01 Thread Oskar Andero
Hi,

On 16:07 Wed 01 May , Lars-Peter Clausen wrote:
 On 05/01/2013 12:21 AM, Oskar Andero wrote:
  This adds support for Microchip's 12 bit AD converters MCP3204 and
  MCP3208. These chips communicates over SPI and supports single-ended
  and pseudo-differential configurations.
  
  Cc: Jonathan Cameron ji...@cam.ac.uk
  Cc: Lars-Peter Clausen l...@metafoo.de
  Signed-off-by: Oskar Andero oskar.and...@gmail.com
 
 Hi,
 
 Looks very good in general. A few minor things, mostly related to the 
 regulator
 handling and a couple of nitpicks inline.

Thanks for reviewing! I will prepare version 2 shortly.

  +
  +   ret = regulator_enable(adc-reg);
  +   if (ret  0)
  +   goto reg_free;
  +   } else {
  +   adc-ref_mv = pdata-ref_mv;
 
 I'd like to see this fallback path go away. For supplies with a const voltage
 the fixed-voltage-regulator can be used.
 

Ok. I added this since the voltage I use for reference is behind a 
level-shifter,
meaning there is actually no regulator on the board providing that exact
voltage level. Not sure what you mean with the fixed-voltage-regulator, but
maybe that is what I am looking for in my case?

Thanks!

-Oskar
--
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] iio: adc: add driver for MCP3204/08 12-bit ADC

2013-04-30 Thread Oskar Andero
This adds support for Microchip's 12 bit AD converters MCP3204 and
MCP3208. These chips communicates over SPI and supports single-ended
and pseudo-differential configurations.

Cc: Jonathan Cameron 
Cc: Lars-Peter Clausen 
Signed-off-by: Oskar Andero 
---
 drivers/iio/adc/Kconfig   |  10 ++
 drivers/iio/adc/Makefile  |   1 +
 drivers/iio/adc/mcp320x.c | 261 ++
 include/linux/platform_data/mcp320x.h |  23 +++
 4 files changed, 295 insertions(+)
 create mode 100644 drivers/iio/adc/mcp320x.c
 create mode 100644 include/linux/platform_data/mcp320x.h

diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index ab0767e6..93129ec 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -133,6 +133,16 @@ config MAX1363
  max11646, max11647) Provides direct access via sysfs and buffered
  data via the iio dev interface.
 
+config MCP320X
+   tristate "Microchip Technology MCP3204/08"
+   depends on SPI
+   help
+ Say yes here to build support for Microchip Technology's MCP3204 or
+ MCP3208 analog to digital converter.
+
+ This driver can also be built as a module. If so, the module will be
+ called mcp320x.
+
 config TI_ADC081C
tristate "Texas Instruments ADC081C021/027"
depends on I2C
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 0a825be..8f475d3 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_AT91_ADC) += at91_adc.o
 obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o
 obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
 obj-$(CONFIG_MAX1363) += max1363.o
+obj-$(CONFIG_MCP320X) += mcp320x.o
 obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
 obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
 obj-$(CONFIG_VIPERBOARD_ADC) += viperboard_adc.o
diff --git a/drivers/iio/adc/mcp320x.c b/drivers/iio/adc/mcp320x.c
new file mode 100644
index 000..cb308e8
--- /dev/null
+++ b/drivers/iio/adc/mcp320x.c
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2013 Oskar Andero 
+ *
+ * Driver for Microchip Technology's MCP3204 and MCP3208 ADC chips.
+ * Datasheet can be found here:
+ * http://ww1.microchip.com/downloads/en/devicedoc/21298c.pdf
+ *
+ * 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 
+
+#define MCP_SINGLE_ENDED   (1 << 3)
+#define MCP_START_BIT  (1 << 4)
+
+enum {
+   mcp3204,
+   mcp3208,
+};
+
+struct mcp320x {
+   struct spi_device *spi;
+   struct spi_message msg;
+   struct spi_transfer transfer[2];
+
+   u8 tx_buf;
+   u8 rx_buf[2];
+
+   struct regulator *reg;
+   unsigned int ref_mv;
+
+   struct mutex lock;
+};
+
+static int mcp320x_adc_conversion(struct mcp320x *adc, u8 msg)
+{
+   int ret;
+
+   adc->tx_buf = msg;
+   ret = spi_sync(adc->spi, >msg);
+   if (ret < 0)
+   return ret;
+
+   return ((adc->rx_buf[0] & 0x3f) << 6)  |
+   (adc->rx_buf[1] >> 2);
+}
+
+static int mcp320x_read_raw(struct iio_dev *iio,
+   struct iio_chan_spec const *channel, int *val,
+   int *val2, long mask)
+{
+   struct mcp320x *adc = iio_priv(iio);
+   int ret = -EINVAL;
+
+   mutex_lock(>lock);
+
+   switch (mask) {
+   case IIO_CHAN_INFO_RAW:
+   if (channel->differential)
+   ret = mcp320x_adc_conversion(adc,
+   MCP_START_BIT | channel->address);
+   else
+   ret = mcp320x_adc_conversion(adc,
+   MCP_START_BIT | MCP_SINGLE_ENDED |
+   channel->address);
+   if (ret < 0)
+   goto out;
+
+   *val = ret;
+   ret = IIO_VAL_INT;
+   break;
+
+   case IIO_CHAN_INFO_SCALE:
+   /* Digital output code = (4096 * Vin) / Vref */
+   if (!IS_ERR_OR_NULL(adc->reg)) {
+   ret = regulator_get_voltage(adc->reg);
+   if (ret < 0)
+   goto out;
+   *val = ret / 1000;
+   } else {
+   *val = adc->ref_mv;
+   }
+   *val2 = 4096 * 1000;
+   ret = IIO_VAL_FRACTIONAL;
+   break;
+
+   default:
+   break;
+   }
+
+out:
+   mutex_unlock(>lock);
+
+   return ret;
+}
+
+#define MCP320X_VOLTAGE_CHANNEL(num)   \
+   {   \
+   .type = IIO_VOLTAGE,

[PATCH] iio: adc: add driver for MCP3204/08 12-bit ADC

2013-04-30 Thread Oskar Andero
This adds support for Microchip's 12 bit AD converters MCP3204 and
MCP3208. These chips communicates over SPI and supports single-ended
and pseudo-differential configurations.

Cc: Jonathan Cameron ji...@cam.ac.uk
Cc: Lars-Peter Clausen l...@metafoo.de
Signed-off-by: Oskar Andero oskar.and...@gmail.com
---
 drivers/iio/adc/Kconfig   |  10 ++
 drivers/iio/adc/Makefile  |   1 +
 drivers/iio/adc/mcp320x.c | 261 ++
 include/linux/platform_data/mcp320x.h |  23 +++
 4 files changed, 295 insertions(+)
 create mode 100644 drivers/iio/adc/mcp320x.c
 create mode 100644 include/linux/platform_data/mcp320x.h

diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index ab0767e6..93129ec 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -133,6 +133,16 @@ config MAX1363
  max11646, max11647) Provides direct access via sysfs and buffered
  data via the iio dev interface.
 
+config MCP320X
+   tristate Microchip Technology MCP3204/08
+   depends on SPI
+   help
+ Say yes here to build support for Microchip Technology's MCP3204 or
+ MCP3208 analog to digital converter.
+
+ This driver can also be built as a module. If so, the module will be
+ called mcp320x.
+
 config TI_ADC081C
tristate Texas Instruments ADC081C021/027
depends on I2C
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 0a825be..8f475d3 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_AT91_ADC) += at91_adc.o
 obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o
 obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
 obj-$(CONFIG_MAX1363) += max1363.o
+obj-$(CONFIG_MCP320X) += mcp320x.o
 obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
 obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
 obj-$(CONFIG_VIPERBOARD_ADC) += viperboard_adc.o
diff --git a/drivers/iio/adc/mcp320x.c b/drivers/iio/adc/mcp320x.c
new file mode 100644
index 000..cb308e8
--- /dev/null
+++ b/drivers/iio/adc/mcp320x.c
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2013 Oskar Andero oskar.and...@gmail.com
+ *
+ * Driver for Microchip Technology's MCP3204 and MCP3208 ADC chips.
+ * Datasheet can be found here:
+ * http://ww1.microchip.com/downloads/en/devicedoc/21298c.pdf
+ *
+ * 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/err.h
+#include linux/spi/spi.h
+#include linux/module.h
+#include linux/iio/iio.h
+#include linux/regulator/consumer.h
+#include linux/platform_data/mcp320x.h
+
+#define MCP_SINGLE_ENDED   (1  3)
+#define MCP_START_BIT  (1  4)
+
+enum {
+   mcp3204,
+   mcp3208,
+};
+
+struct mcp320x {
+   struct spi_device *spi;
+   struct spi_message msg;
+   struct spi_transfer transfer[2];
+
+   u8 tx_buf;
+   u8 rx_buf[2];
+
+   struct regulator *reg;
+   unsigned int ref_mv;
+
+   struct mutex lock;
+};
+
+static int mcp320x_adc_conversion(struct mcp320x *adc, u8 msg)
+{
+   int ret;
+
+   adc-tx_buf = msg;
+   ret = spi_sync(adc-spi, adc-msg);
+   if (ret  0)
+   return ret;
+
+   return ((adc-rx_buf[0]  0x3f)  6)  |
+   (adc-rx_buf[1]  2);
+}
+
+static int mcp320x_read_raw(struct iio_dev *iio,
+   struct iio_chan_spec const *channel, int *val,
+   int *val2, long mask)
+{
+   struct mcp320x *adc = iio_priv(iio);
+   int ret = -EINVAL;
+
+   mutex_lock(adc-lock);
+
+   switch (mask) {
+   case IIO_CHAN_INFO_RAW:
+   if (channel-differential)
+   ret = mcp320x_adc_conversion(adc,
+   MCP_START_BIT | channel-address);
+   else
+   ret = mcp320x_adc_conversion(adc,
+   MCP_START_BIT | MCP_SINGLE_ENDED |
+   channel-address);
+   if (ret  0)
+   goto out;
+
+   *val = ret;
+   ret = IIO_VAL_INT;
+   break;
+
+   case IIO_CHAN_INFO_SCALE:
+   /* Digital output code = (4096 * Vin) / Vref */
+   if (!IS_ERR_OR_NULL(adc-reg)) {
+   ret = regulator_get_voltage(adc-reg);
+   if (ret  0)
+   goto out;
+   *val = ret / 1000;
+   } else {
+   *val = adc-ref_mv;
+   }
+   *val2 = 4096 * 1000;
+   ret = IIO_VAL_FRACTIONAL;
+   break;
+
+   default:
+   break;
+   }
+
+out:
+   mutex_unlock(adc-lock);
+
+   return ret;
+}
+
+#define MCP320X_VOLTAGE_CHANNEL(num

Re: [PATCH] lowmemorykiller: prevent multiple instances of low memory killer

2013-04-23 Thread Oskar Andero
On 22:00 Tue 16 Apr , David Rientjes wrote:
> On Tue, 16 Apr 2013, Oskar Andero wrote:
> 
> > > > The comment in shrinker.h is misleading, not the source code.
> > > > do_shrinker_shrink() will fail for anything negative and 0.
> > > 
> > > The comment is correct.  The only acceptable negative return is -1.
> > > Look at the second time do_shrinker_shrink() is called from
> > > shrink_slab().
> > > 
> > >283  while (total_scan >= batch_size) {
> > >284  int nr_before;
> > >285  
> > >286  nr_before = do_shrinker_shrink(shrinker, 
> > > shrink, 0);
> > >287  shrink_ret = do_shrinker_shrink(shrinker, 
> > > shrink,
> > >288  
> > > batch_size);
> > >289  if (shrink_ret == -1)
> > >290  break;
> > >291  if (shrink_ret < nr_before)
> > >292  ret += nr_before - shrink_ret;
> > >293  count_vm_events(SLABS_SCANNED, 
> > > batch_size);
> > 
> > Yes, the comment is correct with what is implemented in the code, but
> > that doesn't mean the code is right. IMHO, relaying on magical numbers is 
> > highly
> > questionable coding style.
> > 
> 
> No, it's not.  This is controlled higher in shrink_slab() by this:
> 
>   max_pass = do_shrinker_shrink(shrinker, shrink, 0);
>   if (max_pass <= 0)
>   continue;
> 

Sure, that looks ok, but that doesn't change the fact that line 289
above has a magical number and I guess that explains the comment:
> > >289  if (shrink_ret == -1)
> > >290  break;

Just to be clear - this is not about lowmemkiller, but rather a generic
clean-up of shrinkers that is needed IMO.

> and your patch is implemented incorrectly, i.e. it does not return 
> LMK_BUSY if the spinlock is contended which needlessly recalls the 
> shrinker later.
> 
> You have a couple of options:
> 
>  - return -1 when the spinlock is contended immediately when
>!sc->nr_to_scan (although it should really be a cmpxchg since a
>spinlock isn't needed), or

I leave it to Snild to comment on the patch, but could you elaborate on why
you think cmpxchg is a better alternative than a spin_trylock? I just had a
brief look at the implementation for ARM and it looks like cmpxchg means
two unconditional memory barriers, whereas spin_trylock has one
conditional memory barrier. See arch/arm/include/asm/spinlock.h:
if (tmp == 0) {
smp_mb();
return 1;
} else {
return 0;
}

...and arch/arm/include/asm/cmpxchg.h:
smp_mb();
ret = __cmpxchg(ptr, old, new, size);
smp_mb();

AFAIK a memory barrier is pretty costly.

-Oskar
--
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] lowmemorykiller: prevent multiple instances of low memory killer

2013-04-23 Thread Oskar Andero
On 22:00 Tue 16 Apr , David Rientjes wrote:
 On Tue, 16 Apr 2013, Oskar Andero wrote:
 
The comment in shrinker.h is misleading, not the source code.
do_shrinker_shrink() will fail for anything negative and 0.
   
   The comment is correct.  The only acceptable negative return is -1.
   Look at the second time do_shrinker_shrink() is called from
   shrink_slab().
   
  283  while (total_scan = batch_size) {
  284  int nr_before;
  285  
  286  nr_before = do_shrinker_shrink(shrinker, 
   shrink, 0);
  287  shrink_ret = do_shrinker_shrink(shrinker, 
   shrink,
  288  
   batch_size);
  289  if (shrink_ret == -1)
  290  break;
  291  if (shrink_ret  nr_before)
  292  ret += nr_before - shrink_ret;
  293  count_vm_events(SLABS_SCANNED, 
   batch_size);
  
  Yes, the comment is correct with what is implemented in the code, but
  that doesn't mean the code is right. IMHO, relaying on magical numbers is 
  highly
  questionable coding style.
  
 
 No, it's not.  This is controlled higher in shrink_slab() by this:
 
   max_pass = do_shrinker_shrink(shrinker, shrink, 0);
   if (max_pass = 0)
   continue;
 

Sure, that looks ok, but that doesn't change the fact that line 289
above has a magical number and I guess that explains the comment:
  289  if (shrink_ret == -1)
  290  break;

Just to be clear - this is not about lowmemkiller, but rather a generic
clean-up of shrinkers that is needed IMO.

 and your patch is implemented incorrectly, i.e. it does not return 
 LMK_BUSY if the spinlock is contended which needlessly recalls the 
 shrinker later.
 
 You have a couple of options:
 
  - return -1 when the spinlock is contended immediately when
!sc-nr_to_scan (although it should really be a cmpxchg since a
spinlock isn't needed), or

I leave it to Snild to comment on the patch, but could you elaborate on why
you think cmpxchg is a better alternative than a spin_trylock? I just had a
brief look at the implementation for ARM and it looks like cmpxchg means
two unconditional memory barriers, whereas spin_trylock has one
conditional memory barrier. See arch/arm/include/asm/spinlock.h:
if (tmp == 0) {
smp_mb();
return 1;
} else {
return 0;
}

...and arch/arm/include/asm/cmpxchg.h:
smp_mb();
ret = __cmpxchg(ptr, old, new, size);
smp_mb();

AFAIK a memory barrier is pretty costly.

-Oskar
--
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] lowmemorykiller: prevent multiple instances of low memory killer

2013-04-16 Thread Oskar Andero
On 08:19 Tue 16 Apr , Dan Carpenter wrote:
> On Mon, Apr 15, 2013 at 04:11:18PM -0700, David Rientjes wrote:
> > On Mon, 15 Apr 2013, Greg Kroah-Hartman wrote:
> > 
> > > > The positive numbers are used to return information on the remaining
> > > > cache size (again, see the comment I pasted above). We could use
> > > > -EBUSY, but we'd have to change vmscan.c, which checks specifically
> > > > for -1. I can't see a technical reason why -EBUSY couldn't have been
> > > > chosen instead, but there's also no real reason to change it now.
> > > 
> > > If it's not the correct thing to do, sure we can change it, just send a
> > > patch.  It makes way more sense than some random -1 return value to me.
> > > 
> > > Care to send a series of patches fixing this up properly?
> > > 
> > 
> > The comment in shrinker.h is misleading, not the source code.
> > do_shrinker_shrink() will fail for anything negative and 0.
> 
> The comment is correct.  The only acceptable negative return is -1.
> Look at the second time do_shrinker_shrink() is called from
> shrink_slab().
> 
>283  while (total_scan >= batch_size) {
>284  int nr_before;
>285  
>286  nr_before = do_shrinker_shrink(shrinker, 
> shrink, 0);
>287  shrink_ret = do_shrinker_shrink(shrinker, 
> shrink,
>288  batch_size);
>289  if (shrink_ret == -1)
>290  break;
>291  if (shrink_ret < nr_before)
>292  ret += nr_before - shrink_ret;
>293  count_vm_events(SLABS_SCANNED, batch_size);

Yes, the comment is correct with what is implemented in the code, but
that doesn't mean the code is right. IMHO, relaying on magical numbers is highly
questionable coding style.

If there are no objections I will prepare a patch-set and let's discuss it from 
there.

-Oskar
--
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] lowmemorykiller: prevent multiple instances of low memory killer

2013-04-16 Thread Oskar Andero
On 08:19 Tue 16 Apr , Dan Carpenter wrote:
 On Mon, Apr 15, 2013 at 04:11:18PM -0700, David Rientjes wrote:
  On Mon, 15 Apr 2013, Greg Kroah-Hartman wrote:
  
The positive numbers are used to return information on the remaining
cache size (again, see the comment I pasted above). We could use
-EBUSY, but we'd have to change vmscan.c, which checks specifically
for -1. I can't see a technical reason why -EBUSY couldn't have been
chosen instead, but there's also no real reason to change it now.
   
   If it's not the correct thing to do, sure we can change it, just send a
   patch.  It makes way more sense than some random -1 return value to me.
   
   Care to send a series of patches fixing this up properly?
   
  
  The comment in shrinker.h is misleading, not the source code.
  do_shrinker_shrink() will fail for anything negative and 0.
 
 The comment is correct.  The only acceptable negative return is -1.
 Look at the second time do_shrinker_shrink() is called from
 shrink_slab().
 
283  while (total_scan = batch_size) {
284  int nr_before;
285  
286  nr_before = do_shrinker_shrink(shrinker, 
 shrink, 0);
287  shrink_ret = do_shrinker_shrink(shrinker, 
 shrink,
288  batch_size);
289  if (shrink_ret == -1)
290  break;
291  if (shrink_ret  nr_before)
292  ret += nr_before - shrink_ret;
293  count_vm_events(SLABS_SCANNED, batch_size);

Yes, the comment is correct with what is implemented in the code, but
that doesn't mean the code is right. IMHO, relaying on magical numbers is highly
questionable coding style.

If there are no objections I will prepare a patch-set and let's discuss it from 
there.

-Oskar
--
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] lowmemorykiller: prevent multiple instances of low memory killer

2013-04-15 Thread Oskar Andero
On 16:13 Mon 15 Apr , Dan Carpenter wrote:
> On Mon, Apr 15, 2013 at 03:38:08PM +0200, Dolkow, Snild wrote:
> > >Where is lowmem_shrink called from?  I only see shrink called from the
> > >bcache sysfs handler __bch_cache_set().  The return value isn't checked
> > >there.
> > >
> > >Up to now this function has only returns positive numbers.
> > >
> > >There isn't a place which check LMK_BUSY so maybe it's best to just
> > >return zero?
> > 
> > Hey Dan,
> > 
> > lowmem_shrink is assigned to a shrinker struct
> > (include/linux/shrinker.h) and called in do_shrinker_shrink() in
> > mm/vmscan.c. That, in turn, is called and checked in a few places
> > in vmscan.c.
> >
> > >From the comments in shrinker.h: 
> > "It should return the number of objects which remain in the
> > cache. If it returns -1, it means it cannot do any scanning at
> > this time (eg. there is a risk of deadlock). The callback must not
> > return -1 if nr_to_scan is zero."
> 
> Ah.  Good.  -1 is the right return.
> 
> But really should be a #define in shrinker.h instead of in
> drivers/staging/android/.

IMO one should use the errno.h values - e.g. EBUSY might be a good
value in this case. Does anyone know why the shrinker wants -1? Is there
a reason?

-Oskar
--
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] lowmemorykiller: prevent multiple instances of low memory killer

2013-04-15 Thread Oskar Andero
From: Snild Dolkow 

Running multiple instances of LMK is not useful since it will try to
kill the same process.

This patch adds a spinlock to prevent multiple instances of the LMK
running at the same time. Uses spin_trylock and return on failure to
avoid blocking.

Cc: Greg Kroah-Hartman 
Cc: Brian Swetland 
Reviewed-by: Radovan Lekanovic 
Signed-off-by: Snild Dolkow 
Signed-off-by: Oskar Andero 
---
 drivers/staging/android/lowmemorykiller.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/staging/android/lowmemorykiller.c 
b/drivers/staging/android/lowmemorykiller.c
index 3b91b0f..0b19353 100644
--- a/drivers/staging/android/lowmemorykiller.c
+++ b/drivers/staging/android/lowmemorykiller.c
@@ -38,6 +38,7 @@
 #include 
 #include 
 #include 
+#include 
 
 static uint32_t lowmem_debug_level = 2;
 static short lowmem_adj[6] = {
@@ -57,6 +58,8 @@ static int lowmem_minfree_size = 4;
 
 static unsigned long lowmem_deathpending_timeout;
 
+#define LMK_BUSY (-1)
+
 #define lowmem_print(level, x...)  \
do {\
if (lowmem_debug_level >= (level))  \
@@ -65,6 +68,7 @@ static unsigned long lowmem_deathpending_timeout;
 
 static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc)
 {
+   static DEFINE_SPINLOCK(lowmem_lock);
struct task_struct *tsk;
struct task_struct *selected = NULL;
int rem = 0;
@@ -104,6 +108,9 @@ static int lowmem_shrink(struct shrinker *s, struct 
shrink_control *sc)
}
selected_oom_score_adj = min_score_adj;
 
+   if (spin_trylock(_lock) == 0)
+   return LMK_BUSY;
+
rcu_read_lock();
for_each_process(tsk) {
struct task_struct *p;
@@ -120,6 +127,7 @@ static int lowmem_shrink(struct shrinker *s, struct 
shrink_control *sc)
time_before_eq(jiffies, lowmem_deathpending_timeout)) {
task_unlock(p);
rcu_read_unlock();
+   spin_unlock(_lock);
return 0;
}
oom_score_adj = p->signal->oom_score_adj;
@@ -156,6 +164,7 @@ static int lowmem_shrink(struct shrinker *s, struct 
shrink_control *sc)
lowmem_print(4, "lowmem_shrink %lu, %x, return %d\n",
 sc->nr_to_scan, sc->gfp_mask, rem);
rcu_read_unlock();
+   spin_unlock(_lock);
return rem;
 }
 
-- 
1.8.1.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/


[PATCH] lowmemorykiller: prevent multiple instances of low memory killer

2013-04-15 Thread Oskar Andero
From: Snild Dolkow snild.dol...@sonymobile.com

Running multiple instances of LMK is not useful since it will try to
kill the same process.

This patch adds a spinlock to prevent multiple instances of the LMK
running at the same time. Uses spin_trylock and return on failure to
avoid blocking.

Cc: Greg Kroah-Hartman gre...@linuxfoundation.org
Cc: Brian Swetland swetl...@google.com
Reviewed-by: Radovan Lekanovic radovan.lekano...@sonymobile.com
Signed-off-by: Snild Dolkow snild.dol...@sonymobile.com
Signed-off-by: Oskar Andero oskar.and...@sonymobile.com
---
 drivers/staging/android/lowmemorykiller.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/staging/android/lowmemorykiller.c 
b/drivers/staging/android/lowmemorykiller.c
index 3b91b0f..0b19353 100644
--- a/drivers/staging/android/lowmemorykiller.c
+++ b/drivers/staging/android/lowmemorykiller.c
@@ -38,6 +38,7 @@
 #include linux/rcupdate.h
 #include linux/profile.h
 #include linux/notifier.h
+#include linux/spinlock.h
 
 static uint32_t lowmem_debug_level = 2;
 static short lowmem_adj[6] = {
@@ -57,6 +58,8 @@ static int lowmem_minfree_size = 4;
 
 static unsigned long lowmem_deathpending_timeout;
 
+#define LMK_BUSY (-1)
+
 #define lowmem_print(level, x...)  \
do {\
if (lowmem_debug_level = (level))  \
@@ -65,6 +68,7 @@ static unsigned long lowmem_deathpending_timeout;
 
 static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc)
 {
+   static DEFINE_SPINLOCK(lowmem_lock);
struct task_struct *tsk;
struct task_struct *selected = NULL;
int rem = 0;
@@ -104,6 +108,9 @@ static int lowmem_shrink(struct shrinker *s, struct 
shrink_control *sc)
}
selected_oom_score_adj = min_score_adj;
 
+   if (spin_trylock(lowmem_lock) == 0)
+   return LMK_BUSY;
+
rcu_read_lock();
for_each_process(tsk) {
struct task_struct *p;
@@ -120,6 +127,7 @@ static int lowmem_shrink(struct shrinker *s, struct 
shrink_control *sc)
time_before_eq(jiffies, lowmem_deathpending_timeout)) {
task_unlock(p);
rcu_read_unlock();
+   spin_unlock(lowmem_lock);
return 0;
}
oom_score_adj = p-signal-oom_score_adj;
@@ -156,6 +164,7 @@ static int lowmem_shrink(struct shrinker *s, struct 
shrink_control *sc)
lowmem_print(4, lowmem_shrink %lu, %x, return %d\n,
 sc-nr_to_scan, sc-gfp_mask, rem);
rcu_read_unlock();
+   spin_unlock(lowmem_lock);
return rem;
 }
 
-- 
1.8.1.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] lowmemorykiller: prevent multiple instances of low memory killer

2013-04-15 Thread Oskar Andero
On 16:13 Mon 15 Apr , Dan Carpenter wrote:
 On Mon, Apr 15, 2013 at 03:38:08PM +0200, Dolkow, Snild wrote:
  Where is lowmem_shrink called from?  I only see shrink called from the
  bcache sysfs handler __bch_cache_set().  The return value isn't checked
  there.
  
  Up to now this function has only returns positive numbers.
  
  There isn't a place which check LMK_BUSY so maybe it's best to just
  return zero?
  
  Hey Dan,
  
  lowmem_shrink is assigned to a shrinker struct
  (include/linux/shrinker.h) and called in do_shrinker_shrink() in
  mm/vmscan.c. That, in turn, is called and checked in a few places
  in vmscan.c.
 
  From the comments in shrinker.h: 
  It should return the number of objects which remain in the
  cache. If it returns -1, it means it cannot do any scanning at
  this time (eg. there is a risk of deadlock). The callback must not
  return -1 if nr_to_scan is zero.
 
 Ah.  Good.  -1 is the right return.
 
 But really should be a #define in shrinker.h instead of in
 drivers/staging/android/.

IMO one should use the errno.h values - e.g. EBUSY might be a good
value in this case. Does anyone know why the shrinker wants -1? Is there
a reason?

-Oskar
--
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] scsi: fix null pointer dereference in sd_revalidate_disk

2013-04-09 Thread Oskar Andero
Hi James,

On 18:39 Mon 08 Apr , James Bottomley wrote:
> On Mon, 2013-04-08 at 13:42 +0200, Oskar Andero wrote:
> > On 14:36 Thu 07 Mar , oskar.and...@sonymobile.com wrote:
> > > From: "syunsuke.x.itou" 
> > > 
> > > By repeatadly connecting/disconnecting a USB masstorage device
> > > a null pointer dereference can be provoked. This is caused by
> > > sd_revalidate_disk() assuming sdkp to be a valid pointer. This
> > > patch adds a null pointer check.
> > > 
> > > Reviewed-by: Radovan Lekanovic 
> > > Signed-off-by: syunsuke.x.itou 
> > > Signed-off-by: Oskar Andero 
> > > ---
> > >  drivers/scsi/sd.c |7 ++-
> > >  1 files changed, 6 insertions(+), 1 deletions(-)
> > > 
> > > diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
> > > index 7992635..49849ce 100644
> > > --- a/drivers/scsi/sd.c
> > > +++ b/drivers/scsi/sd.c
> > > @@ -1,6 +1,7 @@
> > >  /*
> > >   *  sd.c Copyright (C) 1992 Drew Eckhardt
> > >   *   Copyright (C) 1993, 1994, 1995, 1999 Eric Youngdale
> > > + *   Copyright (C) 2013 Sony Mobile Communications AB.
> > >   *
> > >   *  Linux scsi disk driver
> > >   *  Initial versions: Drew Eckhardt
> > > @@ -2653,10 +2654,14 @@ static int sd_try_extended_inquiry(struct 
> > > scsi_device *sdp)
> > >  static int sd_revalidate_disk(struct gendisk *disk)
> > >  {
> > >   struct scsi_disk *sdkp = scsi_disk(disk);
> > > - struct scsi_device *sdp = sdkp->device;
> > > + struct scsi_device *sdp;
> > >   unsigned char *buffer;
> > >   unsigned flush = 0;
> > >  
> > > + if (!sdkp)
> > > + return -ENODEV;
> > > + sdp = sdkp->device;
> > > +
> > >   SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp,
> > > "sd_revalidate_disk\n"));
> > >  
> > > -- 
> > > 1.7.8.6
> > > 
> > 
> > Ping. Any input on the patch above?
> 
> For us to give input, the original patch would have to have been sent to
> linux-scsi ...

That's strange. Must have been lost in our mail servers. It explains
why I didn't find the patch in the archives though. :)

> However, I think it's not correct because it fixes a symptom, not the
> cause.  If sdkp can be null, that means something failed to get the
> reference that's required.  What's the stack trace?

This is the stack trace:

[...]
 [ 1896.454417] Unable to handle kernel NULL pointer dereference at virtual 
address 0004
 [ 1896.461834] pgd = d7b2
 [ 1896.464245] [0004] *pgd=85bf6831, *pte=, *ppte=
 [ 1896.470471] Internal error: Oops: 17 [#1] PREEMPT SMP
 [ 1896.475537] Modules linked in:
 [ 1896.476392] hub 1-0:1.0: hub_port_status failed (err = -19)
 [ 1896.476422] hub 1-0:1.0: connect-debounce failed, port 1 disabled
 [ 1896.490248] 
 [ 1896.490279] CPU: 1Tainted: GW
(3.0.21-perf-gd3cbbb2-00351-gbcb8998 #1)
 [ 1896.490279] PC is at sd_revalidate_disk+0x1c/0x1720
 [ 1896.490309] LR is at rescan_partitions+0xb0/0x498
 [ 1896.490309] pc : []lr : []psr: a013
 [ 1896.490309] sp : d7b25c68  ip : 0003  fp : 0001
 [ 1896.490309] r10: e0822a00  r9 :   r8 : dce93c0c
 [ 1896.490309] r7 : 001f  r6 : dce93c00  r5 : dce93c00  r4 : 
 [ 1896.490340] r3 : 271aed09  r2 : d7b25cd8  r1 :   r0 : dce93c00
 [ 1896.490340] Flags: NzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment 
user
 [ 1896.490340] Control: 10c5787d  Table: 9ef2006a  DAC: 0015
[...]
 [ 1896.492049] [] (sd_revalidate_disk+0x1c/0x1720) from [] 
(rescan_partitions+0xb0/0x498)
 [ 1896.492049] [] (rescan_partitions+0xb0/0x498) from [] 
(__blkdev_get+0x154/0x320)
 [ 1896.492079] [] (__blkdev_get+0x154/0x320) from [] 
(__blkdev_get+0x194/0x320)
 [ 1896.492079] [] (__blkdev_get+0x194/0x320) from [] 
(blkdev_get+0x1d8/0x330)
 [ 1896.492110] [] (blkdev_get+0x1d8/0x330) from [] 
(__dentry_open+0x220/0x338)
 [ 1896.492110] [] (__dentry_open+0x220/0x338) from [] 
(nameidata_to_filp+0x50/0x5c)
 [ 1896.492140] [] (nameidata_to_filp+0x50/0x5c) from [] 
(do_last+0x7c8/0x8d4)
 [ 1896.492140] [] (do_last+0x7c8/0x8d4) from [] 
(path_openat+0xc4/0x380)
 [ 1896.492171] [] (path_openat+0xc4/0x380) from [] 
(do_filp_open+0x30/0x7c)
 [ 1896.492171] [] (do_filp_open+0x30/0x7c) from [] 
(do_sys_open+0xd8/0x174)
 [ 1896.492201] [] (do_sys_open+0xd8/0x174) from [] 
(ret_fast_syscall+0x0/0x30)
 [ 1896.492201] Code: e5933000 e58d0024 e59041f0 e58d305c (e5940004) 

The patch above fixes the problem, but you might be right - maybe it only fixes 
the symptom.
Let me know if you have any suggestions or need more information!

-Oskar
--
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] scsi: fix null pointer dereference in sd_revalidate_disk

2013-04-09 Thread Oskar Andero
Hi James,

On 18:39 Mon 08 Apr , James Bottomley wrote:
 On Mon, 2013-04-08 at 13:42 +0200, Oskar Andero wrote:
  On 14:36 Thu 07 Mar , oskar.and...@sonymobile.com wrote:
   From: syunsuke.x.itou syunsuke.x.i...@sonymobile.com
   
   By repeatadly connecting/disconnecting a USB masstorage device
   a null pointer dereference can be provoked. This is caused by
   sd_revalidate_disk() assuming sdkp to be a valid pointer. This
   patch adds a null pointer check.
   
   Reviewed-by: Radovan Lekanovic radovan.lekano...@sonymobile.com
   Signed-off-by: syunsuke.x.itou syunsuke.x.i...@sonymobile.com
   Signed-off-by: Oskar Andero oskar.and...@sonymobile.com
   ---
drivers/scsi/sd.c |7 ++-
1 files changed, 6 insertions(+), 1 deletions(-)
   
   diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
   index 7992635..49849ce 100644
   --- a/drivers/scsi/sd.c
   +++ b/drivers/scsi/sd.c
   @@ -1,6 +1,7 @@
/*
 *  sd.c Copyright (C) 1992 Drew Eckhardt
 *   Copyright (C) 1993, 1994, 1995, 1999 Eric Youngdale
   + *   Copyright (C) 2013 Sony Mobile Communications AB.
 *
 *  Linux scsi disk driver
 *  Initial versions: Drew Eckhardt
   @@ -2653,10 +2654,14 @@ static int sd_try_extended_inquiry(struct 
   scsi_device *sdp)
static int sd_revalidate_disk(struct gendisk *disk)
{
 struct scsi_disk *sdkp = scsi_disk(disk);
   - struct scsi_device *sdp = sdkp-device;
   + struct scsi_device *sdp;
 unsigned char *buffer;
 unsigned flush = 0;

   + if (!sdkp)
   + return -ENODEV;
   + sdp = sdkp-device;
   +
 SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp,
   sd_revalidate_disk\n));

   -- 
   1.7.8.6
   
  
  Ping. Any input on the patch above?
 
 For us to give input, the original patch would have to have been sent to
 linux-scsi ...

That's strange. Must have been lost in our mail servers. It explains
why I didn't find the patch in the archives though. :)

 However, I think it's not correct because it fixes a symptom, not the
 cause.  If sdkp can be null, that means something failed to get the
 reference that's required.  What's the stack trace?

This is the stack trace:

[...]
 [ 1896.454417] Unable to handle kernel NULL pointer dereference at virtual 
address 0004
 [ 1896.461834] pgd = d7b2
 [ 1896.464245] [0004] *pgd=85bf6831, *pte=, *ppte=
 [ 1896.470471] Internal error: Oops: 17 [#1] PREEMPT SMP
 [ 1896.475537] Modules linked in:
 [ 1896.476392] hub 1-0:1.0: hub_port_status failed (err = -19)
 [ 1896.476422] hub 1-0:1.0: connect-debounce failed, port 1 disabled
 [ 1896.490248] 
 [ 1896.490279] CPU: 1Tainted: GW
(3.0.21-perf-gd3cbbb2-00351-gbcb8998 #1)
 [ 1896.490279] PC is at sd_revalidate_disk+0x1c/0x1720
 [ 1896.490309] LR is at rescan_partitions+0xb0/0x498
 [ 1896.490309] pc : [c043e7ec]lr : [c026a0e4]psr: a013
 [ 1896.490309] sp : d7b25c68  ip : 0003  fp : 0001
 [ 1896.490309] r10: e0822a00  r9 :   r8 : dce93c0c
 [ 1896.490309] r7 : 001f  r6 : dce93c00  r5 : dce93c00  r4 : 
 [ 1896.490340] r3 : 271aed09  r2 : d7b25cd8  r1 :   r0 : dce93c00
 [ 1896.490340] Flags: NzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment 
user
 [ 1896.490340] Control: 10c5787d  Table: 9ef2006a  DAC: 0015
[...]
 [ 1896.492049] [c043e7ec] (sd_revalidate_disk+0x1c/0x1720) from [c026a0e4] 
(rescan_partitions+0xb0/0x498)
 [ 1896.492049] [c026a0e4] (rescan_partitions+0xb0/0x498) from [c024c648] 
(__blkdev_get+0x154/0x320)
 [ 1896.492079] [c024c648] (__blkdev_get+0x154/0x320) from [c024c688] 
(__blkdev_get+0x194/0x320)
 [ 1896.492079] [c024c688] (__blkdev_get+0x194/0x320) from [c024c9ec] 
(blkdev_get+0x1d8/0x330)
 [ 1896.492110] [c024c9ec] (blkdev_get+0x1d8/0x330) from [c021d03c] 
(__dentry_open+0x220/0x338)
 [ 1896.492110] [c021d03c] (__dentry_open+0x220/0x338) from [c021d204] 
(nameidata_to_filp+0x50/0x5c)
 [ 1896.492140] [c021d204] (nameidata_to_filp+0x50/0x5c) from [c022b244] 
(do_last+0x7c8/0x8d4)
 [ 1896.492140] [c022b244] (do_last+0x7c8/0x8d4) from [c022c12c] 
(path_openat+0xc4/0x380)
 [ 1896.492171] [c022c12c] (path_openat+0xc4/0x380) from [c022c4c8] 
(do_filp_open+0x30/0x7c)
 [ 1896.492171] [c022c4c8] (do_filp_open+0x30/0x7c) from [c021cc80] 
(do_sys_open+0xd8/0x174)
 [ 1896.492201] [c021cc80] (do_sys_open+0xd8/0x174) from [c0105e80] 
(ret_fast_syscall+0x0/0x30)
 [ 1896.492201] Code: e5933000 e58d0024 e59041f0 e58d305c (e5940004) 

The patch above fixes the problem, but you might be right - maybe it only fixes 
the symptom.
Let me know if you have any suggestions or need more information!

-Oskar
--
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] scsi: fix null pointer dereference in sd_revalidate_disk

2013-04-08 Thread Oskar Andero
On 14:36 Thu 07 Mar , oskar.and...@sonymobile.com wrote:
> From: "syunsuke.x.itou" 
> 
> By repeatadly connecting/disconnecting a USB masstorage device
> a null pointer dereference can be provoked. This is caused by
> sd_revalidate_disk() assuming sdkp to be a valid pointer. This
> patch adds a null pointer check.
> 
> Reviewed-by: Radovan Lekanovic 
> Signed-off-by: syunsuke.x.itou 
> Signed-off-by: Oskar Andero 
> ---
>  drivers/scsi/sd.c |7 ++-
>  1 files changed, 6 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
> index 7992635..49849ce 100644
> --- a/drivers/scsi/sd.c
> +++ b/drivers/scsi/sd.c
> @@ -1,6 +1,7 @@
>  /*
>   *  sd.c Copyright (C) 1992 Drew Eckhardt
>   *   Copyright (C) 1993, 1994, 1995, 1999 Eric Youngdale
> + *   Copyright (C) 2013 Sony Mobile Communications AB.
>   *
>   *  Linux scsi disk driver
>   *  Initial versions: Drew Eckhardt
> @@ -2653,10 +2654,14 @@ static int sd_try_extended_inquiry(struct scsi_device 
> *sdp)
>  static int sd_revalidate_disk(struct gendisk *disk)
>  {
>   struct scsi_disk *sdkp = scsi_disk(disk);
> - struct scsi_device *sdp = sdkp->device;
> + struct scsi_device *sdp;
>   unsigned char *buffer;
>   unsigned flush = 0;
>  
> + if (!sdkp)
> + return -ENODEV;
> + sdp = sdkp->device;
> +
>   SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp,
> "sd_revalidate_disk\n"));
>  
> -- 
> 1.7.8.6
> 

Ping. Any input on the patch above?

Thanks,

-Oskar
--
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] scsi: fix null pointer dereference in sd_revalidate_disk

2013-04-08 Thread Oskar Andero
On 14:36 Thu 07 Mar , oskar.and...@sonymobile.com wrote:
 From: syunsuke.x.itou syunsuke.x.i...@sonymobile.com
 
 By repeatadly connecting/disconnecting a USB masstorage device
 a null pointer dereference can be provoked. This is caused by
 sd_revalidate_disk() assuming sdkp to be a valid pointer. This
 patch adds a null pointer check.
 
 Reviewed-by: Radovan Lekanovic radovan.lekano...@sonymobile.com
 Signed-off-by: syunsuke.x.itou syunsuke.x.i...@sonymobile.com
 Signed-off-by: Oskar Andero oskar.and...@sonymobile.com
 ---
  drivers/scsi/sd.c |7 ++-
  1 files changed, 6 insertions(+), 1 deletions(-)
 
 diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
 index 7992635..49849ce 100644
 --- a/drivers/scsi/sd.c
 +++ b/drivers/scsi/sd.c
 @@ -1,6 +1,7 @@
  /*
   *  sd.c Copyright (C) 1992 Drew Eckhardt
   *   Copyright (C) 1993, 1994, 1995, 1999 Eric Youngdale
 + *   Copyright (C) 2013 Sony Mobile Communications AB.
   *
   *  Linux scsi disk driver
   *  Initial versions: Drew Eckhardt
 @@ -2653,10 +2654,14 @@ static int sd_try_extended_inquiry(struct scsi_device 
 *sdp)
  static int sd_revalidate_disk(struct gendisk *disk)
  {
   struct scsi_disk *sdkp = scsi_disk(disk);
 - struct scsi_device *sdp = sdkp-device;
 + struct scsi_device *sdp;
   unsigned char *buffer;
   unsigned flush = 0;
  
 + if (!sdkp)
 + return -ENODEV;
 + sdp = sdkp-device;
 +
   SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp,
 sd_revalidate_disk\n));
  
 -- 
 1.7.8.6
 

Ping. Any input on the patch above?

Thanks,

-Oskar
--
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 v3 1/4] kprobes: delay blacklist symbol lookup until we actually need it

2013-04-05 Thread Oskar Andero
From: Toby Collett 

The symbol lookup can take a long time and kprobes is
initialised very early in boot, so delay symbol lookup
until the blacklist is first used.

Cc: Masami Hiramatsu 
Cc: David S. Miller 
Reviewed-by: Radovan Lekanovic 
Signed-off-by: Toby Collett 
Signed-off-by: Oskar Andero 
---
 kernel/kprobes.c | 100 ++-
 1 file changed, 62 insertions(+), 38 deletions(-)

diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index e35be53..c8c2281 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -68,6 +68,7 @@
 #endif
 
 static int kprobes_initialized;
+static bool kprobe_blacklist_initialized;
 static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE];
 static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE];
 
@@ -102,6 +103,62 @@ static struct kprobe_blackpoint kprobe_blacklist[] = {
{NULL}/* Terminator */
 };
 
+/* it can take some time ( > 100ms ) to initialise the
+ * blacklist so we delay this until we actually need it
+ */
+static void init_kprobe_blacklist(void)
+{
+   int i;
+   unsigned long offset = 0, size = 0;
+   char *modname, namebuf[128];
+   const char *symbol_name;
+   void *addr;
+   struct kprobe_blackpoint *kb;
+
+   mutex_lock(_mutex);
+   if (kprobe_blacklist_initialized)
+   goto out;
+
+   /*
+* Lookup and populate the kprobe_blacklist.
+*
+* Unlike the kretprobe blacklist, we'll need to determine
+* the range of addresses that belong to the said functions,
+* since a kprobe need not necessarily be at the beginning
+* of a function.
+*/
+   for (kb = kprobe_blacklist; kb->name != NULL; kb++) {
+   kprobe_lookup_name(kb->name, addr);
+   if (!addr)
+   continue;
+
+   kb->start_addr = (unsigned long)addr;
+   symbol_name = kallsyms_lookup(kb->start_addr,
+   , , , namebuf);
+   if (!symbol_name)
+   kb->range = 0;
+   else
+   kb->range = size;
+   }
+
+   if (kretprobe_blacklist_size) {
+   /* lookup the function address from its name */
+   for (i = 0; kretprobe_blacklist[i].name != NULL; i++) {
+   kprobe_lookup_name(kretprobe_blacklist[i].name,
+  kretprobe_blacklist[i].addr);
+   if (!kretprobe_blacklist[i].addr)
+   printk("kretprobe: lookup failed: %s\n",
+  kretprobe_blacklist[i].name);
+   }
+   }
+
+   smp_wmb();
+   kprobe_blacklist_initialized = true;
+
+out:
+   mutex_unlock(_mutex);
+}
+
 #ifdef __ARCH_WANT_KPROBES_INSN_SLOT
 /*
  * kprobe->ainsn.insn points to the copy of the instruction to be
@@ -1331,6 +1388,9 @@ static int __kprobes in_kprobes_functions(unsigned long 
addr)
if (addr >= (unsigned long)__kprobes_text_start &&
addr < (unsigned long)__kprobes_text_end)
return -EINVAL;
+
+   if (unlikely(!kprobe_blacklist_initialized))
+   init_kprobe_blacklist();
/*
 * If there exists a kprobe_blacklist, verify and
 * fail any probe registration in the prohibited area
@@ -1816,6 +1876,8 @@ int __kprobes register_kretprobe(struct kretprobe *rp)
void *addr;
 
if (kretprobe_blacklist_size) {
+   if (unlikely(!kprobe_blacklist_initialized))
+   init_kprobe_blacklist();
addr = kprobe_addr(>kp);
if (IS_ERR(addr))
return PTR_ERR(addr);
@@ -2065,11 +2127,6 @@ static struct notifier_block kprobe_module_nb = {
 static int __init init_kprobes(void)
 {
int i, err = 0;
-   unsigned long offset = 0, size = 0;
-   char *modname, namebuf[128];
-   const char *symbol_name;
-   void *addr;
-   struct kprobe_blackpoint *kb;
 
/* FIXME allocate the probe table, currently defined statically */
/* initialize all list heads */
@@ -2079,39 +2136,6 @@ static int __init init_kprobes(void)
raw_spin_lock_init(&(kretprobe_table_locks[i].lock));
}
 
-   /*
-* Lookup and populate the kprobe_blacklist.
-*
-* Unlike the kretprobe blacklist, we'll need to determine
-* the range of addresses that belong to the said functions,
-* since a kprobe need not necessarily be at the beginning
-* of a function.
-*/
-   for (kb = kprobe_blacklist; kb->name != NULL; kb++) {
-   kprobe_lookup_name(kb->name, addr);
-   if (!addr)
-   continue;
-
-   kb->start_addr = (unsigned long)addr;
-   symbol_name = kallsyms_look

[PATCH v3 3/4] kprobes: move x86-specific blacklist symbols to arch directory

2013-04-05 Thread Oskar Andero
From: Björn Davidsson 

The common kprobes blacklist contains x86-specific symbols.
Looking for these in kallsyms takes unnecessary time during startup
on non-X86 platform. The symbols where moved to
arch/x86/kernel/kprobes/core.c.

Cc: Masami Hiramatsu 
Cc: David S. Miller 
Cc: linux-a...@vger.kernel.org
Reviewed-by: Radovan Lekanovic 
Signed-off-by: Björn Davidsson 
Signed-off-by: Oskar Andero 
Acked-by: Masami Hiramatsu 
---
 arch/x86/kernel/kprobes/core.c | 7 +++
 kernel/kprobes.c   | 3 ---
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c
index 7bfe318..41ce6c1 100644
--- a/arch/x86/kernel/kprobes/core.c
+++ b/arch/x86/kernel/kprobes/core.c
@@ -65,6 +65,13 @@ void jprobe_return_end(void);
 DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
 DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
 
+const char * const arch_kprobes_blacksyms[] = {
+   "native_get_debugreg",
+   "irq_entries_start",
+   "common_interrupt",
+};
+const size_t arch_kprobes_blacksyms_size = ARRAY_SIZE(arch_kprobes_blacksyms);
+
 #define stack_addr(regs) ((unsigned long *)kernel_stack_pointer(regs))
 
 #define W(row, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf)\
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 2458ae1..b289384 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -95,9 +95,6 @@ static raw_spinlock_t *kretprobe_table_lock_ptr(unsigned long 
hash)
  */
 static const char * const common_kprobes_blacksyms[] = {
"preempt_schedule",
-   "native_get_debugreg",
-   "irq_entries_start",
-   "common_interrupt",
"mcount",   /* mcount can be called from everywhere */
 };
 static const size_t common_kprobes_blacksyms_size =
-- 
1.8.1.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/


[PATCH v3 2/4] kprobes: split blacklist into common and arch

2013-04-05 Thread Oskar Andero
Some blackpoints are only valid for specific architectures. To let each
architecture specify its own blackpoints the list has been split in two
lists: common and arch. The common list is kept in kernel/kprobes.c and
the arch list is kept in the arch/ directory.

Cc: Masami Hiramatsu 
Cc: David S. Miller 
Cc: linux-a...@vger.kernel.org
Signed-off-by: Oskar Andero 
---
 kernel/kprobes.c | 88 +---
 1 file changed, 59 insertions(+), 29 deletions(-)

diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index c8c2281..2458ae1 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -68,7 +68,6 @@
 #endif
 
 static int kprobes_initialized;
-static bool kprobe_blacklist_initialized;
 static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE];
 static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE];
 
@@ -94,31 +93,64 @@ static raw_spinlock_t *kretprobe_table_lock_ptr(unsigned 
long hash)
  *
  * For such cases, we now have a blacklist
  */
-static struct kprobe_blackpoint kprobe_blacklist[] = {
-   {"preempt_schedule",},
-   {"native_get_debugreg",},
-   {"irq_entries_start",},
-   {"common_interrupt",},
-   {"mcount",},/* mcount can be called from everywhere */
-   {NULL}/* Terminator */
+static const char * const common_kprobes_blacksyms[] = {
+   "preempt_schedule",
+   "native_get_debugreg",
+   "irq_entries_start",
+   "common_interrupt",
+   "mcount",   /* mcount can be called from everywhere */
 };
+static const size_t common_kprobes_blacksyms_size =
+   ARRAY_SIZE(common_kprobes_blacksyms);
+
+/*
+ * These weak symbols can be overridden from the arch/ directory for
+ * architecure specific blackpoints.
+ */
+const char * const __weak arch_kprobes_blacksyms[] = {};
+const size_t __weak arch_kprobes_blacksyms_size;
+
+static struct kprobe_blackpoint *kprobe_blacklist;
+static size_t kprobe_blacklist_size;
+
+static void init_kprobe_blacklist_entry(struct kprobe_blackpoint *kb,
+   const char * const name)
+{
+   const char *symbol_name;
+   char *modname, namebuf[128];
+   void *addr;
+   unsigned long offset = 0, size = 0;
+
+   kb->name = name;
+   kprobe_lookup_name(kb->name, addr);
+   if (!addr)
+   return;
+
+   kb->start_addr = (unsigned long)addr;
+   symbol_name = kallsyms_lookup(kb->start_addr,
+   , , , namebuf);
+   if (!symbol_name)
+   kb->range = 0;
+   else
+   kb->range = size;
+}
 
 /* it can take some time ( > 100ms ) to initialise the
  * blacklist so we delay this until we actually need it
  */
 static void init_kprobe_blacklist(void)
 {
-   int i;
-   unsigned long offset = 0, size = 0;
-   char *modname, namebuf[128];
-   const char *symbol_name;
-   void *addr;
+   int i, j = 0;
struct kprobe_blackpoint *kb;
 
mutex_lock(_mutex);
-   if (kprobe_blacklist_initialized)
+   if (kprobe_blacklist)
goto out;
 
+   kprobe_blacklist_size = common_kprobes_blacksyms_size +
+   arch_kprobes_blacksyms_size;
+   kb = kzalloc(sizeof(*kb) * kprobe_blacklist_size, GFP_KERNEL);
+
/*
 * Lookup and populate the kprobe_blacklist.
 *
@@ -127,18 +159,14 @@ static void init_kprobe_blacklist(void)
 * since a kprobe need not necessarily be at the beginning
 * of a function.
 */
-   for (kb = kprobe_blacklist; kb->name != NULL; kb++) {
-   kprobe_lookup_name(kb->name, addr);
-   if (!addr)
-   continue;
+   for (i = 0; i < common_kprobes_blacksyms_size; i++, j++) {
+   init_kprobe_blacklist_entry([j],
+   common_kprobes_blacksyms[i]);
+   }
 
-   kb->start_addr = (unsigned long)addr;
-   symbol_name = kallsyms_lookup(kb->start_addr,
-   , , , namebuf);
-   if (!symbol_name)
-   kb->range = 0;
-   else
-   kb->range = size;
+   for (i = 0; i < arch_kprobes_blacksyms_size; i++, j++) {
+   init_kprobe_blacklist_entry([j],
+   arch_kprobes_blacksyms[i]);
}
 
if (kretprobe_blacklist_size) {
@@ -153,7 +181,7 @@ static void init_kprobe_blacklist(void)
}
 
smp_wmb();
-   kprobe_blacklist_initialized = true;
+   kprobe_blacklist = kb;
 
 out:
mutex_unlock(_mutex);
@@ -1384,18 +1412,20 @@ out:
 static int __kprobes in_kprobes_functions(unsigned long addr)
 {
struct kprobe_blackpoint *kb;
+   int i;
 
if (addr >=

[PATCH v3 0/4] kprobes: split blacklist into common and arch

2013-04-05 Thread Oskar Andero
Hi,

This is version 3 of the patch-set for splitting arch and common kprobe
blackpoints.

Changes since last version are:
- 1/4: Add write memory barrier at blacklist initialization.
- 1/4: Change kprobe_blacklist_initialized type to boolean.
- 2/4: Fix racing of kprobe_blacklist.
- 2/4: Define arch_kprobes_blacksyms.* as __weak symbols.

-Oskar

Björn Davidsson (1):
  kprobes: move x86-specific blacklist symbols to arch directory

Oskar Andero (2):
  kprobes: split blacklist into common and arch
  kprobes: replace printk with pr_-functions

Toby Collett (1):
  kprobes: delay blacklist symbol lookup until we actually need it

 arch/x86/kernel/kprobes/core.c |   7 ++
 kernel/kprobes.c   | 159 +++--
 2 files changed, 112 insertions(+), 54 deletions(-)

-- 
1.8.1.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/


[PATCH v3 4/4] kprobes: replace printk with pr_-functions

2013-04-05 Thread Oskar Andero
Instead of using printk use pr_info/pr_err/pr_warn. This was
detected by the checkpatch.pl script.

Cc: Masami Hiramatsu 
Cc: David S. Miller 
Signed-off-by: Oskar Andero 
Acked-by: Masami Hiramatsu 
---
 kernel/kprobes.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index b289384..08facfc 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -172,7 +172,7 @@ static void init_kprobe_blacklist(void)
kprobe_lookup_name(kretprobe_blacklist[i].name,
   kretprobe_blacklist[i].addr);
if (!kretprobe_blacklist[i].addr)
-   printk("kretprobe: lookup failed: %s\n",
+   pr_err("kretprobe: lookup failed: %s\n",
   kretprobe_blacklist[i].name);
}
}
@@ -787,7 +787,7 @@ static void reuse_unused_kprobe(struct kprobe *ap)
 */
op = container_of(ap, struct optimized_kprobe, kp);
if (unlikely(list_empty(>list)))
-   printk(KERN_WARNING "Warning: found a stray unused "
+   pr_warn("Warning: found a stray unused "
"aggrprobe@%p\n", ap->addr);
/* Enable the probe again */
ap->flags &= ~KPROBE_FLAG_DISABLED;
@@ -894,7 +894,7 @@ static void __kprobes optimize_all_kprobes(void)
if (!kprobe_disabled(p))
optimize_kprobe(p);
}
-   printk(KERN_INFO "Kprobes globally optimized\n");
+   pr_info("Kprobes globally optimized\n");
 }
 
 /* This should be called with kprobe_mutex locked */
@@ -918,7 +918,7 @@ static void __kprobes unoptimize_all_kprobes(void)
}
/* Wait for unoptimizing completion */
wait_for_kprobe_optimizer();
-   printk(KERN_INFO "Kprobes globally unoptimized\n");
+   pr_info("Kprobes globally unoptimized\n");
 }
 
 int sysctl_kprobes_optimization;
@@ -989,7 +989,7 @@ static void __kprobes __disarm_kprobe(struct kprobe *p, 
bool reopt)
 /* There should be no unused kprobes can be reused without optimization */
 static void reuse_unused_kprobe(struct kprobe *ap)
 {
-   printk(KERN_ERR "Error: There should be no unused kprobe here.\n");
+   pr_err("Error: There should be no unused kprobe here.\n");
BUG_ON(kprobe_unused(ap));
 }
 
@@ -2103,8 +2103,8 @@ EXPORT_SYMBOL_GPL(enable_kprobe);
 
 void __kprobes dump_kprobe(struct kprobe *kp)
 {
-   printk(KERN_WARNING "Dumping kprobe:\n");
-   printk(KERN_WARNING "Name: %s\nAddress: %p\nOffset: %x\n",
+   pr_warn("Dumping kprobe:\n");
+   pr_warn("Name: %s\nAddress: %p\nOffset: %x\n",
   kp->symbol_name, kp->addr, kp->offset);
 }
 
@@ -2300,7 +2300,7 @@ static void __kprobes arm_all_kprobes(void)
}
 
kprobes_all_disarmed = false;
-   printk(KERN_INFO "Kprobes globally enabled\n");
+   pr_info("Kprobes globally enabled\n");
 
 already_enabled:
mutex_unlock(_mutex);
@@ -2322,7 +2322,7 @@ static void __kprobes disarm_all_kprobes(void)
}
 
kprobes_all_disarmed = true;
-   printk(KERN_INFO "Kprobes globally disabled\n");
+   pr_info("Kprobes globally disabled\n");
 
for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
head = _table[i];
-- 
1.8.1.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: Re: [PATCH v2 1/4] kprobes: delay blacklist symbol lookup until we actually need it

2013-04-05 Thread Oskar Andero
Thanks for your input guys!

On 04:16 Fri 05 Apr , Masami Hiramatsu wrote:
> (2013/04/05 9:56), Joonsoo Kim wrote:
> > Hello, Oskar.
> > 
> > On Thu, Apr 04, 2013 at 02:51:26PM +0200, Oskar Andero wrote:
> >> From: Toby Collett 
> >>
> >> The symbol lookup can take a long time and kprobes is
> >> initialised very early in boot, so delay symbol lookup
> >> until the blacklist is first used.
> >>
> >> Cc: Masami Hiramatsu 
> >> Cc: David S. Miller 
> >> Reviewed-by: Radovan Lekanovic 
> >> Signed-off-by: Toby Collett 
> >> Signed-off-by: Oskar Andero 
> >> ---
> >>  kernel/kprobes.c | 98 
> >> ++--
> >>  1 file changed, 60 insertions(+), 38 deletions(-)
> >>
> >> diff --git a/kernel/kprobes.c b/kernel/kprobes.c
> >> index e35be53..0a270e5 100644
> >> --- a/kernel/kprobes.c
> >> +++ b/kernel/kprobes.c
> >> @@ -68,6 +68,7 @@
> >>  #endif
> >>  
> >>  static int kprobes_initialized;
> >> +static int kprobe_blacklist_initialized;
> >>  static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE];
> >>  static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE];
> >>  
> >> @@ -102,6 +103,60 @@ static struct kprobe_blackpoint kprobe_blacklist[] = {
> >>{NULL}/* Terminator */
> >>  };
> >>  
> >> +/* it can take some time ( > 100ms ) to initialise the
> >> + * blacklist so we delay this until we actually need it
> >> + */
> >> +static void init_kprobe_blacklist(void)
> >> +{
> >> +  int i;
> >> +  unsigned long offset = 0, size = 0;
> >> +  char *modname, namebuf[128];
> >> +  const char *symbol_name;
> >> +  void *addr;
> >> +  struct kprobe_blackpoint *kb;
> >> +
> >> +  mutex_lock(_mutex);
> >> +  if (kprobe_blacklist_initialized)
> >> +  goto out;
> >> +
> >> +  /*
> >> +   * Lookup and populate the kprobe_blacklist.
> >> +   *
> >> +   * Unlike the kretprobe blacklist, we'll need to determine
> >> +   * the range of addresses that belong to the said functions,
> >> +   * since a kprobe need not necessarily be at the beginning
> >> +   * of a function.
> >> +   */
> >> +  for (kb = kprobe_blacklist; kb->name != NULL; kb++) {
> >> +  kprobe_lookup_name(kb->name, addr);
> >> +  if (!addr)
> >> +  continue;
> >> +
> >> +  kb->start_addr = (unsigned long)addr;
> >> +  symbol_name = kallsyms_lookup(kb->start_addr,
> >> +  , , , namebuf);
> >> +  if (!symbol_name)
> >> +  kb->range = 0;
> >> +  else
> >> +  kb->range = size;
> >> +  }
> >> +
> >> +  if (kretprobe_blacklist_size) {
> >> +  /* lookup the function address from its name */
> >> +  for (i = 0; kretprobe_blacklist[i].name != NULL; i++) {
> >> +  kprobe_lookup_name(kretprobe_blacklist[i].name,
> >> + kretprobe_blacklist[i].addr);
> >> +  if (!kretprobe_blacklist[i].addr)
> >> +  printk("kretprobe: lookup failed: %s\n",
> >> + kretprobe_blacklist[i].name);
> >> +  }
> >> +  }
> >> +  kprobe_blacklist_initialized = 1;
> > 
> > You need smp_wmb() before assigning 'kprobe_blacklist_initialized = 1'.
> > This guarantee that who see kprobe_blacklist_initialized = 1 will get
> > updated data of kprobe_blacklist.
> 
> Right, to ensure blacklist is updated, memory barrier is required.

Agreed.

> > Please refer my previous patch once more :)
> > 
> > And How about define kprobe_blacklist_initialized as boolean?
> 
> Good idea :)
> 

I'll fix it for v3.

-Oskar
> 
--
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] input: don't call input_dev_release_keys() in resume

2013-04-05 Thread Oskar Andero
On 18:33 Thu 04 Apr , Dmitry Torokhov wrote:
> Hi Oskar,
> 
> On Thu, Mar 07, 2013 at 03:01:22PM +0100, oskar.and...@sonymobile.com wrote:
> > From: Aleksej Makarov 
> > 
> > When waking up the platform by pressing a specific key, sending a
> > release on that key makes it impossible to react on the event in
> > user-space.
> > 
> 
> No, we can not simply not release keys after resume from suspend, as
> this leads to keys being stuck. Consider you are holding an 'I' key on
> your external USB keyboard and close your laptop's lid. Then you release
> the key and leave. Later you come back, open the lid waking the laptop
> and observe endless stream of 'I' in your open terminal.

You're absolutely right. But I guess you also see the case that the
patch is trying to fix, right?

To explain our use-case: We have a physical camera button on some devices.
When the user long-presses the button, the system will wake up and jump
directly in to the camera application.

> Maybe we should release the keys during suspend time? I am not sure how
> Android infrastructure will react to this though...

That sounds like a good idea! Let me do some testing on that.

Thanks!

-Oskar
--
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] input: don't call input_dev_release_keys() in resume

2013-04-05 Thread Oskar Andero
On 18:33 Thu 04 Apr , Dmitry Torokhov wrote:
 Hi Oskar,
 
 On Thu, Mar 07, 2013 at 03:01:22PM +0100, oskar.and...@sonymobile.com wrote:
  From: Aleksej Makarov aleksej.maka...@sonymobile.com
  
  When waking up the platform by pressing a specific key, sending a
  release on that key makes it impossible to react on the event in
  user-space.
  
 
 No, we can not simply not release keys after resume from suspend, as
 this leads to keys being stuck. Consider you are holding an 'I' key on
 your external USB keyboard and close your laptop's lid. Then you release
 the key and leave. Later you come back, open the lid waking the laptop
 and observe endless stream of 'I' in your open terminal.

You're absolutely right. But I guess you also see the case that the
patch is trying to fix, right?

To explain our use-case: We have a physical camera button on some devices.
When the user long-presses the button, the system will wake up and jump
directly in to the camera application.

 Maybe we should release the keys during suspend time? I am not sure how
 Android infrastructure will react to this though...

That sounds like a good idea! Let me do some testing on that.

Thanks!

-Oskar
--
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: Re: [PATCH v2 1/4] kprobes: delay blacklist symbol lookup until we actually need it

2013-04-05 Thread Oskar Andero
Thanks for your input guys!

On 04:16 Fri 05 Apr , Masami Hiramatsu wrote:
 (2013/04/05 9:56), Joonsoo Kim wrote:
  Hello, Oskar.
  
  On Thu, Apr 04, 2013 at 02:51:26PM +0200, Oskar Andero wrote:
  From: Toby Collett toby.coll...@sonymobile.com
 
  The symbol lookup can take a long time and kprobes is
  initialised very early in boot, so delay symbol lookup
  until the blacklist is first used.
 
  Cc: Masami Hiramatsu masami.hiramatsu...@hitachi.com
  Cc: David S. Miller da...@davemloft.net
  Reviewed-by: Radovan Lekanovic radovan.lekano...@sonymobile.com
  Signed-off-by: Toby Collett toby.coll...@sonymobile.com
  Signed-off-by: Oskar Andero oskar.and...@sonymobile.com
  ---
   kernel/kprobes.c | 98 
  ++--
   1 file changed, 60 insertions(+), 38 deletions(-)
 
  diff --git a/kernel/kprobes.c b/kernel/kprobes.c
  index e35be53..0a270e5 100644
  --- a/kernel/kprobes.c
  +++ b/kernel/kprobes.c
  @@ -68,6 +68,7 @@
   #endif
   
   static int kprobes_initialized;
  +static int kprobe_blacklist_initialized;
   static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE];
   static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE];
   
  @@ -102,6 +103,60 @@ static struct kprobe_blackpoint kprobe_blacklist[] = {
 {NULL}/* Terminator */
   };
   
  +/* it can take some time (  100ms ) to initialise the
  + * blacklist so we delay this until we actually need it
  + */
  +static void init_kprobe_blacklist(void)
  +{
  +  int i;
  +  unsigned long offset = 0, size = 0;
  +  char *modname, namebuf[128];
  +  const char *symbol_name;
  +  void *addr;
  +  struct kprobe_blackpoint *kb;
  +
  +  mutex_lock(kprobe_mutex);
  +  if (kprobe_blacklist_initialized)
  +  goto out;
  +
  +  /*
  +   * Lookup and populate the kprobe_blacklist.
  +   *
  +   * Unlike the kretprobe blacklist, we'll need to determine
  +   * the range of addresses that belong to the said functions,
  +   * since a kprobe need not necessarily be at the beginning
  +   * of a function.
  +   */
  +  for (kb = kprobe_blacklist; kb-name != NULL; kb++) {
  +  kprobe_lookup_name(kb-name, addr);
  +  if (!addr)
  +  continue;
  +
  +  kb-start_addr = (unsigned long)addr;
  +  symbol_name = kallsyms_lookup(kb-start_addr,
  +  size, offset, modname, namebuf);
  +  if (!symbol_name)
  +  kb-range = 0;
  +  else
  +  kb-range = size;
  +  }
  +
  +  if (kretprobe_blacklist_size) {
  +  /* lookup the function address from its name */
  +  for (i = 0; kretprobe_blacklist[i].name != NULL; i++) {
  +  kprobe_lookup_name(kretprobe_blacklist[i].name,
  + kretprobe_blacklist[i].addr);
  +  if (!kretprobe_blacklist[i].addr)
  +  printk(kretprobe: lookup failed: %s\n,
  + kretprobe_blacklist[i].name);
  +  }
  +  }
  +  kprobe_blacklist_initialized = 1;
  
  You need smp_wmb() before assigning 'kprobe_blacklist_initialized = 1'.
  This guarantee that who see kprobe_blacklist_initialized = 1 will get
  updated data of kprobe_blacklist.
 
 Right, to ensure blacklist is updated, memory barrier is required.

Agreed.

  Please refer my previous patch once more :)
  
  And How about define kprobe_blacklist_initialized as boolean?
 
 Good idea :)
 

I'll fix it for v3.

-Oskar
 
--
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 v3 4/4] kprobes: replace printk with pr_-functions

2013-04-05 Thread Oskar Andero
Instead of using printk use pr_info/pr_err/pr_warn. This was
detected by the checkpatch.pl script.

Cc: Masami Hiramatsu masami.hiramatsu...@hitachi.com
Cc: David S. Miller da...@davemloft.net
Signed-off-by: Oskar Andero oskar.and...@sonymobile.com
Acked-by: Masami Hiramatsu masami.hiramatsu...@hitachi.com
---
 kernel/kprobes.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index b289384..08facfc 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -172,7 +172,7 @@ static void init_kprobe_blacklist(void)
kprobe_lookup_name(kretprobe_blacklist[i].name,
   kretprobe_blacklist[i].addr);
if (!kretprobe_blacklist[i].addr)
-   printk(kretprobe: lookup failed: %s\n,
+   pr_err(kretprobe: lookup failed: %s\n,
   kretprobe_blacklist[i].name);
}
}
@@ -787,7 +787,7 @@ static void reuse_unused_kprobe(struct kprobe *ap)
 */
op = container_of(ap, struct optimized_kprobe, kp);
if (unlikely(list_empty(op-list)))
-   printk(KERN_WARNING Warning: found a stray unused 
+   pr_warn(Warning: found a stray unused 
aggrprobe@%p\n, ap-addr);
/* Enable the probe again */
ap-flags = ~KPROBE_FLAG_DISABLED;
@@ -894,7 +894,7 @@ static void __kprobes optimize_all_kprobes(void)
if (!kprobe_disabled(p))
optimize_kprobe(p);
}
-   printk(KERN_INFO Kprobes globally optimized\n);
+   pr_info(Kprobes globally optimized\n);
 }
 
 /* This should be called with kprobe_mutex locked */
@@ -918,7 +918,7 @@ static void __kprobes unoptimize_all_kprobes(void)
}
/* Wait for unoptimizing completion */
wait_for_kprobe_optimizer();
-   printk(KERN_INFO Kprobes globally unoptimized\n);
+   pr_info(Kprobes globally unoptimized\n);
 }
 
 int sysctl_kprobes_optimization;
@@ -989,7 +989,7 @@ static void __kprobes __disarm_kprobe(struct kprobe *p, 
bool reopt)
 /* There should be no unused kprobes can be reused without optimization */
 static void reuse_unused_kprobe(struct kprobe *ap)
 {
-   printk(KERN_ERR Error: There should be no unused kprobe here.\n);
+   pr_err(Error: There should be no unused kprobe here.\n);
BUG_ON(kprobe_unused(ap));
 }
 
@@ -2103,8 +2103,8 @@ EXPORT_SYMBOL_GPL(enable_kprobe);
 
 void __kprobes dump_kprobe(struct kprobe *kp)
 {
-   printk(KERN_WARNING Dumping kprobe:\n);
-   printk(KERN_WARNING Name: %s\nAddress: %p\nOffset: %x\n,
+   pr_warn(Dumping kprobe:\n);
+   pr_warn(Name: %s\nAddress: %p\nOffset: %x\n,
   kp-symbol_name, kp-addr, kp-offset);
 }
 
@@ -2300,7 +2300,7 @@ static void __kprobes arm_all_kprobes(void)
}
 
kprobes_all_disarmed = false;
-   printk(KERN_INFO Kprobes globally enabled\n);
+   pr_info(Kprobes globally enabled\n);
 
 already_enabled:
mutex_unlock(kprobe_mutex);
@@ -2322,7 +2322,7 @@ static void __kprobes disarm_all_kprobes(void)
}
 
kprobes_all_disarmed = true;
-   printk(KERN_INFO Kprobes globally disabled\n);
+   pr_info(Kprobes globally disabled\n);
 
for (i = 0; i  KPROBE_TABLE_SIZE; i++) {
head = kprobe_table[i];
-- 
1.8.1.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/


[PATCH v3 0/4] kprobes: split blacklist into common and arch

2013-04-05 Thread Oskar Andero
Hi,

This is version 3 of the patch-set for splitting arch and common kprobe
blackpoints.

Changes since last version are:
- 1/4: Add write memory barrier at blacklist initialization.
- 1/4: Change kprobe_blacklist_initialized type to boolean.
- 2/4: Fix racing of kprobe_blacklist.
- 2/4: Define arch_kprobes_blacksyms.* as __weak symbols.

-Oskar

Björn Davidsson (1):
  kprobes: move x86-specific blacklist symbols to arch directory

Oskar Andero (2):
  kprobes: split blacklist into common and arch
  kprobes: replace printk with pr_-functions

Toby Collett (1):
  kprobes: delay blacklist symbol lookup until we actually need it

 arch/x86/kernel/kprobes/core.c |   7 ++
 kernel/kprobes.c   | 159 +++--
 2 files changed, 112 insertions(+), 54 deletions(-)

-- 
1.8.1.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/


[PATCH v3 2/4] kprobes: split blacklist into common and arch

2013-04-05 Thread Oskar Andero
Some blackpoints are only valid for specific architectures. To let each
architecture specify its own blackpoints the list has been split in two
lists: common and arch. The common list is kept in kernel/kprobes.c and
the arch list is kept in the arch/ directory.

Cc: Masami Hiramatsu masami.hiramatsu...@hitachi.com
Cc: David S. Miller da...@davemloft.net
Cc: linux-a...@vger.kernel.org
Signed-off-by: Oskar Andero oskar.and...@sonymobile.com
---
 kernel/kprobes.c | 88 +---
 1 file changed, 59 insertions(+), 29 deletions(-)

diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index c8c2281..2458ae1 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -68,7 +68,6 @@
 #endif
 
 static int kprobes_initialized;
-static bool kprobe_blacklist_initialized;
 static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE];
 static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE];
 
@@ -94,31 +93,64 @@ static raw_spinlock_t *kretprobe_table_lock_ptr(unsigned 
long hash)
  *
  * For such cases, we now have a blacklist
  */
-static struct kprobe_blackpoint kprobe_blacklist[] = {
-   {preempt_schedule,},
-   {native_get_debugreg,},
-   {irq_entries_start,},
-   {common_interrupt,},
-   {mcount,},/* mcount can be called from everywhere */
-   {NULL}/* Terminator */
+static const char * const common_kprobes_blacksyms[] = {
+   preempt_schedule,
+   native_get_debugreg,
+   irq_entries_start,
+   common_interrupt,
+   mcount,   /* mcount can be called from everywhere */
 };
+static const size_t common_kprobes_blacksyms_size =
+   ARRAY_SIZE(common_kprobes_blacksyms);
+
+/*
+ * These weak symbols can be overridden from the arch/ directory for
+ * architecure specific blackpoints.
+ */
+const char * const __weak arch_kprobes_blacksyms[] = {};
+const size_t __weak arch_kprobes_blacksyms_size;
+
+static struct kprobe_blackpoint *kprobe_blacklist;
+static size_t kprobe_blacklist_size;
+
+static void init_kprobe_blacklist_entry(struct kprobe_blackpoint *kb,
+   const char * const name)
+{
+   const char *symbol_name;
+   char *modname, namebuf[128];
+   void *addr;
+   unsigned long offset = 0, size = 0;
+
+   kb-name = name;
+   kprobe_lookup_name(kb-name, addr);
+   if (!addr)
+   return;
+
+   kb-start_addr = (unsigned long)addr;
+   symbol_name = kallsyms_lookup(kb-start_addr,
+   size, offset, modname, namebuf);
+   if (!symbol_name)
+   kb-range = 0;
+   else
+   kb-range = size;
+}
 
 /* it can take some time (  100ms ) to initialise the
  * blacklist so we delay this until we actually need it
  */
 static void init_kprobe_blacklist(void)
 {
-   int i;
-   unsigned long offset = 0, size = 0;
-   char *modname, namebuf[128];
-   const char *symbol_name;
-   void *addr;
+   int i, j = 0;
struct kprobe_blackpoint *kb;
 
mutex_lock(kprobe_mutex);
-   if (kprobe_blacklist_initialized)
+   if (kprobe_blacklist)
goto out;
 
+   kprobe_blacklist_size = common_kprobes_blacksyms_size +
+   arch_kprobes_blacksyms_size;
+   kb = kzalloc(sizeof(*kb) * kprobe_blacklist_size, GFP_KERNEL);
+
/*
 * Lookup and populate the kprobe_blacklist.
 *
@@ -127,18 +159,14 @@ static void init_kprobe_blacklist(void)
 * since a kprobe need not necessarily be at the beginning
 * of a function.
 */
-   for (kb = kprobe_blacklist; kb-name != NULL; kb++) {
-   kprobe_lookup_name(kb-name, addr);
-   if (!addr)
-   continue;
+   for (i = 0; i  common_kprobes_blacksyms_size; i++, j++) {
+   init_kprobe_blacklist_entry(kb[j],
+   common_kprobes_blacksyms[i]);
+   }
 
-   kb-start_addr = (unsigned long)addr;
-   symbol_name = kallsyms_lookup(kb-start_addr,
-   size, offset, modname, namebuf);
-   if (!symbol_name)
-   kb-range = 0;
-   else
-   kb-range = size;
+   for (i = 0; i  arch_kprobes_blacksyms_size; i++, j++) {
+   init_kprobe_blacklist_entry(kb[j],
+   arch_kprobes_blacksyms[i]);
}
 
if (kretprobe_blacklist_size) {
@@ -153,7 +181,7 @@ static void init_kprobe_blacklist(void)
}
 
smp_wmb();
-   kprobe_blacklist_initialized = true;
+   kprobe_blacklist = kb;
 
 out:
mutex_unlock(kprobe_mutex);
@@ -1384,18 +1412,20 @@ out:
 static int __kprobes in_kprobes_functions(unsigned long addr)
 {
struct kprobe_blackpoint *kb;
+   int i;
 
if (addr = (unsigned long)__kprobes_text_start 
addr  (unsigned long

[PATCH v3 3/4] kprobes: move x86-specific blacklist symbols to arch directory

2013-04-05 Thread Oskar Andero
From: Björn Davidsson bjorn.davids...@sonymobile.com

The common kprobes blacklist contains x86-specific symbols.
Looking for these in kallsyms takes unnecessary time during startup
on non-X86 platform. The symbols where moved to
arch/x86/kernel/kprobes/core.c.

Cc: Masami Hiramatsu masami.hiramatsu...@hitachi.com
Cc: David S. Miller da...@davemloft.net
Cc: linux-a...@vger.kernel.org
Reviewed-by: Radovan Lekanovic radovan.lekano...@sonymobile.com
Signed-off-by: Björn Davidsson bjorn.davids...@sonymobile.com
Signed-off-by: Oskar Andero oskar.and...@sonymobile.com
Acked-by: Masami Hiramatsu masami.hiramatsu...@hitachi.com
---
 arch/x86/kernel/kprobes/core.c | 7 +++
 kernel/kprobes.c   | 3 ---
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c
index 7bfe318..41ce6c1 100644
--- a/arch/x86/kernel/kprobes/core.c
+++ b/arch/x86/kernel/kprobes/core.c
@@ -65,6 +65,13 @@ void jprobe_return_end(void);
 DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
 DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
 
+const char * const arch_kprobes_blacksyms[] = {
+   native_get_debugreg,
+   irq_entries_start,
+   common_interrupt,
+};
+const size_t arch_kprobes_blacksyms_size = ARRAY_SIZE(arch_kprobes_blacksyms);
+
 #define stack_addr(regs) ((unsigned long *)kernel_stack_pointer(regs))
 
 #define W(row, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf)\
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 2458ae1..b289384 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -95,9 +95,6 @@ static raw_spinlock_t *kretprobe_table_lock_ptr(unsigned long 
hash)
  */
 static const char * const common_kprobes_blacksyms[] = {
preempt_schedule,
-   native_get_debugreg,
-   irq_entries_start,
-   common_interrupt,
mcount,   /* mcount can be called from everywhere */
 };
 static const size_t common_kprobes_blacksyms_size =
-- 
1.8.1.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/


[PATCH v3 1/4] kprobes: delay blacklist symbol lookup until we actually need it

2013-04-05 Thread Oskar Andero
From: Toby Collett toby.coll...@sonymobile.com

The symbol lookup can take a long time and kprobes is
initialised very early in boot, so delay symbol lookup
until the blacklist is first used.

Cc: Masami Hiramatsu masami.hiramatsu...@hitachi.com
Cc: David S. Miller da...@davemloft.net
Reviewed-by: Radovan Lekanovic radovan.lekano...@sonymobile.com
Signed-off-by: Toby Collett toby.coll...@sonymobile.com
Signed-off-by: Oskar Andero oskar.and...@sonymobile.com
---
 kernel/kprobes.c | 100 ++-
 1 file changed, 62 insertions(+), 38 deletions(-)

diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index e35be53..c8c2281 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -68,6 +68,7 @@
 #endif
 
 static int kprobes_initialized;
+static bool kprobe_blacklist_initialized;
 static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE];
 static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE];
 
@@ -102,6 +103,62 @@ static struct kprobe_blackpoint kprobe_blacklist[] = {
{NULL}/* Terminator */
 };
 
+/* it can take some time (  100ms ) to initialise the
+ * blacklist so we delay this until we actually need it
+ */
+static void init_kprobe_blacklist(void)
+{
+   int i;
+   unsigned long offset = 0, size = 0;
+   char *modname, namebuf[128];
+   const char *symbol_name;
+   void *addr;
+   struct kprobe_blackpoint *kb;
+
+   mutex_lock(kprobe_mutex);
+   if (kprobe_blacklist_initialized)
+   goto out;
+
+   /*
+* Lookup and populate the kprobe_blacklist.
+*
+* Unlike the kretprobe blacklist, we'll need to determine
+* the range of addresses that belong to the said functions,
+* since a kprobe need not necessarily be at the beginning
+* of a function.
+*/
+   for (kb = kprobe_blacklist; kb-name != NULL; kb++) {
+   kprobe_lookup_name(kb-name, addr);
+   if (!addr)
+   continue;
+
+   kb-start_addr = (unsigned long)addr;
+   symbol_name = kallsyms_lookup(kb-start_addr,
+   size, offset, modname, namebuf);
+   if (!symbol_name)
+   kb-range = 0;
+   else
+   kb-range = size;
+   }
+
+   if (kretprobe_blacklist_size) {
+   /* lookup the function address from its name */
+   for (i = 0; kretprobe_blacklist[i].name != NULL; i++) {
+   kprobe_lookup_name(kretprobe_blacklist[i].name,
+  kretprobe_blacklist[i].addr);
+   if (!kretprobe_blacklist[i].addr)
+   printk(kretprobe: lookup failed: %s\n,
+  kretprobe_blacklist[i].name);
+   }
+   }
+
+   smp_wmb();
+   kprobe_blacklist_initialized = true;
+
+out:
+   mutex_unlock(kprobe_mutex);
+}
+
 #ifdef __ARCH_WANT_KPROBES_INSN_SLOT
 /*
  * kprobe-ainsn.insn points to the copy of the instruction to be
@@ -1331,6 +1388,9 @@ static int __kprobes in_kprobes_functions(unsigned long 
addr)
if (addr = (unsigned long)__kprobes_text_start 
addr  (unsigned long)__kprobes_text_end)
return -EINVAL;
+
+   if (unlikely(!kprobe_blacklist_initialized))
+   init_kprobe_blacklist();
/*
 * If there exists a kprobe_blacklist, verify and
 * fail any probe registration in the prohibited area
@@ -1816,6 +1876,8 @@ int __kprobes register_kretprobe(struct kretprobe *rp)
void *addr;
 
if (kretprobe_blacklist_size) {
+   if (unlikely(!kprobe_blacklist_initialized))
+   init_kprobe_blacklist();
addr = kprobe_addr(rp-kp);
if (IS_ERR(addr))
return PTR_ERR(addr);
@@ -2065,11 +2127,6 @@ static struct notifier_block kprobe_module_nb = {
 static int __init init_kprobes(void)
 {
int i, err = 0;
-   unsigned long offset = 0, size = 0;
-   char *modname, namebuf[128];
-   const char *symbol_name;
-   void *addr;
-   struct kprobe_blackpoint *kb;
 
/* FIXME allocate the probe table, currently defined statically */
/* initialize all list heads */
@@ -2079,39 +2136,6 @@ static int __init init_kprobes(void)
raw_spin_lock_init((kretprobe_table_locks[i].lock));
}
 
-   /*
-* Lookup and populate the kprobe_blacklist.
-*
-* Unlike the kretprobe blacklist, we'll need to determine
-* the range of addresses that belong to the said functions,
-* since a kprobe need not necessarily be at the beginning
-* of a function.
-*/
-   for (kb = kprobe_blacklist; kb-name != NULL; kb++) {
-   kprobe_lookup_name(kb-name, addr);
-   if (!addr)
-   continue

Re: [PATCH] input: don't call input_dev_release_keys() in resume

2013-04-04 Thread Oskar Andero
On 15:01 Thu 07 Mar , oskar.and...@sonymobile.com wrote:
> From: Aleksej Makarov 
> 
> When waking up the platform by pressing a specific key, sending a
> release on that key makes it impossible to react on the event in
> user-space.
> 
> Cc: Dmitry Torokhov 
> Reviewed-by: Radovan Lekanovic 
> Signed-off-by: Aleksej Makarov 
> Signed-off-by: Oskar Andero 
> ---
>  drivers/input/input.c |5 -
>  1 files changed, 4 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/input/input.c b/drivers/input/input.c
> index c044699..61ce19f 100644
> --- a/drivers/input/input.c
> +++ b/drivers/input/input.c
> @@ -1690,7 +1690,10 @@ static int input_dev_resume(struct device *dev)
>  {
>   struct input_dev *input_dev = to_input_dev(dev);
>  
> - input_reset_device(input_dev);
> + mutex_lock(_dev->mutex);
> + if (input_dev->users)
> + input_dev_toggle(input_dev, true);
> + mutex_unlock(_dev->mutex);
>  
>   return 0;
>  }
> -- 
> 1.7.8.6
> 

Ping. Any input on the patch above?

-Oskar
--
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 v2 2/4] kprobes: split blacklist into common and arch

2013-04-04 Thread Oskar Andero
Some blackpoints are only valid for specific architectures. To let each
architecture specify its own blackpoints the list has been split in two
lists: common and arch. The common list is kept in kernel/kprobes.c and
the arch list is kept in the arch/ directory.

Cc: Masami Hiramatsu 
Cc: David S. Miller 
Cc: linux-a...@vger.kernel.org
Signed-off-by: Oskar Andero 
---
 arch/arc/kernel/kprobes.c  |  3 ++
 arch/arm/kernel/kprobes.c  |  2 +
 arch/avr32/kernel/kprobes.c|  3 ++
 arch/ia64/kernel/kprobes.c |  3 ++
 arch/mips/kernel/kprobes.c |  3 ++
 arch/mn10300/kernel/kprobes.c  |  2 +
 arch/powerpc/kernel/kprobes.c  |  3 ++
 arch/s390/kernel/kprobes.c |  3 ++
 arch/sh/kernel/kprobes.c   |  3 ++
 arch/sparc/kernel/kprobes.c|  3 ++
 arch/x86/kernel/kprobes/core.c |  3 ++
 kernel/kprobes.c   | 85 +++---
 12 files changed, 86 insertions(+), 30 deletions(-)

diff --git a/arch/arc/kernel/kprobes.c b/arch/arc/kernel/kprobes.c
index 3bfeacb..894eee6 100644
--- a/arch/arc/kernel/kprobes.c
+++ b/arch/arc/kernel/kprobes.c
@@ -24,6 +24,9 @@
 DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
 DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
 
+const char * const arch_kprobes_blacksyms[] = {};
+const size_t arch_kprobes_blacksyms_size = ARRAY_SIZE(arch_kprobes_blacksyms);
+
 int __kprobes arch_prepare_kprobe(struct kprobe *p)
 {
/* Attempt to probe at unaligned address */
diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/kernel/kprobes.c
index 170e9f3..772d9ec 100644
--- a/arch/arm/kernel/kprobes.c
+++ b/arch/arm/kernel/kprobes.c
@@ -46,6 +46,8 @@
 DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
 DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
 
+const char * const arch_kprobes_blacksyms[] = {};
+const size_t arch_kprobes_blacksyms_size = ARRAY_SIZE(arch_kprobes_blacksyms);
 
 int __kprobes arch_prepare_kprobe(struct kprobe *p)
 {
diff --git a/arch/avr32/kernel/kprobes.c b/arch/avr32/kernel/kprobes.c
index f820e9f..3b02c1e 100644
--- a/arch/avr32/kernel/kprobes.c
+++ b/arch/avr32/kernel/kprobes.c
@@ -24,6 +24,9 @@ static struct pt_regs jprobe_saved_regs;
 
 struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}};
 
+const char * const arch_kprobes_blacksyms[] = {};
+const size_t arch_kprobes_blacksyms_size = ARRAY_SIZE(arch_kprobes_blacksyms);
+
 int __kprobes arch_prepare_kprobe(struct kprobe *p)
 {
int ret = 0;
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c
index f8280a7..239f2fd 100644
--- a/arch/ia64/kernel/kprobes.c
+++ b/arch/ia64/kernel/kprobes.c
@@ -42,6 +42,9 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
 
 struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}};
 
+const char * const arch_kprobes_blacksyms[] = {};
+const size_t arch_kprobes_blacksyms_size = ARRAY_SIZE(arch_kprobes_blacksyms);
+
 enum instruction_type {A, I, M, F, B, L, X, u};
 static enum instruction_type bundle_encoding[32][3] = {
   { M, I, I }, /* 00 */
diff --git a/arch/mips/kernel/kprobes.c b/arch/mips/kernel/kprobes.c
index 12bc4eb..de6a1aa 100644
--- a/arch/mips/kernel/kprobes.c
+++ b/arch/mips/kernel/kprobes.c
@@ -53,6 +53,9 @@ static const union mips_instruction breakpoint2_insn = {
 DEFINE_PER_CPU(struct kprobe *, current_kprobe);
 DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
 
+const char * const arch_kprobes_blacksyms[] = {};
+const size_t arch_kprobes_blacksyms_size = ARRAY_SIZE(arch_kprobes_blacksyms);
+
 static int __kprobes insn_has_delayslot(union mips_instruction insn)
 {
switch (insn.i_format.opcode) {
diff --git a/arch/mn10300/kernel/kprobes.c b/arch/mn10300/kernel/kprobes.c
index 0311a7f..ed57094 100644
--- a/arch/mn10300/kernel/kprobes.c
+++ b/arch/mn10300/kernel/kprobes.c
@@ -41,6 +41,8 @@ static unsigned long cur_kprobe_bp_addr;
 
 DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
 
+const char * const arch_kprobes_blacksyms[] = {};
+const size_t arch_kprobes_blacksyms_size = ARRAY_SIZE(arch_kprobes_blacksyms);
 
 /* singlestep flag bits */
 #define SINGLESTEP_BRANCH 1
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index 11f5b03..b18ba45 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -47,6 +47,9 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
 
 struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}};
 
+const char * const arch_kprobes_blacksyms[] = {};
+const size_t arch_kprobes_blacksyms_size = ARRAY_SIZE(arch_kprobes_blacksyms);
+
 int __kprobes arch_prepare_kprobe(struct kprobe *p)
 {
int ret = 0;
diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c
index 3388b2b..2077bb0 100644
--- a/arch/s390/kernel/kprobes.c
+++ b/arch/s390/kernel/kprobes.c
@@ -37,6 +37,9 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
 
 struct kretprobe_blackpoint kretprobe_blacklist[] = { };
 
+const char * const

[PATCH v2 3/4] kprobes: move x86-specific blacklist symbols to arch directory

2013-04-04 Thread Oskar Andero
From: Björn Davidsson 

The common kprobes blacklist contains x86-specific symbols.
Looking for these in kallsyms takes unnecessary time during startup
on non-X86 platform. The symbols where moved to
arch/x86/kernel/kprobes/core.c.

Cc: Masami Hiramatsu 
Cc: David S. Miller 
Cc: linux-a...@vger.kernel.org
Reviewed-by: Radovan Lekanovic 
Signed-off-by: Björn Davidsson 
Signed-off-by: Oskar Andero 
---
 arch/x86/kernel/kprobes/core.c | 6 +-
 kernel/kprobes.c   | 3 ---
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c
index 4aa71a5..41ce6c1 100644
--- a/arch/x86/kernel/kprobes/core.c
+++ b/arch/x86/kernel/kprobes/core.c
@@ -65,7 +65,11 @@ void jprobe_return_end(void);
 DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
 DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
 
-const char * const arch_kprobes_blacksyms[] = {};
+const char * const arch_kprobes_blacksyms[] = {
+   "native_get_debugreg",
+   "irq_entries_start",
+   "common_interrupt",
+};
 const size_t arch_kprobes_blacksyms_size = ARRAY_SIZE(arch_kprobes_blacksyms);
 
 #define stack_addr(regs) ((unsigned long *)kernel_stack_pointer(regs))
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 7654278..58c9f4e 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -95,9 +95,6 @@ static raw_spinlock_t *kretprobe_table_lock_ptr(unsigned long 
hash)
  */
 static const char * const common_kprobes_blacksyms[] = {
"preempt_schedule",
-   "native_get_debugreg",
-   "irq_entries_start",
-   "common_interrupt",
"mcount",   /* mcount can be called from everywhere */
 };
 static const size_t common_kprobes_blacksyms_size =
-- 
1.8.1.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/


[PATCH v2 0/4] kprobes: split blacklist into common and arch

2013-04-04 Thread Oskar Andero
Hi,

This is version 2 of the patch-set for splitting arch and common kprobe
blackpoints.

Changes since last version are:
- Don't use double pointer for blacklist.
- Add mutex around blacklist initialization code.
- Use unlikely in if-statement around init_kprobe_blacklist() calls.

I have also included linux-arch in Cc for this post.

-Oskar

Björn Davidsson (1):
  kprobes: move x86-specific blacklist symbols to arch directory

Oskar Andero (2):
  kprobes: split blacklist into common and arch
  kprobes: replace printk with pr_-functions

Toby Collett (1):
  kprobes: delay blacklist symbol lookup until we actually need it

 arch/arc/kernel/kprobes.c  |   3 +
 arch/arm/kernel/kprobes.c  |   2 +
 arch/avr32/kernel/kprobes.c|   3 +
 arch/ia64/kernel/kprobes.c |   3 +
 arch/mips/kernel/kprobes.c |   3 +
 arch/mn10300/kernel/kprobes.c  |   2 +
 arch/powerpc/kernel/kprobes.c  |   3 +
 arch/s390/kernel/kprobes.c |   3 +
 arch/sh/kernel/kprobes.c   |   3 +
 arch/sparc/kernel/kprobes.c|   3 +
 arch/x86/kernel/kprobes/core.c |   7 ++
 kernel/kprobes.c   | 152 ++---
 12 files changed, 133 insertions(+), 54 deletions(-)

-- 
1.8.1.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/


[PATCH v2 1/4] kprobes: delay blacklist symbol lookup until we actually need it

2013-04-04 Thread Oskar Andero
From: Toby Collett 

The symbol lookup can take a long time and kprobes is
initialised very early in boot, so delay symbol lookup
until the blacklist is first used.

Cc: Masami Hiramatsu 
Cc: David S. Miller 
Reviewed-by: Radovan Lekanovic 
Signed-off-by: Toby Collett 
Signed-off-by: Oskar Andero 
---
 kernel/kprobes.c | 98 ++--
 1 file changed, 60 insertions(+), 38 deletions(-)

diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index e35be53..0a270e5 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -68,6 +68,7 @@
 #endif
 
 static int kprobes_initialized;
+static int kprobe_blacklist_initialized;
 static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE];
 static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE];
 
@@ -102,6 +103,60 @@ static struct kprobe_blackpoint kprobe_blacklist[] = {
{NULL}/* Terminator */
 };
 
+/* it can take some time ( > 100ms ) to initialise the
+ * blacklist so we delay this until we actually need it
+ */
+static void init_kprobe_blacklist(void)
+{
+   int i;
+   unsigned long offset = 0, size = 0;
+   char *modname, namebuf[128];
+   const char *symbol_name;
+   void *addr;
+   struct kprobe_blackpoint *kb;
+
+   mutex_lock(_mutex);
+   if (kprobe_blacklist_initialized)
+   goto out;
+
+   /*
+* Lookup and populate the kprobe_blacklist.
+*
+* Unlike the kretprobe blacklist, we'll need to determine
+* the range of addresses that belong to the said functions,
+* since a kprobe need not necessarily be at the beginning
+* of a function.
+*/
+   for (kb = kprobe_blacklist; kb->name != NULL; kb++) {
+   kprobe_lookup_name(kb->name, addr);
+   if (!addr)
+   continue;
+
+   kb->start_addr = (unsigned long)addr;
+   symbol_name = kallsyms_lookup(kb->start_addr,
+   , , , namebuf);
+   if (!symbol_name)
+   kb->range = 0;
+   else
+   kb->range = size;
+   }
+
+   if (kretprobe_blacklist_size) {
+   /* lookup the function address from its name */
+   for (i = 0; kretprobe_blacklist[i].name != NULL; i++) {
+   kprobe_lookup_name(kretprobe_blacklist[i].name,
+  kretprobe_blacklist[i].addr);
+   if (!kretprobe_blacklist[i].addr)
+   printk("kretprobe: lookup failed: %s\n",
+  kretprobe_blacklist[i].name);
+   }
+   }
+   kprobe_blacklist_initialized = 1;
+
+out:
+   mutex_unlock(_mutex);
+}
+
 #ifdef __ARCH_WANT_KPROBES_INSN_SLOT
 /*
  * kprobe->ainsn.insn points to the copy of the instruction to be
@@ -1331,6 +1386,9 @@ static int __kprobes in_kprobes_functions(unsigned long 
addr)
if (addr >= (unsigned long)__kprobes_text_start &&
addr < (unsigned long)__kprobes_text_end)
return -EINVAL;
+
+   if (unlikely(!kprobe_blacklist_initialized))
+   init_kprobe_blacklist();
/*
 * If there exists a kprobe_blacklist, verify and
 * fail any probe registration in the prohibited area
@@ -1816,6 +1874,8 @@ int __kprobes register_kretprobe(struct kretprobe *rp)
void *addr;
 
if (kretprobe_blacklist_size) {
+   if (unlikely(!kprobe_blacklist_initialized))
+   init_kprobe_blacklist();
addr = kprobe_addr(>kp);
if (IS_ERR(addr))
return PTR_ERR(addr);
@@ -2065,11 +2125,6 @@ static struct notifier_block kprobe_module_nb = {
 static int __init init_kprobes(void)
 {
int i, err = 0;
-   unsigned long offset = 0, size = 0;
-   char *modname, namebuf[128];
-   const char *symbol_name;
-   void *addr;
-   struct kprobe_blackpoint *kb;
 
/* FIXME allocate the probe table, currently defined statically */
/* initialize all list heads */
@@ -2079,39 +2134,6 @@ static int __init init_kprobes(void)
raw_spin_lock_init(&(kretprobe_table_locks[i].lock));
}
 
-   /*
-* Lookup and populate the kprobe_blacklist.
-*
-* Unlike the kretprobe blacklist, we'll need to determine
-* the range of addresses that belong to the said functions,
-* since a kprobe need not necessarily be at the beginning
-* of a function.
-*/
-   for (kb = kprobe_blacklist; kb->name != NULL; kb++) {
-   kprobe_lookup_name(kb->name, addr);
-   if (!addr)
-   continue;
-
-   kb->start_addr = (unsigned long)addr;
-   symbol_name = kallsyms_lookup(kb->start_addr,
-

[PATCH v2 4/4] kprobes: replace printk with pr_-functions

2013-04-04 Thread Oskar Andero
Instead of using printk use pr_info/pr_err/pr_warn. This was
detected by the checkpatch.pl script.

Cc: Masami Hiramatsu 
Cc: David S. Miller 
Signed-off-by: Oskar Andero 
Acked-by: Masami Hiramatsu 
---
 kernel/kprobes.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 58c9f4e..d61cbad 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -168,7 +168,7 @@ static void init_kprobe_blacklist(void)
kprobe_lookup_name(kretprobe_blacklist[i].name,
   kretprobe_blacklist[i].addr);
if (!kretprobe_blacklist[i].addr)
-   printk("kretprobe: lookup failed: %s\n",
+   pr_err("kretprobe: lookup failed: %s\n",
   kretprobe_blacklist[i].name);
}
}
@@ -780,7 +780,7 @@ static void reuse_unused_kprobe(struct kprobe *ap)
 */
op = container_of(ap, struct optimized_kprobe, kp);
if (unlikely(list_empty(>list)))
-   printk(KERN_WARNING "Warning: found a stray unused "
+   pr_warn("Warning: found a stray unused "
"aggrprobe@%p\n", ap->addr);
/* Enable the probe again */
ap->flags &= ~KPROBE_FLAG_DISABLED;
@@ -887,7 +887,7 @@ static void __kprobes optimize_all_kprobes(void)
if (!kprobe_disabled(p))
optimize_kprobe(p);
}
-   printk(KERN_INFO "Kprobes globally optimized\n");
+   pr_info("Kprobes globally optimized\n");
 }
 
 /* This should be called with kprobe_mutex locked */
@@ -911,7 +911,7 @@ static void __kprobes unoptimize_all_kprobes(void)
}
/* Wait for unoptimizing completion */
wait_for_kprobe_optimizer();
-   printk(KERN_INFO "Kprobes globally unoptimized\n");
+   pr_info("Kprobes globally unoptimized\n");
 }
 
 int sysctl_kprobes_optimization;
@@ -982,7 +982,7 @@ static void __kprobes __disarm_kprobe(struct kprobe *p, 
bool reopt)
 /* There should be no unused kprobes can be reused without optimization */
 static void reuse_unused_kprobe(struct kprobe *ap)
 {
-   printk(KERN_ERR "Error: There should be no unused kprobe here.\n");
+   pr_err("Error: There should be no unused kprobe here.\n");
BUG_ON(kprobe_unused(ap));
 }
 
@@ -2096,8 +2096,8 @@ EXPORT_SYMBOL_GPL(enable_kprobe);
 
 void __kprobes dump_kprobe(struct kprobe *kp)
 {
-   printk(KERN_WARNING "Dumping kprobe:\n");
-   printk(KERN_WARNING "Name: %s\nAddress: %p\nOffset: %x\n",
+   pr_warn("Dumping kprobe:\n");
+   pr_warn("Name: %s\nAddress: %p\nOffset: %x\n",
   kp->symbol_name, kp->addr, kp->offset);
 }
 
@@ -2293,7 +2293,7 @@ static void __kprobes arm_all_kprobes(void)
}
 
kprobes_all_disarmed = false;
-   printk(KERN_INFO "Kprobes globally enabled\n");
+   pr_info("Kprobes globally enabled\n");
 
 already_enabled:
mutex_unlock(_mutex);
@@ -2315,7 +2315,7 @@ static void __kprobes disarm_all_kprobes(void)
}
 
kprobes_all_disarmed = true;
-   printk(KERN_INFO "Kprobes globally disabled\n");
+   pr_info("Kprobes globally disabled\n");
 
for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
head = _table[i];
-- 
1.8.1.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 2/4] kprobes: split blacklist into common and arch

2013-04-04 Thread Oskar Andero
On 08:17 Thu 04 Apr , Masami Hiramatsu wrote:
> (2013/04/03 17:28), oskar.and...@sonymobile.com wrote:
> > Some blackpoints are only valid for specific architectures. To let each
> > architecture specify its own blackpoints the list has been split in two
> > lists: common and arch. The common list is kept in kernel/kprobes.c and
> > the arch list is kept in the arch/ directory.
> 
> Hmm, I think you'd better merge this with patch 3/4.

IMHO I think it's more logical to keep them separated instead of
squashing a generic patch with an architecture specific patch.
Also, there is the matter of authorship and credits.

Of course, it's your call, so let me know if this is ok with you.

> [...]
> > +static const size_t common_kprobes_blacksyms_size =
> > +   ARRAY_SIZE(common_kprobes_blacksyms);
> > +
> > +extern const char * const arch_kprobes_blacksyms[];
> > +extern const size_t arch_kprobes_blacksyms_size;
> > +
> > +static struct kprobe_blackpoint **kprobe_blacklist;
> > +static size_t kprobe_blacklist_size;
> 
> Since the blacklist is allocated once and never be updated,
> we just need an array of struct kprobe_blackpoint, no need
> to allocate each entry.

Right. I'll change that.

Thanks!

-Oskar
--
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 0/4] kprobes: split blacklist into common and arch

2013-04-04 Thread Oskar Andero
On 13:32 Thu 04 Apr , Vineet Gupta wrote:
> Hi Oskar,
> 
> On 04/03/2013 01:58 PM, oskar.and...@sonymobile.com wrote:
> > Hi,
> > 
> > This is a slight rework of the following patches which I posted earlier:
> > [PATCH] Kprobes blacklist: Conditionally add x86-specific symbols
> > [PATCH] delay blacklist symbol lookup until we actually need it
> > 
> > This serie includes a patch that moves the architecture dependent black 
> > points
> > to the arch/ directory and the x86 patch was modified to follow that patch.
> > 
> > -Oskar
> > 
> > Björn Davidsson (1):
> >   kprobes: move x86-specific blacklist symbols to arch directory
> > 
> > Oskar Andero (2):
> >   kprobes: split blacklist into common and arch
> >   kprobes: replace printk with pr_-functions
> > 
> > Toby Collett (1):
> >   kprobes: delay blacklist symbol lookup until we actually need it
> > 
> >  arch/arc/kernel/kprobes.c  |   3 +
> >  arch/arm/kernel/kprobes.c  |   2 +
> >  arch/avr32/kernel/kprobes.c|   3 +
> >  arch/ia64/kernel/kprobes.c |   3 +
> >  arch/mips/kernel/kprobes.c |   3 +
> >  arch/mn10300/kernel/kprobes.c  |   2 +
> >  arch/powerpc/kernel/kprobes.c  |   3 +
> >  arch/s390/kernel/kprobes.c |   3 +
> >  arch/sh/kernel/kprobes.c   |   3 +
> >  arch/sparc/kernel/kprobes.c|   3 +
> >  arch/x86/kernel/kprobes/core.c |   7 ++
> >  kernel/kprobes.c   | 149 
> > ++---
> >  12 files changed, 130 insertions(+), 54 deletions(-)
> > 
> 
> For any arch changes, however trivial they might be, you need to CC the 
> respective
> maintainers, or atleast post the patches on linux-arch so we know what's 
> going on !

Thanks Vineet! I will make sure to add linux-arch on CC for version 2.

-Oskar
--
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/4] kprobes: delay blacklist symbol lookup until we actually need it

2013-04-04 Thread Oskar Andero
On 08:44 Thu 04 Apr , Masami Hiramatsu wrote:
> (2013/04/03 17:28), oskar.and...@sonymobile.com wrote:
> >  
> > +/* it can take some time ( > 100ms ) to initialise the
> > + * blacklist so we delay this until we actually need it
> > + */
> > +static void init_kprobe_blacklist(void)
> > +{
> > +   int i;
> > +   unsigned long offset = 0, size = 0;
> > +   char *modname, namebuf[128];
> > +   const char *symbol_name;
> > +   void *addr;
> > +   struct kprobe_blackpoint *kb;
> > +
> > +   /*
> > +* Lookup and populate the kprobe_blacklist.
> > +*
> > +* Unlike the kretprobe blacklist, we'll need to determine
> > +* the range of addresses that belong to the said functions,
> > +* since a kprobe need not necessarily be at the beginning
> > +* of a function.
> > +*/
> > +   for (kb = kprobe_blacklist; kb->name != NULL; kb++) {
> > +   kprobe_lookup_name(kb->name, addr);
> > +   if (!addr)
> > +   continue;
> > +
> > +   kb->start_addr = (unsigned long)addr;
> > +   symbol_name = kallsyms_lookup(kb->start_addr,
> > +   , , , namebuf);
> > +   if (!symbol_name)
> > +   kb->range = 0;
> > +   else
> > +   kb->range = size;
> > +   }
> > +
> > +   if (kretprobe_blacklist_size) {
> > +   /* lookup the function address from its name */
> > +   for (i = 0; kretprobe_blacklist[i].name != NULL; i++) {
> > +   kprobe_lookup_name(kretprobe_blacklist[i].name,
> > +  kretprobe_blacklist[i].addr);
> > +   if (!kretprobe_blacklist[i].addr)
> > +   printk("kretprobe: lookup failed: %s\n",
> > +  kretprobe_blacklist[i].name);
> > +   }
> > +   }
> > +   kprobe_blacklist_initialized = 1;
> > +}
> > +
> >  #ifdef __ARCH_WANT_KPROBES_INSN_SLOT
> >  /*
> >   * kprobe->ainsn.insn points to the copy of the instruction to be
> > @@ -1331,6 +1379,9 @@ static int __kprobes in_kprobes_functions(unsigned 
> > long addr)
> > if (addr >= (unsigned long)__kprobes_text_start &&
> > addr < (unsigned long)__kprobes_text_end)
> > return -EINVAL;
> > +
> > +   if (!kprobe_blacklist_initialized)
> > +   init_kprobe_blacklist();
> > /*
> >  * If there exists a kprobe_blacklist, verify and
> >  * fail any probe registration in the prohibited area
> > @@ -1816,6 +1867,8 @@ int __kprobes register_kretprobe(struct kretprobe *rp)
> > void *addr;
> >  
> > if (kretprobe_blacklist_size) {
> > +   if (!kprobe_blacklist_initialized)
> > +   init_kprobe_blacklist();
> 
> Joonsoo reminds me that these calling points are not protected by 
> kprobe_mutex,
> thus we have to do something for avoiding concurrent initialization.
> 
> Perhaps, the easiest way is to protect init_kprobe_blacklist() by kprobe_mutex
> and check kprobe_blacklist_initialized again in the top of that.

Yes, you are right. I had a second look at Joonsoo's patch and I will
add a similar mutex for v2.

-Oskar
--
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/4] kprobes: delay blacklist symbol lookup until we actually need it

2013-04-04 Thread Oskar Andero
On 08:44 Thu 04 Apr , Masami Hiramatsu wrote:
 (2013/04/03 17:28), oskar.and...@sonymobile.com wrote:
   
  +/* it can take some time (  100ms ) to initialise the
  + * blacklist so we delay this until we actually need it
  + */
  +static void init_kprobe_blacklist(void)
  +{
  +   int i;
  +   unsigned long offset = 0, size = 0;
  +   char *modname, namebuf[128];
  +   const char *symbol_name;
  +   void *addr;
  +   struct kprobe_blackpoint *kb;
  +
  +   /*
  +* Lookup and populate the kprobe_blacklist.
  +*
  +* Unlike the kretprobe blacklist, we'll need to determine
  +* the range of addresses that belong to the said functions,
  +* since a kprobe need not necessarily be at the beginning
  +* of a function.
  +*/
  +   for (kb = kprobe_blacklist; kb-name != NULL; kb++) {
  +   kprobe_lookup_name(kb-name, addr);
  +   if (!addr)
  +   continue;
  +
  +   kb-start_addr = (unsigned long)addr;
  +   symbol_name = kallsyms_lookup(kb-start_addr,
  +   size, offset, modname, namebuf);
  +   if (!symbol_name)
  +   kb-range = 0;
  +   else
  +   kb-range = size;
  +   }
  +
  +   if (kretprobe_blacklist_size) {
  +   /* lookup the function address from its name */
  +   for (i = 0; kretprobe_blacklist[i].name != NULL; i++) {
  +   kprobe_lookup_name(kretprobe_blacklist[i].name,
  +  kretprobe_blacklist[i].addr);
  +   if (!kretprobe_blacklist[i].addr)
  +   printk(kretprobe: lookup failed: %s\n,
  +  kretprobe_blacklist[i].name);
  +   }
  +   }
  +   kprobe_blacklist_initialized = 1;
  +}
  +
   #ifdef __ARCH_WANT_KPROBES_INSN_SLOT
   /*
* kprobe-ainsn.insn points to the copy of the instruction to be
  @@ -1331,6 +1379,9 @@ static int __kprobes in_kprobes_functions(unsigned 
  long addr)
  if (addr = (unsigned long)__kprobes_text_start 
  addr  (unsigned long)__kprobes_text_end)
  return -EINVAL;
  +
  +   if (!kprobe_blacklist_initialized)
  +   init_kprobe_blacklist();
  /*
   * If there exists a kprobe_blacklist, verify and
   * fail any probe registration in the prohibited area
  @@ -1816,6 +1867,8 @@ int __kprobes register_kretprobe(struct kretprobe *rp)
  void *addr;
   
  if (kretprobe_blacklist_size) {
  +   if (!kprobe_blacklist_initialized)
  +   init_kprobe_blacklist();
 
 Joonsoo reminds me that these calling points are not protected by 
 kprobe_mutex,
 thus we have to do something for avoiding concurrent initialization.
 
 Perhaps, the easiest way is to protect init_kprobe_blacklist() by kprobe_mutex
 and check kprobe_blacklist_initialized again in the top of that.

Yes, you are right. I had a second look at Joonsoo's patch and I will
add a similar mutex for v2.

-Oskar
--
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 0/4] kprobes: split blacklist into common and arch

2013-04-04 Thread Oskar Andero
On 13:32 Thu 04 Apr , Vineet Gupta wrote:
 Hi Oskar,
 
 On 04/03/2013 01:58 PM, oskar.and...@sonymobile.com wrote:
  Hi,
  
  This is a slight rework of the following patches which I posted earlier:
  [PATCH] Kprobes blacklist: Conditionally add x86-specific symbols
  [PATCH] delay blacklist symbol lookup until we actually need it
  
  This serie includes a patch that moves the architecture dependent black 
  points
  to the arch/ directory and the x86 patch was modified to follow that patch.
  
  -Oskar
  
  Björn Davidsson (1):
kprobes: move x86-specific blacklist symbols to arch directory
  
  Oskar Andero (2):
kprobes: split blacklist into common and arch
kprobes: replace printk with pr_-functions
  
  Toby Collett (1):
kprobes: delay blacklist symbol lookup until we actually need it
  
   arch/arc/kernel/kprobes.c  |   3 +
   arch/arm/kernel/kprobes.c  |   2 +
   arch/avr32/kernel/kprobes.c|   3 +
   arch/ia64/kernel/kprobes.c |   3 +
   arch/mips/kernel/kprobes.c |   3 +
   arch/mn10300/kernel/kprobes.c  |   2 +
   arch/powerpc/kernel/kprobes.c  |   3 +
   arch/s390/kernel/kprobes.c |   3 +
   arch/sh/kernel/kprobes.c   |   3 +
   arch/sparc/kernel/kprobes.c|   3 +
   arch/x86/kernel/kprobes/core.c |   7 ++
   kernel/kprobes.c   | 149 
  ++---
   12 files changed, 130 insertions(+), 54 deletions(-)
  
 
 For any arch changes, however trivial they might be, you need to CC the 
 respective
 maintainers, or atleast post the patches on linux-arch so we know what's 
 going on !

Thanks Vineet! I will make sure to add linux-arch on CC for version 2.

-Oskar
--
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/4] kprobes: split blacklist into common and arch

2013-04-04 Thread Oskar Andero
On 08:17 Thu 04 Apr , Masami Hiramatsu wrote:
 (2013/04/03 17:28), oskar.and...@sonymobile.com wrote:
  Some blackpoints are only valid for specific architectures. To let each
  architecture specify its own blackpoints the list has been split in two
  lists: common and arch. The common list is kept in kernel/kprobes.c and
  the arch list is kept in the arch/ directory.
 
 Hmm, I think you'd better merge this with patch 3/4.

IMHO I think it's more logical to keep them separated instead of
squashing a generic patch with an architecture specific patch.
Also, there is the matter of authorship and credits.

Of course, it's your call, so let me know if this is ok with you.

 [...]
  +static const size_t common_kprobes_blacksyms_size =
  +   ARRAY_SIZE(common_kprobes_blacksyms);
  +
  +extern const char * const arch_kprobes_blacksyms[];
  +extern const size_t arch_kprobes_blacksyms_size;
  +
  +static struct kprobe_blackpoint **kprobe_blacklist;
  +static size_t kprobe_blacklist_size;
 
 Since the blacklist is allocated once and never be updated,
 we just need an array of struct kprobe_blackpoint, no need
 to allocate each entry.

Right. I'll change that.

Thanks!

-Oskar
--
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 v2 1/4] kprobes: delay blacklist symbol lookup until we actually need it

2013-04-04 Thread Oskar Andero
From: Toby Collett toby.coll...@sonymobile.com

The symbol lookup can take a long time and kprobes is
initialised very early in boot, so delay symbol lookup
until the blacklist is first used.

Cc: Masami Hiramatsu masami.hiramatsu...@hitachi.com
Cc: David S. Miller da...@davemloft.net
Reviewed-by: Radovan Lekanovic radovan.lekano...@sonymobile.com
Signed-off-by: Toby Collett toby.coll...@sonymobile.com
Signed-off-by: Oskar Andero oskar.and...@sonymobile.com
---
 kernel/kprobes.c | 98 ++--
 1 file changed, 60 insertions(+), 38 deletions(-)

diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index e35be53..0a270e5 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -68,6 +68,7 @@
 #endif
 
 static int kprobes_initialized;
+static int kprobe_blacklist_initialized;
 static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE];
 static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE];
 
@@ -102,6 +103,60 @@ static struct kprobe_blackpoint kprobe_blacklist[] = {
{NULL}/* Terminator */
 };
 
+/* it can take some time (  100ms ) to initialise the
+ * blacklist so we delay this until we actually need it
+ */
+static void init_kprobe_blacklist(void)
+{
+   int i;
+   unsigned long offset = 0, size = 0;
+   char *modname, namebuf[128];
+   const char *symbol_name;
+   void *addr;
+   struct kprobe_blackpoint *kb;
+
+   mutex_lock(kprobe_mutex);
+   if (kprobe_blacklist_initialized)
+   goto out;
+
+   /*
+* Lookup and populate the kprobe_blacklist.
+*
+* Unlike the kretprobe blacklist, we'll need to determine
+* the range of addresses that belong to the said functions,
+* since a kprobe need not necessarily be at the beginning
+* of a function.
+*/
+   for (kb = kprobe_blacklist; kb-name != NULL; kb++) {
+   kprobe_lookup_name(kb-name, addr);
+   if (!addr)
+   continue;
+
+   kb-start_addr = (unsigned long)addr;
+   symbol_name = kallsyms_lookup(kb-start_addr,
+   size, offset, modname, namebuf);
+   if (!symbol_name)
+   kb-range = 0;
+   else
+   kb-range = size;
+   }
+
+   if (kretprobe_blacklist_size) {
+   /* lookup the function address from its name */
+   for (i = 0; kretprobe_blacklist[i].name != NULL; i++) {
+   kprobe_lookup_name(kretprobe_blacklist[i].name,
+  kretprobe_blacklist[i].addr);
+   if (!kretprobe_blacklist[i].addr)
+   printk(kretprobe: lookup failed: %s\n,
+  kretprobe_blacklist[i].name);
+   }
+   }
+   kprobe_blacklist_initialized = 1;
+
+out:
+   mutex_unlock(kprobe_mutex);
+}
+
 #ifdef __ARCH_WANT_KPROBES_INSN_SLOT
 /*
  * kprobe-ainsn.insn points to the copy of the instruction to be
@@ -1331,6 +1386,9 @@ static int __kprobes in_kprobes_functions(unsigned long 
addr)
if (addr = (unsigned long)__kprobes_text_start 
addr  (unsigned long)__kprobes_text_end)
return -EINVAL;
+
+   if (unlikely(!kprobe_blacklist_initialized))
+   init_kprobe_blacklist();
/*
 * If there exists a kprobe_blacklist, verify and
 * fail any probe registration in the prohibited area
@@ -1816,6 +1874,8 @@ int __kprobes register_kretprobe(struct kretprobe *rp)
void *addr;
 
if (kretprobe_blacklist_size) {
+   if (unlikely(!kprobe_blacklist_initialized))
+   init_kprobe_blacklist();
addr = kprobe_addr(rp-kp);
if (IS_ERR(addr))
return PTR_ERR(addr);
@@ -2065,11 +2125,6 @@ static struct notifier_block kprobe_module_nb = {
 static int __init init_kprobes(void)
 {
int i, err = 0;
-   unsigned long offset = 0, size = 0;
-   char *modname, namebuf[128];
-   const char *symbol_name;
-   void *addr;
-   struct kprobe_blackpoint *kb;
 
/* FIXME allocate the probe table, currently defined statically */
/* initialize all list heads */
@@ -2079,39 +2134,6 @@ static int __init init_kprobes(void)
raw_spin_lock_init((kretprobe_table_locks[i].lock));
}
 
-   /*
-* Lookup and populate the kprobe_blacklist.
-*
-* Unlike the kretprobe blacklist, we'll need to determine
-* the range of addresses that belong to the said functions,
-* since a kprobe need not necessarily be at the beginning
-* of a function.
-*/
-   for (kb = kprobe_blacklist; kb-name != NULL; kb++) {
-   kprobe_lookup_name(kb-name, addr);
-   if (!addr)
-   continue;
-
-   kb

[PATCH v2 4/4] kprobes: replace printk with pr_-functions

2013-04-04 Thread Oskar Andero
Instead of using printk use pr_info/pr_err/pr_warn. This was
detected by the checkpatch.pl script.

Cc: Masami Hiramatsu masami.hiramatsu...@hitachi.com
Cc: David S. Miller da...@davemloft.net
Signed-off-by: Oskar Andero oskar.and...@sonymobile.com
Acked-by: Masami Hiramatsu masami.hiramatsu...@hitachi.com
---
 kernel/kprobes.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 58c9f4e..d61cbad 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -168,7 +168,7 @@ static void init_kprobe_blacklist(void)
kprobe_lookup_name(kretprobe_blacklist[i].name,
   kretprobe_blacklist[i].addr);
if (!kretprobe_blacklist[i].addr)
-   printk(kretprobe: lookup failed: %s\n,
+   pr_err(kretprobe: lookup failed: %s\n,
   kretprobe_blacklist[i].name);
}
}
@@ -780,7 +780,7 @@ static void reuse_unused_kprobe(struct kprobe *ap)
 */
op = container_of(ap, struct optimized_kprobe, kp);
if (unlikely(list_empty(op-list)))
-   printk(KERN_WARNING Warning: found a stray unused 
+   pr_warn(Warning: found a stray unused 
aggrprobe@%p\n, ap-addr);
/* Enable the probe again */
ap-flags = ~KPROBE_FLAG_DISABLED;
@@ -887,7 +887,7 @@ static void __kprobes optimize_all_kprobes(void)
if (!kprobe_disabled(p))
optimize_kprobe(p);
}
-   printk(KERN_INFO Kprobes globally optimized\n);
+   pr_info(Kprobes globally optimized\n);
 }
 
 /* This should be called with kprobe_mutex locked */
@@ -911,7 +911,7 @@ static void __kprobes unoptimize_all_kprobes(void)
}
/* Wait for unoptimizing completion */
wait_for_kprobe_optimizer();
-   printk(KERN_INFO Kprobes globally unoptimized\n);
+   pr_info(Kprobes globally unoptimized\n);
 }
 
 int sysctl_kprobes_optimization;
@@ -982,7 +982,7 @@ static void __kprobes __disarm_kprobe(struct kprobe *p, 
bool reopt)
 /* There should be no unused kprobes can be reused without optimization */
 static void reuse_unused_kprobe(struct kprobe *ap)
 {
-   printk(KERN_ERR Error: There should be no unused kprobe here.\n);
+   pr_err(Error: There should be no unused kprobe here.\n);
BUG_ON(kprobe_unused(ap));
 }
 
@@ -2096,8 +2096,8 @@ EXPORT_SYMBOL_GPL(enable_kprobe);
 
 void __kprobes dump_kprobe(struct kprobe *kp)
 {
-   printk(KERN_WARNING Dumping kprobe:\n);
-   printk(KERN_WARNING Name: %s\nAddress: %p\nOffset: %x\n,
+   pr_warn(Dumping kprobe:\n);
+   pr_warn(Name: %s\nAddress: %p\nOffset: %x\n,
   kp-symbol_name, kp-addr, kp-offset);
 }
 
@@ -2293,7 +2293,7 @@ static void __kprobes arm_all_kprobes(void)
}
 
kprobes_all_disarmed = false;
-   printk(KERN_INFO Kprobes globally enabled\n);
+   pr_info(Kprobes globally enabled\n);
 
 already_enabled:
mutex_unlock(kprobe_mutex);
@@ -2315,7 +2315,7 @@ static void __kprobes disarm_all_kprobes(void)
}
 
kprobes_all_disarmed = true;
-   printk(KERN_INFO Kprobes globally disabled\n);
+   pr_info(Kprobes globally disabled\n);
 
for (i = 0; i  KPROBE_TABLE_SIZE; i++) {
head = kprobe_table[i];
-- 
1.8.1.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/


  1   2   >