Re: [PATCH 2/2] gpio / ACPI: add support for GPIO operation regions

2013-09-14 Thread Mika Westerberg
On Sat, Sep 14, 2013 at 12:10:37AM +, Zheng, Lv wrote:
> Is it possible to install the handler for ACPI_ROOT_OBJECT?
> Can it be achieved by implementing a setup callback?

Yes that can be done. However, that would mean that we always install the
operation region handler even if there is no suitable GPIO driver loaded.
With this patch we install the handler once the GPIO driver for this device
is registered. If nothing is registered no handlers will be installed.

What would be the advantage in doing what you propose?

> Maybe you can also eliminate acpi_attach_data usages by doing so.

I think we still need that for ACPI _EVT handling.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2 1/9] i2c: prepare runtime PM support for I2C client devices

2013-09-14 Thread Mika Westerberg
On Fri, Sep 13, 2013 at 02:10:43PM -0700, Kevin Hilman wrote:
> >
> > // This makes sure that the controller itself is powered on
> > // (adapter device follows its parent which is the controller). The
> > // controller is attached to the ACPI power domain so it is
> > // brought to D0 now.
> > pm_runtime_get_sync(&client->adapter->dev);
> >
> > // This binds the client device to the ACPI power domain, and in
> > // addition to that brings the client device to D0.
> 
> OK, then here is where the problem is, because you're building ACPI
> assumptions into the core. For non-ACPI devices, this part is a nop, so
> the client device is still powered off, which breaks the assumptions
> below.

We expect that once the driver ->probe() is called, and it doesn't
participate the runtime PM prepared here, the device is regarded as powered
on, runtime PM active.

If the driver participates in runtime PM, it needs to power on the device
and then call pm_runtime_put() to suspend the device.

> > if (ACPI_HANDLE(&client->dev))
> > acpi_dev_pm_attach(&client->dev, true);
> >
> > // Increase the refcount so that client can start runtime PM
> > // transitions when it calls _put().
> > pm_runtime_get_noresume(&client->dev);
> 
> > // Mark the device being active as
> > //  1) In ACPI case we know that is true as we just powered the
> > // device on.
> > //  2) We treat the device by default to be runtime PM active and
> > // powered on (that's in the changelog and should follow what
> > // the PCI bus did).
> > pm_runtime_set_active(&client->dev);
> >
> > // Enable runtime PM but nothing happens yet as long as the client
> > // driver doesn't call _put().
> > pm_runtime_enable(&client->dev);
> >
> > So, yes there might be a disconnect between the runtime PM state and the
> > device HW state now (same is with default to suspended).
> 
> Yes, but until now, default to suspended has been assumed, so any
> changes to that will likely require more thorough auditing of other drivers.

I agree. And it looks like I missed few existing drivers as well. I'm going
to update them in the next version of the series.

There's also a less intrusive way of fixing the problem we see with ACPI
enabled I2C devices:

1. In I2C core i2c_device_probe() we power on the I2C controller
and attach the client device to the ACPI power domain. Just like in
this patch but we don't touch the I2C client device runtime PM.

-> This should allow the existing drivers to keep using whatever
runtime PM strategy they have chosen.

2. For ACPI enumerated I2C client devices drivers we need to
implement the runtime PM in order to save power (otherwise the
devices will be left powered on).

and do the same for SPI devices as well.

Then only thing that changes for non-ACPI devices is that the controller
will be powered on during the client device probe (well, and during
remove).

Thoughts?
--
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 alt 4/4] pinctrl: at91: rework debounce configuration

2013-09-14 Thread boris brezillon

Hello Jean-Christophe,

Le 14/09/2013 18:37, Jean-Christophe PLAGNIOL-VILLARD a écrit :

On 09:53 Fri 13 Sep , Boris BREZILLON wrote:

AT91 SoCs do not support per pin debounce time configuration.
Instead you have to configure a debounce time which will be used for all
pins of a given bank (PIOA, PIOB, ...).

Signed-off-by: Boris BREZILLON 
---
  .../bindings/pinctrl/atmel,at91-pinctrl.txt|9 ++-
  drivers/pinctrl/pinctrl-at91.c |   79 
  include/dt-bindings/pinctrl/at91.h |1 -
  3 files changed, 73 insertions(+), 16 deletions(-)

diff --git a/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt 
b/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt
index cf7c7bc..8a4cdeb 100644
--- a/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt
@@ -78,6 +78,14 @@ PA31 TXD4
  
  => 0xffc00c3b
  
+Optional properties for iomux controller:

+- atmel,default-debounce-div: array of debounce divisors (one divisor per bank)
+  which describes the debounce timing in use for all pins of a given bank
+  configured with the DEBOUNCE option (see the following description).
+  Debounce timing is obtained with this formula:
+  Tdebounce = 2 * (debouncediv + 1) / Fslowclk
+  with Fslowclk = 32KHz

I known that I put the div in the original binding

but maybe we should just put the debounce timing in the DT and calculate the
div in C


Sure, I can do this: retrieve a debounce time (in usec ?) and compute the
according div value.


+
  Required properties for pin configuration node:
  - atmel,pins: 4 integers array, represents a group of pins mux and config
setting. The format is atmel,pins = .
@@ -91,7 +99,6 @@ DEGLITCH  (1 << 2): indicate this pin need deglitch.
  PULL_DOWN (1 << 3): indicate this pin need a pull down.
  DIS_SCHMIT(1 << 4): indicate this pin need to disable schmit trigger.
  DEBOUNCE  (1 << 16): indicate this pin need debounce.
-DEBOUNCE_VAL   (0x3fff << 17): debounce val.
  
  NOTE:

  Some requirements for using atmel,at91rm9200-pinctrl binding:
diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c
index ac9dbea..2903758 100644
--- a/drivers/pinctrl/pinctrl-at91.c
+++ b/drivers/pinctrl/pinctrl-at91.c
@@ -62,8 +62,6 @@ static int gpio_banks;
  #define PULL_DOWN (1 << 3)
  #define DIS_SCHMIT(1 << 4)
  #define DEBOUNCE  (1 << 16)
-#define DEBOUNCE_VAL_SHIFT 17
-#define DEBOUNCE_VAL   (0x3fff << DEBOUNCE_VAL_SHIFT)
  
  /**

   * struct at91_pmx_func - describes AT91 pinmux functions
@@ -145,8 +143,10 @@ struct at91_pinctrl_mux_ops {
void (*mux_D_periph)(void __iomem *pio, unsigned mask);
bool (*get_deglitch)(void __iomem *pio, unsigned pin);
void (*set_deglitch)(void __iomem *pio, unsigned mask, bool is_on);
-   bool (*get_debounce)(void __iomem *pio, unsigned pin, u32 *div);
-   void (*set_debounce)(void __iomem *pio, unsigned mask, bool is_on, u32 
div);
+   bool (*get_debounce)(void __iomem *pio, unsigned pin);
+   void (*set_debounce)(void __iomem *pio, unsigned mask, bool is_on);
+   u32 (*get_debounce_div)(void __iomem *pio);
+   void (*set_debounce_div)(void __iomem *pio, u32 div);

why do you split it?

if it's just get if on or not put NULL to div but do not add more function
pointer


I not sure I got your point.
Are you suggesting we should store the default bank bebounce div values 
in struct at91_pinctrl
(during probe process) and pass these values each time the set_debounce 
function is called ?


IMHO if we split the logic (split debounce activation and debounce time 
definition) we should split

these callbacks:
 - one callback to enable debounce option on a given pin
 - one callback to configure the debounce time for a given bank

If you keep the div parameter in the debounce enable/disable callback 
you will reconfigure the div
register (PIO_SCDR_DIV) each time you enable the debounce option, which 
is kind of useless

because the div value will never change.


bool (*get_pulldown)(void __iomem *pio, unsigned pin);
void (*set_pulldown)(void __iomem *pio, unsigned mask, bool is_on);
bool (*get_schmitt_trig)(void __iomem *pio, unsigned pin);
@@ -432,25 +432,32 @@ static void at91_mux_pio3_set_deglitch(void __iomem *pio, 
unsigned mask, bool is
at91_mux_set_deglitch(pio, mask, is_on);
  }
  
-static bool at91_mux_pio3_get_debounce(void __iomem *pio, unsigned pin, u32 *div)

+static bool at91_mux_pio3_get_debounce(void __iomem *pio, unsigned pin)
  {
-   *div = __raw_readl(pio + PIO_SCDR);
-
return ((__raw_readl(pio + PIO_IFSR) >> pin) & 0x1) &&
   ((__raw_readl(pio + PIO_IFSCSR) >> pin) & 0x1);
  }
  
  static void at91_mux_pio3_set_debounce(void __iomem *pio, unsigned mask,

-   bool is_on, u32 div)
+ 

Re: [PATCH 1/2] ipc/sem.c: Race in sem_lock()

2013-09-14 Thread Mike Galbraith
On Sat, 2013-09-14 at 23:34 +0200, Manfred Spraul wrote:

> The bug is probably also present in 3.10 and 3.11, but for these kernels
> is is probably simpler just to move the test of sma->complex_count after
> the spin_is_locked() test.

IMHO, your 6 patch series should go to stable as well.  Scalability is
still BAD without them.  Now, you've shown the lock split to be buggy.

Logically, the whole thing should be reverted entirely in stable, or
fixed up properly.  Humongous improvements will find their way into
every long term stable kernel on the planet regardless, so..

Stable may as well do the Borg thing, resistance really is futile ;-)

-Mike

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


[git pull] Input updates for 3.12-rc0

2013-09-14 Thread Dmitry Torokhov
Hi Linus,

Please pull from:

git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git for-linus
or
master.kernel.org:/pub/scm/linux/kernel/git/dtor/input.git for-linus

to receive updates for the input subsystem. The only change is David
Hermann's new EVIOCREVOKE evdev ioctl that allows safely passing file
descriptors to input devices to session processes and later being able
to stop delivery of events through these fds so that inactive sessions
will no longer receive user input that does not belong to them.

Changelog:
-

David Herrmann (1):
  Input: evdev - add EVIOCREVOKE ioctl


Diffstat:


 drivers/input/evdev.c  | 37 +++--
 include/uapi/linux/input.h |  1 +
 2 files changed, 32 insertions(+), 6 deletions(-)

-- 
Dmitry



pgpsyYHbNTfmP.pgp
Description: PGP signature


Re: [PATCH 211/228] cpufreq: tegra: remove calls to cpufreq_notify_transition()

2013-09-14 Thread Rafael J. Wysocki
On Saturday, September 14, 2013 09:39:31 AM Viresh Kumar wrote:
> On 14 September 2013 04:22, Stephen Warren  wrote:
> > I wonder if this series is bisectable? Perhaps I should just go and read
> > the rest of the series, but I presume there's a patch somewhere else
> > that adds those two cpufreq_notify_transition() to the cpufreq core.
> > Either that happens before this patch (in which case listeners will get
> > two notifications each time; perhaps that is safe?), or after this patch
> > (in which case with just this patch applied, no notifications will be
> > sent until a later patch!
> 
> Hmm.. Good Catch..
> 
> So, yes git bisect would be compilable but not runnable.. As we are
> already serialized notifications and so two PRE notifications will
> generate a crash..
> 
> But I don't want to get all that in a single patch as that would be:
> 
>  40 files changed, 192 insertions(+), 623 deletions(-)
> 
> And that would be hard to review it..
> 
> Any suggestions?

Well, I guess you can assume that everyone has a chance to review the series
by now and send it as one patch in the next iteration.

A patch that adds 192 lines of code isn't shockingly large by any measure.

Thanks,
Rafael

--
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] modpost: Fix secondary errors seen if a single module build fails

2013-09-14 Thread Guenter Roeck
Commit ea4054a23 (modpost: handle huge numbers of modules) added
support for building a large number of modules.

Unfortunately, the commit changed the semantics of the makefile: Instead of
passing only existing object files to modpost, make now passes all expected
object files. If make was started with option -i, this results in a modpost
error if a single file failed to build.

Example with the current btrfs build falure on m68k:

fs/btrfs/btrfs.o: No such file or directory
make[1]: [__modpost] Error 1 (ignored)

This error is followed by lots of errors such as:

m68k-linux-gcc: error: arch/m68k/emu/nfcon.mod.c: No such file or directory
m68k-linux-gcc: fatal error: no input files
compilation terminated.
make[1]: [arch/m68k/emu/nfcon.mod.o] Error 1 (ignored)

This doesn't matter much for normal builds, but it is annoying for builds
started with "make -i" due to the large number of secondary errors.
Those errors unnececessarily clog any error log and make it difficult
to find the real errors in the build.

Fix the problem by only passing existing object files to modpost.

Cc: Rusty Russell 
Signed-off-by: Guenter Roeck 
---
 scripts/Makefile.modpost |3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
index 8dcdca2..387c806 100644
--- a/scripts/Makefile.modpost
+++ b/scripts/Makefile.modpost
@@ -81,7 +81,8 @@ modpost = scripts/mod/modpost\
 
 # We can go over command line length here, so be careful.
 quiet_cmd_modpost = MODPOST $(words $(filter-out vmlinux FORCE, $^)) modules
-  cmd_modpost = $(MODLISTCMD) | sed 's/\.ko$$/.o/' | $(modpost) -s -T -
+  cmd_modpost = $(MODLISTCMD) | sed 's/\.ko$$/.o/' | \
+   while read a; do [ -f $$a ] && echo $$a; done | $(modpost) -s -T -
 
 PHONY += __modpost
 __modpost: $(modules:.ko=.o) FORCE
-- 
1.7.9.7

--
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 net 2/3] lib: introduce upper case hex ascii helpers

2013-09-14 Thread Andrew Morton
On Sun, 15 Sep 2013 01:27:03 -0300 Thiago Farina  wrote:

> On Fri, Sep 13, 2013 at 2:37 PM, Andre Naujoks  wrote:
> > To be able to use the hex ascii functions in case sensitive environments
> > the array hex_asc_upper[] and the needed functions for hex_byte_pack_upper()
> > are introduced.
> >
> > Signed-off-by: Andre Naujoks 
> > ---
> >  include/linux/kernel.h | 11 +++
> >  lib/hexdump.c  |  2 ++
> >  2 files changed, 13 insertions(+)
> >
> > diff --git a/include/linux/kernel.h b/include/linux/kernel.h
> > index 482ad2d..672ddc4 100644
> > --- a/include/linux/kernel.h
> > +++ b/include/linux/kernel.h
> > @@ -439,6 +439,17 @@ static inline char *hex_byte_pack(char *buf, u8 byte)
> > return buf;
> >  }
> >
> > +extern const char hex_asc_upper[];
> > +#define hex_asc_upper_lo(x)hex_asc_upper[((x) & 0x0f)]
> > +#define hex_asc_upper_hi(x)hex_asc_upper[((x) & 0xf0) >> 4]
> Does using a macro instead of a real function (static inline)
> generates a better code?

Yes, a static inline would be nicer, but these are derived from
hex_asc_lo/hex_asc_hi.  If we change one we should change the other
and that becomes a separate cleanup.  So I think this patch is
OK as-is.

Also, it would make sense to get all the *hex* stuff out of kernel.h
and into a new header file (hexchar.h?).  They're a clean
self-contained thing and kernel.h is rather a dumping ground.

--
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 net 2/3] lib: introduce upper case hex ascii helpers

2013-09-14 Thread Thiago Farina
On Fri, Sep 13, 2013 at 2:37 PM, Andre Naujoks  wrote:
> To be able to use the hex ascii functions in case sensitive environments
> the array hex_asc_upper[] and the needed functions for hex_byte_pack_upper()
> are introduced.
>
> Signed-off-by: Andre Naujoks 
> ---
>  include/linux/kernel.h | 11 +++
>  lib/hexdump.c  |  2 ++
>  2 files changed, 13 insertions(+)
>
> diff --git a/include/linux/kernel.h b/include/linux/kernel.h
> index 482ad2d..672ddc4 100644
> --- a/include/linux/kernel.h
> +++ b/include/linux/kernel.h
> @@ -439,6 +439,17 @@ static inline char *hex_byte_pack(char *buf, u8 byte)
> return buf;
>  }
>
> +extern const char hex_asc_upper[];
> +#define hex_asc_upper_lo(x)hex_asc_upper[((x) & 0x0f)]
> +#define hex_asc_upper_hi(x)hex_asc_upper[((x) & 0xf0) >> 4]
Does using a macro instead of a real function (static inline)
generates a better code?

--
Thiago Farina
--
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] mm: numa: adjust hinting fault record if page is migrated

2013-09-14 Thread Hillf Danton
Hello Rik

On Sat, Sep 14, 2013 at 11:55 PM, Rik van Riel  wrote:
> On 09/14/2013 07:53 AM, Hillf Danton wrote:
>> After page A on source node is migrated to page B on target node, hinting
>> fault is recorded on the target node for B. On the source node there is
>> another record for A, since a two-stage filter is used when migrating pages.
>>
>> Page A is no longer used after migration, so we have to erase its record.
>
> What kind of performance changes have you observed with this patch?
>
> What benchmarks have you run, and on what kind of systems?
>
Due to no NUMA box, I can not answer you now.
I will try best to borrow one next Monday.

Thanks
Hillf
--
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 V4 03/15] asymmetric keys: separate the length checking of octet string from RSA_I2OSP

2013-09-14 Thread Lee, Chun-Yi
Due to RSA_I2OSP is not only used by signature verification path but also used
in signature generation path. So, separate the length checking of octet string
because it's not for generate 0x00 0x01 leading string when used in signature
generation.

The naming of _RSA_I2OSP and the variables used in this function accord PKCS#1
spec but not follow kernel naming convention, it useful when look at them with
spec.

Reference: ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1v2/pkcs1ietffinal.txt
Reference: 
http://www.emc.com/collateral/white-papers/h11300-pkcs-1v2-2-rsa-cryptography-standard-wp.pdf

Cc: Pavel Machek 
Reviewed-by: Jiri Kosina 
Signed-off-by: Lee, Chun-Yi 
---
 crypto/asymmetric_keys/rsa.c |   33 -
 1 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/crypto/asymmetric_keys/rsa.c b/crypto/asymmetric_keys/rsa.c
index 352ba45..aac8b77 100644
--- a/crypto/asymmetric_keys/rsa.c
+++ b/crypto/asymmetric_keys/rsa.c
@@ -121,12 +121,30 @@ static int RSAVP1(const struct public_key *key, MPI s, 
MPI *_m)
 /*
  * Integer to Octet String conversion [RFC3447 sec 4.1]
  */
-static int RSA_I2OSP(MPI x, size_t xLen, u8 **_X)
+static int _RSA_I2OSP(MPI x, unsigned *X_size, u8 **_X)
 {
-   unsigned X_size, x_size;
int X_sign;
u8 *X;
 
+   X = mpi_get_buffer(x, X_size, &X_sign);
+   if (!X)
+   return -ENOMEM;
+   if (X_sign < 0) {
+   kfree(X);
+   return -EBADMSG;
+   }
+
+   *_X = X;
+   return 0;
+}
+
+static int RSA_I2OSP(MPI x, size_t xLen, u8 **_X)
+{
+   unsigned x_size;
+   unsigned X_size;
+   u8 *X = NULL;
+   int ret;
+
/* Make sure the string is the right length.  The number should begin
 * with { 0x00, 0x01, ... } so we have to account for 15 leading zero
 * bits not being reported by MPI.
@@ -136,13 +154,10 @@ static int RSA_I2OSP(MPI x, size_t xLen, u8 **_X)
if (x_size != xLen * 8 - 15)
return -ERANGE;
 
-   X = mpi_get_buffer(x, &X_size, &X_sign);
-   if (!X)
-   return -ENOMEM;
-   if (X_sign < 0) {
-   kfree(X);
-   return -EBADMSG;
-   }
+   ret = _RSA_I2OSP(x, &X_size, &X);
+   if (ret < 0)
+   return ret;
+
if (X_size != xLen - 1) {
kfree(X);
return -EBADMSG;
-- 
1.6.0.2

--
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 V4 01/15] asymmetric keys: add interface and skeleton for implement signature generation

2013-09-14 Thread Lee, Chun-Yi
Add generate_signature interface on signature.c, asymmetric-subtype and
rsa.c for prepare to implement signature generation.

Reviewed-by: Jiri Kosina 
Signed-off-by: Lee, Chun-Yi 
---
 crypto/asymmetric_keys/private_key.h |   29 +
 crypto/asymmetric_keys/public_key.c  |   31 +++
 crypto/asymmetric_keys/rsa.c |   22 ++
 crypto/asymmetric_keys/signature.c   |   28 
 include/crypto/public_key.h  |   25 +
 include/keys/asymmetric-subtype.h|6 ++
 6 files changed, 141 insertions(+), 0 deletions(-)
 create mode 100644 crypto/asymmetric_keys/private_key.h

diff --git a/crypto/asymmetric_keys/private_key.h 
b/crypto/asymmetric_keys/private_key.h
new file mode 100644
index 000..c022eee
--- /dev/null
+++ b/crypto/asymmetric_keys/private_key.h
@@ -0,0 +1,29 @@
+/* Private key algorithm internals
+ *
+ * Copyright (C) 2013 SUSE Linux Products GmbH. All rights reserved.
+ * Written by Chun-Yi Lee (j...@suse.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include 
+
+extern struct asymmetric_key_subtype private_key_subtype;
+
+/*
+ * Private key algorithm definition.
+ */
+struct private_key_algorithm {
+   const char  *name;
+   u8  n_pub_mpi;  /* Number of MPIs in public key */
+   u8  n_sec_mpi;  /* Number of MPIs in secret key */
+   u8  n_sig_mpi;  /* Number of MPIs in a signature */
+   struct public_key_signature* (*generate_signature)(
+   const struct private_key *key, u8 *M,
+   enum pkey_hash_algo hash_algo, const bool hash);
+};
+
+extern const struct private_key_algorithm RSA_private_key_algorithm;
diff --git a/crypto/asymmetric_keys/public_key.c 
b/crypto/asymmetric_keys/public_key.c
index cb2e291..80c19cd 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include "public_key.h"
+#include "private_key.h"
 
 MODULE_LICENSE("GPL");
 
@@ -96,6 +97,24 @@ static int public_key_verify_signature(const struct key *key,
 }
 
 /*
+ * Generate a signature using a private key.
+ */
+static struct public_key_signature *private_key_generate_signature(
+   const struct key *key, u8 *M, enum pkey_hash_algo hash_algo,
+   const bool hash)
+{
+   const struct private_key *pk = key->payload.data;
+
+   pr_info("private_key_generate_signature start\n");
+
+   if (!pk->algo->generate_signature)
+   return ERR_PTR(-ENOTSUPP);
+
+   return pk->algo->generate_signature(pk, M, hash_algo, hash);
+
+}
+
+/*
  * Public key algorithm asymmetric key subtype
  */
 struct asymmetric_key_subtype public_key_subtype = {
@@ -106,3 +125,15 @@ struct asymmetric_key_subtype public_key_subtype = {
.verify_signature   = public_key_verify_signature,
 };
 EXPORT_SYMBOL_GPL(public_key_subtype);
+
+/*
+ * Private key algorithm asymmetric key subtype
+ */
+struct asymmetric_key_subtype private_key_subtype = {
+   .owner  = THIS_MODULE,
+   .name   = "private_key",
+   .describe   = public_key_describe,
+   .destroy= public_key_destroy,
+   .generate_signature = private_key_generate_signature,
+};
+EXPORT_SYMBOL_GPL(private_key_subtype);
diff --git a/crypto/asymmetric_keys/rsa.c b/crypto/asymmetric_keys/rsa.c
index 4a6a069..47f3be4 100644
--- a/crypto/asymmetric_keys/rsa.c
+++ b/crypto/asymmetric_keys/rsa.c
@@ -14,6 +14,7 @@
 #include 
 #include 
 #include "public_key.h"
+#include "private_key.h"
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("RSA Public Key Algorithm");
@@ -267,6 +268,18 @@ error:
return ret;
 }
 
+/*
+ * Perform the generation step [RFC3447 sec 8.2.1].
+ */
+static struct public_key_signature *RSA_generate_signature(
+   const struct private_key *key, u8 *M,
+   enum pkey_hash_algo hash_algo, const bool hash)
+{
+   pr_info("RSA_generate_signature start\n");
+
+   return 0;
+}
+
 const struct public_key_algorithm RSA_public_key_algorithm = {
.name   = "RSA",
.n_pub_mpi  = 2,
@@ -275,3 +288,12 @@ const struct public_key_algorithm RSA_public_key_algorithm 
= {
.verify_signature = RSA_verify_signature,
 };
 EXPORT_SYMBOL_GPL(RSA_public_key_algorithm);
+
+const struct private_key_algorithm RSA_private_key_algorithm = {
+   .name   = "RSA",
+   .n_pub_mpi  = 2,
+   .n_sec_mpi  = 3,
+   .n_sig_mpi  = 1,
+   .generate_signature = RSA_generate_signature,
+};
+EXPORT_SYMBOL_GPL(RSA_private_key_algorithm);
diff --git a/crypto/asymme

[PATCH V4 12/15] Hibernate: show the verification time for monitor performance

2013-09-14 Thread Lee, Chun-Yi
Show the verification time for monitor the performance of SHA256 and RSA
verification.

Reviewed-by: Jiri Kosina 
Signed-off-by: Lee, Chun-Yi 
---
 kernel/power/snapshot.c |7 +++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index 8a166e1..804feb6 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -2529,6 +2529,8 @@ static void snapshot_fill_sig_forward_info(int 
sig_check_ret)
 
 int snapshot_image_verify(void)
 {
+   struct timeval start;
+   struct timeval stop;
struct crypto_shash *tfm = NULL
struct shash_desc *desc;
u8 *digest = NULL;
@@ -2560,6 +2562,8 @@ int snapshot_image_verify(void)
desc->tfm = tfm;
desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
 
+   do_gettimeofday(&start);
+
ret = crypto_shash_init(desc);
if (ret < 0)
goto error_shash;
@@ -2580,6 +2584,9 @@ int snapshot_image_verify(void)
else
pr_info("PM: snapshot signature check SUCCESS!\n");
 
+   do_gettimeofday(&stop);
+   swsusp_show_speed(&start, &stop, nr_copy_pages, "Verified");
+
 forward_ret:
/* forward check result when pass or not enforce verify success */
if (!ret || !sig_enforced()) {
-- 
1.6.0.2

--
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 10/15] Hibernate: Avoid S4 sign key data included in snapshot image

2013-09-14 Thread Lee, Chun-Yi
This patch add swsusp_page_is_sign_key() method to hibernate_key.c and
check the page is S4 sign key data when collect saveable page in
snapshot.c to avoid sign key data included in snapshot image.

Reviewed-by: Jiri Kosina 
Signed-off-by: Lee, Chun-Yi 
---
 kernel/power/snapshot.c |6 ++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index edab31f..d3e14aa 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -860,6 +860,9 @@ static struct page *saveable_highmem_page(struct zone 
*zone, unsigned long pfn)
 
BUG_ON(!PageHighMem(page));
 
+   if (swsusp_page_is_sign_key(page))
+   return NULL;
+
if (swsusp_page_is_forbidden(page) ||  swsusp_page_is_free(page) ||
PageReserved(page))
return NULL;
@@ -922,6 +925,9 @@ static struct page *saveable_page(struct zone *zone, 
unsigned long pfn)
 
BUG_ON(PageHighMem(page));
 
+   if (swsusp_page_is_sign_key(page))
+   return NULL;
+
if (swsusp_page_is_forbidden(page) || swsusp_page_is_free(page))
return NULL;
 
-- 
1.6.0.2

--
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 V4 15/15] Hibernate: adapt to UEFI secure boot with signature check

2013-09-14 Thread Lee, Chun-Yi
Base on Matthew Garrett's 2 patches in
"[PATCH] Add additional security checks when module loading is restricted" 
series
  [PATCH 01/10] Add secure_modules() call
  [PATCH V3 11/11] Add option to automatically enforce module signatures when 
in Secure Boot mode

This patch introduced EFI_SECURE_BOOT_SNAPSHOT_SIG_ENFORCE kernel config, it's
provide user to binding UEFI secure boot with SIG_ENFORCE flag of hibernate.

In current solution, the snapshot signature check used the RSA key-pair
that are generated by bootloader(e.g. shim) then pass the key-pair to
kernel through EFI variables. Simply say: The root of trust is base on
UEFI secure boot enabled. So, that makes sense to binding the snapshot
signature check mechanism with UEFI secure boot for provide stronger
protection of hibernate. The behavior when enabled
EFI_SECURE_BOOT_SNAPSHOT_SIG_ENFORCE as following:

 + UEFI Secure Boot ON (means SIG_ENFORCE on),
   and Kernel found key-pair from bootloader:
   Will do the S4 signature check.

 + UEFI Secure Boot ON, (SIG_ENFORCE on)
   but Kernel didn't find key-pair from shim:
   Will lock down S4 function.

 + UEFI Secure Boot OFF (means SIG_ENFORCE off)
   taint kernel when signature check fail or didn't find key-pair.

V3:
Use helper function secure_hibernate() to reduce ifdef block.

V2:
Replace sign_key_data_loaded() by skey_data_available() to check sign key data
is available for hibernate.

Reviewed-by: Jiri Kosina 
Signed-off-by: Lee, Chun-Yi 
---
 arch/x86/kernel/setup.c   |7 ++
 kernel/power/hibernate.c  |   17 ++
 kernel/power/hibernate_keys.c |   16 +
 kernel/power/main.c   |7 +-
 kernel/power/power.h  |   13 +++
 kernel/power/snapshot.c   |   49 +---
 kernel/power/swap.c   |4 +-
 kernel/power/user.c   |5 +++-
 8 files changed, 91 insertions(+), 27 deletions(-)

diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index deeb7bc..b3878b4 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -50,6 +50,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -1135,6 +1136,12 @@ void __init setup_arch(char **cmdline_p)
}
 #endif
 
+#ifdef CONFIG_EFI_SECURE_BOOT_SNAPSHOT_SIG_ENFORCE
+   if (boot_params.secure_boot) {
+   enforce_signed_snapshot();
+   }
+#endif
+
/*
 * Parse the ACPI tables for possible boot-time SMP configuration.
 */
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index 6336499..abbc5b0 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "power.h"
 
@@ -633,6 +634,9 @@ int hibernate(void)
 {
int error;
 
+   if (secure_hibernate(SIG_ENFORCE | SIG_CHECK_SKEY))
+   return -EPERM;
+
lock_system_sleep();
/* The snapshot device should not be opened while we're running */
if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
@@ -800,6 +804,11 @@ static int software_resume(void)
if (error)
goto Unlock;
 
+   if (secure_hibernate(SIG_ENFORCE | SIG_CHECK_WKEY)) {
+   mutex_unlock(&pm_mutex);
+   return -EPERM;
+   }
+
/* The snapshot device should not be opened while we're running */
if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
error = -EBUSY;
@@ -893,6 +902,11 @@ static ssize_t disk_show(struct kobject *kobj, struct 
kobj_attribute *attr,
int i;
char *start = buf;
 
+   if (secure_hibernate(SIG_ENFORCE | SIG_CHECK_SKEY)) {
+   buf += sprintf(buf, "[%s]\n", "disabled");
+   return buf-start;
+   }
+
for (i = HIBERNATION_FIRST; i <= HIBERNATION_MAX; i++) {
if (!hibernation_modes[i])
continue;
@@ -927,6 +941,9 @@ static ssize_t disk_store(struct kobject *kobj, struct 
kobj_attribute *attr,
char *p;
int mode = HIBERNATION_INVALID;
 
+   if (secure_hibernate(SIG_ENFORCE | SIG_CHECK_SKEY))
+   return -EPERM;
+
p = memchr(buf, '\n', n);
len = p ? p - buf : n;
 
diff --git a/kernel/power/hibernate_keys.c b/kernel/power/hibernate_keys.c
index 72d5c7a..b70f397 100644
--- a/kernel/power/hibernate_keys.c
+++ b/kernel/power/hibernate_keys.c
@@ -367,6 +367,22 @@ static int clean_key_regen_flag(void)
return ret;
 }
 
+bool secure_hibernate(u8 check_items)
+{
+   bool ret = true;
+
+   if (check_items & SIG_ENFORCE)
+   ret = sig_enforce;
+
+   /* check S4 key to lock hibernate when not available */
+   if (ret && (check_items & SIG_CHECK_SKEY))
+   ret = ret && !skey_data_available();
+   if (ret && (check_items & SIG_CHECK_WKEY))
+   ret = ret && (wkey_data_available() != 0);
+
+   return ret;
+}
+
 stati

[PATCH V4 11/15] Hibernate: taint kernel when signature check fail

2013-09-14 Thread Lee, Chun-Yi
We will not direct fail the hibernate snapshot restore when the
signature check fail, instead kernel will complain by warning
message and taint kernel.

This patch also introduced a sig_enforce flag to indicate if we want
direct fail the snapshot restore when signature check fail. User can
enable it through snapshot_sig_enforce parameter or
EFI_SECURE_BOOT_SNAPSHOT_SIG_ENFORCE.

Signed-off-by: Lee, Chun-Yi 
---
 Documentation/kernel-parameters.txt |7 +++
 arch/x86/Kconfig|   11 +++
 include/linux/kernel.h  |1 +
 include/linux/suspend.h |7 +++
 kernel/panic.c  |2 ++
 kernel/power/hibernate_keys.c   |   35 +++
 kernel/power/power.h|1 +
 kernel/power/snapshot.c |6 +-
 8 files changed, 69 insertions(+), 1 deletions(-)

diff --git a/Documentation/kernel-parameters.txt 
b/Documentation/kernel-parameters.txt
index 7f9d4f5..4c686c0 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -2730,6 +2730,13 @@ bytes respectively. Such letter suffixes can also be 
entirely omitted.
Useful for devices that are detected asynchronously
(e.g. USB and MMC devices).
 
+   snapshot_sig_enforce
+   [HIBERNATE] When CONFIG_SNAPSHOT_VERIFICATION is set,
+   this means the snapshot image without (valid) signatures
+   will fail to recover. This parameter provides user to
+   force launch the snapshot signature check even the UEFI
+   secure boot didn't enable.
+
hibernate=  [HIBERNATION]
noresumeDon't check if there's a hibernation image
present during boot.
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index ea73d2f..b43217a 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1591,6 +1591,17 @@ config EFI_SECURE_BOOT_SIG_ENFORCE
  Say Y here to automatically enable module signature enforcement
  when a system boots with UEFI Secure Boot enabled.
 
+config EFI_SECURE_BOOT_SNAPSHOT_SIG_ENFORCE
+   def_bool n
+   prompt "Force snapshot signing when UEFI Secure Boot is enabled"
+   ---help---
+ UEFI Secure Boot provides a mechanism for ensuring that the
+ firmware will only load signed bootloaders and kernels. Certain
+ use cases may also require that the snapshot image of hibernate
+ also be signed.
+ Say Y here to automatically enable snapshot iage signature
+ enforcement when a system boots with UEFI Secure Boot enabled.
+
 config SECCOMP
def_bool y
prompt "Enable seccomp to safely compute untrusted bytecode"
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 482ad2d..95df772 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -427,6 +427,7 @@ extern enum system_states {
 #define TAINT_CRAP 10
 #define TAINT_FIRMWARE_WORKAROUND  11
 #define TAINT_OOT_MODULE   12
+#define TAINT_UNSAFE_HIBERNATE 13
 
 extern const char hex_asc[];
 #define hex_asc_lo(x)  hex_asc[((x) & 0x0f)]
diff --git a/include/linux/suspend.h b/include/linux/suspend.h
index f73cabf..6b46726 100644
--- a/include/linux/suspend.h
+++ b/include/linux/suspend.h
@@ -320,6 +320,13 @@ extern unsigned long get_safe_page(gfp_t gfp_mask);
 extern void hibernation_set_ops(const struct platform_hibernation_ops *ops);
 extern int hibernate(void);
 extern bool system_entering_hibernation(void);
+
+#ifdef CONFIG_SNAPSHOT_VERIFICATION
+extern void enforce_signed_snapshot(void);
+#else
+static inline void enforce_signed_snapshot(void) {};
+#endif
+
 #else /* CONFIG_HIBERNATION */
 static inline void register_nosave_region(unsigned long b, unsigned long e) {}
 static inline void register_nosave_region_late(unsigned long b, unsigned long 
e) {}
diff --git a/kernel/panic.c b/kernel/panic.c
index 8018646..c59b1f6 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -206,6 +206,7 @@ static const struct tnt tnts[] = {
{ TAINT_CRAP,   'C', ' ' },
{ TAINT_FIRMWARE_WORKAROUND,'I', ' ' },
{ TAINT_OOT_MODULE, 'O', ' ' },
+   { TAINT_UNSAFE_HIBERNATE,   'H', ' ' },
 };
 
 /**
@@ -224,6 +225,7 @@ static const struct tnt tnts[] = {
  *  'C' - modules from drivers/staging are loaded.
  *  'I' - Working around severe firmware bug.
  *  'O' - Out-of-tree module has been loaded.
+ *  'H' - System restored from unsafe hibernate snapshot image.
  *
  * The string is overwritten by the next call to print_tainted().
  */
diff --git a/kernel/power/hibernate_keys.c b/kernel/power/hibernate_keys.c
index 0bce9ab..daf08e0 100644
--- a/kernel/power/hibernate_keys.c
+++ b/kernel/power/hibernate_keys.c
@@ -17,6 +17,7 @@ struct forward_info {
 static 

[PATCH V4 14/15] Hibernate: notify bootloader regenerate key-pair for snapshot verification

2013-09-14 Thread Lee, Chun-Yi
This patch introduced SNAPSHOT_REGEN_KEYS kernel config, enable this
option let kernel notify booloader (e.g. shim) to regenerate key-pair of
snapshot verification for each hibernate.

Kernel loaded S4 sign key in efi stub, so the private key forward from
efi bootloader to kernel in UEFI secure environment. Regenerate key-pair
for each hibernate will gain more security but it hurt the lifetime of
EFI flash memory.

Kernel write an non-volatile runtime efi variable, the name is
GenS4Key-fe141863-c070-478e-b8a3-878a5dc9ef21, to notify efi bootloader
regenerate key-pair for next hibernate cycle.

Userland hibernate tool can write GenS4Key at runtime, kernel will
respect the value but not overwrite it when S4. This mechanism let
userland tool can also notify bootloader to regenerate key-pair through
GenS4Key flag.

V4:
- Use efivar API to access GenS4Key variable.
- Call set_key_regen_flag() in hibernate.c and user.c

Cc: Matthew Garrett 
Signed-off-by: Lee, Chun-Yi 
---
 kernel/power/Kconfig  |   15 +
 kernel/power/hibernate.c  |4 ++-
 kernel/power/hibernate_keys.c |   67 +
 kernel/power/power.h  |5 +++
 kernel/power/user.c   |6 +++-
 5 files changed, 95 insertions(+), 2 deletions(-)

diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index 79b34fa..63bda98 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -78,6 +78,21 @@ config SNAPSHOT_VERIFICATION
  dependent on UEFI environment. EFI bootloader should generate the
  key-pair.
 
+config SNAPSHOT_REGEN_KEYS
+   bool "Regenerate key-pair for each snapshot verification"
+depends on SNAPSHOT_VERIFICATION
+   help
+ Enabled this option let kernel notify booloader (e.g. shim) to
+ regenerate key-pair of snapshot verification for each hibernate.
+ Linux kernel write an non-volatile runtime EFI variable, the name
+ is GenS4Key-fe141863-c070-478e-b8a3-878a5dc9ef21, to notify EFI
+ bootloader regenerate key-pair for next hibernate cycle.
+
+ Userland hibernate tool can write GenS4Key at runtime then kernel
+ will respect the value but not overwrite it when S4. This mechanism
+ let userland tool can also notify bootloader to regenerate key-pair
+ through GenS4Key flag.
+
 choice
prompt "Which hash algorithm should snapshot be signed with?"
 depends on SNAPSHOT_VERIFICATION
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index 90a25c7..6336499 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -675,8 +675,10 @@ int hibernate(void)
pr_debug("PM: writing image.\n");
error = swsusp_write(flags);
swsusp_free();
-   if (!error)
+   if (!error) {
+   set_key_regen_flag();
power_down();
+   }
in_suspend = 0;
pm_restore_gfp_mask();
} else {
diff --git a/kernel/power/hibernate_keys.c b/kernel/power/hibernate_keys.c
index daf08e0..72d5c7a 100644
--- a/kernel/power/hibernate_keys.c
+++ b/kernel/power/hibernate_keys.c
@@ -14,6 +14,8 @@ struct forward_info {
unsigned char   skey_data_buf[SKEY_DBUF_MAX_SIZE];
 };
 
+static efi_char16_t efi_gens4key_name[9] = { 'G', 'e', 'n', 'S', '4', 'K', 
'e', 'y', 0 };
+
 static void *skey_data;
 static void *forward_info_buf;
 static unsigned long skey_dsize;
@@ -301,6 +303,70 @@ bool sig_enforced(void)
return sig_enforce;
 }
 
+int set_key_regen_flag(void)
+{
+#ifdef CONFIG_SNAPSHOT_REGEN_KEYS
+   struct efivar_entry *entry;
+   unsigned long datasize;
+   u8 gens4key;
+   int ret;
+
+   entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+   if (!entry)
+   return -ENOMEM;
+
+   memcpy(entry->var.VariableName, efi_gens4key_name, 
sizeof(efi_gens4key_name));
+   memcpy(&(entry->var.VendorGuid), &EFI_HIBERNATE_GUID, 
sizeof(efi_guid_t));
+
+   /* existing flag may set by userland, respect it do not overwrite */
+   datasize = 0;
+   ret = efivar_entry_size(entry, &datasize);
+   if (!ret && datasize > 0) {
+   kfree(entry);
+   return 0;
+   }
+
+   /* set flag of key-pair regeneration */
+   gens4key = 1;
+   ret = efivar_entry_set(entry,
+  EFI_VARIABLE_NON_VOLATILE |
+  EFI_VARIABLE_BOOTSERVICE_ACCESS |
+  EFI_VARIABLE_RUNTIME_ACCESS,
+  1, (void *)&gens4key, false);
+   if (ret)
+   pr_err("PM: Set GenS4Key flag fail: %d\n", ret);
+
+   kfree(entry);
+
+   return ret;
+#else
+   return 0;
+#endif
+}
+
+static int clean_key_regen_flag(void)
+{
+   struct efivar_entry *entry;
+   int ret;
+
+   entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+  

[PATCH V4 13/15] Hibernate: introduced SNAPSHOT_SIG_HASH config for select hash algorithm

2013-09-14 Thread Lee, Chun-Yi
This patch introduced SNAPSHOT_SIG_HASH config for user to select which
hash algorithm will be used during signature generation of snapshot.

v2:
Add define check of oCONFIG_SNAPSHOT_VERIFICATION in snapshot.c before
declare pkey_hash().

Reviewed-by: Jiri Kosina 
Signed-off-by: Lee, Chun-Yi 
---
 kernel/power/Kconfig|   46 ++
 kernel/power/snapshot.c |   25 -
 2 files changed, 66 insertions(+), 5 deletions(-)

diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index b592d88..79b34fa 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -78,6 +78,52 @@ config SNAPSHOT_VERIFICATION
  dependent on UEFI environment. EFI bootloader should generate the
  key-pair.
 
+choice
+   prompt "Which hash algorithm should snapshot be signed with?"
+depends on SNAPSHOT_VERIFICATION
+help
+  This determines which sort of hashing algorithm will be used during
+  signature generation of snapshot. This algorithm _must_ be built into
+ the kernel directly so that signature verification can take place.
+ It is not possible to load a signed snapshot containing the algorithm
+ to check the signature on that module.
+
+config SNAPSHOT_SIG_SHA1
+bool "Sign modules with SHA-1"
+select CRYPTO_SHA1
+   select CRYPTO_SHA1_SSSE3 if X86_64
+
+config SNAPSHOT_SIG_SHA224
+bool "Sign modules with SHA-224"
+select CRYPTO_SHA256
+   select CRYPTO_SHA256_SSSE3 if X86_64
+
+config SNAPSHOT_SIG_SHA256
+bool "Sign modules with SHA-256"
+select CRYPTO_SHA256
+   select CRYPTO_SHA256_SSSE3 if X86_64
+
+config SNAPSHOT_SIG_SHA384
+bool "Sign modules with SHA-384"
+select CRYPTO_SHA512
+   select CRYPTO_SHA512_SSSE3 if X86_64
+
+config SNAPSHOT_SIG_SHA512
+bool "Sign modules with SHA-512"
+select CRYPTO_SHA512
+   select CRYPTO_SHA512_SSSE3 if X86_64
+
+endchoice
+
+config SNAPSHOT_SIG_HASH
+string
+depends on SNAPSHOT_VERIFICATION
+default "sha1" if SNAPSHOT_SIG_SHA1
+default "sha224" if SNAPSHOT_SIG_SHA224
+default "sha256" if SNAPSHOT_SIG_SHA256
+default "sha384" if SNAPSHOT_SIG_SHA384
+default "sha512" if SNAPSHOT_SIG_SHA512
+
 config PM_STD_PARTITION
string "Default resume partition"
depends on HIBERNATION
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index 804feb6..896f11d 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -1041,7 +1041,22 @@ static inline void copy_data_page(unsigned long dst_pfn, 
unsigned long src_pfn)
 #endif /* CONFIG_HIGHMEM */
 
 #ifdef CONFIG_SNAPSHOT_VERIFICATION
-#define SNAPSHOT_HASH "sha256"
+static const char *snapshot_hash = CONFIG_SNAPSHOT_SIG_HASH;
+
+static int pkey_hash(void)
+{
+   int i, ret;
+
+   ret = -1;
+   for (i = 0; i < PKEY_HASH__LAST; i++) {
+   if (!strcmp(pkey_hash_algo[i], snapshot_hash)) {
+   ret = i;
+   break;
+   }
+   }
+
+   return ret;
+}
 #endif
 
 /*
@@ -1074,7 +1089,7 @@ swsusp_generate_signature(struct memory_bitmap *copy_bm, 
unsigned int nr_pages)
int ret, i;
 
ret = -ENOMEM;
-   tfm = crypto_alloc_shash(SNAPSHOT_HASH, 0, 0);
+   tfm = crypto_alloc_shash(snapshot_hash, 0, 0);
if (IS_ERR(tfm)) {
pr_err("IS_ERR(tfm): %ld", PTR_ERR(tfm));
return PTR_ERR(tfm);
@@ -1127,7 +1142,7 @@ swsusp_generate_signature(struct memory_bitmap *copy_bm, 
unsigned int nr_pages)
goto error_key;
}
 
-   pks = generate_signature(s4_sign_key, digest, PKEY_HASH_SHA256, false);
+   pks = generate_signature(s4_sign_key, digest, pkey_hash(), false);
if (IS_ERR(pks)) {
pr_err("Generate signature fail: %lx", PTR_ERR(pks));
ret = PTR_ERR(pks);
@@ -2491,7 +2506,7 @@ int snapshot_verify_signature(u8 *digest, size_t 
digest_size)
pr_err("PM: Allocate public key signature fail!");
return -ENOMEM;
}
-   pks->pkey_hash_algo = PKEY_HASH_SHA256;
+   pks->pkey_hash_algo = pkey_hash();
pks->digest = digest;
pks->digest_size = digest_size;
 
@@ -2544,7 +2559,7 @@ int snapshot_image_verify(void)
if (ret)
goto forward_ret;
 
-   tfm = crypto_alloc_shash(SNAPSHOT_HASH, 0, 0);
+   tfm = crypto_alloc_shash(snapshot_hash, 0, 0);
if (IS_ERR(tfm)) {
pr_err("IS_ERR(tfm): %ld", PTR_ERR(tfm));
return PTR_ERR(tfm);
-- 
1.6.0.2

--
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 V4 09/15] Hibernate: generate and verify signature of snapshot

2013-09-14 Thread Lee, Chun-Yi
This patch add the code for generate/verify signature of snapshot, it
put the signature to snapshot header. This approach can support both
on userspace hibernate and in-kernel hibernate.

v3:
- Change the naming of SIG_LENG to SIG_LEN
- Extracts the code of signature generation code from copy_data_pages() to
  swsusp_generate_signature(), call it in swsusp_save() after copy_data_pages()
  finished.
- Change the naming of h_buf to handle_buffers.
- Removed duplicate code in snapshot_verify_signature() and
  snapshot_image_verify().
- Merged [PATCH 14/18]
  Hibernate: applied SNAPSHOT_VERIFICATION config to switch signature check

v2:
- Due to loaded S4 sign key before ExitBootServices, we need forward key from
  boot kernel to resume target kernel. So this patch add a empty page in
  snapshot image, then we keep the pfn of this empty page in snapshot header.
  When system resume from hibernate, we fill new sign key to this empty page
  space after snapshot image checked pass. This mechanism let boot kernel can
  forward new sign key to resume target kernel but don't need write new private
  key to any other storage, e.g. swap.

Cc: Matthew Garrett 
Cc: Pavel Machek 
Reviewed-by: Jiri Kosina 
Signed-off-by: Lee, Chun-Yi 
---
 kernel/power/power.h|   13 ++
 kernel/power/snapshot.c |  288 ++-
 kernel/power/swap.c |4 +
 kernel/power/user.c |5 +
 4 files changed, 307 insertions(+), 3 deletions(-)

diff --git a/kernel/power/power.h b/kernel/power/power.h
index 661f124..d2da75b 100644
--- a/kernel/power/power.h
+++ b/kernel/power/power.h
@@ -3,6 +3,9 @@
 #include 
 #include 
 
+/* The maximum length of snapshot signature */
+#define SIG_LEN 512
+
 struct swsusp_info {
struct new_utsname  uts;
u32 version_code;
@@ -11,6 +14,8 @@ struct swsusp_info {
unsigned long   image_pages;
unsigned long   pages;
unsigned long   size;
+   unsigned long   sig_forward_info_pfn;
+   u8  signature[SIG_LEN];
 } __attribute__((aligned(PAGE_SIZE)));
 
 #ifdef CONFIG_HIBERNATION
@@ -134,6 +139,14 @@ extern int snapshot_read_next(struct snapshot_handle 
*handle);
 extern int snapshot_write_next(struct snapshot_handle *handle);
 extern void snapshot_write_finalize(struct snapshot_handle *handle);
 extern int snapshot_image_loaded(struct snapshot_handle *handle);
+#ifdef CONFIG_SNAPSHOT_VERIFICATION
+extern int snapshot_image_verify(void);
+#else
+static inline int snapshot_image_verify(void)
+{
+   return 0;
+}
+#endif
 
 /* If unset, the snapshot device cannot be open. */
 extern atomic_t snapshot_device_available;
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index 349587b..edab31f 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -27,6 +27,9 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 
 #include 
 #include 
@@ -1031,6 +1034,126 @@ static inline void copy_data_page(unsigned long 
dst_pfn, unsigned long src_pfn)
 }
 #endif /* CONFIG_HIGHMEM */
 
+#ifdef CONFIG_SNAPSHOT_VERIFICATION
+#define SNAPSHOT_HASH "sha256"
+#endif
+
+/*
+ * Signature of snapshot for check.
+ */
+static u8 signature[SIG_LEN];
+
+/*
+ * Keep the pfn of forward information buffer from resume target. We write
+ * the next time sign key to this page in snapshot image before restore.
+ */
+unsigned long sig_forward_info_pfn;
+
+void **handle_buffers;
+void *sig_forward_info_buf;
+
+static int
+swsusp_generate_signature(struct memory_bitmap *copy_bm, unsigned int nr_pages)
+{
+#ifdef CONFIG_SNAPSHOT_VERIFICATION
+   unsigned long pfn;
+   struct page *d_page;
+   void *hash_buffer = NULL;
+   struct crypto_shash *tfm;
+   struct shash_desc *desc;
+   u8 *digest;
+   size_t digest_size, desc_size;
+   struct key *s4_sign_key;
+   struct public_key_signature *pks;
+   int ret, i;
+
+   ret = -ENOMEM;
+   tfm = crypto_alloc_shash(SNAPSHOT_HASH, 0, 0);
+   if (IS_ERR(tfm)) {
+   pr_err("IS_ERR(tfm): %ld", PTR_ERR(tfm));
+   return PTR_ERR(tfm);
+   }
+
+   desc_size = crypto_shash_descsize(tfm) + sizeof(*desc);
+   digest_size = crypto_shash_digestsize(tfm);
+   digest = kzalloc(digest_size + desc_size, GFP_KERNEL);
+   if (!digest) {
+   pr_err("digest allocate fail");
+   ret = -ENOMEM;
+   goto error_digest;
+   }
+   desc = (void *) digest + digest_size;
+   desc->tfm = tfm;
+   desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
+   ret = crypto_shash_init(desc);
+   if (ret < 0)
+   goto error_shash;
+
+   memory_bm_position_reset(copy_bm);
+   for (i = 0; i < nr_pages; i++) {
+   pfn = memory_bm_next_pfn(copy_bm);
+
+   /* Generate digest */
+   d_page = pfn_to_page(pfn);
+   if (PageHighMem(d_page)) {
+ 

[PATCH V4 08/15] Hibernate: introduced RSA key-pair to verify signature of snapshot

2013-09-14 Thread Lee, Chun-Yi
Introduced a hibernate_key.c file to query the key pair from EFI variables
and maintain key pair for check signature of S4 snapshot image. We
loaded the private key when snapshot image stored success.

This patch introduced 2 EFI variables for store the key to sign S4 image and
verify signature when S4 wake up. The names and GUID are:
  S4SignKey-fe141863-c070-478e-b8a3-878a5dc9ef21[BOOT SERVICES][NV]
  S4WakeKey-fe141863-c070-478e-b8a3-878a5dc9ef21[RUNTIME SERVICES][V]

S4SignKey is used by EFI bootloader to pass the RSA private key that packaged
by PKCS#8 format, kernel will read and parser it when system boot and reload
it when S4 resume. EFI bootloader need gnerate a new private key when every
time system boot.

S4WakeKey is used to parse the RSA public key that packaged by X.509
certificate, kernel will read and parse it for check the signature of
S4 snapshot image when S4 resume.

The follow-up patch will remove S4SignKey and S4WakeKey after load them
to kernel for avoid anyone can access it through efivarfs.

V4:
- Removed duplicate cast of params->hdr.setup_data
- Declare dummy function of setup_s4_keys() and efi_reserve_s4_skey_data() to
  avoid ifdef.
- Use forward_info structure to maintain the empty of forward information and
  new sign key from boot kernel to resume target kernel.
- Use efivar API to access S4WakeKey variable.

V3:
- Load S4 sign key before ExitBootServices.
  Load private key before ExitBootServices() then bootloader doesn't need
  generate key-pair for each booting:
   + Add setup_s4_keys() to eboot.c to load S4 sign key before ExitBootServices.
   + Reserve the memory block of sign key data blob in efi.c
- In Makefile, moved hibernate_keys.o before hibernate.o for load S4 sign
  key before check hibernate image. It makes sure the new sign key will be
  transfer to resume target kernel.
- Set "depends on EFI_STUB" in Kconfig

V2:
Add CONFIG_SNAPSHOT_VERIFICATION for build of hibernate_keys.c depend on
Kconfig.

Cc: Matthew Garrett 
Cc: Takashi Iwai 
Reviewed-by: Jiri Kosina 
Signed-off-by: Lee, Chun-Yi 
---
 arch/x86/boot/compressed/eboot.c  |   92 +++
 arch/x86/include/asm/efi.h|9 +
 arch/x86/include/uapi/asm/bootparam.h |1 +
 arch/x86/platform/efi/efi.c   |   68 
 include/linux/efi.h   |   25 +++
 kernel/power/Kconfig  |   16 ++-
 kernel/power/Makefile |1 +
 kernel/power/hibernate.c  |2 +
 kernel/power/hibernate_keys.c |  292 +
 kernel/power/power.h  |   30 
 10 files changed, 534 insertions(+), 2 deletions(-)
 create mode 100644 kernel/power/hibernate_keys.c

diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index 53bfe4f..983dc7d 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -369,6 +369,96 @@ free_handle:
return status;
 }
 
+#ifdef CONFIG_SNAPSHOT_VERIFICATION
+static efi_status_t setup_s4_keys(struct boot_params *params)
+{
+   struct setup_data *data;
+   unsigned long datasize;
+   u32 attr;
+   struct efi_s4_key *s4key;
+   efi_status_t status;
+
+   data = (struct setup_data *)params->hdr.setup_data;
+
+   while (data && data->next)
+   data = (struct setup_data *)(unsigned long)data->next;
+
+   status = efi_call_phys3(sys_table->boottime->allocate_pool,
+   EFI_LOADER_DATA, sizeof(*s4key), &s4key);
+   if (status != EFI_SUCCESS) {
+   efi_printk("Failed to alloc memory for efi_s4_key\n");
+   goto error_setup;
+   }
+
+   s4key->data.type = SETUP_S4_KEY;
+   s4key->data.len = sizeof(struct efi_s4_key) -
+   sizeof(struct setup_data);
+   s4key->data.next = 0;
+   s4key->skey_dsize = 0;
+   s4key->err_status = 0;
+
+   if (data)
+   data->next = (unsigned long)s4key;
+   else
+   params->hdr.setup_data = (unsigned long)s4key;
+
+   /* obtain the size of key data */
+   datasize = 0;
+   status = efi_call_phys5(sys_table->runtime->get_variable,
+   EFI_S4_SIGN_KEY_NAME, &EFI_HIBERNATE_GUID,
+   NULL, &datasize, NULL);
+   if (status != EFI_BUFFER_TOO_SMALL) {
+   efi_printk("Couldn't get S4 key data size\n");
+   goto error_size;
+   }
+   if (datasize > SKEY_DBUF_MAX_SIZE) {
+   efi_printk("The size of S4 sign key is too large\n");
+   status = EFI_UNSUPPORTED;
+   goto error_size;
+   }
+
+   s4key->skey_dsize = datasize;
+   status = efi_call_phys3(sys_table->boottime->allocate_pool,
+   EFI_LOADER_DATA, s4key->skey_dsize,
+   &s4key->skey_data_addr);
+   if (status != EFI_SUCCESS) {
+   efi_printk("Failed to 

[PATCH V4 04/15] asymmetric keys: implement OS2IP in rsa

2013-09-14 Thread Lee, Chun-Yi
Implement Octet String to Integer conversion [RFC3447 sec 4.2] in rsa.c. It's
the second step of signature generation operation.

This patch is temporary set non-RSASP1 message to pks->S for debugging.

The naming of RSA_OS2IP and the variables used in this function accord PKCS#1
spec but not follow kernel naming convention, it useful when look at them with
spec.

Reference: ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1v2/pkcs1ietffinal.txt
Reference: 
http://www.emc.com/collateral/white-papers/h11300-pkcs-1v2-2-rsa-cryptography-standard-wp.pdf

Cc: Pavel Machek 
Reviewed-by: Jiri Kosina 
Signed-off-by: Lee, Chun-Yi 
---
 crypto/asymmetric_keys/rsa.c |   29 -
 1 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/crypto/asymmetric_keys/rsa.c b/crypto/asymmetric_keys/rsa.c
index aac8b77..a092aac 100644
--- a/crypto/asymmetric_keys/rsa.c
+++ b/crypto/asymmetric_keys/rsa.c
@@ -168,6 +168,20 @@ static int RSA_I2OSP(MPI x, size_t xLen, u8 **_X)
 }
 
 /*
+ * Octet String to Integer conversion [RFC3447 sec 4.2]
+ */
+static int RSA_OS2IP(u8 *X, size_t XLen, MPI *_x)
+{
+   MPI x;
+
+   x = mpi_alloc((XLen + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB);
+   mpi_set_buffer(x, X, XLen, 0);
+
+   *_x = x;
+   return 0;
+}
+
+/*
  * EMSA_PKCS1-v1_5-ENCODE [RFC3447 sec 9.2]
  * @M: message to be signed, an octet string
  * @emLen: intended length in octets of the encoded message
@@ -419,6 +433,9 @@ static struct public_key_signature *RSA_generate_signature(
 {
struct public_key_signature *pks;
u8 *EM = NULL;
+   MPI m = NULL;
+   MPI s = NULL;
+   unsigned X_size;
size_t emLen;
int ret;
 
@@ -438,14 +455,16 @@ static struct public_key_signature 
*RSA_generate_signature(
if (ret < 0)
goto error_v1_5_encode;
 
-   /* TODO 2): m = OS2IP (EM) */
+   /* 2): m = OS2IP (EM) */
+   ret = RSA_OS2IP(EM, emLen, &m);
+   if (ret < 0)
+   goto error_v1_5_encode;
 
/* TODO 3): s = RSASP1 (K, m) */
+   s = m;
 
-   /* TODO 4): S = I2OSP (s, k) */
-
-   /* TODO: signature S to a u8* S or set to sig->rsa.s? */
-   pks->S = EM;/* TODO: temporary set S to EM */
+   /* 4): S = I2OSP (s, k) */
+   _RSA_I2OSP(s, &X_size, &pks->S);
 
return pks;
 
-- 
1.6.0.2

--
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 V4 05/15] asymmetric keys: implement RSASP1

2013-09-14 Thread Lee, Chun-Yi
Implement RSASP1 and fill-in the following data to public key signature
structure: signature length (pkcs->k), signature octet
strings (pks->S) and MPI of signature (pks->rsa.s).

The naming of RSASP1 and the variables used in this function accord PKCS#1
spec but not follow kernel naming convention, it useful when look at them with
spec.

Reference: ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1v2/pkcs1ietffinal.txt
Reference: 
http://www.emc.com/collateral/white-papers/h11300-pkcs-1v2-2-rsa-cryptography-standard-wp.pdf

Cc: Pavel Machek 
Reviewed-by: Jiri Kosina 
Signed-off-by: Lee, Chun-Yi 
---
 crypto/asymmetric_keys/rsa.c |   47 +++--
 1 files changed, 44 insertions(+), 3 deletions(-)

diff --git a/crypto/asymmetric_keys/rsa.c b/crypto/asymmetric_keys/rsa.c
index a092aac..0ede317 100644
--- a/crypto/asymmetric_keys/rsa.c
+++ b/crypto/asymmetric_keys/rsa.c
@@ -86,6 +86,39 @@ static const struct {
 };
 
 /*
+ * RSASP1() function [RFC3447 sec 5.2.1]
+ */
+static int RSASP1(const struct private_key *key, MPI m, MPI *_s)
+{
+   MPI s;
+   int ret;
+
+   /* (1) Validate 0 <= m < n */
+   if (mpi_cmp_ui(m, 0) < 0) {
+   kleave(" = -EBADMSG [m < 0]");
+   return -EBADMSG;
+   }
+   if (mpi_cmp(m, key->rsa.n) >= 0) {
+   kleave(" = -EBADMSG [m >= n]");
+   return -EBADMSG;
+   }
+
+   s = mpi_alloc(0);
+   if (!s)
+   return -ENOMEM;
+
+   /* (2) s = m^d mod n */
+   ret = mpi_powm(s, m, key->rsa.d, key->rsa.n);
+   if (ret < 0) {
+   mpi_free(s);
+   return ret;
+   }
+
+   *_s = s;
+   return 0;
+}
+
+/*
  * RSAVP1() function [RFC3447 sec 5.2.2]
  */
 static int RSAVP1(const struct public_key *key, MPI s, MPI *_m)
@@ -173,9 +206,12 @@ static int RSA_I2OSP(MPI x, size_t xLen, u8 **_X)
 static int RSA_OS2IP(u8 *X, size_t XLen, MPI *_x)
 {
MPI x;
+   int ret;
 
x = mpi_alloc((XLen + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB);
-   mpi_set_buffer(x, X, XLen, 0);
+   ret = mpi_set_buffer(x, X, XLen, 0);
+   if (ret < 0)
+   return ret;
 
*_x = x;
return 0;
@@ -460,8 +496,13 @@ static struct public_key_signature *RSA_generate_signature(
if (ret < 0)
goto error_v1_5_encode;
 
-   /* TODO 3): s = RSASP1 (K, m) */
-   s = m;
+   /* 3): s = RSASP1 (K, m) */
+   RSASP1(key, m, &s);
+
+   pks->rsa.s = s;
+   pks->nr_mpi = 1;
+   pks->k = mpi_get_nbits(s);
+   pks->k = (pks->k + 7) / 8;
 
/* 4): S = I2OSP (s, k) */
_RSA_I2OSP(s, &X_size, &pks->S);
-- 
1.6.0.2

--
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 V4 06/15] asymmetric keys: support parsing PKCS #8 private key information

2013-09-14 Thread Lee, Chun-Yi
Add ASN.1 files and parser to support parsing PKCS #8 noncompressed private
key information. It's better than direct parsing pure private key because
PKCS #8 has a privateKeyAlgorithm to indicate the algorithm of private
key, e.g. RSA from PKCS #1

v2:
- Removed bitfield declare of privkey_algo in struct pkcs8_info because it does
  not help on reduce memory space.
- Replace privkey_algo by pkey_algo in struct pkcs8_info to simplify naming.

Cc: Pavel Machek 
Reviewed-by: Jiri Kosina 
Signed-off-by: Lee, Chun-Yi 
---
 crypto/asymmetric_keys/Kconfig |   11 ++
 crypto/asymmetric_keys/Makefile|   16 +++
 crypto/asymmetric_keys/pkcs8.asn1  |   19 
 crypto/asymmetric_keys/pkcs8_info_parser.c |  152 
 crypto/asymmetric_keys/pkcs8_parser.h  |   23 
 crypto/asymmetric_keys/pkcs8_private_key.c |  148 +++
 crypto/asymmetric_keys/pkcs8_rsakey.asn1   |   29 ++
 crypto/asymmetric_keys/public_key.c|1 +
 include/crypto/public_key.h|1 +
 9 files changed, 400 insertions(+), 0 deletions(-)
 create mode 100644 crypto/asymmetric_keys/pkcs8.asn1
 create mode 100644 crypto/asymmetric_keys/pkcs8_info_parser.c
 create mode 100644 crypto/asymmetric_keys/pkcs8_parser.h
 create mode 100644 crypto/asymmetric_keys/pkcs8_private_key.c
 create mode 100644 crypto/asymmetric_keys/pkcs8_rsakey.asn1

diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig
index 6d2c2ea..c0ebd57 100644
--- a/crypto/asymmetric_keys/Kconfig
+++ b/crypto/asymmetric_keys/Kconfig
@@ -35,4 +35,15 @@ config X509_CERTIFICATE_PARSER
  data and provides the ability to instantiate a crypto key from a
  public key packet found inside the certificate.
 
+config PKCS8_PRIVATE_KEY_INFO_PARSER
+   tristate "PKCS #8 private key info parser"
+   depends on ASYMMETRIC_PUBLIC_KEY_SUBTYPE
+   select ASN1
+   select OID_REGISTRY
+   select CRYPTO_SHA256
+   help
+ This option provides support for parsing PKCS #8 RSA private key info
+ format blobs for key data and provides the ability to instantiate a
+ crypto key from a private key packet.
+
 endif # ASYMMETRIC_KEY_TYPE
diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile
index 0727204..65fbc45 100644
--- a/crypto/asymmetric_keys/Makefile
+++ b/crypto/asymmetric_keys/Makefile
@@ -23,5 +23,21 @@ $(obj)/x509_cert_parser.o: $(obj)/x509-asn1.h 
$(obj)/x509_rsakey-asn1.h
 $(obj)/x509-asn1.o: $(obj)/x509-asn1.c $(obj)/x509-asn1.h
 $(obj)/x509_rsakey-asn1.o: $(obj)/x509_rsakey-asn1.c $(obj)/x509_rsakey-asn1.h
 
+#
+# PKCS8 Private Key handling
+#
+obj-$(CONFIG_PKCS8_PRIVATE_KEY_INFO_PARSER) += pkcs8_key_parser.o
+pkcs8_key_parser-y := \
+   pkcs8-asn1.o \
+   pkcs8_rsakey-asn1.o \
+   pkcs8_info_parser.o \
+   pkcs8_private_key.o
+
+$(obj)/pkcs8_info_parser.o: $(obj)/pkcs8-asn1.c $(obj)/pkcs8_rsakey-asn1.h
+$(obj)/pkcs8-asn1.o: $(obj)/pkcs8-asn1.c $(obj)/pkcs8-asn1.h
+$(obj)/pkcs8_rsakey-asn1.o: $(obj)/pkcs8_rsakey-asn1.c 
$(obj)/pkcs8_rsakey-asn1.h
+
 clean-files+= x509-asn1.c x509-asn1.h
 clean-files+= x509_rsakey-asn1.c x509_rsakey-asn1.h
+clean-files+= pkcs8-asn1.c pkcs8-asn1.h
+clean-files+= pkcs8_rsakey-asn1.c pkcs8_rsakey-asn1.h
diff --git a/crypto/asymmetric_keys/pkcs8.asn1 
b/crypto/asymmetric_keys/pkcs8.asn1
new file mode 100644
index 000..89e845d
--- /dev/null
+++ b/crypto/asymmetric_keys/pkcs8.asn1
@@ -0,0 +1,19 @@
+--
+-- Representation of RSA PKCS#8 private key information.
+--
+
+PrivateKeyInfo ::= SEQUENCE {
+   version Version,
+privateKeyAlgorithmAlgorithmIdentifier,
+   privateKey  OCTET STRING ({ pkcs8_extract_key_data })
+   -- Does not support attributes
+   -- attributes   [ 0 ] Attributes OPTIONAL
+   }
+
+-- Version ::= INTEGER { two-prime(0), multi(1) }
+Version ::= INTEGER
+
+AlgorithmIdentifier ::= SEQUENCE {
+algorithm   OBJECT IDENTIFIER ({ pkcs8_note_OID }),
+parameters  ANY OPTIONAL
+   }
diff --git a/crypto/asymmetric_keys/pkcs8_info_parser.c 
b/crypto/asymmetric_keys/pkcs8_info_parser.c
new file mode 100644
index 000..7475732
--- /dev/null
+++ b/crypto/asymmetric_keys/pkcs8_info_parser.c
@@ -0,0 +1,152 @@
+/* X.509 certificate parser
+ *
+ * Copyright (C) 2013 SUSE Linux Products GmbH. All rights reserved.
+ * Written by Lee, Chun-Yi (j...@suse.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#define pr_fmt(fmt) "PKCS8: "fmt
+#include 
+#include 
+#include 
+#include 
+#include "public_key.h"
+#include "pkcs8_parser.h"
+#include "pkcs8-asn1.h"
+#include "pkcs8_rsakey-asn1.h"
+
+struct pkcs8_pars

[PATCH V4 02/15] asymmetric keys: implement EMSA_PKCS1-v1_5-ENCODE in rsa

2013-09-14 Thread Lee, Chun-Yi
Implement EMSA_PKCS1-v1_5-ENCODE [RFC3447 sec 9.2] in rsa.c. It's the
first step of signature generation operation (RSASSA-PKCS1-v1_5-SIGN).

This patch is temporary set emLen to pks->k, and temporary set EM to
pks->S for debugging. We will replace the above values to real signature
after implement RSASP1.

The naming of EMSA_PKCS1_v1_5_ENCODE and the variables used in this function
accord PKCS#1 spec but not follow kernel naming convention, it useful when look
at them with spec.

Reference: ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1v2/pkcs1ietffinal.txt
Reference: 
http://www.emc.com/collateral/white-papers/h11300-pkcs-1v2-2-rsa-cryptography-standard-wp.pdf

V2:
- Clean up naming of variable: replace _EM by EM, replace EM by EM_tmp.
- Add comment to EMSA_PKCS1-v1_5-ENCODE function.

Cc: Pavel Machek 
Reviewed-by: Jiri Kosina 
Signed-off-by: Lee, Chun-Yi 
---
 crypto/asymmetric_keys/rsa.c |  163 +-
 include/crypto/public_key.h  |2 +
 2 files changed, 164 insertions(+), 1 deletions(-)

diff --git a/crypto/asymmetric_keys/rsa.c b/crypto/asymmetric_keys/rsa.c
index 47f3be4..352ba45 100644
--- a/crypto/asymmetric_keys/rsa.c
+++ b/crypto/asymmetric_keys/rsa.c
@@ -13,6 +13,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "public_key.h"
 #include "private_key.h"
 
@@ -152,6 +153,132 @@ static int RSA_I2OSP(MPI x, size_t xLen, u8 **_X)
 }
 
 /*
+ * EMSA_PKCS1-v1_5-ENCODE [RFC3447 sec 9.2]
+ * @M: message to be signed, an octet string
+ * @emLen: intended length in octets of the encoded message
+ * @hash_algo: hash function (option)
+ * @hash: true means hash M, otherwise M is already a digest
+ * @EM: encoded message, an octet string of length emLen
+ *
+ * This function is a implementation of the EMSA-PKCS1-v1_5 encoding operation
+ * in RSA PKCS#1 spec. It used by the signautre generation operation of
+ * RSASSA-PKCS1-v1_5 to encode message M to encoded message EM.
+ *
+ * The variables used in this function accord PKCS#1 spec but not follow kernel
+ * naming convention, it useful when look at them with spec.
+ */
+static int EMSA_PKCS1_v1_5_ENCODE(const u8 *M, size_t emLen,
+   enum pkey_hash_algo hash_algo, const bool hash,
+   u8 **EM, struct public_key_signature *pks)
+{
+   u8 *digest;
+   struct crypto_shash *tfm;
+   struct shash_desc *desc;
+   size_t digest_size, desc_size;
+   size_t tLen;
+   u8 *T, *PS, *EM_tmp;
+   int i, ret;
+
+   pr_info("EMSA_PKCS1_v1_5_ENCODE start\n");
+
+   if (!RSA_ASN1_templates[hash_algo].data)
+   ret = -ENOTSUPP;
+   else
+   pks->pkey_hash_algo = hash_algo;
+
+   /* 1) Apply the hash function to the message M to produce a hash value 
H */
+   tfm = crypto_alloc_shash(pkey_hash_algo[hash_algo], 0, 0);
+   if (IS_ERR(tfm))
+   return (PTR_ERR(tfm) == -ENOENT) ? -ENOPKG : PTR_ERR(tfm);
+
+   desc_size = crypto_shash_descsize(tfm) + sizeof(*desc);
+   digest_size = crypto_shash_digestsize(tfm);
+
+   ret = -ENOMEM;
+
+   digest = kzalloc(digest_size + desc_size, GFP_KERNEL);
+   if (!digest)
+   goto error_digest;
+   pks->digest = digest;
+   pks->digest_size = digest_size;
+
+   if (hash) {
+   desc = (void *) digest + digest_size;
+   desc->tfm = tfm;
+   desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
+
+   ret = crypto_shash_init(desc);
+   if (ret < 0)
+   goto error_shash;
+   ret = crypto_shash_finup(desc, M, sizeof(M), pks->digest);
+   if (ret < 0)
+   goto error_shash;
+   } else {
+   memcpy(pks->digest, M, pks->digest_size);
+   pks->digest_size = digest_size;
+   }
+   crypto_free_shash(tfm);
+
+   /* 2) Encode the algorithm ID for the hash function and the hash value 
into
+* an ASN.1 value of type DigestInfo with the DER. Let T be the DER 
encoding of
+* the DigestInfo value and let tLen be the length in octets of T.
+*/
+   tLen = RSA_ASN1_templates[hash_algo].size + pks->digest_size;
+   T = kmalloc(tLen, GFP_KERNEL);
+   if (!T)
+   goto error_T;
+
+   memcpy(T, RSA_ASN1_templates[hash_algo].data, 
RSA_ASN1_templates[hash_algo].size);
+   memcpy(T + RSA_ASN1_templates[hash_algo].size, pks->digest, 
pks->digest_size);
+
+   /* 3) check If emLen < tLen + 11, output "intended encoded message 
length too short" */
+   if (emLen < tLen + 11) {
+   ret = -EINVAL;
+   goto error_emLen;
+   }
+
+   /* 4) Generate an octet string PS consisting of emLen - tLen - 3 octets 
with 0xff. */
+   PS = kmalloc(emLen - tLen - 3, GFP_KERNEL);
+   if (!PS)
+   goto error_P;
+
+   for (i = 0; i < (emLen - tLen - 3); i++)
+   PS[i] = 0xff;
+
+   /* 5) Concatenate PS, the DER encoding T,

[PATCH V4 07/15] asymmetric keys: explicitly add the leading zero byte to encoded message

2013-09-14 Thread Lee, Chun-Yi
Per PKCS1 spec, the EMSA-PKCS1-v1_5 encoded message is leading by 0x00 0x01 in
its first 2 bytes. The leading zero byte is suppressed by MPI so we pass a
pointer to the _preceding_ byte to RSA_verify() in original code, but it has
risk for the byte is not zero because it's not in EM buffer's scope, neither
RSA_verify() nor mpi_get_buffer() didn't take care the leading byte.

To avoid the risk, that's better we explicitly add the leading zero byte to EM
for pass to RSA_verify(). This patch allocate a _EM buffer to capture the
result from RSA_I2OSP(), then set the first byte to zero in EM and copy the
remaining bytes from _EM.

V2:
- Check the memory allocate result of EM to avoid use it when allocate fail.

Cc: Pavel Machek 
Reviewed-by: Jiri Kosina 
Signed-off-by: Lee, Chun-Yi 
---
 crypto/asymmetric_keys/rsa.c |   20 +++-
 1 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/crypto/asymmetric_keys/rsa.c b/crypto/asymmetric_keys/rsa.c
index 0ede317..9763df7 100644
--- a/crypto/asymmetric_keys/rsa.c
+++ b/crypto/asymmetric_keys/rsa.c
@@ -408,6 +408,7 @@ static int RSA_verify_signature(const struct public_key 
*key,
/* Variables as per RFC3447 sec 8.2.2 */
const u8 *H = sig->digest;
u8 *EM = NULL;
+   u8 *EM_tmp = NULL;
MPI m = NULL;
size_t k;
 
@@ -442,19 +443,28 @@ static int RSA_verify_signature(const struct public_key 
*key,
/* (2c) Convert the message representative (m) to an encoded message
 *  (EM) of length k octets.
 *
-*  NOTE!  The leading zero byte is suppressed by MPI, so we pass a
-*  pointer to the _preceding_ byte to RSA_verify()!
+*  NOTE!  The leading zero byte is suppressed by MPI, so we add it
+*  back to EM before input to RSA_verify()!
 */
-   ret = RSA_I2OSP(m, k, &EM);
+   ret = RSA_I2OSP(m, k, &EM_tmp);
if (ret < 0)
goto error;
 
-   ret = RSA_verify(H, EM - 1, k, sig->digest_size,
+   EM = kmalloc(k, GFP_KERNEL);
+   if (!EM) {
+   ret = -ENOMEM;
+   goto error;
+   }
+   memset(EM, 0, 1);
+   memcpy(EM + 1, EM_tmp, k-1);
+
+   ret = RSA_verify(H, EM, k, sig->digest_size,
 RSA_ASN1_templates[sig->pkey_hash_algo].data,
 RSA_ASN1_templates[sig->pkey_hash_algo].size);
 
-error:
kfree(EM);
+error:
+   kfree(EM_tmp);
mpi_free(m);
kleave(" = %d", ret);
return ret;
-- 
1.6.0.2

--
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 V4 PATCH 00/15] Signature verification of hibernate snapshot

2013-09-14 Thread Lee, Chun-Yi
Hi experts,

This patchset is the implementation for signature verification of hibernate
snapshot image. The origin idea is from Jiri Kosina: Let EFI bootloader
generate key-pair in UEFI secure boot environment, then pass it to kernel
for sign/verify S4 image.

Due to there have potential threat from the S4 image hacked, it may causes
kernel lost the trust in UEFI secure boot. Hacker attack the S4 snapshot
image in swap partition through whatever exploit from another trusted OS,
and the exploit may don't need physical access machine.

So, this patchset give the ability to kernel for parsing RSA private key
from EFI bootloader, then using the private key to generate the signature
of S4 snapshot image. Kernel put the signature to snapshot header, and
verify the signature when kernel try to recover snapshot image to memory.

How To Enable
==

Set CONFIG_SNAPSHOT_VERIFICATION kernel config to enable. And you can also
choice which hash algorithm should snapshot be signed with. Then rebuild
kernel. This function depends on EFI_STUB.

Please note this function need UEFI bootloader's support to generate key-pair
in UEFI secure boot environment, e.g. shim. Current shim implementation by
Gary Lin:

Git:
 https://github.com/lcp/shim/tree/s4-key-upstream
RPM:
 https://build.opensuse.org/package/show/home:gary_lin:UEFI/shim

Please use the shim from above URL if you want to try. Please remember add
the hash of shim to db in UEFI BIOS because it didn't sign by Microsoft or
any OSV key.

The default behavior is taint kernel when signature check fail. If you want
direct fail whole hibernate snapshot restore procedure when signature check
does not pass, please use snapshot_sig_enforce kernel parameter or
CONFIG_EFI_SECURE_BOOT_SNAPSHOT_SIG_ENFORCE config.

If you want binding UEF secure boot with sig_enforce flag, then you can use
CONFIG_EFI_SECURE_BOOT_SNAPSHOT_SIG_ENFORCE config. The sig_enforce flag will
auto enabled when UEFI secure boot enabled.

Behavior
=

The RSA key-pair are generated by EFI bootloader(e.g. shim) in UEFI secure
boot environment, then put private key to S4SignKey, public key to S4WakeKey
EFI variable. Kernel's behavior as following:

 + First, EFI stub kernel will check the following 2 EFI variable:
   S4SignKey-fe141863-c070-478e-b8a3-878a5dc9ef21[BootService]
   S4WakeKey-fe141863-c070-478e-b8a3-878a5dc9ef21[Runtime][Volatile]

   S4SignKey and S4WakeKey is a RSA key-pair:
- S4SignKey is a private key that's used to generate signature of S4
  snapshot.
  The blob format of S4SignKey is PKCS#8 _uncompressed_ format, it should
  packaged a RSA private key that's followed PKCS#1.

- S4WakeKey is a public key that's used to verify signature of S4
  snapshot.
  The blob format of S4WakeKey is X.509 format, it should packaged a RSA
  public key that's followed PKCS#1.

 + EFI stub kernel will load the S4SignKey blob to RAM before ExitBootServices,
   then copy to a memory page that's maintained by hibernate_key.c. This
   private key will be used to sign snapshot when hibernate launched.

 + When sig_enforce flag set to TRUE, means force check verification pass:
- If kernel didn't find S4 key-pair, then kernel will block hibernate
  functions including kernel space and userspace hibernate.
- If snapshot signature check fail when hibernate resume, the snapshot
  restore procedure will fail and running normal boot process.

 + When sig_enforce flag set to FALSE, means not force the verification pass:
- If kernel didn't find S4 key-pair, then the hibernate function still
  available. But kernel will be tainted after hibernate resume.
- If snapshot signature check fail when hibernate resume, the snapshot
  restore procedure will allow continue. But kernel will be tainted.

On EFI bootloader side, the behavior as following:

 + EFI bootloader must generate RSA key-pair when:
- First time boot, bootloader generate key-pair when didn't find it.

- Bootloader need re-generate after found GenS4Key efi variable from OS:
GenS4Key-fe141863-c070-478e-b8a3-878a5dc9ef21   [Runtime][Non-Volatile]
  The size of GenS4Key is 1 byte, OS(kernel or userland tool) will set it to
  "1" for notify efi bootloader regenerate key-pair.

- If re-generate key-pair, bootloader need store the new public key to
  EFI bootservices variable by itself, e.g. store to NextWakeKey variable
  When system resumed from hibernate, bootloader need copy public key from
  NextWakeKey to S4WakeKey, then kernel will use it to verify snapshot
  image.

Implementation
==

Whole implementation including 3 parts: shim, asymmetric keys and hibernate:

 + shim:
   Current solution implemented by Gary Lin:
 https://github.com/lcp/shim/tree/s4-key-upstream

   Please use shim from the above URL if you want to try. Please remember add
   this shim to db because it didn't sign by Microsoft or any OSV k

Re: [RESEND PATCH v2 3/4] mm/hwpoison: fix false report 2nd try page recovery

2013-09-14 Thread Andi Kleen
> Reviewed-by: Naoya Horiguchi 
> Signed-off-by: Wanpeng Li 

Acked-by: Andi Kleen 

-Andi
--
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: [RESEND PATCH v2 4/4] mm/hwpoison: fix the lack of one reference count against poisoned page

2013-09-14 Thread Andi Kleen
> Reviewed-by: Naoya Horiguchi 
> Signed-off-by: Wanpeng Li 

Acked-by: Andi Kleen 

-Andi
--
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: [RESEND PATCH v2 2/4] mm/hwpoison: fix miss catch transparent huge page

2013-09-14 Thread Andi Kleen
> Reviewed-by: Naoya Horiguchi 
> Signed-off-by: Wanpeng Li 

Acked-by: Andi Kleen 

-Andi
--
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: [RESEND PATCH v2 1/4] mm/hwpoison: fix traverse hugetlbfs page to avoid printk flood

2013-09-14 Thread Andi Kleen
> Reviewed-by: Naoya Horiguchi 
> Signed-off-by: Wanpeng Li 

Acked-by: Andi Kleen 
--
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] argv_split: Return NULL if argument contains nonon-whitespace.

2013-09-14 Thread Tetsuo Handa
Oleg Nesterov wrote:
> > upon core dump because helper_argv[0] == NULL at
> >
> >   helper_argv = argv_split(GFP_KERNEL, cn.corename, NULL);
> >   call_usermodehelper_setup(helper_argv[0], ...);
> 
> Are you sure? See above.
> 

Yes, I'm sure. execve(NULL) from user space is safe, but
do_execve(NULL) from kernel space is not safe.

-- patch start --
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -763,6 +763,9 @@ struct file *open_exec(const char *name)
.lookup_flags = LOOKUP_FOLLOW,
};
 
+   if (WARN_ON(!name))
+   return ERR_PTR(-EINVAL);
+
file = do_filp_open(AT_FDCWD, &tmp, &open_exec_flags);
if (IS_ERR(file))
goto out;
-- patch end --

-- dmesg start --
die[3924]: segfault at 0 ip 0804839c sp bf9d3c78 error 4 in die[8048000+1000]
[ cut here ]
WARNING: CPU: 1 PID: 3925 at fs/exec.c:766 open_exec+0xfd/0x110()
Modules linked in: ipv6 binfmt_misc
CPU: 1 PID: 3925 Comm: kworker/u4:0 Not tainted 3.11.0-10050-g3711d86-dirty #111
Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference 
Platform, BIOS 6.00 08/15/2008
  c0557e9e c068909b c0139756 c067af64 0001 0f55 c068909b
 02fe c01da24d c01da24d  de754a80 df120b50  c013979b
 0009  c01da24d de6626c0 c0158c68 df120b50  
Call Trace:
 [] ? dump_stack+0x3e/0x50
 [] ? warn_slowpath_common+0x86/0xb0
 [] ? open_exec+0xfd/0x110
 [] ? open_exec+0xfd/0x110
 [] ? warn_slowpath_null+0x1b/0x20
 [] ? open_exec+0xfd/0x110
 [] ? prepare_creds+0x88/0xb0
 [] ? do_execve+0x18c/0x560
 [] ? call_usermodehelper+0xbc/0xe0
 [] ? ret_from_kernel_thread+0x1b/0x28
 [] ? call_usermodehelper+0xe0/0xe0
---[ end trace 63bb92bc8d58b0c2 ]---
Core dump to | pipe failed
-- dmesg end --

> Perhaps
> 
>   --- x/kernel/kmod.c
>   +++ x/kernel/kmod.c
>   @@ -571,6 +571,9 @@ int call_usermodehelper_exec(struct subp
>   DECLARE_COMPLETION_ONSTACK(done);
>   int retval = 0;
>
>   +   if (!sub_info->path)
>   +   return -EXXX;
>   +
>   helper_lock();
>   if (!khelper_wq || usermodehelper_disabled) {
>   retval = -EBUSY;
> 
> ?
> 

I'm OK with that.
--
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/


[RESEND PATCH v2 2/4] mm/hwpoison: fix miss catch transparent huge page

2013-09-14 Thread Wanpeng Li
Changelog:
 *v1 -> v2: reverse PageTransHuge(page) && !PageHuge(page) check 

PageTransHuge() can't guarantee the page is transparent huge page since it 
return true for both transparent huge and hugetlbfs pages. This patch fix 
it by check the page is also !hugetlbfs page.

Before patch:

[  121.571128] Injecting memory failure at pfn 23a200
[  121.571141] MCE 0x23a200: huge page recovery: Delayed
[  140.355100] MCE: Memory failure is now running on 0x23a200

After patch:

[   94.290793] Injecting memory failure at pfn 23a000
[   94.290800] MCE 0x23a000: huge page recovery: Delayed
[  105.722303] MCE: Software-unpoisoned page 0x23a000

Reviewed-by: Naoya Horiguchi 
Signed-off-by: Wanpeng Li 
---
 mm/memory-failure.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index e28ee77..b114570 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -1349,7 +1349,7 @@ int unpoison_memory(unsigned long pfn)
 * worked by memory_failure() and the page lock is not held yet.
 * In such case, we yield to memory_failure() and make unpoison fail.
 */
-   if (PageTransHuge(page)) {
+   if (!PageHuge(page) && PageTransHuge(page)) {
pr_info("MCE: Memory failure is now running on %#lx\n", pfn);
return 0;
}
-- 
1.8.1.2

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


[RESEND PATCH v2 3/4] mm/hwpoison: fix false report 2nd try page recovery

2013-09-14 Thread Wanpeng Li
If the page is poisoned by software inject w/ MF_COUNT_INCREASED flag, there
is a false report 2nd try page recovery which is not truth, this patch fix it
by report first try free buddy page recovery if MF_COUNT_INCREASED is set.

Before patch:

[  346.332041] Injecting memory failure at pfn 200010
[  346.332189] MCE 0x200010: free buddy, 2nd try page recovery: Delayed

After patch:

[  297.742600] Injecting memory failure at pfn 200010
[  297.742941] MCE 0x200010: free buddy page recovery: Delayed

Reviewed-by: Naoya Horiguchi 
Signed-off-by: Wanpeng Li 
---
 mm/memory-failure.c |6 --
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/mm/memory-failure.c b/mm/memory-failure.c
index b114570..6293164 100644
--- a/mm/memory-failure.c
+++ b/mm/memory-failure.c
@@ -1114,8 +1114,10 @@ int memory_failure(unsigned long pfn, int trapno, int 
flags)
 * shake_page could have turned it free.
 */
if (is_free_buddy_page(p)) {
-   action_result(pfn, "free buddy, 2nd try",
-   DELAYED);
+   if (flags & MF_COUNT_INCREASED)
+   action_result(pfn, "free buddy", 
DELAYED);
+   else
+   action_result(pfn, "free buddy, 2nd 
try", DELAYED);
return 0;
}
action_result(pfn, "non LRU", IGNORED);
-- 
1.7.5.4

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


[RESEND PATCH v2 4/4] mm/hwpoison: fix the lack of one reference count against poisoned page

2013-09-14 Thread Wanpeng Li
The lack of one reference count against poisoned page for hwpoison_inject w/o 
hwpoison_filter enabled result in hwpoison detect -1 users still referenced 
the page, however, the number should be 0 except the poison handler held one 
after successfully unmap. This patch fix it by hold one referenced count 
against 
poisoned page for hwpoison_inject w/ and w/o hwpoison_filter enabled.

Before patch:

[   71.902112] Injecting memory failure at pfn 224706
[   71.902137] MCE 0x224706: dirty LRU page recovery: Failed
[   71.902138] MCE 0x224706: dirty LRU page still referenced by -1 users

After patch:

[   94.710860] Injecting memory failure at pfn 215b68
[   94.710885] MCE 0x215b68: dirty LRU page recovery: Recovered

Reviewed-by: Naoya Horiguchi 
Signed-off-by: Wanpeng Li 
---
 mm/hwpoison-inject.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/mm/hwpoison-inject.c b/mm/hwpoison-inject.c
index afc2daa..4c84678 100644
--- a/mm/hwpoison-inject.c
+++ b/mm/hwpoison-inject.c
@@ -20,8 +20,6 @@ static int hwpoison_inject(void *data, u64 val)
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
 
-   if (!hwpoison_filter_enable)
-   goto inject;
if (!pfn_valid(pfn))
return -ENXIO;
 
@@ -33,6 +31,9 @@ static int hwpoison_inject(void *data, u64 val)
if (!get_page_unless_zero(hpage))
return 0;
 
+   if (!hwpoison_filter_enable)
+   goto inject;
+
if (!PageLRU(p) && !PageHuge(p))
shake_page(p, 0);
/*
-- 
1.8.1.2

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


[RESEND PATCH v2 1/4] mm/hwpoison: fix traverse hugetlbfs page to avoid printk flood

2013-09-14 Thread Wanpeng Li
madvise_hwpoison won't check if the page is small page or huge page and 
traverse 
in small page granularity against the range unconditional, which result in a 
printk 
flood "MCE xxx: already hardware poisoned" if the page is huge page. This patch 
fix 
it by increase compound_order(compound_head(page)) for huge page iterator.

Testcase:

#define _GNU_SOURCE
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define PAGES_TO_TEST 3
#define PAGE_SIZE   4096 * 512

int main(void)
{
char *mem;
int i;

mem = mmap(NULL, PAGES_TO_TEST * PAGE_SIZE,
PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | 
MAP_HUGETLB, 0, 0);

if (madvise(mem, PAGES_TO_TEST * PAGE_SIZE, MADV_HWPOISON) == -1)
return -1;

munmap(mem, PAGES_TO_TEST * PAGE_SIZE);

return 0;
}

Reviewed-by: Naoya Horiguchi 
Signed-off-by: Wanpeng Li 
---
 mm/madvise.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/mm/madvise.c b/mm/madvise.c
index 6975bc8..539eeb9 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -343,10 +343,11 @@ static long madvise_remove(struct vm_area_struct *vma,
  */
 static int madvise_hwpoison(int bhv, unsigned long start, unsigned long end)
 {
+   struct page *p;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
-   for (; start < end; start += PAGE_SIZE) {
-   struct page *p;
+   for (; start < end; start += PAGE_SIZE <<
+   compound_order(compound_head(p))) {
int ret;
 
ret = get_user_pages_fast(start, 1, 0, &p);
-- 
1.8.1.2

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


[RESEND PATCH v5 4/4] mm/vmalloc: fix show vmap_area information race with vmap_area tear down

2013-09-14 Thread Wanpeng Li
Changelog:
 *v4 -> v5: return directly for !VM_VM_AREA case and remove (VM_LAZY_FREE | 
VM_LAZY_FREEING) check 

There is a race window between vmap_area tear down and show vmap_area 
information.

AB

remove_vm_area
spin_lock(&vmap_area_lock);
va->vm = NULL;
va->flags &= ~VM_VM_AREA;
spin_unlock(&vmap_area_lock);
spin_lock(&vmap_area_lock);
if (va->flags & (VM_LAZY_FREE | 
VM_LAZY_FREEZING))
return 0;
if (!(va->flags & VM_VM_AREA)) {
seq_printf(m, 
"0x%pK-0x%pK %7ld vm_map_ram\n",
(void 
*)va->va_start, (void *)va->va_end,
va->va_end - 
va->va_start);
return 0;
}
free_unmap_vmap_area(va);
flush_cache_vunmap
free_unmap_vmap_area_noflush
unmap_vmap_area
free_vmap_area_noflush
va->flags |= VM_LAZY_FREE 

The assumption !VM_VM_AREA represents vm_map_ram allocation is introduced by 
commit: d4033afd(mm, vmalloc: iterate vmap_area_list, instead of vmlist, in 
vmallocinfo()). However, !VM_VM_AREA also represents vmap_area is being tear 
down in race window mentioned above. This patch fix it by don't dump any 
information for !VM_VM_AREA case and also remove (VM_LAZY_FREE | 
VM_LAZY_FREEING)
check since they are not possible for !VM_VM_AREA case.

Suggested-by: Joonsoo Kim 
Signed-off-by: Wanpeng Li 
---
 mm/vmalloc.c | 15 ++-
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 5368b17..9b75028 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -2582,16 +2582,13 @@ static int s_show(struct seq_file *m, void *p)
 {
struct vmap_area *va = p;
struct vm_struct *v;
-
-   if (va->flags & (VM_LAZY_FREE | VM_LAZY_FREEING))
-   return 0;
-
-   if (!(va->flags & VM_VM_AREA)) {
-   seq_printf(m, "0x%pK-0x%pK %7ld vm_map_ram\n",
-   (void *)va->va_start, (void *)va->va_end,
-   va->va_end - va->va_start);
+
+   /*
+* s_show can encounter race with remove_vm_area, !VM_VM_AREA on
+* behalf of vmap area is being tear down or vm_map_ram allocation.
+*/
+   if (!(va->flags & VM_VM_AREA))
return 0;
-   }
 
v = va->vm;
 
-- 
1.8.1.2

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


[RESEND PATCH v5 1/4] mm/vmalloc: don't set area->caller twice

2013-09-14 Thread Wanpeng Li
Changelog:
 *v1 -> v2: rebase against mmotm tree

The caller address has already been set in set_vmalloc_vm(), there's no need
to set it again in __vmalloc_area_node.

Reviewed-by: Zhang Yanfei 
Signed-off-by: Wanpeng Li 
---
 mm/vmalloc.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 1074543..d78d117 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -1566,7 +1566,6 @@ static void *__vmalloc_area_node(struct vm_struct *area, 
gfp_t gfp_mask,
pages = kmalloc_node(array_size, nested_gfp, node);
}
area->pages = pages;
-   area->caller = caller;
if (!area->pages) {
remove_vm_area(area->addr);
kfree(area);
-- 
1.8.1.2

--
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] kthread: Make kthread_create() killable.

2013-09-14 Thread Tetsuo Handa
Oleg Nesterov wrote:
> I am wondering if this can be simplified...
> 
> At least you can move create->done from kthread_create_info to the
> stack, and turn create->owner into the pointer to that completion.

Use of DECLARE_COMPLETION_ONSTACK() looks harmful to me because current thread
needs to be able to terminate as soon as possible if SIGKILLed (especially when
SIGKILLed by OOM killer). If we move something from kmalloc()ed zone to stack,
current thread cannot be terminated until that something is guaranteed to no
longer be used.

I think we need to convert from on-stack objects to kmalloc()ed objects so that
current thread acquires ability to terminate as soon as possible.
--
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/


[RESEND PATCH v5 2/4] mm/vmalloc: revert "mm/vmalloc.c: emit the failure message before return"

2013-09-14 Thread Wanpeng Li
Changelog:
 *v2 -> v3: revert commit 46c001a2 directly

Don't warning twice in __vmalloc_area_node and __vmalloc_node_range if
__vmalloc_area_node allocation failure. This patch revert commit 46c001a2
(mm/vmalloc.c: emit the failure message before return).

Reviewed-by: Zhang Yanfei 
Signed-off-by: Wanpeng Li 
---
 mm/vmalloc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index d78d117..e3ec8b4 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -1635,7 +1635,7 @@ void *__vmalloc_node_range(unsigned long size, unsigned 
long align,
 
addr = __vmalloc_area_node(area, gfp_mask, prot, node, caller);
if (!addr)
-   goto fail;
+   return NULL;
 
/*
 * In this function, newly allocated vm_struct has VM_UNINITIALIZED
-- 
1.8.1.2

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


[RESEND PATCH v5 3/4] mm/vmalloc: revert "mm/vmalloc.c: check VM_UNINITIALIZED flag in s_show instead of show_numa_info"

2013-09-14 Thread Wanpeng Li
Changelog:
 *v2 -> v3: revert commit d157a558 directly

The VM_UNINITIALIZED/VM_UNLIST flag introduced by commit f5252e00(mm: avoid
null pointer access in vm_struct via /proc/vmallocinfo) is used to avoid
accessing the pages field with unallocated page when show_numa_info() is
called. This patch move the check just before show_numa_info in order that
some messages still can be dumped via /proc/vmallocinfo. This patch revert 
commit d157a558 (mm/vmalloc.c: check VM_UNINITIALIZED flag in s_show instead 
of show_numa_info);

Reviewed-by: Zhang Yanfei 
Signed-off-by: Wanpeng Li 
---
 mm/vmalloc.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index e3ec8b4..5368b17 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -2562,6 +2562,11 @@ static void show_numa_info(struct seq_file *m, struct 
vm_struct *v)
if (!counters)
return;
 
+   /* Pair with smp_wmb() in clear_vm_uninitialized_flag() */
+   smp_rmb();
+   if (v->flags & VM_UNINITIALIZED)
+   return;
+
memset(counters, 0, nr_node_ids * sizeof(unsigned int));
 
for (nr = 0; nr < v->nr_pages; nr++)
@@ -2590,11 +2595,6 @@ static int s_show(struct seq_file *m, void *p)
 
v = va->vm;
 
-   /* Pair with smp_wmb() in clear_vm_uninitialized_flag() */
-   smp_rmb();
-   if (v->flags & VM_UNINITIALIZED)
-   return 0;
-
seq_printf(m, "0x%pK-0x%pK %7ld",
v->addr, v->addr + v->size, v->size);
 
-- 
1.8.1.2

--
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: scripts/config: fix variable substitution command

2013-09-14 Thread Yann E. MORIN
Sedat, All,

On 2013-09-14 16:43 +0200, Sedat Dilek spake thusly:
> On Sat, Sep 14, 2013 at 4:21 PM, Clément Chauplannaz  
> wrote:
> > 2013/9/14 Sedat Dilek :
[--SNIP--]
> >> So, can you point me/us to the correct commit with subject, please?!
> >
> > My apologies for that mistake. The initial commit, as present in Linus 
> > tree, is:
> > 83e8b90e1d2cc5ff5d2443f2486c2d786a4997ce - scripts/config: use sed's
> > POSIX interface
> >
> > Thus, the commit message for this patch should read:
> > scripts/config: fix variable substitution command
> >
> > Commit 83e8b90e1d2cc5ff5d2443f2486c2d786a4997ce ("scripts/config: use sed's
> > POSIX interface") accidentally changed the separator between sed `s' command
> > and its parameters from ':' to '/'.
> >
> > Revert this change.
> >
> > Reported-and-tested-by: Linus Walleij 
> > Signed-off-by: Clement Chauplannaz 
> > Signed-off-by: Michal Marek 
> >
> 
> What means "pending" [1]?

The current script had a latent bug that would trigger when the user want
to set a string that contains a colon ':'.

This behaviour was changed by Clément, and the bug was then about strings
with a '/' instead. This was a regression for some users.

The behaviour was then reverted to break on strings containing ':'.

What is pending is a final fix that will fix both cases.

> Pending in sense of "we are working on it" or in the sense of
> "exists-but-not-published".

The final fix is trivial and identified, so I guess that Clément has yet
had time to send the patch.

> I did not found a hint on the offline linux-kbuild ML.

That would be Michal's suggestion there:
http://marc.info/?l=linux-kbuild&m=137907001305533&w=2

> BTW, the GIT repo of Yann is not browsable (which is sh*t for checking
> commits quickl, I don't want to be forced to checkout).

Yes, I know about that one. I've already notified the gitorious guys
about the issue, they supposedly fixed it, but it is broken again.

I will re-open my ticket in a moment.

Regards,
Yann E. MORIN.

-- 
.-..--..
|  Yann E. MORIN  | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: |
| +33 662 376 056 | Software  Designer | \ / CAMPAIGN |  ___   |
| +33 223 225 172 `.---:  X  AGAINST  |  \e/  There is no  |
| http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL|   v   conspiracy.  |
'--^---^--^'
--
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: scripts/config: fix variable substitution command

2013-09-14 Thread Yann E. MORIN
Sedat, All,

On 2013-09-14 14:21 +0200, Sedat Dilek spake thusly:
> The ChangeLog from [1] says:
> 
> Commit 229455bc02b87f7128f190c4491b4ce38648 accidentally changed
> the separator between sed `s' command and its parameters from ':' to
> '/'.
> Revert this change.
[--SNIP--]
> Is this patch even "CC: stable"?

It was not in any previous released version, since it went in Linus'
tree for 3.12. As such, it does not make sense to Cc: stable.

Regards,
Yann E. MORIN.

-- 
.-..--..
|  Yann E. MORIN  | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: |
| +33 662 376 056 | Software  Designer | \ / CAMPAIGN |  ___   |
| +33 223 225 172 `.---:  X  AGAINST  |  \e/  There is no  |
| http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL|   v   conspiracy.  |
'--^---^--^'
--
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 136/228] cpufreq: loongson2: use cpufreq_generic_init() routine

2013-09-14 Thread Aaro Koskinen
On Fri, Sep 13, 2013 at 06:31:22PM +0530, Viresh Kumar wrote:
> Use generic cpufreq_generic_init() routine instead of replicating the same 
> code
> here. This driver wasn't setting transition_latency and so is getting set to 0
> by default. Lets mark it explicitly by calling the generic routine with
> transition_latency as 0.
> 
> Cc: Aaro Koskinen 
> Cc: John Crispin 
> Signed-off-by: Viresh Kumar 

Acked-by: Aaro Koskinen 

BTW, this is not ARM but MIPS board, so adding linux-mips to CC.

A.

> ---
>  drivers/cpufreq/loongson2_cpufreq.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/drivers/cpufreq/loongson2_cpufreq.c 
> b/drivers/cpufreq/loongson2_cpufreq.c
> index dd4f3e4..2c8ec8e 100644
> --- a/drivers/cpufreq/loongson2_cpufreq.c
> +++ b/drivers/cpufreq/loongson2_cpufreq.c
> @@ -131,8 +131,7 @@ static int loongson2_cpufreq_cpu_init(struct 
> cpufreq_policy *policy)
>   return ret;
>   }
>  
> - return cpufreq_table_validate_and_show(policy,
> - &loongson2_clockmod_table[0]);
> + return cpufreq_generic_init(policy, &loongson2_clockmod_table[0], 0);
>  }
>  
>  static int loongson2_cpufreq_exit(struct cpufreq_policy *policy)
> -- 
> 1.7.12.rc2.18.g61b472e
> 
--
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 2/2] ipc/sem.c: optimize sem_lock().

2013-09-14 Thread Manfred Spraul
Operations that need access to the whole array must guarantee that there are
no simple operations ongoing. Right now this is achieved by
spin_unlock_wait(sem->lock) on all semaphores.

If complex_count is nonzero, then this spin_unlock_wait() is not necessary,
because it was already performed in the past by the thread that increased
complex_count and even though sem_perm.lock was dropped inbetween, no simple
operation could have started, because simple operations cannot start when
complex_count is non-zero.

What do you think?
The patch survived some testing.

Its not a bugfix - thus I don't know if it should go into linux-next first.

Signed-off-by: Manfred Spraul 
Cc: Mike Galbraith 
Cc: Rik van Riel 
Cc: Davidlohr Bueso 
Cc: Andrew Morton 
---
 ipc/sem.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/ipc/sem.c b/ipc/sem.c
index 4836ea7..5274ed1 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -248,12 +248,20 @@ static void merge_queues(struct sem_array *sma)
  * Caller must own sem_perm.lock.
  * New simple ops can start, because simple ops first check
  * that sem_perm.lock is free.
+ * that a) sem_perm.lock is free and b) complex_count is 0.
  */
 static void sem_wait_array(struct sem_array *sma)
 {
int i;
struct sem *sem;
 
+   if (sma->complex_count)  {
+   /* The thread that increased sma->complex_count waited on
+* all sem->lock locks. Thus we don't need to wait again.
+*/
+   return;
+   }
+
for (i = 0; i < sma->sem_nsems; i++) {
sem = sma->sem_base + i;
spin_unlock_wait(&sem->lock);
-- 
1.8.3.1

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


[PATCH 1/2] ipc/sem.c: Race in sem_lock()

2013-09-14 Thread Manfred Spraul
The exclusion of complex operations in sem_lock() is insufficient:
After acquiring the per-semaphore lock, a simple op must first check that
sem_perm.lock is not locked and only after that test check complex_count.
The current code does it the other way around - and that creates a race.
Details are below.

The patch is a complete rewrite of sem_lock(), based in part on the code from
Mike Galbraith. It removes all gotos and all loops and thus the risk of
livelocks.

I have tested the patch (together with the next one) on my i3 laptop and it
didn't cause any problems.

What do you think?
I think the patch should be merged because the current sem_lock function is
much more complex than necessary.

The bug is probably also present in 3.10 and 3.11, but for these kernels
is is probably simpler just to move the test of sma->complex_count after
the spin_is_locked() test.

Details of the bug:

Assume:
- sma->complex_count = 0.
- Thread 1: semtimedop(complex op that must sleep)
- Thread 2: semtimedop(simple op).

Pseudo-Trace:

Thread 1: sem_lock(): acquire sem_perm.lock
Thread 1: sem_lock(): check for ongoing simple ops
Nothing ongoing, thread 2 is still before sem_lock().
Thread 1: try_atomic_semop()
<<< preempted.

Thread 2: sem_lock():
static inline int sem_lock(struct sem_array *sma, struct sembuf *sops,
  int nsops)
{
int locknum;
 again:
if (nsops == 1 && !sma->complex_count) {
struct sem *sem = sma->sem_base + sops->sem_num;

/* Lock just the semaphore we are interested in. */
spin_lock(&sem->lock);

/*
 * If sma->complex_count was set while we were spinning,
 * we may need to look at things we did not lock here.
 */
if (unlikely(sma->complex_count)) {
spin_unlock(&sem->lock);
goto lock_array;
}
<
<<< complex_count is still 0.
<<<
<<< Here it is preempted
<

Thread 1: try_atomic_semop() returns, notices that it must sleep.
Thread 1: increases sma->complex_count.
Thread 1: drops sem_perm.lock
Thread 2:
/*
 * Another process is holding the global lock on the
 * sem_array; we cannot enter our critical section,
 * but have to wait for the global lock to be released.
 */
if (unlikely(spin_is_locked(&sma->sem_perm.lock))) {
spin_unlock(&sem->lock);
spin_unlock_wait(&sma->sem_perm.lock);
goto again;
}
<<< sem_perm.lock already dropped, thus no "goto again;"

locknum = sops->sem_num;

Signed-off-by: Manfred Spraul 
Cc: Mike Galbraith 
Cc: Rik van Riel 
Cc: Davidlohr Bueso 
Cc: Andrew Morton 
---
 ipc/sem.c | 122 +++---
 1 file changed, 78 insertions(+), 44 deletions(-)

diff --git a/ipc/sem.c b/ipc/sem.c
index 69b6a21..4836ea7 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -244,70 +244,104 @@ static void merge_queues(struct sem_array *sma)
 }
 
 /*
+ * Wait until all currently ongoing simple ops have completed.
+ * Caller must own sem_perm.lock.
+ * New simple ops can start, because simple ops first check
+ * that sem_perm.lock is free.
+ */
+static void sem_wait_array(struct sem_array *sma)
+{
+   int i;
+   struct sem *sem;
+
+   for (i = 0; i < sma->sem_nsems; i++) {
+   sem = sma->sem_base + i;
+   spin_unlock_wait(&sem->lock);
+   }
+}
+
+/*
  * If the request contains only one semaphore operation, and there are
  * no complex transactions pending, lock only the semaphore involved.
  * Otherwise, lock the entire semaphore array, since we either have
  * multiple semaphores in our own semops, or we need to look at
  * semaphores from other pending complex operations.
- *
- * Carefully guard against sma->complex_count changing between zero
- * and non-zero while we are spinning for the lock. The value of
- * sma->complex_count cannot change while we are holding the lock,
- * so sem_unlock should be fine.
- *
- * The global lock path checks that all the local locks have been released,
- * checking each local lock once. This means that the local lock paths
- * cannot start their critical sections while the global lock is held.
  */
 static inline int sem_lock(struct sem_array *sma, struct sembuf *sops,
  int nsops)
 {
-   int locknum;
- again:
-   if (nsops == 1 && !sma->complex_count) {
-   struct sem *sem = sma->sem_base + sops->sem_num;
+   struct sem *sem;
 
-   /* Lock just the semaphore we are interes

Re: [Linaro-mm-sig] [RFC 0/1] drm/pl111: Initial drm/kms driver for pl111

2013-09-14 Thread Daniel Stone
Hi,

On Tue, 2013-08-06 at 12:31 +0100, Tom Cooksey wrote:
> > >> On Fri, Jul 26, 2013 at 11:58 AM, Tom Cooksey 
> > >> wrote:
> > that was part of the reason to punt this problem to userspace ;-)
> >
> > In practice, the kernel drivers doesn't usually know too much about
> > the dimensions/format/etc.. that is really userspace level knowledge.
> > There are a few exceptions when the kernel needs to know how to setup
> > GTT/etc for tiled buffers, but normally this sort of information is up
> > at the next level up (userspace, and drm_framebuffer in case of
> > scanout).  Userspace media frameworks like GStreamer already have a
> > concept of format/caps negotiation.  For non-display<->gpu sharing, I
> > think this is probably where this sort of constraint negotiation
> > should be handled.

Egads.  GStreamer's caps negotiation is already close to unbounded time;
seems like most of the optimisation work that goes into it these days is
all about _reducing_ the complexity of caps negotiation!

> I agree that user-space will know which devices will access the buffer
> and thus can figure out at least a common pixel format.

Hm, are you sure about that? The answer is yes for 'userspace' as a
broad handwave, but not necessarily for individual processes.  Take, for
instance, media decode through GStreamer, being displayed by Wayland
using a KMS plane/overlay/sprite/cursor/etc.  The media player knows
that the buffers are coming from the decode engine, and Wayland knows
that the buffers are going to a KMS plane, but neither of them knows the
full combination of the two.

Though this kinda feeds into an idea I've been kicking around for a
while, which is an 'optimal hint' mechanism in the Wayland protocol.  So
for our hypothetical dmabuf-using protocol, we'd start off with buffers
which satisfied all the constraints of our media decode engine, but
perhaps just the GPU rather than display controller.  At this point,
we'd note that we could place the video in a plane if only the buffers
were better-allocated, and send an event to the client letting it know
how to tweak its buffer allocation for more optimal display.

But ...

> Though I'm not
> so sure userspace can figure out more low-level details like alignment
> and placement in physical memory, etc.
> 
> Anyway, assuming user-space can figure out how a buffer should be 
> stored in memory, how does it indicate this to a kernel driver and 
> actually allocate it? Which ioctl on which device does user-space
> call, with what parameters? Are you suggesting using something like
> ION which exposes the low-level details of how buffers are laid out in
> physical memory to userspace? If not, what?

... this is still rather unresolved. ;)

Cheers,
Daniel


> 
> Cheers,
> 
> Tom
> 
> 
> 
> 
> 
> 
> ___
> Linaro-mm-sig mailing list
> linaro-mm-...@lists.linaro.org
> http://lists.linaro.org/mailman/listinfo/linaro-mm-sig


--
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 v3] dma: add driver for R-Car HPB-DMAC

2013-09-14 Thread Guennadi Liakhovetski
Hi Sergei

On Sat, 14 Sep 2013, Sergei Shtylyov wrote:

> Hello.
> 
> On 09/14/2013 10:33 PM, Guennadi Liakhovetski wrote:
> 
> > > From: Max Filippov 
> 
> > > Add support for HPB-DMAC found in Renesas R-Car SoCs, using 'shdma-base'
> > > DMA
> > > driver framework.
> 
> > > Based on the original patch by Phil Edworthy .
> 
> > > Signed-off-by: Max Filippov 
> > > [Sergei: removed useless #include, sorted #include's, fixed
> > > HPB_DMA_TCR_MAX,
> > > fixed formats and removed line breaks in the dev_dbg() calls, rephrased
> > > and
> > > added IRQ # to the shdma_request_irq() failure message, added
> > > MODULE_AUTHOR(),
> > > removed '__init'/'__exit' annotations from the probe()/remove() methods,
> > > removed
> > > '__initdata' annotation from 'hpb_dmae_driver', fixed guard macro name in
> > > the
> > > header file, fixed #define ASYNCRSTR_ASRST20, added #define
> > > ASYNCRSTR_ASRST24,
> > > added the necessary runtime PM calls to the probe() and remove() methods,
> > > handled errors returned by dma_async_device_register(), beautified
> > > comments
> > > and #define's.]
> > > Signed-off-by: Sergei Shtylyov 
> 
> > > ---
> 
> > [snip]
> 
> > > Index: slave-dma/drivers/dma/sh/rcar-hpbdma.c
> > > ===
> > > --- /dev/null
> > > +++ slave-dma/drivers/dma/sh/rcar-hpbdma.c
> > > @@ -0,0 +1,655 @@
> 
> > [snip]
> 
> > > +static int hpb_dmae_chan_probe(struct hpb_dmae_device *hpbdev, int id)
> > > +{
> > > + struct shdma_dev *sdev = &hpbdev->shdma_dev;
> > > + struct platform_device *pdev =
> > > + to_platform_device(hpbdev->shdma_dev.dma_dev.dev);
> > > + struct hpb_dmae_chan *new_hpb_chan;
> > > + struct shdma_chan *schan;
> > > +
> > > + /* Alloc channel */
> > > + new_hpb_chan = devm_kzalloc(&pdev->dev,
> > > + sizeof(struct hpb_dmae_chan), GFP_KERNEL);
> > > + if (!new_hpb_chan) {
> > > + dev_err(hpbdev->shdma_dev.dma_dev.dev,
> > > + "No free memory for allocating DMA channels!\n");
> > > + return -ENOMEM;
> > > + }
> > > +
> > > + schan = &new_hpb_chan->shdma_chan;
> 
> > A suggestion for an incremental patch - you might want to initialise the
> > max_xfer_len field like
> 
> > schan->max_xfer_len = 64 * 1024 * 1024 - 1;
> 
>IIRC, the HPB-DMAC's maximum transfer length is 16 MiB, without -1. You
> probably mixed it with LBSC-DMAC which is indeed capable of 64 MiB.

Sorry, no idea what the correct value for HPB DMAC is. This was just an 
example.

Thanks
Guennadi

> > because if it isn't initialised your max transfer length will be 4k,
> > which will hurt your performance. I think you should get a better
> > throughput after that
> 
>OK, note taken. We'll look into it.
> 
> WBR, Sergei

---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/
--
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] perf tools: New comm infrastructure

2013-09-14 Thread David Ahern

On 9/13/13 5:43 AM, Frederic Weisbecker wrote:

  The only way would be perhaps to be able to limit the deepness
of the callchain branches.


I was thinking about such a feature two days ago. Max callchain depth is 
set to 255 at compile time which can generate huge event sizes. perf 
needs to allow the user to specify max depth for an event at less than that.


David
--
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] ES938 support for ES18xx driver

2013-09-14 Thread Ondrej Zary
Hello,
this is an attempt to support ES938 3-D Audio Effects Processor found on some
ES18xx (and possibly other) sound cards, doing bass/treble and 3D control.

ES938 is controlled by MIDI SysEx commands sent through card's MPU401 port.

The following patch works but has a problem: the midi port cannot be used by
userspace applications. Opening and closing the rawmidi device on each control
change would probably work (as long as the port is not used by an application)
but that just does not seem right. Is there a way to cleanly fix this?

(There are two problems: 3D level does not have any effect and alsamixer does
not display the TLV dB values - but don't know why).

---
 sound/isa/Kconfig  |4 +
 sound/isa/Makefile |2 +
 sound/isa/es18xx.c |   12 +++-
 sound/isa/es938.c  |  181 
 sound/isa/es938.h  |   24 +++
 5 files changed, 222 insertions(+), 1 deletions(-)
 create mode 100644 sound/isa/es938.c
 create mode 100644 sound/isa/es938.h

diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig
index affa134..a8bf3e3 100644
--- a/sound/isa/Kconfig
+++ b/sound/isa/Kconfig
@@ -17,6 +17,9 @@ config SND_SB16_DSP
 select SND_PCM
 select SND_SB_COMMON
 
+config SND_ES938
+   tristate
+
 menuconfig SND_ISA
bool "ISA sound devices"
depends on ISA && ISA_DMA_API
@@ -183,6 +186,7 @@ config SND_ES18XX
select SND_OPL3_LIB
select SND_MPU401_UART
select SND_PCM
+   select SND_ES938
help
  Say Y here to include support for ESS AudioDrive ES18xx chips.
 
diff --git a/sound/isa/Makefile b/sound/isa/Makefile
index 9a15f14..d59e0bf 100644
--- a/sound/isa/Makefile
+++ b/sound/isa/Makefile
@@ -8,6 +8,7 @@ snd-als100-objs := als100.o
 snd-azt2320-objs := azt2320.o
 snd-cmi8328-objs := cmi8328.o
 snd-cmi8330-objs := cmi8330.o
+snd-es938-objs := es938.o
 snd-es18xx-objs := es18xx.o
 snd-opl3sa2-objs := opl3sa2.o
 snd-sc6000-objs := sc6000.o
@@ -19,6 +20,7 @@ obj-$(CONFIG_SND_ALS100) += snd-als100.o
 obj-$(CONFIG_SND_AZT2320) += snd-azt2320.o
 obj-$(CONFIG_SND_CMI8328) += snd-cmi8328.o
 obj-$(CONFIG_SND_CMI8330) += snd-cmi8330.o
+obj-$(CONFIG_SND_ES938) += snd-es938.o
 obj-$(CONFIG_SND_ES18XX) += snd-es18xx.o
 obj-$(CONFIG_SND_OPL3SA2) += snd-opl3sa2.o
 obj-$(CONFIG_SND_SC6000) += snd-sc6000.o
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c
index 12978b8..c502aa0 100644
--- a/sound/isa/es18xx.c
+++ b/sound/isa/es18xx.c
@@ -96,6 +96,7 @@
 #define SNDRV_LEGACY_FIND_FREE_IRQ
 #define SNDRV_LEGACY_FIND_FREE_DMA
 #include 
+#include "es938.h"
 
 #define PFX "es18xx: "
 
@@ -122,6 +123,7 @@ struct snd_es18xx {
struct snd_pcm_substream *playback_b_substream;
 
struct snd_rawmidi *rmidi;
+   struct snd_es938 es938;
 
struct snd_kcontrol *hw_volume;
struct snd_kcontrol *hw_switch;
@@ -2166,7 +2168,15 @@ static int snd_audiodrive_probe(struct snd_card *card, 
int dev)
return err;
}
 
-   return snd_card_register(card);
+   err = snd_card_register(card);
+   if (err < 0)
+   return err;
+
+   if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT)
+   if (snd_es938_init(&chip->es938, card, 0, 0) == 0)
+   printk("es938 found!\n");
+
+   return 0;
 }
 
 static int snd_es18xx_isa_match(struct device *pdev, unsigned int dev)
diff --git a/sound/isa/es938.c b/sound/isa/es938.c
new file mode 100644
index 000..cfe8ae7
--- /dev/null
+++ b/sound/isa/es938.c
@@ -0,0 +1,181 @@
+/*
+ *  Driver for ESS ES938 3-D Audio Effects Processor
+ *  Copyright (c) 2013 Ondrej Zary
+ *
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+//#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "es938.h"
+
+#define PFX "es938: "
+
+MODULE_AUTHOR("Ondrej Zary");  
+MODULE_DESCRIPTION("ESS ES938");
+MODULE_LICENSE("GPL");
+
+static int snd_es938_read_reg(struct snd_es938 *chip, u8 reg, u8 *out)
+{
+   u8 buf[8];
+   int i = 0, res;
+   u8 sysex[] = { MIDI_CMD_COMMON_SYSEX, ES938_ID, ES938_CMD_REG_R, reg,
+  MIDI_CMD_COMMON_SYSEX_END };
+
+   snd_rawmidi_kernel_write(chip->rfile.output, sysex, sizeof(sysex));
+
+   memset(buf, 0, sizeof(bu

[PATCH 1/1] isdn: hfcpci_softirq: get func return to suppress compiler warning

2013-09-14 Thread Antonio Alecrim Jr
Signed-off-by: Antonio Alecrim Jr 
---
 drivers/isdn/hardware/mISDN/hfcpci.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c 
b/drivers/isdn/hardware/mISDN/hfcpci.c
index 7f910c7..3c92780 100644
--- a/drivers/isdn/hardware/mISDN/hfcpci.c
+++ b/drivers/isdn/hardware/mISDN/hfcpci.c
@@ -2295,8 +2295,8 @@ _hfcpci_softirq(struct device *dev, void *arg)
 static void
 hfcpci_softirq(void *arg)
 {
-   (void) driver_for_each_device(&hfc_driver.driver, NULL, arg,
- _hfcpci_softirq);
+   WARN_ON_ONCE(driver_for_each_device(&hfc_driver.driver, NULL, arg,
+ _hfcpci_softirq) != 0);
 
/* if next event would be in the past ... */
if ((s32)(hfc_jiffies + tics - jiffies) <= 0)
-- 
1.8.3.1

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


[PATCH 5/7] clocksource: add latch to clocksource

2013-09-14 Thread Mathieu Desnoyers
Add latch for data used by clock read operations. This is in preparation
for the clock latch synchronization scheme. "cycle_last" rely on
timekeeper seqlock synchronization, and will therefore need to be
latched.

Add:
- cycle_last_latch (array of 2 elements),
- read_latch(),
- update_latch().

Signed-off-by: Mathieu Desnoyers 
Cc: John Stultz 
Cc: Thomas Gleixner 
Cc: Peter Zijlstra 
---
 include/linux/clocksource.h |4 
 1 file changed, 4 insertions(+)

diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h
index dbbf8aa..ef9c2e5 100644
--- a/include/linux/clocksource.h
+++ b/include/linux/clocksource.h
@@ -180,6 +180,10 @@ struct clocksource {
 #ifdef CONFIG_ARCH_CLOCKSOURCE_DATA
struct arch_clocksource_data archdata;
 #endif
+   cycle_t (*read_latch)(struct clocksource *cs, int index);
+   void (*update_latch)(struct clocksource *cs, int oldindex,
+   int newindex);
+   cycle_t cycle_last_latch[2];
 
const char *name;
struct list_head list;
-- 
1.7.10.4

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


[PATCH 1/7] Move ntp variables into struct timekeeper_ntp

2013-09-14 Thread Mathieu Desnoyers
Signed-off-by: Mathieu Desnoyers 
Cc: John Stultz 
Cc: Thomas Gleixner 
Cc: Peter Zijlstra 
---
 include/linux/timekeeper_internal.h |   47 ++
 kernel/time/ntp.c   |  318 +++
 2 files changed, 187 insertions(+), 178 deletions(-)

diff --git a/include/linux/timekeeper_internal.h 
b/include/linux/timekeeper_internal.h
index c1825eb..eab26e0 100644
--- a/include/linux/timekeeper_internal.h
+++ b/include/linux/timekeeper_internal.h
@@ -10,6 +10,53 @@
 #include 
 #include 
 
+/* structure holding internal NTP timekeeping values. */
+struct timekeeper_ntp {
+   /* USER_HZ period (usecs): */
+   unsigned long   tick_usec;
+
+   /* SHIFTED_HZ period (nsecs): */
+   unsigned long   tick_nsec;
+
+   u64 tick_length;
+   u64 tick_length_base;
+
+   /* phase-lock loop variables */
+
+   /*
+* clock synchronization status
+*
+* (TIME_ERROR prevents overwriting the CMOS clock)
+*/
+   int time_state;
+
+   /* clock status bits: */
+   int time_status;
+
+   /* time adjustment (nsecs): */
+   s64 time_offset;
+
+   /* pll time constant: */
+   longtime_constant;
+
+   /* maximum error (usecs): */
+   longtime_maxerror;
+
+   /* estimated error (usecs): */
+   longtime_esterror;
+
+   /* frequency offset (scaled nsecs/secs): */
+   s64 time_freq;
+
+   /* time at last adjustment (secs): */
+   longtime_reftime;
+
+   longtime_adjust;
+
+   /* constant (boot-param configurable) NTP tick adjustment (upscaled) */
+   s64 ntp_tick_adj;
+};
+
 /* Structure holding internal timekeeping values. */
 struct timekeeper {
/* Current clocksource used for timekeeping. */
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index bb22151..983c212 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -16,66 +16,23 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "tick-internal.h"
 #include "ntp_internal.h"
 
-/*
- * NTP timekeeping variables:
- *
- * Note: All of the NTP state is protected by the timekeeping locks.
- */
-
-
-/* USER_HZ period (usecs): */
-unsigned long  tick_usec = TICK_USEC;
-
-/* SHIFTED_HZ period (nsecs): */
-unsigned long  tick_nsec;
-
-static u64 tick_length;
-static u64 tick_length_base;
-
 #define MAX_TICKADJ500LL   /* usecs */
 #define MAX_TICKADJ_SCALED \
(((MAX_TICKADJ * NSEC_PER_USEC) << NTP_SCALE_SHIFT) / NTP_INTERVAL_FREQ)
 
-/*
- * phase-lock loop variables
- */
-
-/*
- * clock synchronization status
- *
- * (TIME_ERROR prevents overwriting the CMOS clock)
- */
-static int time_state = TIME_OK;
-
-/* clock status bits:  */
-static int time_status = STA_UNSYNC;
-
-/* time adjustment (nsecs):*/
-static s64 time_offset;
-
-/* pll time constant:  */
-static longtime_constant = 2;
-
-/* maximum error (usecs):  */
-static longtime_maxerror = NTP_PHASE_LIMIT;
-
-/* estimated error (usecs):*/
-static longtime_esterror = NTP_PHASE_LIMIT;
-
-/* frequency offset (scaled nsecs/secs):   */
-static s64 time_freq;
-
-/* time at last adjustment (secs): */
-static longtime_reftime;
-
-static longtime_adjust;
-
-/* constant (boot-param configurable) NTP tick adjustment (upscaled)   */
-static s64 ntp_tick_adj;
+static struct timekeeper_ntp tk_ntp = {
+   .tick_usec = TICK_USEC,
+   .time_state = TIME_OK,
+   .time_status = STA_UNSYNC,
+   .time_constant = 2,
+   .time_maxerror = NTP_PHASE_LIMIT,
+   .time_esterror = NTP_PHASE_LIMIT,
+};
 
 #ifdef CONFIG_NTP_PPS
 
@@ -116,10 +73,11 @@ static long pps_errcnt;/* calibration errors */
  */
 static inline s64 ntp_offset_chunk(s64 offset)
 {
-   if (time_status & STA_PPSTIME && time_status & STA_PPSSIGNAL)
+   if (tk_ntp.time_status & STA_PPSTIME
+   && tk_ntp.time_status & STA_PPSSIGNAL)
return offset;
else
-   return shift_right(offset, SHIFT_PLL + time_constant);
+   return shift_right(offset, SHIFT_PLL + tk_ntp.time_constant);
 }
 
 static inline void pps_reset_freq_interval(void)
@@ -152,7 +110,7 @@ static inline void pps_dec_val

[PATCH 6/7] x86 tsc clock: implement clock latch

2013-09-14 Thread Mathieu Desnoyers
Signed-off-by: Mathieu Desnoyers 
Cc: John Stultz 
Cc: Thomas Gleixner 
Cc: Peter Zijlstra 
---
 arch/x86/kernel/tsc.c |   22 +-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 6ff4924..c75e9f9 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -766,10 +766,28 @@ static cycle_t read_tsc(struct clocksource *cs)
ret : clocksource_tsc.cycle_last;
 }
 
+static cycle_t read_tsc_latch(struct clocksource *cs, int index)
+{
+   cycle_t ret = (cycle_t)get_cycles();
+
+   return ret >= clocksource_tsc.cycle_last_latch[index] ?
+   ret : clocksource_tsc.cycle_last_latch[index];
+}
+
+static void update_tsc_latch(struct clocksource *cs, int oldindex,
+   int newindex)
+{
+   clocksource_tsc.cycle_last_latch[newindex] =
+   clocksource_tsc.cycle_last_latch[oldindex];
+}
+
 static void resume_tsc(struct clocksource *cs)
 {
-   if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC_S3))
+   if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC_S3)) {
clocksource_tsc.cycle_last = 0;
+   clocksource_tsc.cycle_last_latch[0] = 0;
+   clocksource_tsc.cycle_last_latch[1] = 0;
+   }
 }
 
 static struct clocksource clocksource_tsc = {
@@ -783,6 +801,8 @@ static struct clocksource clocksource_tsc = {
 #ifdef CONFIG_X86_64
.archdata   = { .vclock_mode = VCLOCK_TSC },
 #endif
+   .read_latch = read_tsc_latch,
+   .update_latch   = update_tsc_latch,
 };
 
 void mark_tsc_unstable(char *reason)
-- 
1.7.10.4

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


[PATCH 3/7] Move ntp structure into struct timekeeper

2013-09-14 Thread Mathieu Desnoyers
This is in preparation for the latch synchronization scheme.

Signed-off-by: Mathieu Desnoyers 
Cc: John Stultz 
Cc: Thomas Gleixner 
Cc: Peter Zijlstra 
---
 include/linux/timekeeper_internal.h |4 +
 kernel/time/ntp.c   |  361 +--
 kernel/time/timekeeping.c   |   12 +-
 3 files changed, 191 insertions(+), 186 deletions(-)

diff --git a/include/linux/timekeeper_internal.h 
b/include/linux/timekeeper_internal.h
index 02c25c0..6f0532d 100644
--- a/include/linux/timekeeper_internal.h
+++ b/include/linux/timekeeper_internal.h
@@ -147,8 +147,12 @@ struct timekeeper {
/* Offset clock monotonic -> clock tai */
ktime_t offs_tai;
 
+   /* NTP variables */
+   struct timekeeper_ntp   ntp;
 };
 
+extern struct timekeeper timekeeper;
+
 static inline struct timespec tk_xtime(struct timekeeper *tk)
 {
struct timespec ts;
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index b095070..d61e700 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -25,15 +25,6 @@
 #define MAX_TICKADJ_SCALED \
(((MAX_TICKADJ * NSEC_PER_USEC) << NTP_SCALE_SHIFT) / NTP_INTERVAL_FREQ)
 
-static struct timekeeper_ntp tk_ntp = {
-   .tick_usec = TICK_USEC,
-   .time_state = TIME_OK,
-   .time_status = STA_UNSYNC,
-   .time_constant = 2,
-   .time_maxerror = NTP_PHASE_LIMIT,
-   .time_esterror = NTP_PHASE_LIMIT,
-};
-
 #ifdef CONFIG_NTP_PPS
 
 #define PPS_VALID  10  /* PPS signal watchdog max (s) */
@@ -50,19 +41,19 @@ static struct timekeeper_ntp tk_ntp = {
  */
 static inline s64 ntp_offset_chunk(s64 offset)
 {
-   if (tk_ntp.time_status & STA_PPSTIME
-   && tk_ntp.time_status & STA_PPSSIGNAL)
+   if (timekeeper.ntp.time_status & STA_PPSTIME
+   && timekeeper.ntp.time_status & STA_PPSSIGNAL)
return offset;
else
-   return shift_right(offset, SHIFT_PLL + tk_ntp.time_constant);
+   return shift_right(offset, SHIFT_PLL + 
timekeeper.ntp.time_constant);
 }
 
 static inline void pps_reset_freq_interval(void)
 {
/* the PPS calibration interval may end
   surprisingly early */
-   tk_ntp.pps.shift = PPS_INTMIN;
-   tk_ntp.pps.intcnt = 0;
+   timekeeper.ntp.pps.shift = PPS_INTMIN;
+   timekeeper.ntp.pps.intcnt = 0;
 }
 
 /**
@@ -71,11 +62,11 @@ static inline void pps_reset_freq_interval(void)
 static inline void pps_clear(void)
 {
pps_reset_freq_interval();
-   tk_ntp.pps.tf[0] = 0;
-   tk_ntp.pps.tf[1] = 0;
-   tk_ntp.pps.tf[2] = 0;
-   tk_ntp.pps.fbase.tv_sec = tk_ntp.pps.fbase.tv_nsec = 0;
-   tk_ntp.pps.freq = 0;
+   timekeeper.ntp.pps.tf[0] = 0;
+   timekeeper.ntp.pps.tf[1] = 0;
+   timekeeper.ntp.pps.tf[2] = 0;
+   timekeeper.ntp.pps.fbase.tv_sec = timekeeper.ntp.pps.fbase.tv_nsec = 0;
+   timekeeper.ntp.pps.freq = 0;
 }
 
 /* Decrease pps_valid to indicate that another second has passed since
@@ -84,10 +75,10 @@ static inline void pps_clear(void)
  */
 static inline void pps_dec_valid(void)
 {
-   if (tk_ntp.pps.valid > 0)
-   tk_ntp.pps.valid--;
+   if (timekeeper.ntp.pps.valid > 0)
+   timekeeper.ntp.pps.valid--;
else {
-   tk_ntp.time_status &= ~(STA_PPSSIGNAL | STA_PPSJITTER |
+   timekeeper.ntp.time_status &= ~(STA_PPSSIGNAL | STA_PPSJITTER |
 STA_PPSWANDER | STA_PPSERROR);
pps_clear();
}
@@ -95,48 +86,48 @@ static inline void pps_dec_valid(void)
 
 static inline void pps_set_freq(s64 freq)
 {
-   tk_ntp.pps.freq = freq;
+   timekeeper.ntp.pps.freq = freq;
 }
 
 static inline int is_error_status(int status)
 {
-   return (tk_ntp.time_status & (STA_UNSYNC|STA_CLOCKERR))
+   return (timekeeper.ntp.time_status & (STA_UNSYNC|STA_CLOCKERR))
/* PPS signal lost when either PPS time or
 * PPS frequency synchronization requested
 */
-   || ((tk_ntp.time_status & (STA_PPSFREQ|STA_PPSTIME))
-   && !(tk_ntp.time_status & STA_PPSSIGNAL))
+   || ((timekeeper.ntp.time_status & (STA_PPSFREQ|STA_PPSTIME))
+   && !(timekeeper.ntp.time_status & STA_PPSSIGNAL))
/* PPS jitter exceeded when
 * PPS time synchronization requested */
-   || ((tk_ntp.time_status & (STA_PPSTIME|STA_PPSJITTER))
+   || ((timekeeper.ntp.time_status & (STA_PPSTIME|STA_PPSJITTER))
== (STA_PPSTIME|STA_PPSJITTER))
/* PPS wander exceeded or calibration error when
 * PPS frequency synchronization requested
 */
-   || ((tk_ntp.time_status & STA_PPSFREQ)
-   && (tk_ntp.time_status & (STA_PPSWANDER|STA_PPSERROR)));
+   || ((timekeeper.ntp.time_status & STA_PP

[PATCH 2/7] Move PPS variables into struct timekeeper_pps

2013-09-14 Thread Mathieu Desnoyers
Signed-off-by: Mathieu Desnoyers 
Cc: John Stultz 
Cc: Thomas Gleixner 
Cc: Peter Zijlstra 
---
 include/linux/timekeeper_internal.h |   31 
 kernel/time/ntp.c   |  134 +++
 2 files changed, 87 insertions(+), 78 deletions(-)

diff --git a/include/linux/timekeeper_internal.h 
b/include/linux/timekeeper_internal.h
index eab26e0..02c25c0 100644
--- a/include/linux/timekeeper_internal.h
+++ b/include/linux/timekeeper_internal.h
@@ -10,6 +10,32 @@
 #include 
 #include 
 
+#ifdef CONFIG_NTP_PPS
+/*
+ * The following variables are used when a pulse-per-second (PPS) signal
+ * is available. They establish the engineering parameters of the clock
+ * discipline loop when controlled by the PPS signal.
+ */
+struct timekeeper_pps {
+   int valid;  /* signal watchdog counter */
+   long tf[3]; /* phase median filter */
+   long jitter;/* current jitter (ns) */
+   struct timespec fbase;  /* beginning of the last freq interval */
+   int shift;  /* current interval duration (s) (shift) */
+   int intcnt; /* interval counter */
+   s64 freq;   /* frequency offset (scaled ns/s) */
+   long stabil;/* current stability (scaled ns/s) */
+
+   /*
+* PPS signal quality monitors
+*/
+   long calcnt;/* calibration intervals */
+   long jitcnt;/* jitter limit exceeded */
+   long stbcnt;/* stability limit exceeded */
+   long errcnt;/* calibration errors */
+};
+#endif /* !CONFIG_NTP_PPS */
+
 /* structure holding internal NTP timekeeping values. */
 struct timekeeper_ntp {
/* USER_HZ period (usecs): */
@@ -55,6 +81,11 @@ struct timekeeper_ntp {
 
/* constant (boot-param configurable) NTP tick adjustment (upscaled) */
s64 ntp_tick_adj;
+
+#ifdef CONFIG_NTP_PPS
+   /* PPS variables */
+   struct timekeeper_pps   pps;
+#endif /* CONFIG_NTP_PPS */
 };
 
 /* Structure holding internal timekeeping values. */
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index 983c212..b095070 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -36,11 +36,6 @@ static struct timekeeper_ntp tk_ntp = {
 
 #ifdef CONFIG_NTP_PPS
 
-/*
- * The following variables are used when a pulse-per-second (PPS) signal
- * is available. They establish the engineering parameters of the clock
- * discipline loop when controlled by the PPS signal.
- */
 #define PPS_VALID  10  /* PPS signal watchdog max (s) */
 #define PPS_POPCORN4   /* popcorn spike threshold (shift) */
 #define PPS_INTMIN 2   /* min freq interval (s) (shift) */
@@ -50,24 +45,6 @@ static struct timekeeper_ntp tk_ntp = {
   intervals to decrease it */
 #define PPS_MAXWANDER  10  /* max PPS freq wander (ns/s) */
 
-static int pps_valid;  /* signal watchdog counter */
-static long pps_tf[3]; /* phase median filter */
-static long pps_jitter;/* current jitter (ns) */
-static struct timespec pps_fbase; /* beginning of the last freq interval */
-static int pps_shift;  /* current interval duration (s) (shift) */
-static int pps_intcnt; /* interval counter */
-static s64 pps_freq;   /* frequency offset (scaled ns/s) */
-static long pps_stabil;/* current stability (scaled ns/s) */
-
-/*
- * PPS signal quality monitors
- */
-static long pps_calcnt;/* calibration intervals */
-static long pps_jitcnt;/* jitter limit exceeded */
-static long pps_stbcnt;/* stability limit exceeded */
-static long pps_errcnt;/* calibration errors */
-
-
 /* PPS kernel consumer compensates the whole phase error immediately.
  * Otherwise, reduce the offset by a fixed factor times the time constant.
  */
@@ -84,8 +61,8 @@ static inline void pps_reset_freq_interval(void)
 {
/* the PPS calibration interval may end
   surprisingly early */
-   pps_shift = PPS_INTMIN;
-   pps_intcnt = 0;
+   tk_ntp.pps.shift = PPS_INTMIN;
+   tk_ntp.pps.intcnt = 0;
 }
 
 /**
@@ -94,11 +71,11 @@ static inline void pps_reset_freq_interval(void)
 static inline void pps_clear(void)
 {
pps_reset_freq_interval();
-   pps_tf[0] = 0;
-   pps_tf[1] = 0;
-   pps_tf[2] = 0;
-   pps_fbase.tv_sec = pps_fbase.tv_nsec = 0;
-   pps_freq = 0;
+   tk_ntp.pps.tf[0] = 0;
+   tk_ntp.pps.tf[1] = 0;
+   tk_ntp.pps.tf[2] = 0;
+   tk_ntp.pps.fbase.tv_sec = tk_ntp.pps.fbase.tv_nsec = 0;
+   tk_ntp.pps.freq = 0;
 }
 
 /* Decrease pps_valid to indicate that another second has passed since
@@ -107,8 +84,8 @@ static inline void pps_clear(void)
  */
 static inline void pps_dec_valid(void)
 {
-   if (pps_valid > 0)
-   pps_valid--;
+   if (tk_ntp.pps.valid > 0)
+   tk_ntp.pps

[PATCH 4/7] Pass struct timekeeper_ntp as parameter from timekeeper to ntp

2013-09-14 Thread Mathieu Desnoyers
This is in preparation for the latch synchronization scheme.

Signed-off-by: Mathieu Desnoyers 
Cc: John Stultz 
Cc: Thomas Gleixner 
Cc: Peter Zijlstra 
---
 kernel/time/ntp.c  |  472 ++--
 kernel/time/ntp_internal.h |   16 +-
 kernel/time/timekeeping.c  |   17 +-
 3 files changed, 260 insertions(+), 245 deletions(-)

diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index d61e700..2a1b4ef 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -39,108 +39,108 @@
 /* PPS kernel consumer compensates the whole phase error immediately.
  * Otherwise, reduce the offset by a fixed factor times the time constant.
  */
-static inline s64 ntp_offset_chunk(s64 offset)
+static inline s64 ntp_offset_chunk(struct timekeeper_ntp *ntp, s64 offset)
 {
-   if (timekeeper.ntp.time_status & STA_PPSTIME
-   && timekeeper.ntp.time_status & STA_PPSSIGNAL)
+   if (ntp->time_status & STA_PPSTIME
+   && ntp->time_status & STA_PPSSIGNAL)
return offset;
else
-   return shift_right(offset, SHIFT_PLL + 
timekeeper.ntp.time_constant);
+   return shift_right(offset, SHIFT_PLL + ntp->time_constant);
 }
 
-static inline void pps_reset_freq_interval(void)
+static inline void pps_reset_freq_interval(struct timekeeper_ntp *ntp)
 {
/* the PPS calibration interval may end
   surprisingly early */
-   timekeeper.ntp.pps.shift = PPS_INTMIN;
-   timekeeper.ntp.pps.intcnt = 0;
+   ntp->pps.shift = PPS_INTMIN;
+   ntp->pps.intcnt = 0;
 }
 
 /**
  * pps_clear - Clears the PPS state variables
  */
-static inline void pps_clear(void)
+static inline void pps_clear(struct timekeeper_ntp *ntp)
 {
-   pps_reset_freq_interval();
-   timekeeper.ntp.pps.tf[0] = 0;
-   timekeeper.ntp.pps.tf[1] = 0;
-   timekeeper.ntp.pps.tf[2] = 0;
-   timekeeper.ntp.pps.fbase.tv_sec = timekeeper.ntp.pps.fbase.tv_nsec = 0;
-   timekeeper.ntp.pps.freq = 0;
+   pps_reset_freq_interval(ntp);
+   ntp->pps.tf[0] = 0;
+   ntp->pps.tf[1] = 0;
+   ntp->pps.tf[2] = 0;
+   ntp->pps.fbase.tv_sec = ntp->pps.fbase.tv_nsec = 0;
+   ntp->pps.freq = 0;
 }
 
 /* Decrease pps_valid to indicate that another second has passed since
  * the last PPS signal. When it reaches 0, indicate that PPS signal is
  * missing.
  */
-static inline void pps_dec_valid(void)
+static inline void pps_dec_valid(struct timekeeper_ntp *ntp)
 {
-   if (timekeeper.ntp.pps.valid > 0)
-   timekeeper.ntp.pps.valid--;
+   if (ntp->pps.valid > 0)
+   ntp->pps.valid--;
else {
-   timekeeper.ntp.time_status &= ~(STA_PPSSIGNAL | STA_PPSJITTER |
+   ntp->time_status &= ~(STA_PPSSIGNAL | STA_PPSJITTER |
 STA_PPSWANDER | STA_PPSERROR);
-   pps_clear();
+   pps_clear(ntp);
}
 }
 
-static inline void pps_set_freq(s64 freq)
+static inline void pps_set_freq(struct timekeeper_ntp *ntp, s64 freq)
 {
-   timekeeper.ntp.pps.freq = freq;
+   ntp->pps.freq = freq;
 }
 
-static inline int is_error_status(int status)
+static inline int is_error_status(struct timekeeper_ntp *ntp, int status)
 {
-   return (timekeeper.ntp.time_status & (STA_UNSYNC|STA_CLOCKERR))
+   return (ntp->time_status & (STA_UNSYNC|STA_CLOCKERR))
/* PPS signal lost when either PPS time or
 * PPS frequency synchronization requested
 */
-   || ((timekeeper.ntp.time_status & (STA_PPSFREQ|STA_PPSTIME))
-   && !(timekeeper.ntp.time_status & STA_PPSSIGNAL))
+   || ((ntp->time_status & (STA_PPSFREQ|STA_PPSTIME))
+   && !(ntp->time_status & STA_PPSSIGNAL))
/* PPS jitter exceeded when
 * PPS time synchronization requested */
-   || ((timekeeper.ntp.time_status & (STA_PPSTIME|STA_PPSJITTER))
+   || ((ntp->time_status & (STA_PPSTIME|STA_PPSJITTER))
== (STA_PPSTIME|STA_PPSJITTER))
/* PPS wander exceeded or calibration error when
 * PPS frequency synchronization requested
 */
-   || ((timekeeper.ntp.time_status & STA_PPSFREQ)
-   && (timekeeper.ntp.time_status & 
(STA_PPSWANDER|STA_PPSERROR)));
+   || ((ntp->time_status & STA_PPSFREQ)
+   && (ntp->time_status & (STA_PPSWANDER|STA_PPSERROR)));
 }
 
-static inline void pps_fill_timex(struct timex *txc)
+static inline void pps_fill_timex(struct timekeeper_ntp *ntp, struct timex 
*txc)
 {
-   txc->ppsfreq = shift_right((timekeeper.ntp.pps.freq >> 
PPM_SCALE_INV_SHIFT) *
+   txc->ppsfreq = shift_right((ntp->pps.freq >> PPM_SCALE_INV_SHIFT) *
 PPM_SCALE_INV, NTP_SCALE_SHIFT);
-   txc->jitter = timekeeper.ntp.pps.jitter;
-  

[PATCH 7/7] Introduce timekeeper latch synchronization

2013-09-14 Thread Mathieu Desnoyers
Unlike the sequence lock, this latch synchronization scheme, proposed by
Peter Zijlstra, always keeps a readable copy of the data. Therefore,
readers will never deadlock if they nest on the writer, whether this
happens because the read-side is explicitly called within the write-side
critical section, executed in a nested interrupt (e.g. NMI), or executed
in an execution context that has lock dependency with the write-side
critical section.

The only situations in which readers have to retry is if 2 updates or
more happen concurrently with the read. Therefore, the only situation
that can trigger a reader retry involves updater progress, therefore if
a reader interrupts an update, it would interrupt progress of every
updates, and therefore the reader never has to retry.

A nice side-effect of this scheme is that the reader latency in the
case readers execute concurrently with updaters should be diminished,
because readers don't have to busy-loop when executing concurrently with
updaters, unless 2 or more updates are performed concurrently with the
read.

The overhead of this scheme is that every update must perform a copy of
struct timekeeper and then modify this copy rather than to do the update
in-place.

There should not be any significant overhead added to the read-side,
given the number of memory barriers is unchanged.

Signed-off-by: Mathieu Desnoyers 
Cc: John Stultz 
Cc: Thomas Gleixner 
Cc: Peter Zijlstra 
---
 include/linux/timekeeper_internal.h |   93 -
 kernel/time/ntp.c   |   20 +-
 kernel/time/timekeeping.c   |  375 ---
 3 files changed, 317 insertions(+), 171 deletions(-)

diff --git a/include/linux/timekeeper_internal.h 
b/include/linux/timekeeper_internal.h
index 6f0532d..af54571 100644
--- a/include/linux/timekeeper_internal.h
+++ b/include/linux/timekeeper_internal.h
@@ -151,7 +151,98 @@ struct timekeeper {
struct timekeeper_ntp   ntp;
 };
 
-extern struct timekeeper timekeeper;
+struct timekeeper_latch {
+   unsigned long head, tail;
+   struct timekeeper data[2];
+};
+
+static inline
+int timekeeper_index(struct timekeeper_latch *tl, const struct timekeeper *tk)
+{
+   return tk - &tl->data[0];
+}
+
+extern struct timekeeper_latch timekeeper_latch;
+extern raw_spinlock_t timekeeper_lock;
+
+/**
+ * timekeeper_write_begin - begin timekeeper update.
+ *
+ " @tl: struct timekeeper_latch to update.
+ * @next: pointer to next element (output parameter).
+ *
+ * The area pointed to by "next" should be considered uninitialized.
+ * The caller needs to have exclusive update access to struct timekeeper_latch.
+ */
+static inline
+void timekeeper_write_begin(struct timekeeper_latch *tl,
+   struct timekeeper **next)
+{
+   const struct timekeeper *_prev;
+   struct timekeeper *_next;
+
+   tl->head++;
+   smp_wmb();  /* Store head before storing into next entry */
+   _prev = &tl->data[tl->tail & 1];
+   _next = &tl->data[tl->head & 1];
+   *_next = *_prev;/* Copy prev content into next */
+   if (_next->clock && _next->clock->update_latch)
+   _next->clock->update_latch(_next->clock,
+   timekeeper_index(tl, _prev),
+   timekeeper_index(tl, _next));
+   *next = _next;
+}
+
+/**
+ * timekeeper_write_end - end timekeeper update.
+ *
+ " @tl: struct timekeeper_latch.
+ *
+ * The caller needs to have exclusive update access to struct timekeeper_latch.
+ */
+static inline
+void timekeeper_write_end(struct timekeeper_latch *tl)
+{
+   smp_wmb();  /* Store into next entry before storing into tail */
+   tl->tail++;
+}
+
+/**
+ * timekeeper_read_begin - begin timekeeper read.
+ *
+ " @tl: struct timekeeper_latch to read.
+ * @tail: pointer to unsigned long containing tail position (output).
+ */
+static inline
+struct timekeeper *timekeeper_read_begin(struct timekeeper_latch *tl,
+   unsigned long *tail)
+{
+   unsigned long ret;
+
+   ret = ACCESS_ONCE(tl->tail);
+   smp_rmb();  /* Load tail before loading entry */
+   *tail = ret;
+   return &tl->data[ret & 1];
+}
+
+/**
+ * timekeeper_read_retry - end timekeeper read, trigger retry if needed.
+ *
+ " @tl: struct timekeeper_latch read.
+ * @tail: tail position returned as output by timekeeper_read_begin().
+ *
+ * If timekeeper_read_retry() returns nonzero, the content of the read should
+ * be considered invalid, and the read should be performed again to
+ * reattempt reading coherent data, starting with timekeeper_read_begin().
+ */
+static inline
+int timekeeper_read_retry(struct timekeeper_latch *tl, unsigned long tail)
+{
+   smp_rmb();  /* Load entry before loading head */
+   return (ACCESS_ONCE(tl->head) - tail >= 2);
+}
+
+extern struct timekeeper *timekeeper_get_init(void);
 
 static inline struct timespec tk_xtime(struct timekeeper *tk)
 {
diff --git a/kernel/time/nt

[RFC PATCH v2] timekeeper latch synchronization

2013-09-14 Thread Mathieu Desnoyers
Hi,

Here is my timekeeper latch synchronization series update, still as RFC.
It now passes the timetests provided by John Stultz
(https://github.com/johnstultz-work/timetests.git). See the changelog of
"Introduce timekeeper latch synchronization" to get a clear picture of
all the goodness introduced by this scheme. ;-)

Comments are welcome,

Thanks!

Mathieu

--
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] ptp: measure the time offset between PHC and system clock

2013-09-14 Thread Sergei Shtylyov

Hello.

On 09/14/2013 12:03 PM, Dong Zhu wrote:


This patch add a method into testptp.c to measure the time offset
between phc and system clock through the ioctl PTP_SYS_OFFSET.



Signed-off-by: Dong Zhu 
---
  Documentation/ptp/testptp.c | 40 ++--
  1 file changed, 38 insertions(+), 2 deletions(-)



diff --git a/Documentation/ptp/testptp.c b/Documentation/ptp/testptp.c
index f59ded0..72bb030 100644
--- a/Documentation/ptp/testptp.c
+++ b/Documentation/ptp/testptp.c

[...]

@@ -376,6 +387,31 @@ int main(int argc, char *argv[])
}
}

+   if (offset) {
+   sysoff = calloc(1, sizeof(*sysoff));
+   if (!sysoff) {
+   perror("calloc");
+   return -1;
+   }
+   sysoff->n_samples = n_samples;
+
+   if (ioctl(fd, PTP_SYS_OFFSET, sysoff))
+   perror("PTP_SYS_OFFSET");
+   else
+   puts("time offset between PHC and
+system clock request okay");


   Don't break the string constant that way, there'll be all spaces between 
"and" and "system" included in it. Do it like this:


puts("time offset between PHC and "
 "system clock request okay");

WBR, Sergei

--
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 0/9] Introduce hwmon_device_register_with_groups and

2013-09-14 Thread Guenter Roeck

On 09/14/2013 11:31 AM, Jean Delvare wrote:

Hi Guenter,

On Mon, 02 Sep 2013 12:25:35 -0700, Guenter Roeck wrote:

On 08/31/2013 07:48 PM, Guenter Roeck wrote:

This patch series introduces new hwmon API functions
hwmon_device_register_with_groups() and 
devm_hwmon_device_register_with_groups().

hwmon_device_register_with_groups() lets callers register hwmon devices
as well as associated sysfs attributes with a single call. This simplifies
hwmon device registration and avoids potential race conditions seen
if sysfs attributes are created after the initial hwmon device was
registered.

devm_hwmon_device_register_with_groups() is the managed version of the same
function.


Jean, any comments on this patch series ?

If you are ok with it, I would like to push the new API (patches 1 and 7 of the 
series)
into 3.12, and keep the rest for 3.13.


I'm afraid I won't have the time to review all these patches. The
concept looks good to me and I trust that you implemented things right
so feel free to push the patches upstream even without my review.



No problem. I'll add the entire series to -next after the commit window closes.

Thanks,
Guenter

--
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 v3] dma: add driver for R-Car HPB-DMAC

2013-09-14 Thread Sergei Shtylyov

Hello.

On 09/14/2013 10:33 PM, Guennadi Liakhovetski wrote:


From: Max Filippov 



Add support for HPB-DMAC found in Renesas R-Car SoCs, using 'shdma-base' DMA
driver framework.



Based on the original patch by Phil Edworthy .



Signed-off-by: Max Filippov 
[Sergei: removed useless #include, sorted #include's, fixed HPB_DMA_TCR_MAX,
fixed formats and removed line breaks in the dev_dbg() calls, rephrased and
added IRQ # to the shdma_request_irq() failure message, added MODULE_AUTHOR(),
removed '__init'/'__exit' annotations from the probe()/remove() methods, removed
'__initdata' annotation from 'hpb_dmae_driver', fixed guard macro name in the
header file, fixed #define ASYNCRSTR_ASRST20, added #define ASYNCRSTR_ASRST24,
added the necessary runtime PM calls to the probe() and remove() methods,
handled errors returned by dma_async_device_register(), beautified comments
and #define's.]
Signed-off-by: Sergei Shtylyov 



---



[snip]



Index: slave-dma/drivers/dma/sh/rcar-hpbdma.c
===
--- /dev/null
+++ slave-dma/drivers/dma/sh/rcar-hpbdma.c
@@ -0,0 +1,655 @@



[snip]



+static int hpb_dmae_chan_probe(struct hpb_dmae_device *hpbdev, int id)
+{
+   struct shdma_dev *sdev = &hpbdev->shdma_dev;
+   struct platform_device *pdev =
+   to_platform_device(hpbdev->shdma_dev.dma_dev.dev);
+   struct hpb_dmae_chan *new_hpb_chan;
+   struct shdma_chan *schan;
+
+   /* Alloc channel */
+   new_hpb_chan = devm_kzalloc(&pdev->dev,
+   sizeof(struct hpb_dmae_chan), GFP_KERNEL);
+   if (!new_hpb_chan) {
+   dev_err(hpbdev->shdma_dev.dma_dev.dev,
+   "No free memory for allocating DMA channels!\n");
+   return -ENOMEM;
+   }
+
+   schan = &new_hpb_chan->shdma_chan;



A suggestion for an incremental patch - you might want to initialise the
max_xfer_len field like



schan->max_xfer_len = 64 * 1024 * 1024 - 1;


   IIRC, the HPB-DMAC's maximum transfer length is 16 MiB, without -1. You 
probably mixed it with LBSC-DMAC which is indeed capable of 64 MiB.



because if it isn't initialised your max transfer length will be 4k,
which will hurt your performance. I think you should get a better
throughput after that


   OK, note taken. We'll look into it.

WBR, Sergei

--
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] sched: Fix task_h_load calculation

2013-09-14 Thread Paul Turner
On Sat, Sep 14, 2013 at 8:39 AM, Vladimir Davydov
 wrote:
> Patch a003a2 (sched: Consider runnable load average in move_tasks())
> sets all top-level cfs_rqs' h_load to rq->avg.load_avg_contrib, which is
> always 0. This mistype leads to all tasks having weight 0 when load
> balancing in a cpu-cgroup enabled setup. There obviously should be sum
> of weights of all runnable tasks there instead. Fix it.
>

load_avg_contrib is the weight that
> Signed-off-by: Vladimir Davydov 
> ---
>  kernel/sched/fair.c |2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
> index 9b3fe1c..13abc29 100644
> --- a/kernel/sched/fair.c
> +++ b/kernel/sched/fair.c
> @@ -4242,7 +4242,7 @@ static void update_cfs_rq_h_load(struct cfs_rq *cfs_rq)
> } Once we'v Once we've made it that e made it that
>
> if (!se) {
> -   cfs_rq->h_load = rq->avg.load_avg_contrib;
> +   cfs_rq->h_load = cfs_rq->runnable_load_avg;

Looks good.

Reviewed-by: Paul Turner 

> cfs_rq->last_h_load_update = now;
> }
>
> --
> 1.7.10.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
--
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] rcu: Fix CONFIG_RCU_NOCB_CPU_ALL panic on machines with sparse CPU mask

2013-09-14 Thread Paul E. McKenney
On Sat, Sep 14, 2013 at 05:03:20PM +0400, Kirill Tkhai wrote:
> When a system has a sparse cpumask and CONFIG_RCU_NOCB_CPU_ALL is enabled,
> rcu_spawn_nocb_kthreads() creates nocb threads for nonexistent CPUS.
> 
> The problem is in rcu_bootup_announce_oddness(). cpumask_setall() sets all
> bits from 0 to nr_cpu_ids existent and nonexistent CPUs both.
> 
> The sample. My cpuinfo(sparc64):
> 
> CPU0: online
> CPU2: online
> 
> I get these oopses every boot:
> 
> Unable to handle kernel NULL pointer dereference
> CPU: 0 PID: 23 Comm: rcuos/1 Not tainted 3.11.0+ #103
> task: f800be9792c0 ti: f800be98c000 task.ti: f800be98c000
> TSTATE: 004480e01604 TPC: 0047cffc TNPC: 0047d000 Y: 
> Not tainted
> TPC: 
> g0:  g1:  g2: f800be98fd58 g3: 
> 00acb718
> g4: f800be9792c0 g5: f800be536000 g6: f800be98c000 g7: 
> 
> o0:  o1: 00a33d34 o2: 0001 o3: 
> 
> o4:  o5:  sp: f800be98f3d1 ret_pc: 
> 0047cfd8
> RPC: 
> l0: 00a33ce8 l1: 0001 l2: 00a7d800 l3: 
> f800bf004dc0
> l4: f800be880310 l5: 00a33ce8 l6: 00ad l7: 
> 00a33800
> i0: 00acb710 i1: f800be98fd40 i2: 0001 i3: 
> f800be98fd40
> i4:  i5:  i6: f800be98f491 i7: 
> 004d3f50
> I7: 
> Call Trace:
>  [004d3f50] rcu_nocb_kthread+0x5c/0x224
>  [0047c604] kthread+0x88/0x9c
>  [00406084] ret_from_fork+0x1c/0x2c
>  []   (null)
> 
> So, not possible CPUs have to be cleared.

Good catch!

I am hoping that your setup always has CPU 0 defined.  If not, there are
many other problems in addition to CONFIG_RCU_NOCB_CPU_ZERO=y!

> Signed-off-by: Kirill Tkhai 
> CC: Dipankar Sarma 
> CC: Paul E. McKenney 
> ---
>  kernel/rcutree_plugin.h |1 +
>  1 files changed, 1 insertions(+), 0 deletions(-)
> diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h
> index 130c97b..1f17e99 100644
> --- a/kernel/rcutree_plugin.h
> +++ b/kernel/rcutree_plugin.h
> @@ -97,6 +97,7 @@ static void __init rcu_bootup_announce_oddness(void)
>  #ifdef CONFIG_RCU_NOCB_CPU_ALL
>   pr_info("\tOffload RCU callbacks from all CPUs\n");
>   cpumask_setall(rcu_nocb_mask);
> + cpumask_and(rcu_nocb_mask, cpu_possible_mask, rcu_nocb_mask);

Would it make sense to combine the cpumask_setall() and the cpumask_and()
into a single cpumask_copy()?  

>  #endif /* #ifdef CONFIG_RCU_NOCB_CPU_ALL */
>  #endif /* #ifndef CONFIG_RCU_NOCB_CPU_NONE */
>   if (have_rcu_nocb_mask) {

Do we need a cpumask_and() within this "if" statement to handle the
case where the kernel's rcu_nocbs= boot parameter specified a CPU
that is not present?  (If so, probably also giving a warning about the
non-present CPUs specified.)

I believe that the answer to both questions is "yes", and I would
welcome an updated patch that covered these cases.

All that said...  Why does the system have a sparse cpu_possible_mask?
This does cause overallocation of memory in a number of areas, including
RCU's combining tree of rcu_node structures, to say nothing of the
cpumasks themselves.

Thanx, Paul

--
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: 3.10.5: rcu_sched detected stalls on CPUs/tasks

2013-09-14 Thread Paul E. McKenney
On Sat, Sep 14, 2013 at 01:28:34PM +0200, Jochen Striepe wrote:
>   Hello again,
> 
> On Mon, Sep 09, 2013 at 03:27:51PM -0700, Paul E. McKenney wrote:
> > Several people helped track down another source of spurious stall
> > warnings on large systems, please see below for the patch.
> [...]
> > 
> > 
> > rcu: Reject memory-order-induced stall-warning false positives
> 
> I run this patch on top of 3.10.11 vanilla since Wednesday, so far
> without any further stalls, on light to heavy loads. Works smooth
> as pie.
> 
> Tested-by: Jochen Striepe 

Very good!  I have added your Tested-by.

> Have a nice weekend and a big thank you,

And thank you for your testing efforts!

Thanx, Paul

--
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 v3] dma: add driver for R-Car HPB-DMAC

2013-09-14 Thread Guennadi Liakhovetski
On Sun, 25 Aug 2013, Sergei Shtylyov wrote:

> From: Max Filippov 
> 
> Add support for HPB-DMAC found in Renesas R-Car SoCs, using 'shdma-base' DMA 
> driver framework.
> 
> Based on the original patch by Phil Edworthy .
> 
> Signed-off-by: Max Filippov 
> [Sergei: removed useless #include, sorted #include's, fixed HPB_DMA_TCR_MAX,
> fixed formats and removed line breaks in the dev_dbg() calls, rephrased and
> added IRQ # to the shdma_request_irq() failure message, added MODULE_AUTHOR(),
> removed '__init'/'__exit' annotations from the probe()/remove() methods, 
> removed
> '__initdata' annotation from 'hpb_dmae_driver', fixed guard macro name in the
> header file, fixed #define ASYNCRSTR_ASRST20, added #define ASYNCRSTR_ASRST24,
> added the necessary runtime PM calls to the probe() and remove() methods,
> handled errors returned by dma_async_device_register(), beautified comments
> and #define's.]
> Signed-off-by: Sergei Shtylyov 
> 
> ---

[snip]

> Index: slave-dma/drivers/dma/sh/rcar-hpbdma.c
> ===
> --- /dev/null
> +++ slave-dma/drivers/dma/sh/rcar-hpbdma.c
> @@ -0,0 +1,655 @@

[snip]

> +static int hpb_dmae_chan_probe(struct hpb_dmae_device *hpbdev, int id)
> +{
> + struct shdma_dev *sdev = &hpbdev->shdma_dev;
> + struct platform_device *pdev =
> + to_platform_device(hpbdev->shdma_dev.dma_dev.dev);
> + struct hpb_dmae_chan *new_hpb_chan;
> + struct shdma_chan *schan;
> +
> + /* Alloc channel */
> + new_hpb_chan = devm_kzalloc(&pdev->dev,
> + sizeof(struct hpb_dmae_chan), GFP_KERNEL);
> + if (!new_hpb_chan) {
> + dev_err(hpbdev->shdma_dev.dma_dev.dev,
> + "No free memory for allocating DMA channels!\n");
> + return -ENOMEM;
> + }
> +
> + schan = &new_hpb_chan->shdma_chan;

A suggestion for an incremental patch - you might want to initialise the
max_xfer_len field like

schan->max_xfer_len = 64 * 1024 * 1024 - 1;

because if it isn't initialised your max transfer length will be 4k,
which will hurt your performance. I think you should get a better
throughput after that

> + shdma_chan_probe(sdev, schan, id);
> +
> + if (pdev->id >= 0)
> + snprintf(new_hpb_chan->dev_id, sizeof(new_hpb_chan->dev_id),
> +  "hpb-dmae%d.%d", pdev->id, id);
> + else
> + snprintf(new_hpb_chan->dev_id, sizeof(new_hpb_chan->dev_id),
> +  "hpb-dma.%d", id);
> +
> + return 0;
> +}

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/
--
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: [PATCHv2 00/25] perf tool: Add support for multiple data file storage

2013-09-14 Thread David Ahern

On 9/9/13 9:03 AM, David Ahern wrote:

I have a flight recorder style command that address this problem
(long-running/daemons) by processing task events and then stashing
the sample events on a time-ordered list with chopping to maintain
the time window.


so far I noticed there could be race among EXIT and remaining
SAMPLE events on another CPU mmap than EXIT event.. ending up
with EXIT being stored in the old file, while SAMPLEs will get
to the new one

I was thinking about some 'perf daemon' so I dont need to run that
manually.. seems similar to what you did


Right now I focus on scheduling events. This latest version of it can be
easily recycled for other use cases. Some work would be needed to dump
events to a file versus dumping processed information.

I am in San Jose this week. Not sure if I will have time to finish it to
a point of pushing out patches, but maybe I can push to github in the
next couple of days.


https://github.com/dsahern/linux/tree/perf-sched-timehist-3.11

Take a look at tools/perf/schedmon.c. Task events are processed and 
sample events are stashed on a list (daemon__process_sample). Could 
easily do something similar for mmap, comm, fork events and then on exit 
event flush events for terminated tasks. Then you will have both the 
task and sample events which can be dumped to a file for later processing.


David
--
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 0/9] Introduce hwmon_device_register_with_groups and

2013-09-14 Thread Jean Delvare
Hi Guenter,

On Mon, 02 Sep 2013 12:25:35 -0700, Guenter Roeck wrote:
> On 08/31/2013 07:48 PM, Guenter Roeck wrote:
> > This patch series introduces new hwmon API functions
> > hwmon_device_register_with_groups() and 
> > devm_hwmon_device_register_with_groups().
> >
> > hwmon_device_register_with_groups() lets callers register hwmon devices
> > as well as associated sysfs attributes with a single call. This simplifies
> > hwmon device registration and avoids potential race conditions seen
> > if sysfs attributes are created after the initial hwmon device was
> > registered.
> >
> > devm_hwmon_device_register_with_groups() is the managed version of the same
> > function.
> >
> Jean, any comments on this patch series ?
> 
> If you are ok with it, I would like to push the new API (patches 1 and 7 of 
> the series)
> into 3.12, and keep the rest for 3.13.

I'm afraid I won't have the time to review all these patches. The
concept looks good to me and I trust that you implemented things right
so feel free to push the patches upstream even without my review.

-- 
Jean Delvare
--
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: audit looks unmaintained? [was: Re: [PATCH 11/12] pid: rewrite task helper functions avoiding task->pid and task->tgid]

2013-09-14 Thread Oleg Nesterov
On 09/13, Steve Grubb wrote:
>
> On Tuesday, September 10, 2013 07:20:33 PM Oleg Nesterov wrote:
> >
> > So, Steve, do you still think that patch was wrong? Attached below
> > just in case.
>
> I think this looks OK. If the task filter NACK's auditing the process, then
> clearing the flag is probably correct. I have design notes from back around 
> the
> 2.6.7 kernel saying this was the intention.

Then I do not really understand your previous email... Nevermind ;)

> ACK.

Thanks. I'll resend this patch with your ack applied.

Oleg.

--
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: audit looks unmaintained? [was: Re: [PATCH 11/12] pid: rewrite task helper functions avoiding task->pid and task->tgid]

2013-09-14 Thread Oleg Nesterov
On 09/13, Steve Grubb wrote:
>
> On Sunday, September 08, 2013 05:54:35 PM Oleg Nesterov wrote:
> >
> > Then why audit_alloc() doesn't set TIF_SYSCALL_AUDIT unconditionally?
>
> The code I'm looking at does right at the end of the function.

The code I'm looking at does right at the end too ;) but it also
returns at the start if audit_filter_task() returns AUDIT_DISABLED.

> > And I do not understand "when context == NULL" above. Say,
> > audit_syscall_entry() does nothing if !audit_context, and nobody except
> > copy_process() does audit_alloc(). So why do we need to trigger the audit's
> > paths if it is NULL?
>
> Because if you enter the audit framework,

framework? TIF_SYSCALL_AUDIT has only meaning in entry.S, we need it
to ensure that the audited task can't miss audit_syscall_*().

> that means auditing has been turned
> on at some point in the past, and could be turned back on at some point in the
> future.

And this will change nothing, afaics (wrt TIF_SYSCALL_AUDIT).

Oleg.

--
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 3/4] pinctrl: at91: improve pinconf_set/get function robustness

2013-09-14 Thread Jean-Christophe PLAGNIOL-VILLARD
On 09:49 Fri 13 Sep , Boris BREZILLON wrote:
> Reset caller's config variable before setting current config flags to avoid
> erronous config return.
> 
> DEBOUNCE and DEGLITCH options are mutually exclusive. Return an error if they
> are both defined in the config.
> Do not call set_deglitch if DEBOUNCE is enabled to avoid reseting the IFSR
> register (which will result in disabling the debounce filter).
> 
> Signed-off-by: Boris BREZILLON 
> ---
>  drivers/pinctrl/pinctrl-at91.c |   18 +-
>  1 file changed, 13 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c
> index 6624bce..ac9dbea 100644
> --- a/drivers/pinctrl/pinctrl-at91.c
> +++ b/drivers/pinctrl/pinctrl-at91.c
> @@ -724,6 +724,7 @@ static int at91_pinconf_get(struct pinctrl_dev *pctldev,
>   dev_dbg(info->dev, "%s:%d, pin_id=%d, config=0x%lx", __func__, 
> __LINE__, pin_id, *config);
>   pio = pin_to_controller(info, pin_to_bank(pin_id));
>   pin = pin_id % MAX_NB_GPIO_PER_BANK;
> + *config = 0;
>  
>   if (at91_mux_get_multidrive(pio, pin))
>   *config |= MULTI_DRIVE;
> @@ -757,13 +758,20 @@ static int at91_pinconf_set(struct pinctrl_dev *pctldev,
>   if (config & PULL_UP && config & PULL_DOWN)
>   return -EINVAL;
>  
> - at91_mux_set_pullup(pio, mask, config & PULL_UP);
> - at91_mux_set_multidrive(pio, mask, config & MULTI_DRIVE);
> - if (info->ops->set_deglitch)
> - info->ops->set_deglitch(pio, mask, config & DEGLITCH);
> - if (info->ops->set_debounce)
> + if (config & DEBOUNCE && config & DEGLITCH)
> + return -EINVAL;
here ok
> +
> + if (config & DEBOUNCE) {
> + if (!info->ops->set_debounce)
> + return -ENOTSUPP;
a warning is better here than an error
> +
>   info->ops->set_debounce(pio, mask, config & DEBOUNCE,
>   (config & DEBOUNCE_VAL) >> DEBOUNCE_VAL_SHIFT);
> + } else if (info->ops->set_deglitch)
> + info->ops->set_deglitch(pio, mask, config & DEGLITCH);
> +


> + at91_mux_set_pullup(pio, mask, config & PULL_UP);
> + at91_mux_set_multidrive(pio, mask, config & MULTI_DRIVE);

>   if (info->ops->set_pulldown)
>   info->ops->set_pulldown(pio, mask, config & PULL_DOWN);
>   if (info->ops->disable_schmitt_trig && config & DIS_SCHMIT)
> -- 
> 1.7.9.5
> 
> 
> ___
> linux-arm-kernel mailing list
> linux-arm-ker...@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
--
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] perf session: Add option to copy events when queueing

2013-09-14 Thread David Ahern

On 9/14/13 10:16 AM, Frederic Weisbecker wrote:

@@ -676,7 +682,12 @@ int perf_session_queue_event(struct perf_session *s, union 
perf_event *event,

new->timestamp = timestamp;
new->file_offset = file_offset;
-   new->event = event;
+
+   if (s->copy_on_queue) {
+   new->event = malloc(event->header.size);
+   memcpy(new->event, event, event->header.size);
+   } else
+   new->event = event;


---8<---


So do you think it should stay optional? This looks like a global problem, I 
mean
the event can be unmapped anytime for any builtin tool mapping it, right?


Yes. I could make it the default behavior; just overhead in doing that 
(malloc/copy for each event).




Also we already allocate the sample list node (struct sample_queue) from 
os->sample
buffer. ie: we have our own allocator there.

Probably we should reuse that and include the copied event space in "struct 
sample_queue"?



Right, that's where I put the malloc and copy - I kept the relevant 
change above. I take it you are thinking of something different but I am 
not following you. You definitely do NOT want to change struct 
sample_queue to include an event - like this:


diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 51f5edf..866944a 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -491,7 +491,7 @@ static perf_event__swap_op perf_event__swap_ops[] = {
 struct sample_queue {
u64 timestamp;
u64 file_offset;
-   union perf_event*event;
+   union perf_eventevent;
struct list_headlist;
 };

size of event is determined by mmap_event (mmap2_event in latest code) 
which is > 4096 because of the filename argument. Including the event 
directly in sample_queue would balloon memory usage (learned this the 
hard way!).




Also looking at it now, it seems we have a bug on the existing code:


 if (!list_empty(sc)) {
 new = list_entry(sc->next, struct sample_queue, list);
 list_del(&new->list);
 } else if (os->sample_buffer) {
 new = os->sample_buffer + os->sample_buffer_idx;
 if (++os->sample_buffer_idx == MAX_SAMPLE_BUFFER)
 os->sample_buffer = NULL;
 } else {
os->sample_buffer = malloc(MAX_SAMPLE_BUFFER * sizeof(*new));
if (!os->sample_buffer)
 return -ENOMEM;
list_add(&os->sample_buffer->list, &os->to_free);
os->sample_buffer_idx = 2;
new = os->sample_buffer + 1;
 }

If we actually run out of buffer rooms, we should realloc right after and not
wait for the next entry, otherwise we loose an event:

 if (!list_empty(sc)) {
 new = list_entry(sc->next, struct sample_queue, list);
 list_del(&new->list);
 } else {
 if (os->sample_buffer) {
 new = os->sample_buffer + os->sample_buffer_idx;
 if (++os->sample_buffer_idx == MAX_SAMPLE_BUFFER)
 os->sample_buffer = NULL;
 }

 if (!os->sample_buffer) {
os->sample_buffer = malloc(MAX_SAMPLE_BUFFER * 
sizeof(*new));
 if (!os->sample_buffer)
 return -ENOMEM;
 list_add(&os->sample_buffer->list, &os->to_free);
 os->sample_buffer_idx = 2;
 new = os->sample_buffer + 1;
 }


Although the mirrored os->sample_buffer condition check is a bit ugly and 
should move to
a function. But the idea is there.


Ok. That should be a separate patch. Are you going to submit that one?

David

--
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 2/4] pinctrl: at91: fix sam9x5 debounce/deglitch functions

2013-09-14 Thread Jean-Christophe PLAGNIOL-VILLARD
On 09:47 Fri 13 Sep , Boris BREZILLON wrote:
> Replace at91_mux_get_deglitch with at91_mux_pio3_get_deglitch when using
> sam9x5 (pio3) IP.
> at91_mux_get_deglitch only test the activation of the "Input Filter" which
> may be overloaded by the activation of the "Input Filter Slow Clock" to use
> the input filter as a debounce filter instead of a deglitch filter.
> 
> Fix at91_mux_pio3_get_debounce to test the activation of the Input Filter
> before testing the activation of the debounce filter (Input Filter Slow
> Clock depends on Input Filter).
> 
> Fix at91_mux_pio3_set_debounce function to avoid disabling the deglitch
> filter ("Input Filter") when debounce filter is disabled.
> 
Acked-by: Jean-Christophe PLAGNIOL-VILLARD 
> Signed-off-by: Boris BREZILLON 
> ---
>  drivers/pinctrl/pinctrl-at91.c |   18 +-
>  1 file changed, 13 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c
> index 50b555a..6624bce 100644
> --- a/drivers/pinctrl/pinctrl-at91.c
> +++ b/drivers/pinctrl/pinctrl-at91.c
> @@ -417,6 +417,14 @@ static void at91_mux_set_deglitch(void __iomem *pio, 
> unsigned mask, bool is_on)
>   __raw_writel(mask, pio + (is_on ? PIO_IFER : PIO_IFDR));
>  }
>  
> +static bool at91_mux_pio3_get_deglitch(void __iomem *pio, unsigned pin)
> +{
> + if ((__raw_readl(pio + PIO_IFSR) >> pin) & 0x1)
> + return !((__raw_readl(pio + PIO_IFSCSR) >> pin) & 0x1);
> +
> + return false;
> +}
> +
>  static void at91_mux_pio3_set_deglitch(void __iomem *pio, unsigned mask, 
> bool is_on)
>  {
>   if (is_on)
> @@ -428,7 +436,8 @@ static bool at91_mux_pio3_get_debounce(void __iomem *pio, 
> unsigned pin, u32 *div
>  {
>   *div = __raw_readl(pio + PIO_SCDR);
>  
> - return (__raw_readl(pio + PIO_IFSCSR) >> pin) & 0x1;
> + return ((__raw_readl(pio + PIO_IFSR) >> pin) & 0x1) &&
> +((__raw_readl(pio + PIO_IFSCSR) >> pin) & 0x1);
>  }
>  
>  static void at91_mux_pio3_set_debounce(void __iomem *pio, unsigned mask,
> @@ -438,9 +447,8 @@ static void at91_mux_pio3_set_debounce(void __iomem *pio, 
> unsigned mask,
>   __raw_writel(mask, pio + PIO_IFSCER);
>   __raw_writel(div & PIO_SCDR_DIV, pio + PIO_SCDR);
>   __raw_writel(mask, pio + PIO_IFER);
> - } else {
> - __raw_writel(mask, pio + PIO_IFDR);
> - }
> + } else
> + __raw_writel(mask, pio + PIO_IFSCDR);
>  }
>  
>  static bool at91_mux_pio3_get_pulldown(void __iomem *pio, unsigned pin)
> @@ -478,7 +486,7 @@ static struct at91_pinctrl_mux_ops at91sam9x5_ops = {
>   .mux_B_periph   = at91_mux_pio3_set_B_periph,
>   .mux_C_periph   = at91_mux_pio3_set_C_periph,
>   .mux_D_periph   = at91_mux_pio3_set_D_periph,
> - .get_deglitch   = at91_mux_get_deglitch,
> + .get_deglitch   = at91_mux_pio3_get_deglitch,
>   .set_deglitch   = at91_mux_pio3_set_deglitch,
>   .get_debounce   = at91_mux_pio3_get_debounce,
>   .set_debounce   = at91_mux_pio3_set_debounce,
> -- 
> 1.7.9.5
> 
> 
> ___
> linux-arm-kernel mailing list
> linux-arm-ker...@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
--
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 00/11] Convert more drivers to use devm_hwmon_device_register_with_groups

2013-09-14 Thread Guenter Roeck
The jc42 driver is compile tested only. All other patches were tested
with real hardware.

The patches apply on top of the previously submitted patches introducing
hwmon_device_register_with_groups and devm_hwmon_device_register_with_groups.
--
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 02/11] hwmon: (max6642) Convert to use devm_hwmon_device_register_with_groups

2013-09-14 Thread Guenter Roeck
Also rename new_client variable to client and introduce
new variable dev pointing to client->dev in the probe function,
and use new macro ATTRIBUTE_GROUPS to declare attribute groups.

Signed-off-by: Guenter Roeck 
---
 drivers/hwmon/max6642.c |   72 ---
 1 file changed, 24 insertions(+), 48 deletions(-)

diff --git a/drivers/hwmon/max6642.c b/drivers/hwmon/max6642.c
index 57d58cd..3d61f8d 100644
--- a/drivers/hwmon/max6642.c
+++ b/drivers/hwmon/max6642.c
@@ -87,7 +87,7 @@ static int temp_to_reg(int val)
  */
 
 struct max6642_data {
-   struct device *hwmon_dev;
+   struct i2c_client *client;
struct mutex update_lock;
bool valid; /* zero until following fields are valid */
unsigned long last_updated; /* in jiffies */
@@ -102,10 +102,10 @@ struct max6642_data {
  * Real code
  */
 
-static void max6642_init_client(struct i2c_client *client)
+static void max6642_init_client(struct max6642_data *data,
+   struct i2c_client *client)
 {
u8 config;
-   struct max6642_data *data = i2c_get_clientdata(client);
 
/*
 * Start the conversions.
@@ -168,14 +168,14 @@ static int max6642_detect(struct i2c_client *client,
 
 static struct max6642_data *max6642_update_device(struct device *dev)
 {
-   struct i2c_client *client = to_i2c_client(dev);
-   struct max6642_data *data = i2c_get_clientdata(client);
+   struct max6642_data *data = dev_get_drvdata(dev);
+   struct i2c_client *client = data->client;
u16 val, tmp;
 
mutex_lock(&data->update_lock);
 
if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
-   dev_dbg(&client->dev, "Updating max6642 data.\n");
+   dev_dbg(dev, "Updating max6642 data.\n");
val = i2c_smbus_read_byte_data(client,
MAX6642_REG_R_LOCAL_TEMPL);
tmp = (val >> 6) & 3;
@@ -209,8 +209,8 @@ static struct max6642_data *max6642_update_device(struct 
device *dev)
 static ssize_t show_temp_max10(struct device *dev,
   struct device_attribute *dev_attr, char *buf)
 {
-   struct max6642_data *data = max6642_update_device(dev);
struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
+   struct max6642_data *data = max6642_update_device(dev);
 
return sprintf(buf, "%d\n",
   temp_from_reg10(data->temp_input[attr->index]));
@@ -219,8 +219,8 @@ static ssize_t show_temp_max10(struct device *dev,
 static ssize_t show_temp_max(struct device *dev, struct device_attribute *attr,
 char *buf)
 {
-   struct max6642_data *data = max6642_update_device(dev);
struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(attr);
+   struct max6642_data *data = max6642_update_device(dev);
 
return sprintf(buf, "%d\n", temp_from_reg(data->temp_high[attr2->nr]));
 }
@@ -228,11 +228,10 @@ static ssize_t show_temp_max(struct device *dev, struct 
device_attribute *attr,
 static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
 {
+   struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(attr);
+   struct max6642_data *data = dev_get_drvdata(dev);
unsigned long val;
int err;
-   struct i2c_client *client = to_i2c_client(dev);
-   struct max6642_data *data = i2c_get_clientdata(client);
-   struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(attr);
 
err = kstrtoul(buf, 10, &val);
if (err < 0)
@@ -240,7 +239,7 @@ static ssize_t set_temp_max(struct device *dev, struct 
device_attribute *attr,
 
mutex_lock(&data->update_lock);
data->temp_high[attr2->nr] = clamp_val(temp_to_reg(val), 0, 255);
-   i2c_smbus_write_byte_data(client, attr2->index,
+   i2c_smbus_write_byte_data(data->client, attr2->index,
  data->temp_high[attr2->nr]);
mutex_unlock(&data->update_lock);
return count;
@@ -264,7 +263,7 @@ static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, 
NULL, 2);
 static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 6);
 static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4);
 
-static struct attribute *max6642_attributes[] = {
+static struct attribute *max6642_attrs[] = {
&sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_temp2_input.dev_attr.attr,
&sensor_dev_attr_temp1_max.dev_attr.attr,
@@ -275,52 +274,30 @@ static struct attribute *max6642_attributes[] = {
&sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
NULL
 };
+ATTRIBUTE_GROUPS(max6642);
 
-static const struct attribute_group max6642_group = {
-   .attrs = max6642_attributes,
-};
-
-static int max6642_probe(struct i2c_client *new_client,
+static int max66

[PATCH 04/11] hwmon: (max6697) Convert to use devm_hwmon_device_register_with_groups

2013-09-14 Thread Guenter Roeck
Signed-off-by: Guenter Roeck 
---
 drivers/hwmon/max6697.c |   54 +++
 1 file changed, 17 insertions(+), 37 deletions(-)

diff --git a/drivers/hwmon/max6697.c b/drivers/hwmon/max6697.c
index a41b5f3..0af910a 100644
--- a/drivers/hwmon/max6697.c
+++ b/drivers/hwmon/max6697.c
@@ -77,7 +77,7 @@ struct max6697_chip_data {
 };
 
 struct max6697_data {
-   struct device *hwmon_dev;
+   struct i2c_client *client;
 
enum chips type;
const struct max6697_chip_data *chip;
@@ -181,8 +181,8 @@ static const struct max6697_chip_data max6697_chip_data[] = 
{
 
 static struct max6697_data *max6697_update_device(struct device *dev)
 {
-   struct i2c_client *client = to_i2c_client(dev);
-   struct max6697_data *data = i2c_get_clientdata(client);
+   struct max6697_data *data = dev_get_drvdata(dev);
+   struct i2c_client *client = data->client;
struct max6697_data *ret = data;
int val;
int i;
@@ -303,8 +303,7 @@ static ssize_t set_temp(struct device *dev,
 {
int nr = to_sensor_dev_attr_2(devattr)->nr;
int index = to_sensor_dev_attr_2(devattr)->index;
-   struct i2c_client *client = to_i2c_client(dev);
-   struct max6697_data *data = i2c_get_clientdata(client);
+   struct max6697_data *data = dev_get_drvdata(dev);
long temp;
int ret;
 
@@ -316,7 +315,7 @@ static ssize_t set_temp(struct device *dev,
temp = DIV_ROUND_CLOSEST(temp, 1000) + data->temp_offset;
temp = clamp_val(temp, 0, data->type == max6581 ? 255 : 127);
data->temp[nr][index] = temp;
-   ret = i2c_smbus_write_byte_data(client,
+   ret = i2c_smbus_write_byte_data(data->client,
index == 2 ? MAX6697_REG_MAX[nr]
   : MAX6697_REG_CRIT[nr],
temp);
@@ -405,8 +404,7 @@ static umode_t max6697_is_visible(struct kobject *kobj, 
struct attribute *attr,
  int index)
 {
struct device *dev = container_of(kobj, struct device, kobj);
-   struct i2c_client *client = to_i2c_client(dev);
-   struct max6697_data *data = i2c_get_clientdata(client);
+   struct max6697_data *data = dev_get_drvdata(dev);
const struct max6697_chip_data *chip = data->chip;
int channel = index / 6;/* channel number */
int nr = index % 6; /* attribute index within channel */
@@ -489,6 +487,7 @@ static struct attribute *max6697_attributes[] = {
 static const struct attribute_group max6697_group = {
.attrs = max6697_attributes, .is_visible = max6697_is_visible,
 };
+__ATTRIBUTE_GROUPS(max6697);
 
 static void max6697_get_config_of(struct device_node *node,
  struct max6697_platform_data *pdata)
@@ -525,9 +524,9 @@ static void max6697_get_config_of(struct device_node *node,
}
 }
 
-static int max6697_init_chip(struct i2c_client *client)
+static int max6697_init_chip(struct max6697_data *data,
+struct i2c_client *client)
 {
-   struct max6697_data *data = i2c_get_clientdata(client);
struct max6697_platform_data *pdata = dev_get_platdata(&client->dev);
struct max6697_platform_data p;
const struct max6697_chip_data *chip = data->chip;
@@ -625,6 +624,7 @@ static int max6697_probe(struct i2c_client *client,
struct i2c_adapter *adapter = client->adapter;
struct device *dev = &client->dev;
struct max6697_data *data;
+   struct device *hwmon_dev;
int err;
 
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@@ -636,37 +636,18 @@ static int max6697_probe(struct i2c_client *client,
 
data->type = id->driver_data;
data->chip = &max6697_chip_data[data->type];
-
-   i2c_set_clientdata(client, data);
+   data->client = client;
mutex_init(&data->update_lock);
 
-   err = max6697_init_chip(client);
+   err = max6697_init_chip(data, client);
if (err)
return err;
 
-   err = sysfs_create_group(&client->dev.kobj, &max6697_group);
-   if (err)
-   return err;
-
-   data->hwmon_dev = hwmon_device_register(dev);
-   if (IS_ERR(data->hwmon_dev)) {
-   err = PTR_ERR(data->hwmon_dev);
-   goto error;
-   }
-
-   return 0;
-
-error:
-   sysfs_remove_group(&client->dev.kobj, &max6697_group);
-   return err;
-}
-
-static int max6697_remove(struct i2c_client *client)
-{
-   struct max6697_data *data = i2c_get_clientdata(client);
-
-   hwmon_device_unregister(data->hwmon_dev);
-   sysfs_remove_group(&client->dev.kobj, &max6697_group);
+   hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+  data,
+  max6697_

[PATCH 06/11] hwmon: (ina2xx) Convert to use devm_hwmon_device_register_with_groups

2013-09-14 Thread Guenter Roeck
Also introduce dev variable in probe function to simplify access
to client->dev, and use new macro ATTRIBUTE_GROUPS to declare
attribute groups.

Signed-off-by: Guenter Roeck 
---
 drivers/hwmon/ina2xx.c |   64 
 1 file changed, 21 insertions(+), 43 deletions(-)

diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c
index 70a39a8..93d26e8 100644
--- a/drivers/hwmon/ina2xx.c
+++ b/drivers/hwmon/ina2xx.c
@@ -78,7 +78,7 @@ struct ina2xx_config {
 };
 
 struct ina2xx_data {
-   struct device *hwmon_dev;
+   struct i2c_client *client;
const struct ina2xx_config *config;
 
struct mutex update_lock;
@@ -112,8 +112,8 @@ static const struct ina2xx_config ina2xx_config[] = {
 
 static struct ina2xx_data *ina2xx_update_device(struct device *dev)
 {
-   struct i2c_client *client = to_i2c_client(dev);
-   struct ina2xx_data *data = i2c_get_clientdata(client);
+   struct ina2xx_data *data = dev_get_drvdata(dev);
+   struct i2c_client *client = data->client;
struct ina2xx_data *ret = data;
 
mutex_lock(&data->update_lock);
@@ -203,41 +203,39 @@ static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, 
ina2xx_show_value, NULL,
  INA2XX_POWER);
 
 /* pointers to created device attributes */
-static struct attribute *ina2xx_attributes[] = {
+static struct attribute *ina2xx_attrs[] = {
&sensor_dev_attr_in0_input.dev_attr.attr,
&sensor_dev_attr_in1_input.dev_attr.attr,
&sensor_dev_attr_curr1_input.dev_attr.attr,
&sensor_dev_attr_power1_input.dev_attr.attr,
NULL,
 };
-
-static const struct attribute_group ina2xx_group = {
-   .attrs = ina2xx_attributes,
-};
+ATTRIBUTE_GROUPS(ina2xx);
 
 static int ina2xx_probe(struct i2c_client *client,
const struct i2c_device_id *id)
 {
struct i2c_adapter *adapter = client->adapter;
-   struct ina2xx_data *data;
struct ina2xx_platform_data *pdata;
-   int ret;
-   u32 val;
+   struct device *dev = &client->dev;
+   struct ina2xx_data *data;
+   struct device *hwmon_dev;
long shunt = 1; /* default shunt value 10mOhms */
+   u32 val;
 
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA))
return -ENODEV;
 
-   data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
+   data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
 
-   if (dev_get_platdata(&client->dev)) {
-   pdata = dev_get_platdata(&client->dev);
+   if (dev_get_platdata(dev)) {
+   pdata = dev_get_platdata(dev);
shunt = pdata->shunt_uohms;
-   } else if (!of_property_read_u32(client->dev.of_node,
-   "shunt-resistor", &val)) {
-   shunt = val;
+   } else if (!of_property_read_u32(dev->of_node,
+"shunt-resistor", &val)) {
+   shunt = val;
}
 
if (shunt <= 0)
@@ -255,37 +253,18 @@ static int ina2xx_probe(struct i2c_client *client,
i2c_smbus_write_word_swapped(client, INA2XX_CALIBRATION,
 data->config->calibration_factor / shunt);
 
-   i2c_set_clientdata(client, data);
+   data->client = client;
mutex_init(&data->update_lock);
 
-   ret = sysfs_create_group(&client->dev.kobj, &ina2xx_group);
-   if (ret)
-   return ret;
-
-   data->hwmon_dev = hwmon_device_register(&client->dev);
-   if (IS_ERR(data->hwmon_dev)) {
-   ret = PTR_ERR(data->hwmon_dev);
-   goto out_err_hwmon;
-   }
+   hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+  data, ina2xx_groups);
+   if (IS_ERR(hwmon_dev))
+   return PTR_ERR(hwmon_dev);
 
-   dev_info(&client->dev, "power monitor %s (Rshunt = %li uOhm)\n",
+   dev_info(dev, "power monitor %s (Rshunt = %li uOhm)\n",
 id->name, shunt);
 
return 0;
-
-out_err_hwmon:
-   sysfs_remove_group(&client->dev.kobj, &ina2xx_group);
-   return ret;
-}
-
-static int ina2xx_remove(struct i2c_client *client)
-{
-   struct ina2xx_data *data = i2c_get_clientdata(client);
-
-   hwmon_device_unregister(data->hwmon_dev);
-   sysfs_remove_group(&client->dev.kobj, &ina2xx_group);
-
-   return 0;
 }
 
 static const struct i2c_device_id ina2xx_id[] = {
@@ -302,7 +281,6 @@ static struct i2c_driver ina2xx_driver = {
.name   = "ina2xx",
},
.probe  = ina2xx_probe,
-   .remove = ina2xx_remove,
.id_table   = ina2xx_id,
 };
 
-- 
1.7.9.7

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

[PATCH 05/11] hwmon: (max16065) Convert to use devm_hwmon_device_register_with_groups

2013-09-14 Thread Guenter Roeck
Modify code to use is_visible to determine if an attribute should be created
or not, then use devm_hwmon_device_register_with_groups to create the hwmon
device and all attributes in one operation.

Signed-off-by: Guenter Roeck 
---
 drivers/hwmon/max16065.c |  124 +++---
 1 file changed, 52 insertions(+), 72 deletions(-)

diff --git a/drivers/hwmon/max16065.c b/drivers/hwmon/max16065.c
index 2fa2c02..d4efc79 100644
--- a/drivers/hwmon/max16065.c
+++ b/drivers/hwmon/max16065.c
@@ -83,7 +83,8 @@ static const bool max16065_have_current[] = {
 
 struct max16065_data {
enum chips type;
-   struct device *hwmon_dev;
+   struct i2c_client *client;
+   const struct attribute_group *groups[4];
struct mutex update_lock;
bool valid;
unsigned long last_updated; /* in jiffies */
@@ -144,8 +145,8 @@ static int max16065_read_adc(struct i2c_client *client, int 
reg)
 
 static struct max16065_data *max16065_update_device(struct device *dev)
 {
-   struct i2c_client *client = to_i2c_client(dev);
-   struct max16065_data *data = i2c_get_clientdata(client);
+   struct max16065_data *data = dev_get_drvdata(dev);
+   struct i2c_client *client = data->client;
 
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
@@ -186,7 +187,7 @@ static ssize_t max16065_show_alarm(struct device *dev,
 
val &= (1 << attr2->index);
if (val)
-   i2c_smbus_write_byte_data(to_i2c_client(dev),
+   i2c_smbus_write_byte_data(data->client,
  MAX16065_FAULT(attr2->nr), val);
 
return snprintf(buf, PAGE_SIZE, "%d\n", !!val);
@@ -223,8 +224,7 @@ static ssize_t max16065_set_limit(struct device *dev,
  const char *buf, size_t count)
 {
struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(da);
-   struct i2c_client *client = to_i2c_client(dev);
-   struct max16065_data *data = i2c_get_clientdata(client);
+   struct max16065_data *data = dev_get_drvdata(dev);
unsigned long val;
int err;
int limit;
@@ -238,7 +238,7 @@ static ssize_t max16065_set_limit(struct device *dev,
mutex_lock(&data->update_lock);
data->limit[attr2->nr][attr2->index]
  = LIMIT_TO_MV(limit, data->range[attr2->index]);
-   i2c_smbus_write_byte_data(client,
+   i2c_smbus_write_byte_data(data->client,
  MAX16065_LIMIT(attr2->nr, attr2->index),
  limit);
mutex_unlock(&data->update_lock);
@@ -250,8 +250,7 @@ static ssize_t max16065_show_limit(struct device *dev,
   struct device_attribute *da, char *buf)
 {
struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(da);
-   struct i2c_client *client = to_i2c_client(dev);
-   struct max16065_data *data = i2c_get_clientdata(client);
+   struct max16065_data *data = dev_get_drvdata(dev);
 
return snprintf(buf, PAGE_SIZE, "%d\n",
data->limit[attr2->nr][attr2->index]);
@@ -516,8 +515,32 @@ static struct attribute *max16065_max_attributes[] = {
NULL
 };
 
+static umode_t max16065_basic_is_visible(struct kobject *kobj,
+struct attribute *a, int n)
+{
+   struct device *dev = container_of(kobj, struct device, kobj);
+   struct max16065_data *data = dev_get_drvdata(dev);
+   int index = n / 4;
+
+   if (index >= data->num_adc || !data->range[index])
+   return 0;
+   return a->mode;
+}
+
+static umode_t max16065_secondary_is_visible(struct kobject *kobj,
+struct attribute *a, int index)
+{
+   struct device *dev = container_of(kobj, struct device, kobj);
+   struct max16065_data *data = dev_get_drvdata(dev);
+
+   if (index >= data->num_adc)
+   return 0;
+   return a->mode;
+}
+
 static const struct attribute_group max16065_basic_group = {
.attrs = max16065_basic_attributes,
+   .is_visible = max16065_basic_is_visible,
 };
 
 static const struct attribute_group max16065_current_group = {
@@ -526,38 +549,35 @@ static const struct attribute_group 
max16065_current_group = {
 
 static const struct attribute_group max16065_min_group = {
.attrs = max16065_min_attributes,
+   .is_visible = max16065_secondary_is_visible,
 };
 
 static const struct attribute_group max16065_max_group = {
.attrs = max16065_max_attributes,
+   .is_visible = max16065_secondary_is_visible,
 };
 
-static void max16065_cleanup(struct i2c_client *client)
-{
-   sysfs_remove_group(&client->dev.kobj, &max16065_max_group);
-   sysfs_remove_group(&client->dev.kobj, &max16065_min_group);
-   sysfs_remove_group(&client->dev.kobj, &max16065_current_group);
-   sysfs_remov

[PATCH 03/11] hwmon: (lm73) Convert to use devm_hwmon_device_register_with_groups

2013-09-14 Thread Guenter Roeck
Also introduce new variable dev pointing to client->dev in the probe
function, and use new macro ATTRIBUTE_GROUPS to declare attribute groups.

Signed-off-by: Guenter Roeck 
---
 drivers/hwmon/lm73.c |   70 --
 1 file changed, 22 insertions(+), 48 deletions(-)

diff --git a/drivers/hwmon/lm73.c b/drivers/hwmon/lm73.c
index 9bde964..9653bb8 100644
--- a/drivers/hwmon/lm73.c
+++ b/drivers/hwmon/lm73.c
@@ -55,7 +55,7 @@ static const unsigned short lm73_convrates[] = {
 };
 
 struct lm73_data {
-   struct device *hwmon_dev;
+   struct i2c_client *client;
struct mutex lock;
u8 ctrl;/* control register value */
 };
@@ -66,7 +66,7 @@ static ssize_t set_temp(struct device *dev, struct 
device_attribute *da,
const char *buf, size_t count)
 {
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
-   struct i2c_client *client = to_i2c_client(dev);
+   struct lm73_data *data = dev_get_drvdata(dev);
long temp;
short value;
s32 err;
@@ -77,7 +77,7 @@ static ssize_t set_temp(struct device *dev, struct 
device_attribute *da,
 
/* Write value */
value = clamp_val(temp / 250, LM73_TEMP_MIN, LM73_TEMP_MAX) << 5;
-   err = i2c_smbus_write_word_swapped(client, attr->index, value);
+   err = i2c_smbus_write_word_swapped(data->client, attr->index, value);
return (err < 0) ? err : count;
 }
 
@@ -85,10 +85,10 @@ static ssize_t show_temp(struct device *dev, struct 
device_attribute *da,
 char *buf)
 {
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
-   struct i2c_client *client = to_i2c_client(dev);
+   struct lm73_data *data = dev_get_drvdata(dev);
int temp;
 
-   s32 err = i2c_smbus_read_word_swapped(client, attr->index);
+   s32 err = i2c_smbus_read_word_swapped(data->client, attr->index);
if (err < 0)
return err;
 
@@ -101,8 +101,7 @@ static ssize_t show_temp(struct device *dev, struct 
device_attribute *da,
 static ssize_t set_convrate(struct device *dev, struct device_attribute *da,
const char *buf, size_t count)
 {
-   struct i2c_client *client = to_i2c_client(dev);
-   struct lm73_data *data = i2c_get_clientdata(client);
+   struct lm73_data *data = dev_get_drvdata(dev);
unsigned long convrate;
s32 err;
int res = 0;
@@ -124,7 +123,8 @@ static ssize_t set_convrate(struct device *dev, struct 
device_attribute *da,
mutex_lock(&data->lock);
data->ctrl &= LM73_CTRL_TO_MASK;
data->ctrl |= res << LM73_CTRL_RES_SHIFT;
-   err = i2c_smbus_write_byte_data(client, LM73_REG_CTRL, data->ctrl);
+   err = i2c_smbus_write_byte_data(data->client, LM73_REG_CTRL,
+   data->ctrl);
mutex_unlock(&data->lock);
 
if (err < 0)
@@ -136,8 +136,7 @@ static ssize_t set_convrate(struct device *dev, struct 
device_attribute *da,
 static ssize_t show_convrate(struct device *dev, struct device_attribute *da,
 char *buf)
 {
-   struct i2c_client *client = to_i2c_client(dev);
-   struct lm73_data *data = i2c_get_clientdata(client);
+   struct lm73_data *data = dev_get_drvdata(dev);
int res;
 
res = (data->ctrl & LM73_CTRL_RES_MASK) >> LM73_CTRL_RES_SHIFT;
@@ -147,13 +146,12 @@ static ssize_t show_convrate(struct device *dev, struct 
device_attribute *da,
 static ssize_t show_maxmin_alarm(struct device *dev,
 struct device_attribute *da, char *buf)
 {
-   struct i2c_client *client = to_i2c_client(dev);
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
-   struct lm73_data *data = i2c_get_clientdata(client);
+   struct lm73_data *data = dev_get_drvdata(dev);
s32 ctrl;
 
mutex_lock(&data->lock);
-   ctrl = i2c_smbus_read_byte_data(client, LM73_REG_CTRL);
+   ctrl = i2c_smbus_read_byte_data(data->client, LM73_REG_CTRL);
if (ctrl < 0)
goto abort;
data->ctrl = ctrl;
@@ -183,7 +181,7 @@ static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO,
 static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO,
show_maxmin_alarm, NULL, LM73_CTRL_LO_SHIFT);
 
-static struct attribute *lm73_attributes[] = {
+static struct attribute *lm73_attrs[] = {
&sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_temp1_max.dev_attr.attr,
&sensor_dev_attr_temp1_min.dev_attr.attr,
@@ -192,10 +190,7 @@ static struct attribute *lm73_attributes[] = {
&sensor_dev_attr_temp1_min_alarm.dev_attr.attr,
NULL
 };
-
-static const struct attribute_group lm73_group = {
-   .attrs = lm73_attributes,
-};
+ATTRIBUTE_GROUPS(lm73);
 
 /*---*/
 
@@ -204,16 +199,16 @@ st

[PATCH 08/11] hwmon: (lm95234) Convert to use devm_hwmon_device_register_with_groups

2013-09-14 Thread Guenter Roeck
Also use new macro ATTRIBUTE_GROUPS to declare attribute groups.

Signed-off-by: Guenter Roeck 
---
 drivers/hwmon/lm95234.c |  137 +--
 1 file changed, 50 insertions(+), 87 deletions(-)

diff --git a/drivers/hwmon/lm95234.c b/drivers/hwmon/lm95234.c
index 307c9ea..cf87507 100644
--- a/drivers/hwmon/lm95234.c
+++ b/drivers/hwmon/lm95234.c
@@ -57,7 +57,7 @@ static const unsigned short normal_i2c[] = { 0x18, 0x4d, 
0x4e, I2C_CLIENT_END };
 
 /* Client data (each client gets its own) */
 struct lm95234_data {
-   struct device *hwmon_dev;
+   struct i2c_client *client;
struct mutex update_lock;
unsigned long last_updated, interval;   /* in jiffies */
bool valid; /* false until following fields are valid */
@@ -114,9 +114,9 @@ static u16 update_intervals[] = { 143, 364, 1000, 2500 };
 
 /* Fill value cache. Must be called with update lock held. */
 
-static int lm95234_fill_cache(struct i2c_client *client)
+static int lm95234_fill_cache(struct lm95234_data *data,
+ struct i2c_client *client)
 {
-   struct lm95234_data *data = i2c_get_clientdata(client);
int i, ret;
 
ret = i2c_smbus_read_byte_data(client, LM95234_REG_CONVRATE);
@@ -157,9 +157,9 @@ static int lm95234_fill_cache(struct i2c_client *client)
return 0;
 }
 
-static int lm95234_update_device(struct i2c_client *client,
-struct lm95234_data *data)
+static int lm95234_update_device(struct lm95234_data *data)
 {
+   struct i2c_client *client = data->client;
int ret;
 
mutex_lock(&data->update_lock);
@@ -169,7 +169,7 @@ static int lm95234_update_device(struct i2c_client *client,
int i;
 
if (!data->valid) {
-   ret = lm95234_fill_cache(client);
+   ret = lm95234_fill_cache(data, client);
if (ret < 0)
goto abort;
}
@@ -209,10 +209,9 @@ abort:
 static ssize_t show_temp(struct device *dev, struct device_attribute *attr,
 char *buf)
 {
-   struct i2c_client *client = to_i2c_client(dev);
-   struct lm95234_data *data = i2c_get_clientdata(client);
+   struct lm95234_data *data = dev_get_drvdata(dev);
int index = to_sensor_dev_attr(attr)->index;
-   int ret = lm95234_update_device(client, data);
+   int ret = lm95234_update_device(data);
 
if (ret)
return ret;
@@ -224,10 +223,9 @@ static ssize_t show_temp(struct device *dev, struct 
device_attribute *attr,
 static ssize_t show_alarm(struct device *dev,
  struct device_attribute *attr, char *buf)
 {
-   struct i2c_client *client = to_i2c_client(dev);
-   struct lm95234_data *data = i2c_get_clientdata(client);
+   struct lm95234_data *data = dev_get_drvdata(dev);
u32 mask = to_sensor_dev_attr(attr)->index;
-   int ret = lm95234_update_device(client, data);
+   int ret = lm95234_update_device(data);
 
if (ret)
return ret;
@@ -238,10 +236,9 @@ static ssize_t show_alarm(struct device *dev,
 static ssize_t show_type(struct device *dev, struct device_attribute *attr,
 char *buf)
 {
-   struct i2c_client *client = to_i2c_client(dev);
-   struct lm95234_data *data = i2c_get_clientdata(client);
+   struct lm95234_data *data = dev_get_drvdata(dev);
u8 mask = to_sensor_dev_attr(attr)->index;
-   int ret = lm95234_update_device(client, data);
+   int ret = lm95234_update_device(data);
 
if (ret)
return ret;
@@ -252,11 +249,10 @@ static ssize_t show_type(struct device *dev, struct 
device_attribute *attr,
 static ssize_t set_type(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
 {
-   struct i2c_client *client = to_i2c_client(dev);
-   struct lm95234_data *data = i2c_get_clientdata(client);
+   struct lm95234_data *data = dev_get_drvdata(dev);
unsigned long val;
u8 mask = to_sensor_dev_attr(attr)->index;
-   int ret = lm95234_update_device(client, data);
+   int ret = lm95234_update_device(data);
 
if (ret)
return ret;
@@ -274,7 +270,7 @@ static ssize_t set_type(struct device *dev, struct 
device_attribute *attr,
else
data->sensor_type &= ~mask;
data->valid = false;
-   i2c_smbus_write_byte_data(client, LM95234_REG_REM_MODEL,
+   i2c_smbus_write_byte_data(data->client, LM95234_REG_REM_MODEL,
  data->sensor_type);
mutex_unlock(&data->update_lock);
 
@@ -284,10 +280,9 @@ static ssize_t set_type(struct device *dev, struct 
device_attribute *attr,
 static ssize_t show_tcrit2(struct device *dev, struct device_attribute *attr,
   char *buf)
 {
-   struct

[PATCH 10/11] hwmon: (ltc4261) Convert to use devm_hwmon_device_register_with_groups

2013-09-14 Thread Guenter Roeck
Also use new macro ATTRIBUTE_GROUPS to declare attribute groups.

Signed-off-by: Guenter Roeck 
---
 drivers/hwmon/ltc4261.c |   55 ++-
 1 file changed, 16 insertions(+), 39 deletions(-)

diff --git a/drivers/hwmon/ltc4261.c b/drivers/hwmon/ltc4261.c
index 487da58..6c50db9 100644
--- a/drivers/hwmon/ltc4261.c
+++ b/drivers/hwmon/ltc4261.c
@@ -55,7 +55,7 @@
 #define FAULT_OC   (1<<2)
 
 struct ltc4261_data {
-   struct device *hwmon_dev;
+   struct i2c_client *client;
 
struct mutex update_lock;
bool valid;
@@ -67,8 +67,8 @@ struct ltc4261_data {
 
 static struct ltc4261_data *ltc4261_update_device(struct device *dev)
 {
-   struct i2c_client *client = to_i2c_client(dev);
-   struct ltc4261_data *data = i2c_get_clientdata(client);
+   struct ltc4261_data *data = dev_get_drvdata(dev);
+   struct i2c_client *client = data->client;
struct ltc4261_data *ret = data;
 
mutex_lock(&data->update_lock);
@@ -150,7 +150,6 @@ static ssize_t ltc4261_show_bool(struct device *dev,
 struct device_attribute *da, char *buf)
 {
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
-   struct i2c_client *client = to_i2c_client(dev);
struct ltc4261_data *data = ltc4261_update_device(dev);
u8 fault;
 
@@ -159,7 +158,7 @@ static ssize_t ltc4261_show_bool(struct device *dev,
 
fault = data->regs[LTC4261_FAULT] & attr->index;
if (fault)  /* Clear reported faults in chip register */
-   i2c_smbus_write_byte_data(client, LTC4261_FAULT, ~fault);
+   i2c_smbus_write_byte_data(data->client, LTC4261_FAULT, ~fault);
 
return snprintf(buf, PAGE_SIZE, "%d\n", fault ? 1 : 0);
 }
@@ -197,7 +196,7 @@ static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, 
ltc4261_show_value, NULL,
 static SENSOR_DEVICE_ATTR(curr1_max_alarm, S_IRUGO, ltc4261_show_bool, NULL,
  FAULT_OC);
 
-static struct attribute *ltc4261_attributes[] = {
+static struct attribute *ltc4261_attrs[] = {
&sensor_dev_attr_in1_input.dev_attr.attr,
&sensor_dev_attr_in1_min_alarm.dev_attr.attr,
&sensor_dev_attr_in1_max_alarm.dev_attr.attr,
@@ -210,60 +209,39 @@ static struct attribute *ltc4261_attributes[] = {
 
NULL,
 };
-
-static const struct attribute_group ltc4261_group = {
-   .attrs = ltc4261_attributes,
-};
+ATTRIBUTE_GROUPS(ltc4261);
 
 static int ltc4261_probe(struct i2c_client *client,
 const struct i2c_device_id *id)
 {
struct i2c_adapter *adapter = client->adapter;
+   struct device *dev = &client->dev;
struct ltc4261_data *data;
-   int ret;
+   struct device *hwmon_dev;
 
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return -ENODEV;
 
if (i2c_smbus_read_byte_data(client, LTC4261_STATUS) < 0) {
-   dev_err(&client->dev, "Failed to read status register\n");
+   dev_err(dev, "Failed to read status register\n");
return -ENODEV;
}
 
-   data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
+   data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
 
-   i2c_set_clientdata(client, data);
+   data->client = client;
mutex_init(&data->update_lock);
 
/* Clear faults */
i2c_smbus_write_byte_data(client, LTC4261_FAULT, 0x00);
 
-   /* Register sysfs hooks */
-   ret = sysfs_create_group(&client->dev.kobj, hwmon_dev = hwmon_device_register(&client->dev);
-   if (IS_ERR(data->hwmon_dev)) {
-   ret = PTR_ERR(data->hwmon_dev);
-   goto out_hwmon_device_register;
-   }
-
-   return 0;
-
-out_hwmon_device_register:
-   sysfs_remove_group(&client->dev.kobj, hwmon_dev);
-   sysfs_remove_group(&client->dev.kobj, name,
+  data,
+  ltc4261_groups);
+   if (IS_ERR(hwmon_dev))
+   return PTR_ERR(hwmon_dev);
 
return 0;
 }
@@ -281,7 +259,6 @@ static struct i2c_driver ltc4261_driver = {
   .name = "ltc4261",
   },
.probe = ltc4261_probe,
-   .remove = ltc4261_remove,
.id_table = ltc4261_id,
 };
 
-- 
1.7.9.7

--
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.or

[PATCH v3 01/11] hwmon: (ds1621) Convert to use devm_hwmon_device_register_with_groups

2013-09-14 Thread Guenter Roeck
Also use new macro __ATTRIBUTE_GROUPS to declare attribute groups.

Signed-off-by: Guenter Roeck 
---
v3: Use __ATTRIBUTE_GROUPS

 drivers/hwmon/ds1621.c |   24 
 1 file changed, 4 insertions(+), 20 deletions(-)

diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c
index 595f4ef..5e398c9 100644
--- a/drivers/hwmon/ds1621.c
+++ b/drivers/hwmon/ds1621.c
@@ -354,11 +354,7 @@ static const struct attribute_group ds1621_group = {
.attrs = ds1621_attributes,
.is_visible = ds1621_attribute_visible
 };
-
-static const struct attribute_group *ds1621_groups[] = {
-   &ds1621_group,
-   NULL
-};
+__ATTRIBUTE_GROUPS(ds1621);
 
 static int ds1621_probe(struct i2c_client *client,
const struct i2c_device_id *id)
@@ -379,23 +375,12 @@ static int ds1621_probe(struct i2c_client *client,
/* Initialize the DS1621 chip */
ds1621_init_client(data, client);
 
-   hwmon_dev = hwmon_device_register_with_groups(&client->dev,
- client->name, data,
- ds1621_groups);
+   hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev,
+  client->name, data,
+  ds1621_groups);
if (IS_ERR(hwmon_dev))
return PTR_ERR(hwmon_dev);
 
-   i2c_set_clientdata(client, hwmon_dev);
-
-   return 0;
-}
-
-static int ds1621_remove(struct i2c_client *client)
-{
-   struct device *hwmon_dev = i2c_get_clientdata(client);
-
-   hwmon_device_unregister(hwmon_dev);
-
return 0;
 }
 
@@ -416,7 +401,6 @@ static struct i2c_driver ds1621_driver = {
.name   = "ds1621",
},
.probe  = ds1621_probe,
-   .remove = ds1621_remove,
.id_table   = ds1621_id,
 };
 
-- 
1.7.9.7

--
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 11/11] hwmon: (jc42) Convert to use devm_hwmon_device_register_with_groups

2013-09-14 Thread Guenter Roeck
Signed-off-by: Guenter Roeck 
---
 drivers/hwmon/jc42.c |   61 +-
 1 file changed, 25 insertions(+), 36 deletions(-)

diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c
index 4a58f13..f362cea 100644
--- a/drivers/hwmon/jc42.c
+++ b/drivers/hwmon/jc42.c
@@ -163,7 +163,7 @@ static struct jc42_chips jc42_chips[] = {
 
 /* Each client has this additional data */
 struct jc42_data {
-   struct device   *hwmon_dev;
+   struct i2c_client *client;
struct mutexupdate_lock;/* protect register access */
boolextended;   /* true if extended range supported */
boolvalid;
@@ -193,21 +193,21 @@ MODULE_DEVICE_TABLE(i2c, jc42_id);
 
 static int jc42_suspend(struct device *dev)
 {
-   struct i2c_client *client = to_i2c_client(dev);
-   struct jc42_data *data = i2c_get_clientdata(client);
+   struct jc42_data *data = dev_get_drvdata(dev);
 
data->config |= JC42_CFG_SHUTDOWN;
-   i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG, data->config);
+   i2c_smbus_write_word_swapped(data->client, JC42_REG_CONFIG,
+data->config);
return 0;
 }
 
 static int jc42_resume(struct device *dev)
 {
-   struct i2c_client *client = to_i2c_client(dev);
-   struct jc42_data *data = i2c_get_clientdata(client);
+   struct jc42_data *data = dev_get_drvdata(dev);
 
data->config &= ~JC42_CFG_SHUTDOWN;
-   i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG, data->config);
+   i2c_smbus_write_word_swapped(data->client, JC42_REG_CONFIG,
+data->config);
return 0;
 }
 
@@ -317,15 +317,14 @@ static ssize_t set_##value(struct device *dev,
\
   struct device_attribute *attr,   \
   const char *buf, size_t count)   \
 {  \
-   struct i2c_client *client = to_i2c_client(dev); \
-   struct jc42_data *data = i2c_get_clientdata(client);\
+   struct jc42_data *data = dev_get_drvdata(dev);  \
int err, ret = count;   \
long val;   \
-   if (kstrtol(buf, 10, &val) < 0) \
+   if (kstrtol(buf, 10, &val) < 0) \
return -EINVAL; \
mutex_lock(&data->update_lock); \
data->value = jc42_temp_to_reg(val, data->extended);\
-   err = i2c_smbus_write_word_swapped(client, reg, data->value);   \
+   err = i2c_smbus_write_word_swapped(data->client, reg, data->value); \
if (err < 0)\
ret = err;  \
mutex_unlock(&data->update_lock);   \
@@ -344,8 +343,7 @@ static ssize_t set_temp_crit_hyst(struct device *dev,
  struct device_attribute *attr,
  const char *buf, size_t count)
 {
-   struct i2c_client *client = to_i2c_client(dev);
-   struct jc42_data *data = i2c_get_clientdata(client);
+   struct jc42_data *data = dev_get_drvdata(dev);
unsigned long val;
int diff, hyst;
int err;
@@ -368,7 +366,7 @@ static ssize_t set_temp_crit_hyst(struct device *dev,
mutex_lock(&data->update_lock);
data->config = (data->config & ~JC42_CFG_HYST_MASK)
  | (hyst << JC42_CFG_HYST_SHIFT);
-   err = i2c_smbus_write_word_swapped(client, JC42_REG_CONFIG,
+   err = i2c_smbus_write_word_swapped(data->client, JC42_REG_CONFIG,
   data->config);
if (err < 0)
ret = err;
@@ -430,8 +428,7 @@ static umode_t jc42_attribute_mode(struct kobject *kobj,
  struct attribute *attr, int index)
 {
struct device *dev = container_of(kobj, struct device, kobj);
-   struct i2c_client *client = to_i2c_client(dev);
-   struct jc42_data *data = i2c_get_clientdata(client);
+   struct jc42_data *data = dev_get_drvdata(dev);
unsigned int config = data->config;
bool readonly;
 
@@ -452,6 +449,7 @@ static const struct attribute_group jc42_group = {
.attrs = jc42_attributes,
.is_visible = jc42_attribute_mode,
 };
+__ATTRIBUTE_GROUPS(jc42);
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
 static int jc42_detect(struct i2c_client *client, struct i2c_board_info *info)
@@ -487,14 +485,16 @@ static int jc42_detect(struct i2c_client *client, struct 
i2c_board_info *info)
 
 static int jc42_probe(struct i2c_client *client, const st

[PATCH 09/11] hwmon: (ina209) Convert to use devm_hwmon_device_register_with_groups

2013-09-14 Thread Guenter Roeck
Also use new macro ATTRIBUTE_GROUPS to declare attribute groups.

Signed-off-by: Guenter Roeck 
---
 drivers/hwmon/ina209.c |   46 ++
 1 file changed, 18 insertions(+), 28 deletions(-)

diff --git a/drivers/hwmon/ina209.c b/drivers/hwmon/ina209.c
index c6fdd5b..5378fde 100644
--- a/drivers/hwmon/ina209.c
+++ b/drivers/hwmon/ina209.c
@@ -63,7 +63,7 @@
 #define INA209_SHUNT_DEFAULT   1   /* uOhm */
 
 struct ina209_data {
-   struct device *hwmon_dev;
+   struct i2c_client *client;
 
struct mutex update_lock;
bool valid;
@@ -78,8 +78,8 @@ struct ina209_data {
 
 static struct ina209_data *ina209_update_device(struct device *dev)
 {
-   struct i2c_client *client = to_i2c_client(dev);
-   struct ina209_data *data = i2c_get_clientdata(client);
+   struct ina209_data *data = dev_get_drvdata(dev);
+   struct i2c_client *client = data->client;
struct ina209_data *ret = data;
s32 val;
int i;
@@ -234,7 +234,6 @@ static ssize_t ina209_set_interval(struct device *dev,
   struct device_attribute *da,
   const char *buf, size_t count)
 {
-   struct i2c_client *client = to_i2c_client(dev);
struct ina209_data *data = ina209_update_device(dev);
long val;
u16 regval;
@@ -250,7 +249,8 @@ static ssize_t ina209_set_interval(struct device *dev,
mutex_lock(&data->update_lock);
regval = ina209_reg_from_interval(data->regs[INA209_CONFIGURATION],
  val);
-   i2c_smbus_write_word_swapped(client, INA209_CONFIGURATION, regval);
+   i2c_smbus_write_word_swapped(data->client, INA209_CONFIGURATION,
+regval);
data->regs[INA209_CONFIGURATION] = regval;
data->update_interval = ina209_interval_from_reg(regval);
mutex_unlock(&data->update_lock);
@@ -260,8 +260,7 @@ static ssize_t ina209_set_interval(struct device *dev,
 static ssize_t ina209_show_interval(struct device *dev,
struct device_attribute *da, char *buf)
 {
-   struct i2c_client *client = to_i2c_client(dev);
-   struct ina209_data *data = i2c_get_clientdata(client);
+   struct ina209_data *data = dev_get_drvdata(dev);
 
return snprintf(buf, PAGE_SIZE, "%d\n", data->update_interval);
 }
@@ -285,9 +284,9 @@ static ssize_t ina209_reset_history(struct device *dev,
const char *buf,
size_t count)
 {
-   struct i2c_client *client = to_i2c_client(dev);
-   struct ina209_data *data = i2c_get_clientdata(client);
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+   struct ina209_data *data = dev_get_drvdata(dev);
+   struct i2c_client *client = data->client;
u32 mask = attr->index;
long val;
int i, ret;
@@ -312,7 +311,6 @@ static ssize_t ina209_set_value(struct device *dev,
const char *buf,
size_t count)
 {
-   struct i2c_client *client = to_i2c_client(dev);
struct ina209_data *data = ina209_update_device(dev);
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
int reg = attr->index;
@@ -332,7 +330,7 @@ static ssize_t ina209_set_value(struct device *dev,
count = ret;
goto abort;
}
-   i2c_smbus_write_word_swapped(client, reg, ret);
+   i2c_smbus_write_word_swapped(data->client, reg, ret);
data->regs[reg] = ret;
 abort:
mutex_unlock(&data->update_lock);
@@ -457,7 +455,7 @@ static SENSOR_DEVICE_ATTR(update_interval, S_IRUGO | 
S_IWUSR,
  * Finally, construct an array of pointers to members of the above objects,
  * as required for sysfs_create_group()
  */
-static struct attribute *ina209_attributes[] = {
+static struct attribute *ina209_attrs[] = {
&sensor_dev_attr_in0_input.dev_attr.attr,
&sensor_dev_attr_in0_input_highest.dev_attr.attr,
&sensor_dev_attr_in0_input_lowest.dev_attr.attr,
@@ -498,10 +496,7 @@ static struct attribute *ina209_attributes[] = {
 
NULL,
 };
-
-static const struct attribute_group ina209_group = {
-   .attrs = ina209_attributes,
-};
+ATTRIBUTE_GROUPS(ina209);
 
 static void ina209_restore_conf(struct i2c_client *client,
struct ina209_data *data)
@@ -565,6 +560,7 @@ static int ina209_probe(struct i2c_client *client,
 {
struct i2c_adapter *adapter = client->adapter;
struct ina209_data *data;
+   struct device *hwmon_dev;
int ret;
 
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA))
@@ -575,27 +571,23 @@ static int ina209_probe(struct i2c_client *client,
return -ENOMEM;
 
i2c_set_clientdata(client, data);
+   data->client = client;
mutex_ini

[PATCH 07/11] hwmon: (tmp401) Convert to use devm_hwmon_device_register_with_groups

2013-09-14 Thread Guenter Roeck
Signed-off-by: Guenter Roeck 
---
 drivers/hwmon/tmp401.c |   89 +++-
 1 file changed, 28 insertions(+), 61 deletions(-)

diff --git a/drivers/hwmon/tmp401.c b/drivers/hwmon/tmp401.c
index dfe6d95..49bd122 100644
--- a/drivers/hwmon/tmp401.c
+++ b/drivers/hwmon/tmp401.c
@@ -155,7 +155,8 @@ MODULE_DEVICE_TABLE(i2c, tmp401_id);
  */
 
 struct tmp401_data {
-   struct device *hwmon_dev;
+   struct i2c_client *client;
+   const struct attribute_group *groups[3];
struct mutex update_lock;
char valid; /* zero until following fields are valid */
unsigned long last_updated; /* in jiffies */
@@ -231,8 +232,8 @@ static int tmp401_update_device_reg16(struct i2c_client 
*client,
 
 static struct tmp401_data *tmp401_update_device(struct device *dev)
 {
-   struct i2c_client *client = to_i2c_client(dev);
-   struct tmp401_data *data = i2c_get_clientdata(client);
+   struct tmp401_data *data = dev_get_drvdata(dev);
+   struct i2c_client *client = data->client;
struct tmp401_data *ret = data;
int i, val;
unsigned long next_update;
@@ -350,8 +351,8 @@ static ssize_t store_temp(struct device *dev, struct 
device_attribute *devattr,
 {
int nr = to_sensor_dev_attr_2(devattr)->nr;
int index = to_sensor_dev_attr_2(devattr)->index;
-   struct i2c_client *client = to_i2c_client(dev);
-   struct tmp401_data *data = tmp401_update_device(dev);
+   struct tmp401_data *data = dev_get_drvdata(dev);
+   struct i2c_client *client = data->client;
long val;
u16 reg;
u8 regaddr;
@@ -405,7 +406,7 @@ static ssize_t store_temp_crit_hyst(struct device *dev, 
struct device_attribute
val = clamp_val(val, temp - 255000, temp);
reg = ((temp - val) + 500) / 1000;
 
-   i2c_smbus_write_byte_data(to_i2c_client(dev), TMP401_TEMP_CRIT_HYST,
+   i2c_smbus_write_byte_data(data->client, TMP401_TEMP_CRIT_HYST,
  reg);
 
data->temp_crit_hyst = reg;
@@ -423,8 +424,8 @@ static ssize_t store_temp_crit_hyst(struct device *dev, 
struct device_attribute
 static ssize_t reset_temp_history(struct device *dev,
struct device_attribute *devattr, const char *buf, size_t count)
 {
-   struct i2c_client *client = to_i2c_client(dev);
-   struct tmp401_data *data = i2c_get_clientdata(client);
+   struct tmp401_data *data = dev_get_drvdata(dev);
+   struct i2c_client *client = data->client;
long val;
 
if (kstrtol(buf, 10, &val))
@@ -447,8 +448,7 @@ static ssize_t reset_temp_history(struct device *dev,
 static ssize_t show_update_interval(struct device *dev,
struct device_attribute *attr, char *buf)
 {
-   struct i2c_client *client = to_i2c_client(dev);
-   struct tmp401_data *data = i2c_get_clientdata(client);
+   struct tmp401_data *data = dev_get_drvdata(dev);
 
return sprintf(buf, "%u\n", data->update_interval);
 }
@@ -457,8 +457,8 @@ static ssize_t set_update_interval(struct device *dev,
   struct device_attribute *attr,
   const char *buf, size_t count)
 {
-   struct i2c_client *client = to_i2c_client(dev);
-   struct tmp401_data *data = i2c_get_clientdata(client);
+   struct tmp401_data *data = dev_get_drvdata(dev);
+   struct i2c_client *client = data->client;
unsigned long val;
int err, rate;
 
@@ -616,10 +616,10 @@ static const struct attribute_group tmp432_group = {
  * Begin non sysfs callback code (aka Real code)
  */
 
-static void tmp401_init_client(struct i2c_client *client)
+static void tmp401_init_client(struct tmp401_data *data,
+  struct i2c_client *client)
 {
int config, config_orig;
-   struct tmp401_data *data = i2c_get_clientdata(client);
 
/* Set the conversion rate to 2 Hz */
i2c_smbus_write_byte_data(client, TMP401_CONVERSION_RATE_WRITE, 5);
@@ -705,77 +705,45 @@ static int tmp401_detect(struct i2c_client *client,
return 0;
 }
 
-static int tmp401_remove(struct i2c_client *client)
-{
-   struct device *dev = &client->dev;
-   struct tmp401_data *data = i2c_get_clientdata(client);
-
-   if (data->hwmon_dev)
-   hwmon_device_unregister(data->hwmon_dev);
-
-   sysfs_remove_group(&dev->kobj, &tmp401_group);
-
-   if (data->kind == tmp411)
-   sysfs_remove_group(&dev->kobj, &tmp411_group);
-
-   if (data->kind == tmp432)
-   sysfs_remove_group(&dev->kobj, &tmp432_group);
-
-   return 0;
-}
-
 static int tmp401_probe(struct i2c_client *client,
const struct i2c_device_id *id)
 {
+   const char *names[] = { "TMP401", "TMP411", "TMP431", "TMP432" };
struct device *dev = &client->dev;
-   int err;
+   struct device *hwmon_dev;
struct tmp401_data *data;
-

Re: [RFC PATCH alt 4/4] pinctrl: at91: rework debounce configuration

2013-09-14 Thread Jean-Christophe PLAGNIOL-VILLARD
On 16:40 Fri 13 Sep , Stephen Warren wrote:
> On 09/13/2013 01:53 AM, Boris BREZILLON wrote:
> > AT91 SoCs do not support per pin debounce time configuration.
> > Instead you have to configure a debounce time which will be used for all
> > pins of a given bank (PIOA, PIOB, ...).
> 
> > diff --git 
> > a/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt 
> > b/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt
> 
> > +Optional properties for iomux controller:
> > +- atmel,default-debounce-div: array of debounce divisors (one divisor per 
> > bank)
> > +  which describes the debounce timing in use for all pins of a given bank
> > +  configured with the DEBOUNCE option (see the following description).
> > +  Debounce timing is obtained with this formula:
> > +  Tdebounce = 2 * (debouncediv + 1) / Fslowclk
> > +  with Fslowclk = 32KHz
> > +
> >  Required properties for pin configuration node:
> >  - atmel,pins: 4 integers array, represents a group of pins mux and config
> >setting. The format is atmel,pins =  > CONFIG>.
> > @@ -91,7 +99,6 @@ DEGLITCH  (1 << 2): indicate this pin need deglitch.
> >  PULL_DOWN  (1 << 3): indicate this pin need a pull down.
> >  DIS_SCHMIT (1 << 4): indicate this pin need to disable schmit trigger.
> >  DEBOUNCE   (1 << 16): indicate this pin need debounce.
> > -DEBOUNCE_VAL   (0x3fff << 17): debounce val.
> 
> This change would break the DT ABI since it removes a feature that's
> already present.
> 
> I suppose it's still up to the Atmel maintainers to decide whether this
> is appropriate, or whether the impact to out-of-tree DT files would be
> problematic.

I does ask Boris to break the DT ABI

as anyway no one use it and the current ABI is wrong

and as this is the new SoC the impact of out-of-tree board is limited if ever

Best Regards,
J.
--
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: access efi variables

2013-09-14 Thread Arend van Spriel

On 09/14/13 00:37, H. Peter Anvin wrote:

On 09/13/2013 08:37 AM, Arend van Spriel wrote:

I need to obtain a uefi variable so I went looking at the API in
include/linux/efi.h. I found the following definition:

But according to the specs the variable I need to obtain is 2k bytes.
Should I expect trouble :-p



efivarfs doesn't have those limitations.


Thanks, Peter

Looking into efivarfs it seems to use the functions that I looked at in 
efi.h so I guess I am misinterpreting the 1024 bytes limitation in the 
comment (either that or you are mistaken ;-) ). I need to access the 
variable from within a device driver so using efivarfs does not feel 
like the way to go here.


Regards,
Arend

--
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 v5 0/9] liblockdep: userspace lockdep

2013-09-14 Thread Sasha Levin

On 09/12/2013 02:01 PM, Ingo Molnar wrote:

On 07/08/2013 04:39 AM, Ingo Molnar wrote:

PeterZ is in favor as well so I'll apply them after the merge window, for
v3.12.


Hi Ingo,

Do you intend to send liblockdep in this merge window as planned?


If Peter agrees with them and picks them up then the next merge window
would be fine I guess.


I thought that Peter acked it, and the plan was to push it through the locking
tree for 3.12?


Thanks,
Sasha

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


Re: [RFC PATCH 1/4] pinctrl: at91: fix typos

2013-09-14 Thread Jean-Christophe PLAGNIOL-VILLARD
On 09:45 Fri 13 Sep , Boris BREZILLON wrote:
> Fix AT91_PINCTRL_DEBOUNCE_VAL dt macro typo.
> Fix at91_pinctrl_mux_ops callback typos.
> 
Acked-by: Jean-Christophe PLAGNIOL-VILLARD 
> Signed-off-by: Boris BREZILLON 
> ---
>  drivers/pinctrl/pinctrl-at91.c |6 +++---
>  include/dt-bindings/pinctrl/at91.h |2 +-
>  2 files changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c
> index 19afb9a..50b555a 100644
> --- a/drivers/pinctrl/pinctrl-at91.c
> +++ b/drivers/pinctrl/pinctrl-at91.c
> @@ -144,11 +144,11 @@ struct at91_pinctrl_mux_ops {
>   void (*mux_C_periph)(void __iomem *pio, unsigned mask);
>   void (*mux_D_periph)(void __iomem *pio, unsigned mask);
>   bool (*get_deglitch)(void __iomem *pio, unsigned pin);
> - void (*set_deglitch)(void __iomem *pio, unsigned mask, bool in_on);
> + void (*set_deglitch)(void __iomem *pio, unsigned mask, bool is_on);
>   bool (*get_debounce)(void __iomem *pio, unsigned pin, u32 *div);
> - void (*set_debounce)(void __iomem *pio, unsigned mask, bool in_on, u32 
> div);
> + void (*set_debounce)(void __iomem *pio, unsigned mask, bool is_on, u32 
> div);
>   bool (*get_pulldown)(void __iomem *pio, unsigned pin);
> - void (*set_pulldown)(void __iomem *pio, unsigned mask, bool in_on);
> + void (*set_pulldown)(void __iomem *pio, unsigned mask, bool is_on);
>   bool (*get_schmitt_trig)(void __iomem *pio, unsigned pin);
>   void (*disable_schmitt_trig)(void __iomem *pio, unsigned mask);
>   /* irq */
> diff --git a/include/dt-bindings/pinctrl/at91.h 
> b/include/dt-bindings/pinctrl/at91.h
> index d7988b4..0fee6ff 100644
> --- a/include/dt-bindings/pinctrl/at91.h
> +++ b/include/dt-bindings/pinctrl/at91.h
> @@ -16,7 +16,7 @@
>  #define AT91_PINCTRL_PULL_DOWN   (1 << 3)
>  #define AT91_PINCTRL_DIS_SCHMIT  (1 << 4)
>  #define AT91_PINCTRL_DEBOUNCE(1 << 16)
> -#define AT91_PINCTRL_DEBOUNCE_VA(x)  (x << 17)
> +#define AT91_PINCTRL_DEBOUNCE_VAL(x) (x << 17)
>  
>  #define AT91_PINCTRL_PULL_UP_DEGLITCH(AT91_PINCTRL_PULL_UP | 
> AT91_PINCTRL_DEGLITCH)
>  
> -- 
> 1.7.9.5
> 
> 
> ___
> linux-arm-kernel mailing list
> linux-arm-ker...@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
--
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 38/38] iio: magn-core: st: Provide support for the LSM303DLH

2013-09-14 Thread Jonathan Cameron
On 09/10/13 13:49, Lee Jones wrote:
> Trivial patch adding the LSM303DLH to the list of already supported
> Magnetometer Sensors.
> 
> Signed-off-by: Lee Jones 
err.
> index 12e7e79..b2e2917 100644
> --- a/drivers/iio/magnetometer/st_magn_core.c
> +++ b/drivers/iio/magnetometer/st_magn_core.c
> @@ -151,7 +151,8 @@ static const struct st_sensors st_magn_sensors[] = {
>   .wai = ST_MAGN_1_WAI_EXP,
>   .sensors_supported = {
>   [0] = LSM303DLHC_MAGN_DEV_NAME,
> - [1] = LSM303DLM_MAGN_DEV_NAME,
> + [1] = LSM303DLH_MAGN_DEV_NAME,
> + [0] = LSM303DLM_MAGN_DEV_NAME,
[2]?
>   },
>   .ch = (struct iio_chan_spec *)st_magn_16bit_channels,
>   .odr = {
> 
--
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 32/38] iio: accel-core: st: Move LSM303DLH into correct group

2013-09-14 Thread Jonathan Cameron
On 09/10/13 13:49, Lee Jones wrote:
> The LSM303DLH's WAI (WhoAmI) is 0x33, meaning it should be enabled by
> Accel Sensor group one. For the device to probe without error, we'll
> need to ensure it's registered with the correct WAI.
> 
> Signed-off-by: Lee Jones 
You clearly have a better datasheet than I have as for that part it doesn't 
even claim to
have the relevant register to read a who am I from.

Now that datasheet does list odr values as 50, 100, 400 1000 which would put it 
where it originally
was in these tables.

http://www.st.com/web/en/resource/technical/document/datasheet/CD00260288.pdf

I haven't checked other elements...

I'm confused but suspect we may need another type entry to deal with this one.

> ---
>  drivers/iio/accel/st_accel_core.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/iio/accel/st_accel_core.c 
> b/drivers/iio/accel/st_accel_core.c
> index ea62291..03a2b6b 100644
> --- a/drivers/iio/accel/st_accel_core.c
> +++ b/drivers/iio/accel/st_accel_core.c
> @@ -170,6 +170,7 @@ static const struct st_sensors st_accel_sensors[] = {
>   [2] = LSM330D_ACCEL_DEV_NAME,
>   [3] = LSM330DL_ACCEL_DEV_NAME,
>   [4] = LSM330DLC_ACCEL_DEV_NAME,
> + [5] = LSM303DLH_ACCEL_DEV_NAME,
>   },
>   .ch = (struct iio_chan_spec *)st_accel_12bit_channels,
>   .odr = {
> @@ -238,8 +239,7 @@ static const struct st_sensors st_accel_sensors[] = {
>   .sensors_supported = {
>   [0] = LIS331DLH_ACCEL_DEV_NAME,
>   [1] = LSM303DL_ACCEL_DEV_NAME,
> - [2] = LSM303DLH_ACCEL_DEV_NAME,
> - [3] = LSM303DLM_ACCEL_DEV_NAME,
> + [2] = LSM303DLM_ACCEL_DEV_NAME,
>   },
>   .ch = (struct iio_chan_spec *)st_accel_12bit_channels,
>   .odr = {
> 
--
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] doc: fix some typos

2013-09-14 Thread Randy Dunlap
On 09/13/13 20:49, Xishi Qiu wrote:

> diff --git a/Documentation/kprobes.txt b/Documentation/kprobes.txt
> index 0cfb00f..ca278d5 100644
> --- a/Documentation/kprobes.txt
> +++ b/Documentation/kprobes.txt
> @@ -92,7 +92,7 @@ stack contents as the probed function.  When it is done, 
> the handler
>  calls jprobe_return(), which traps again to restore the original stack
>  contents and processor state and switch to the probed function.
>  
> -By convention, the callee owns its arguments, so gcc may produce code

Are you sure about that?
It looks correct to me (before the patch).

> +By convention, the caller owns its arguments, so gcc may produce code
>  that unexpectedly modifies that portion of the stack.  This is why
>  Kprobes saves a copy of the stack and restores it after the jprobe
>  handler has run.  Up to MAX_STACK_SIZE bytes are copied -- e.g.,
> 


-- 
~Randy
--
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 alt 4/4] pinctrl: at91: rework debounce configuration

2013-09-14 Thread Jean-Christophe PLAGNIOL-VILLARD
On 09:53 Fri 13 Sep , Boris BREZILLON wrote:
> AT91 SoCs do not support per pin debounce time configuration.
> Instead you have to configure a debounce time which will be used for all
> pins of a given bank (PIOA, PIOB, ...).
> 
> Signed-off-by: Boris BREZILLON 
> ---
>  .../bindings/pinctrl/atmel,at91-pinctrl.txt|9 ++-
>  drivers/pinctrl/pinctrl-at91.c |   79 
> 
>  include/dt-bindings/pinctrl/at91.h |1 -
>  3 files changed, 73 insertions(+), 16 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt 
> b/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt
> index cf7c7bc..8a4cdeb 100644
> --- a/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt
> +++ b/Documentation/devicetree/bindings/pinctrl/atmel,at91-pinctrl.txt
> @@ -78,6 +78,14 @@ PA31   TXD4
>  
>  => 0xffc00c3b
>  
> +Optional properties for iomux controller:
> +- atmel,default-debounce-div: array of debounce divisors (one divisor per 
> bank)
> +  which describes the debounce timing in use for all pins of a given bank
> +  configured with the DEBOUNCE option (see the following description).
> +  Debounce timing is obtained with this formula:
> +  Tdebounce = 2 * (debouncediv + 1) / Fslowclk
> +  with Fslowclk = 32KHz

I known that I put the div in the original binding

but maybe we should just put the debounce timing in the DT and calculate the
div in C
> +
>  Required properties for pin configuration node:
>  - atmel,pins: 4 integers array, represents a group of pins mux and config
>setting. The format is atmel,pins = .
> @@ -91,7 +99,6 @@ DEGLITCH(1 << 2): indicate this pin need deglitch.
>  PULL_DOWN(1 << 3): indicate this pin need a pull down.
>  DIS_SCHMIT   (1 << 4): indicate this pin need to disable schmit trigger.
>  DEBOUNCE (1 << 16): indicate this pin need debounce.
> -DEBOUNCE_VAL (0x3fff << 17): debounce val.
>  
>  NOTE:
>  Some requirements for using atmel,at91rm9200-pinctrl binding:
> diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c
> index ac9dbea..2903758 100644
> --- a/drivers/pinctrl/pinctrl-at91.c
> +++ b/drivers/pinctrl/pinctrl-at91.c
> @@ -62,8 +62,6 @@ static int gpio_banks;
>  #define PULL_DOWN(1 << 3)
>  #define DIS_SCHMIT   (1 << 4)
>  #define DEBOUNCE (1 << 16)
> -#define DEBOUNCE_VAL_SHIFT   17
> -#define DEBOUNCE_VAL (0x3fff << DEBOUNCE_VAL_SHIFT)
>  
>  /**
>   * struct at91_pmx_func - describes AT91 pinmux functions
> @@ -145,8 +143,10 @@ struct at91_pinctrl_mux_ops {
>   void (*mux_D_periph)(void __iomem *pio, unsigned mask);
>   bool (*get_deglitch)(void __iomem *pio, unsigned pin);
>   void (*set_deglitch)(void __iomem *pio, unsigned mask, bool is_on);
> - bool (*get_debounce)(void __iomem *pio, unsigned pin, u32 *div);
> - void (*set_debounce)(void __iomem *pio, unsigned mask, bool is_on, u32 
> div);
> + bool (*get_debounce)(void __iomem *pio, unsigned pin);
> + void (*set_debounce)(void __iomem *pio, unsigned mask, bool is_on);
> + u32 (*get_debounce_div)(void __iomem *pio);
> + void (*set_debounce_div)(void __iomem *pio, u32 div);
why do you split it?

if it's just get if on or not put NULL to div but do not add more function
pointer
>   bool (*get_pulldown)(void __iomem *pio, unsigned pin);
>   void (*set_pulldown)(void __iomem *pio, unsigned mask, bool is_on);
>   bool (*get_schmitt_trig)(void __iomem *pio, unsigned pin);
> @@ -432,25 +432,32 @@ static void at91_mux_pio3_set_deglitch(void __iomem 
> *pio, unsigned mask, bool is
>   at91_mux_set_deglitch(pio, mask, is_on);
>  }
>  
> -static bool at91_mux_pio3_get_debounce(void __iomem *pio, unsigned pin, u32 
> *div)
> +static bool at91_mux_pio3_get_debounce(void __iomem *pio, unsigned pin)
>  {
> - *div = __raw_readl(pio + PIO_SCDR);
> -
>   return ((__raw_readl(pio + PIO_IFSR) >> pin) & 0x1) &&
>  ((__raw_readl(pio + PIO_IFSCSR) >> pin) & 0x1);
>  }
>  
>  static void at91_mux_pio3_set_debounce(void __iomem *pio, unsigned mask,
> - bool is_on, u32 div)
> + bool is_on)
>  {
>   if (is_on) {
>   __raw_writel(mask, pio + PIO_IFSCER);
> - __raw_writel(div & PIO_SCDR_DIV, pio + PIO_SCDR);
>   __raw_writel(mask, pio + PIO_IFER);
>   } else
>   __raw_writel(mask, pio + PIO_IFSCDR);
>  }
>  
> +static u32 at91_mux_pio3_get_debounce_div(void __iomem *pio)
> +{
> + return __raw_readl(pio + PIO_SCDR) & PIO_SCDR_DIV;
> +}
> +
> +static void at91_mux_pio3_set_debounce_div(void __iomem *pio, u32 div)
> +{
> + __raw_writel(div & PIO_SCDR_DIV, pio + PIO_SCDR);
> +}
> +
>  static bool at91_mux_pio3_get_pulldown(void __iomem *pio, unsigned pin)
>  {
>   return !((__raw_readl(pio + PIO_PPDSR) >> pin) & 0x1);
> @@ -490,6 +497,8 @@ static struct at91_pinctrl_mux_ops at91sam9x5_ops = {
>

Re: [PATCH 31/38] iio: accel-core: st: Clean up error handling in probe()

2013-09-14 Thread Jonathan Cameron
On 09/10/13 13:49, Lee Jones wrote:
> Reduce the amount of those unnecessary goto calls, as in most cases
> we can simply return immediately. We also only call for the IRQ number
> once and use that value throughout.
> 
> Signed-off-by: Lee Jones 
...
> - if (adata->get_irq_data_ready(indio_dev) > 0) {
> + if (irq > 0) {
>   err = st_accel_allocate_ring(indio_dev);
>   if (err < 0)
> - goto st_accel_common_probe_error;
> + return err;
>  
>   err = st_sensors_allocate_trigger(indio_dev,
>ST_ACCEL_TRIGGER_OPS);
> @@ -492,18 +493,16 @@ int st_accel_common_probe(struct iio_dev *indio_dev,
>   }
>  
>   err = iio_device_register(indio_dev);
> - if (err)
> + if (err && irq > 0)
>   goto st_accel_device_register_error;
This is the same structure I moaned about earlier. Again, put the if (irq > 0) 
in the error handling
not here.
>  
>   return err;
>  
>  st_accel_device_register_error:
> - if (adata->get_irq_data_ready(indio_dev) > 0)
> - st_sensors_deallocate_trigger(indio_dev);
> + st_sensors_deallocate_trigger(indio_dev);
>  st_accel_probe_trigger_error:
> - if (adata->get_irq_data_ready(indio_dev) > 0)
> - st_accel_deallocate_ring(indio_dev);
> -st_accel_common_probe_error:
> + st_accel_deallocate_ring(indio_dev);
> +
>   return err;
>  }
>  EXPORT_SYMBOL(st_accel_common_probe);
> 
--
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 29/38] iio: pressure-core: st: Provide support for the Vdd power supply

2013-09-14 Thread Jonathan Cameron
On 09/10/13 13:49, Lee Jones wrote:
> The power to some of the sensors are controlled by regulators. In most
> cases these are 'always on', but if not they will fail to work until
> the regulator is enabled using the relevant APIs. This patch allows for
> the Vdd power supply to be specified by either platform data or Device
> Tree.
> 
> Signed-off-by: Lee Jones 
Fine, will pick up with the rest.  This optional regulator stuff is nice as
it gets around the annoying platform specific callbacks that tend to do stuff
like this.

If anyone is bored, I suspect there are quite a few cases where this makes sense
in other IIO drivers!
> ---
>  drivers/iio/pressure/st_pressure_core.c | 28 
>  include/linux/iio/common/st_sensors.h   |  3 +++
>  2 files changed, 31 insertions(+)
> 
> diff --git a/drivers/iio/pressure/st_pressure_core.c 
> b/drivers/iio/pressure/st_pressure_core.c
> index b42614a..d52b487 100644
> --- a/drivers/iio/pressure/st_pressure_core.c
> +++ b/drivers/iio/pressure/st_pressure_core.c
> @@ -23,6 +23,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  
>  #include 
> @@ -313,6 +314,29 @@ static const struct iio_trigger_ops st_press_trigger_ops 
> = {
>  #define ST_PRESS_TRIGGER_OPS NULL
>  #endif
>  
> +void st_press_power_enable(struct iio_dev *indio_dev)
> +{
> + struct st_sensor_data *pdata = iio_priv(indio_dev);
> + int err;
> +
> + /* Regulators not mandatory, but if requested we should enable it. */
> + pdata->vdd = devm_regulator_get_optional(&indio_dev->dev, "vdd");
> + if (!IS_ERR(pdata->vdd)) {
> + err = regulator_enable(pdata->vdd);
> + if (err != 0)
> + dev_warn(&indio_dev->dev,
> +  "Failed to enable specified Vdd supply\n");
> + }
> +}
> +
> +void st_press_power_disable(struct iio_dev *indio_dev)
> +{
> + struct st_sensor_data *pdata = iio_priv(indio_dev);
> +
> + if (!IS_ERR(pdata->vdd))
> + regulator_disable(pdata->vdd);
> +}
> +
>  int st_press_common_probe(struct iio_dev *indio_dev,
>   struct st_sensors_platform_data *plat_data)
>  {
> @@ -323,6 +347,8 @@ int st_press_common_probe(struct iio_dev *indio_dev,
>   indio_dev->modes = INDIO_DIRECT_MODE;
>   indio_dev->info = &press_info;
>  
> + st_press_power_enable(indio_dev);
> +
>   err = st_sensors_check_device_support(indio_dev,
> ARRAY_SIZE(st_press_sensors),
> st_press_sensors);
> @@ -382,6 +408,8 @@ void st_press_common_remove(struct iio_dev *indio_dev)
>  {
>   struct st_sensor_data *pdata = iio_priv(indio_dev);
>  
> + st_press_power_disable(indio_dev);
> +
>   iio_device_unregister(indio_dev);
>   if (pdata->get_irq_data_ready(indio_dev) > 0) {
>   st_sensors_deallocate_trigger(indio_dev);
> diff --git a/include/linux/iio/common/st_sensors.h 
> b/include/linux/iio/common/st_sensors.h
> index e732fda..968b84e 100644
> --- a/include/linux/iio/common/st_sensors.h
> +++ b/include/linux/iio/common/st_sensors.h
> @@ -16,6 +16,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include 
>  
> @@ -201,6 +202,7 @@ struct st_sensors {
>   * @trig: The trigger in use by the core driver.
>   * @sensor: Pointer to the current sensor struct in use.
>   * @current_fullscale: Maximum range of measure by the sensor.
> + * @vdd: Pointer to sensor's Vdd power supply
>   * @enabled: Status of the sensor (false->off, true->on).
>   * @multiread_bit: Use or not particular bit for [I2C/SPI] multiread.
>   * @buffer_data: Data used by buffer part.
> @@ -216,6 +218,7 @@ struct st_sensor_data {
>   struct iio_trigger *trig;
>   struct st_sensors *sensor;
>   struct st_sensor_fullscale_avl *current_fullscale;
> + struct regulator *vdd;
>  
>   bool enabled;
>   bool multiread_bit;
> 
--
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 28/38] iio: pressure: st: Add support for new LPS001WP pressure sensor

2013-09-14 Thread Jonathan Cameron
On 09/10/13 13:49, Lee Jones wrote:
> Here we use existing practices to introduce support for another
> pressure/temperature sensor, the LPS001WP.
> 
> Signed-off-by: Lee Jones 
Looks fine to me, will pick this up when the precursors are all sorted.
> ---
>  drivers/iio/pressure/st_pressure.h  |  1 +
>  drivers/iio/pressure/st_pressure_core.c | 84 
> +
>  drivers/iio/pressure/st_pressure_i2c.c  |  1 +
>  3 files changed, 86 insertions(+)
> 
> diff --git a/drivers/iio/pressure/st_pressure.h 
> b/drivers/iio/pressure/st_pressure.h
> index f1bebce..36b1cc6 100644
> --- a/drivers/iio/pressure/st_pressure.h
> +++ b/drivers/iio/pressure/st_pressure.h
> @@ -15,6 +15,7 @@
>  #include 
>  
>  #define LPS331AP_PRESS_DEV_NAME  "lps331ap_press"
> +#define LPS001WP_PRESS_DEV_NAME  "lps001wp_press"
>  
>  /**
>   * struct st_sensors_platform_data - default press platform data
> diff --git a/drivers/iio/pressure/st_pressure_core.c 
> b/drivers/iio/pressure/st_pressure_core.c
> index 34b3fb1..b42614a 100644
> --- a/drivers/iio/pressure/st_pressure_core.c
> +++ b/drivers/iio/pressure/st_pressure_core.c
> @@ -64,6 +64,21 @@
>  #define ST_PRESS_LPS331AP_OUT_XL_ADDR0x28
>  #define ST_TEMP_LPS331AP_OUT_L_ADDR  0x2b
>  
> +/* CUSTOM VALUES FOR LPS001WP SENSOR */
> +#define ST_PRESS_LPS001WP_WAI_EXP0xba
> +#define ST_PRESS_LPS001WP_ODR_ADDR   0x20
> +#define ST_PRESS_LPS001WP_ODR_MASK   0x30
> +#define ST_PRESS_LPS001WP_ODR_AVL_1HZ_VAL0x01
> +#define ST_PRESS_LPS001WP_ODR_AVL_7HZ_VAL0x02
> +#define ST_PRESS_LPS001WP_ODR_AVL_13HZ_VAL   0x03
> +#define ST_PRESS_LPS001WP_PW_ADDR0x20
> +#define ST_PRESS_LPS001WP_PW_MASK0x40
> +#define ST_PRESS_LPS001WP_BDU_ADDR   0x20
> +#define ST_PRESS_LPS001WP_BDU_MASK   0x04
> +#define ST_PRESS_LPS001WP_MULTIREAD_BIT  true
> +#define ST_PRESS_LPS001WP_OUT_L_ADDR 0x28
> +#define ST_TEMP_LPS001WP_OUT_L_ADDR  0x2a
> +
>  static const struct iio_chan_spec st_press_lps331ap_channels[] = {
>   {
>   .type = IIO_PRESSURE,
> @@ -100,6 +115,40 @@ static const struct iio_chan_spec 
> st_press_lps331ap_channels[] = {
>   IIO_CHAN_SOFT_TIMESTAMP(1)
>  };
>  
> +static const struct iio_chan_spec st_press_lps001wp_channels[] = {
> + {
> + .type = IIO_PRESSURE,
> + .channel2 = IIO_NO_MOD,
> + .address = ST_PRESS_LPS001WP_OUT_L_ADDR,
> + .scan_index = ST_SENSORS_SCAN_X,
> + .scan_type = {
> + .sign = 'u',
> + .realbits = 16,
> + .storagebits = 16,
> + .endianness = IIO_LE,
> + },
> + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
> + .modified = 0,
> + },
> + {
> + .type = IIO_TEMP,
> + .channel2 = IIO_NO_MOD,
> + .address = ST_TEMP_LPS001WP_OUT_L_ADDR,
> + .scan_index = -1,
> + .scan_type = {
> + .sign = 'u',
> + .realbits = 16,
> + .storagebits = 16,
> + .endianness = IIO_LE,
> + },
> + .info_mask_separate =
> + BIT(IIO_CHAN_INFO_RAW) |
> + BIT(IIO_CHAN_INFO_OFFSET),
> + .modified = 0,
> + },
> + IIO_CHAN_SOFT_TIMESTAMP(1)
> +};
> +
>  static const struct st_sensors st_press_sensors[] = {
>   {
>   .wai = ST_PRESS_LPS331AP_WAI_EXP,
> @@ -148,6 +197,41 @@ static const struct st_sensors st_press_sensors[] = {
>   .multi_read_bit = ST_PRESS_LPS331AP_MULTIREAD_BIT,
>   .bootime = 2,
>   },
> + {
> + .wai = ST_PRESS_LPS001WP_WAI_EXP,
> + .sensors_supported = {
> + [0] = LPS001WP_PRESS_DEV_NAME,
> + },
> + .ch = (struct iio_chan_spec *)st_press_lps001wp_channels,
> + .num_ch = ARRAY_SIZE(st_press_lps001wp_channels),
> + .odr = {
> + .addr = ST_PRESS_LPS001WP_ODR_ADDR,
> + .mask = ST_PRESS_LPS001WP_ODR_MASK,
> + .odr_avl = {
> + { 1, ST_PRESS_LPS001WP_ODR_AVL_1HZ_VAL, },
> + { 7, ST_PRESS_LPS001WP_ODR_AVL_7HZ_VAL, },
> + { 13, ST_PRESS_LPS001WP_ODR_AVL_13HZ_VAL, },
> + },
> + },
> + .pw = {
> + .addr = ST_PRESS_LPS001WP_PW_ADDR,
> + .mask = ST_PRESS_LPS001WP_PW_MASK,
> + .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
> + .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
> + },
> + .fs = {
> + .addr = 0,
> + },
> + .bdu = {
> + 

Re: [PATCH 26/38] iio: pressure-core: st: Clean-up probe() function

2013-09-14 Thread Jonathan Cameron
On 09/11/13 08:19, Lee Jones wrote:
>>> err = st_sensors_init_sensor(indio_dev, plat_data);
>>> if (err < 0)
>>> -   goto st_press_common_probe_error;
>>> +   return err;
>>>
>>> -   if (pdata->get_irq_data_ready(indio_dev) > 0) {
>>> +   if (irq > 0) {
>>> err = st_press_allocate_ring(indio_dev);
>>> if (err < 0)
>>> -   goto st_press_common_probe_error;
>>> +   return err;
>>>
>>> err = st_sensors_allocate_trigger(indio_dev,
>>> -   ST_PRESS_TRIGGER_OPS);
>>> + ST_PRESS_TRIGGER_OPS);
>>> if (err < 0)
>>> goto st_press_probe_trigger_error;
>>> }
>>>
>>> err = iio_device_register(indio_dev);
>>> -   if (err)
>>
>> This bit of handling is confusing. I would much rather see the if IRQ at the 
>> goto. Here the first thought is why is it not an error if there is no IRQ! 
> 
> I certainly see your point. But surely anyone would see after a second
> or two that we're returning err and not 0 in this case, so the error
> would still be returned, we're not ignoring it. Adding this extra
> comparison saves several lines of code.
> 
> If you think it's 'too' confusing, I'll revert the change.
> 
> Or perhaps a comment:
> 
> /* Only deallocate_[trigger|ring] if they were allocated. */
> or
> /* Only deallocate_[trigger|ring] if we have an IRQ line. */
> or
> /* If no IRQ was specified, just return the error. */
> 

Revert the change.  Whilst not complex to follow it is non obvious to save only
a couple of lines. Adding a comment would take almost as much space as just 
doing
it the 'easy way'.

>>> +   if (err && irq > 0)
>>> goto st_press_device_register_error;
>>>
>>> return err;
>>>
>>> st_press_device_register_error:
>>> -   if (pdata->get_irq_data_ready(indio_dev) > 0)
>>> -   st_sensors_deallocate_trigger(indio_dev);
>>> +   st_sensors_deallocate_trigger(indio_dev);
>>> st_press_probe_trigger_error:
>>> -   if (pdata->get_irq_data_ready(indio_dev) > 0)
>>> -   st_press_deallocate_ring(indio_dev);
>>> -st_press_common_probe_error:
>>> +   st_press_deallocate_ring(indio_dev);
>>> +
>>> return err;
>>> }
>>> EXPORT_SYMBOL(st_press_common_probe);
>>
> 
--
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 25/38] iio: pressure-core: st: Allow for number of channels to vary

2013-09-14 Thread Jonathan Cameron
On 09/10/13 13:49, Lee Jones wrote:
> At the moment the number of channels specified is dictated by the first
> sensor supported by the driver. As we add support for more sensors this
> is likely to vary. Instead of using the ARRAY_SIZE() of the LPS331AP's
> channel specifier we'll use a new adaptable 'struct st_sensors' element
> instead.
> 
> Signed-off-by: Lee Jones 
Applied with Denis ack (again it should have been here)
> ---
>  drivers/iio/pressure/st_pressure_core.c | 3 ++-
>  include/linux/iio/common/st_sensors.h   | 1 +
>  2 files changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/iio/pressure/st_pressure_core.c 
> b/drivers/iio/pressure/st_pressure_core.c
> index 60c2ee4..3abada2 100644
> --- a/drivers/iio/pressure/st_pressure_core.c
> +++ b/drivers/iio/pressure/st_pressure_core.c
> @@ -107,6 +107,7 @@ static const struct st_sensors st_press_sensors[] = {
>   [0] = LPS331AP_PRESS_DEV_NAME,
>   },
>   .ch = (struct iio_chan_spec *)st_press_lps331ap_channels,
> + .num_ch = ARRAY_SIZE(st_press_lps331ap_channels),
>   .odr = {
>   .addr = ST_PRESS_LPS331AP_ODR_ADDR,
>   .mask = ST_PRESS_LPS331AP_ODR_MASK,
> @@ -245,7 +246,7 @@ int st_press_common_probe(struct iio_dev *indio_dev,
>   pdata->num_data_channels = ST_PRESS_NUMBER_DATA_CHANNELS;
>   pdata->multiread_bit = pdata->sensor->multi_read_bit;
>   indio_dev->channels = pdata->sensor->ch;
> - indio_dev->num_channels = ARRAY_SIZE(st_press_lps331ap_channels);
> + indio_dev->num_channels = pdata->sensor->num_ch;
>  
>   if (pdata->sensor->fs.addr != 0)
>   pdata->current_fullscale = (struct st_sensor_fullscale_avl *)
> diff --git a/include/linux/iio/common/st_sensors.h 
> b/include/linux/iio/common/st_sensors.h
> index e51f654..e732fda 100644
> --- a/include/linux/iio/common/st_sensors.h
> +++ b/include/linux/iio/common/st_sensors.h
> @@ -184,6 +184,7 @@ struct st_sensors {
>   u8 wai;
>   char sensors_supported[ST_SENSORS_MAX_4WAI][ST_SENSORS_MAX_NAME];
>   struct iio_chan_spec *ch;
> + int num_ch;
>   struct st_sensor_odr odr;
>   struct st_sensor_power pw;
>   struct st_sensor_axis enable_axis;
> 
--
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] perf session: Add option to copy events when queueing

2013-09-14 Thread Frederic Weisbecker
On Fri, Sep 06, 2013 at 01:37:01PM -0600, David Ahern wrote:
> When processing events the session code has an ordered samples queue which is
> used to time-sort events coming in across multiple mmaps. At a later point in
> time samples on the queue are flushed up to some timestamp at which point the
> event is actually processed.
> 
> When analyzing events live (ie., record/analysis path in the same command)
> there is a race that leads to corrupted events and parse errors which cause
> perf to terminate. The problem is that when the event is placed in the ordered
> samples queue it is only a reference to the event which is really sitting in
> the mmap buffer. Even though the event is queued for later processing the mmap
> tail pointer is updated which indicates to the kernel that the event has been
> processed. The race is flushing the event from the queue before it gets
> overwritten by some other event. For commands trying to process events live
> (versus just writing to a file) and processing a high rate of events this 
> leads
> to parse failures and perf terminates.
> 
> Examples hitting this problem are 'perf kvm stat live', especially with nested
> VMs which generate 100,000+ traces per second, and a command processing
> scheduling events with a high rate of context switching -- e.g., running
> 'perf bench sched pipe'.
> 
> This patch offers live commands an option to copy the event when it is placed 
> in
> the ordered samples queue.
> 
> Signed-off-by: David Ahern 
> Cc: Frederic Weisbecker 
> Cc: Ingo Molnar 
> Cc: Jiri Olsa 
> Cc: Mike Galbraith 
> Cc: Namhyung Kim 
> Cc: Peter Zijlstra 
> Cc: Stephane Eranian 
> ---
>  tools/perf/util/session.c |   17 ++---
>  tools/perf/util/session.h |1 +
>  2 files changed, 15 insertions(+), 3 deletions(-)
> 
> diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
> index 1b185ca..71f16db 100644
> --- a/tools/perf/util/session.c
> +++ b/tools/perf/util/session.c
> @@ -483,6 +483,8 @@ static void perf_session_free_sample_buffers(struct 
> perf_session *session)
>  
>   sq = list_entry(os->to_free.next, struct sample_queue, list);
>   list_del(&sq->list);
> + if (session->copy_on_queue)
> + free(sq->event);
>   free(sq);
>   }
>  }
> @@ -513,11 +515,15 @@ static int flush_sample_queue(struct perf_session *s,
>   break;
>  
>   ret = perf_evlist__parse_sample(s->evlist, iter->event, 
> &sample);
> - if (ret)
> + if (ret) {
>   pr_err("Can't parse sample, err = %d\n", ret);
> - else {
> + if (s->copy_on_queue)
> + free(iter->event);
> + } else {
>   ret = perf_session_deliver_event(s, iter->event, 
> &sample, tool,
>iter->file_offset);
> + if (s->copy_on_queue)
> + free(iter->event);
>   if (ret)
>   return ret;
>   }
> @@ -676,7 +682,12 @@ int perf_session_queue_event(struct perf_session *s, 
> union perf_event *event,
>  
>   new->timestamp = timestamp;
>   new->file_offset = file_offset;
> - new->event = event;
> +
> + if (s->copy_on_queue) {
> + new->event = malloc(event->header.size);
> + memcpy(new->event, event, event->header.size);
> + } else
> + new->event = event;
>  
>   __queue_event(new, s);
>  
> diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
> index 3aa75fb..4adfcbb 100644
> --- a/tools/perf/util/session.h
> +++ b/tools/perf/util/session.h
> @@ -38,6 +38,7 @@ struct perf_session {
>   boolfd_pipe;
>   boolrepipe;
>   struct ordered_samples  ordered_samples;
> + boolcopy_on_queue;

So do you think it should stay optional? This looks like a global problem, I 
mean
the event can be unmapped anytime for any builtin tool mapping it, right?

Also we already allocate the sample list node (struct sample_queue) from 
os->sample
buffer. ie: we have our own allocator there.

Probably we should reuse that and include the copied event space in "struct 
sample_queue"?

Also looking at it now, it seems we have a bug on the existing code:


if (!list_empty(sc)) {
new = list_entry(sc->next, struct sample_queue, list);
list_del(&new->list);
} else if (os->sample_buffer) {
new = os->sample_buffer + os->sample_buffer_idx;
if (++os->sample_buffer_idx == MAX_SAMPLE_BUFFER)
os->sample_buffer = NULL;
} else {
   os->sample_buffer = malloc(MAX_SAMPLE_BUFFER * sizeof(*new));
   if (!os->sample_buffer)
return -ENOMEM;
   list_

Re: [PATCH 24/38] iio: pressure-core: st: Expand and rename LPS331AP's channel descriptor

2013-09-14 Thread Jonathan Cameron
On 09/10/13 13:49, Lee Jones wrote:
> Due to the MACRO used, the task of reading, understanding and maintaining
> the LPS331AP's channel descriptor is substantially difficult. This patch
> is based on the view that it's better to have easy to read, maintainable
> code than to save a few lines here and there. For that reason we're
> expanding the array so initialisation is completed in full.
> 
> Signed-off-by: Lee Jones 
Agreed that in this case it is clearer not to use a macro.  When you have lots
of repeats (e.g. an adc with 16 channels) they can make sense, but here as
you say a few extra lines of code make it much easier to follow.
My only slight addition here would be to drop the IIO_NO_MOD and modified=0 bits
on the basis those are both the obvious defaults (and happen to be equal to 0).
Perhaps worth leaving them in this case as it makes the patch more obviously 
correct.

Applied to the togreg branch of iio.git

Thanks,

Jonathan
> ---
>  drivers/iio/pressure/st_pressure_core.c | 45 
> +
>  1 file changed, 34 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/iio/pressure/st_pressure_core.c 
> b/drivers/iio/pressure/st_pressure_core.c
> index 2ee4bcd..60c2ee4 100644
> --- a/drivers/iio/pressure/st_pressure_core.c
> +++ b/drivers/iio/pressure/st_pressure_core.c
> @@ -64,16 +64,39 @@
>  #define ST_PRESS_LPS331AP_OUT_XL_ADDR0x28
>  #define ST_TEMP_LPS331AP_OUT_L_ADDR  0x2b
>  
> -static const struct iio_chan_spec st_press_channels[] = {
> - ST_SENSORS_LSM_CHANNELS(IIO_PRESSURE,
> +static const struct iio_chan_spec st_press_lps331ap_channels[] = {
> + {
> + .type = IIO_PRESSURE,
> + .channel2 = IIO_NO_MOD,
> + .address = ST_PRESS_LPS331AP_OUT_XL_ADDR,
> + .scan_index = ST_SENSORS_SCAN_X,
> + .scan_type = {
> + .sign = 'u',
> + .realbits = 24,
> + .storagebits = 24,
> + .endianness = IIO_LE,
> + },
> + .info_mask_separate =
>   BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
> - ST_SENSORS_SCAN_X, 0, IIO_NO_MOD, 'u', IIO_LE, 24, 24,
> - ST_PRESS_LPS331AP_OUT_XL_ADDR),
> - ST_SENSORS_LSM_CHANNELS(IIO_TEMP,
> - BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) |
> - BIT(IIO_CHAN_INFO_OFFSET),
> - -1, 0, IIO_NO_MOD, 's', IIO_LE, 16, 16,
> - ST_TEMP_LPS331AP_OUT_L_ADDR),
> + .modified = 0,
> + },
> + {
> + .type = IIO_TEMP,
> + .channel2 = IIO_NO_MOD,
> + .address = ST_TEMP_LPS331AP_OUT_L_ADDR,
> + .scan_index = -1,
> + .scan_type = {
> + .sign = 'u',
> + .realbits = 16,
> + .storagebits = 16,
> + .endianness = IIO_LE,
> + },
> + .info_mask_separate =
> + BIT(IIO_CHAN_INFO_RAW) |
> + BIT(IIO_CHAN_INFO_SCALE) |
> + BIT(IIO_CHAN_INFO_OFFSET),
> + .modified = 0,
> + },
>   IIO_CHAN_SOFT_TIMESTAMP(1)
>  };
>  
> @@ -83,7 +106,7 @@ static const struct st_sensors st_press_sensors[] = {
>   .sensors_supported = {
>   [0] = LPS331AP_PRESS_DEV_NAME,
>   },
> - .ch = (struct iio_chan_spec *)st_press_channels,
> + .ch = (struct iio_chan_spec *)st_press_lps331ap_channels,
>   .odr = {
>   .addr = ST_PRESS_LPS331AP_ODR_ADDR,
>   .mask = ST_PRESS_LPS331AP_ODR_MASK,
> @@ -222,7 +245,7 @@ int st_press_common_probe(struct iio_dev *indio_dev,
>   pdata->num_data_channels = ST_PRESS_NUMBER_DATA_CHANNELS;
>   pdata->multiread_bit = pdata->sensor->multi_read_bit;
>   indio_dev->channels = pdata->sensor->ch;
> - indio_dev->num_channels = ARRAY_SIZE(st_press_channels);
> + indio_dev->num_channels = ARRAY_SIZE(st_press_lps331ap_channels);
>  
>   if (pdata->sensor->fs.addr != 0)
>   pdata->current_fullscale = (struct st_sensor_fullscale_avl *)
> 
--
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] kthread: Make kthread_create() killable.

2013-09-14 Thread Oleg Nesterov
Add lkml.

On 09/13, Tetsuo Handa wrote:
>
> This patch makes kthread_create() killable,

Probably makes sense...

> @@ -255,36 +266,59 @@ struct task_struct *kthread_create_on_node(int 
> (*threadfn)(void *data),
>  const char namefmt[],
>  ...)
>  {
> - struct kthread_create_info create;
> -
> - create.threadfn = threadfn;
> - create.data = data;
> - create.node = node;
> - init_completion(&create.done);
> + struct task_struct *task;
> + struct kthread_create_info *create = kmalloc(sizeof(*create),
> +  GFP_KERNEL);
> +
> + if (!create)
> + return ERR_PTR(-ENOMEM);
> + create->threadfn = threadfn;
> + create->data = data;
> + create->node = node;
> + create->owner = (void *) 1;
> + init_completion(&create->done);
>  
>   spin_lock(&kthread_create_lock);
> - list_add_tail(&create.list, &kthread_create_list);
> + list_add_tail(&create->list, &kthread_create_list);
>   spin_unlock(&kthread_create_lock);
>  
>   wake_up_process(kthreadd_task);
> - wait_for_completion(&create.done);
> -
> - if (!IS_ERR(create.result)) {
> + /*
> +  * Wait for completion in killable state, for I might be chosen by
> +  * the OOM killer while kthreadd is trying to allocate memory for
> +  * new kernel thread.
> +  */
> + if (unlikely(wait_for_completion_killable(&create->done))) {
> + /*
> +  * If I was SIGKILLed before kthreadd (or new kernel thread)
> +  * calls complete(), leave the cleanup of this structure to
> +  * that thread.
> +  */
> + if (xchg(&create->owner, NULL))
> + return ERR_PTR(-ENOMEM);

I am wondering if this can be simplified...

At least you can move create->done from kthread_create_info to the
stack, and turn create->owner into the pointer to that completion.

Oleg.

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