Message ID | 20181210210310.12677-2-wsa+renesas@sang-engineering.com (mailing list archive) |
---|---|
State | RFC |
Headers | show |
Series | i2c: move handling of suspended adapters to the core | expand |
On 2018-12-10 22:02, Wolfram Sang wrote: > Some drivers open code handling of suspended adapters. It should be > handled by the core, though, to ensure generic handling. This patch adds > the flag and an accessor function. > > Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com> > --- > drivers/i2c/i2c-core-base.c | 1 + > include/linux/i2c.h | 9 +++++++++ > 2 files changed, 10 insertions(+) > > diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c > index 28460f6a60cc..9f89e258c8ff 100644 > --- a/drivers/i2c/i2c-core-base.c > +++ b/drivers/i2c/i2c-core-base.c > @@ -1232,6 +1232,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap) > if (!adap->lock_ops) > adap->lock_ops = &i2c_adapter_lock_ops; > > + adap->is_suspended = false; > rt_mutex_init(&adap->bus_lock); > rt_mutex_init(&adap->mux_lock); > mutex_init(&adap->userspace_clients_lock); > diff --git a/include/linux/i2c.h b/include/linux/i2c.h > index 65b4eaed1d96..9852038ee3a7 100644 > --- a/include/linux/i2c.h > +++ b/include/linux/i2c.h > @@ -680,6 +680,7 @@ struct i2c_adapter { > int timeout; /* in jiffies */ > int retries; > struct device dev; /* the adapter device */ > + unsigned int is_suspended:1; /* owned by the I2C core */ When more stuff is added to this bit field (which always happens at some point) updates to all members of the bit field will have to use the same root-adapter-locking, or we will suffer from RMW-races. So this feels like an invitation for future disaster. Maybe a comment about that to remind our future selves? Or perhaps the bit field should be avoided altogether? Cheers, Peter > > int nr; > char name[48]; > @@ -762,6 +763,14 @@ i2c_unlock_bus(struct i2c_adapter *adapter, unsigned int flags) > adapter->lock_ops->unlock_bus(adapter, flags); > } > > +static inline void i2c_mark_adapter_suspended(struct i2c_adapter *adap, > + bool suspended) > +{ > + i2c_lock_bus(adap, I2C_LOCK_ROOT_ADAPTER); > + adap->is_suspended = suspended; > + i2c_unlock_bus(adap, I2C_LOCK_ROOT_ADAPTER); > +} > + > /*flags for the client struct: */ > #define I2C_CLIENT_PEC 0x04 /* Use Packet Error Checking */ > #define I2C_CLIENT_TEN 0x10 /* we have a ten bit chip address */ >
> > + unsigned int is_suspended:1; /* owned by the I2C core */ > > When more stuff is added to this bit field (which always happens at > some point) updates to all members of the bit field will have to use > the same root-adapter-locking, or we will suffer from RMW-races. So > this feels like an invitation for future disaster. Maybe a comment > about that to remind our future selves? Or perhaps the bit field > should be avoided altogether? Changed to bool. Thanks!
Hi Wolfram, On Wed, Dec 19, 2018 at 12:34 AM Wolfram Sang <wsa@the-dreams.de> wrote: > > > + unsigned int is_suspended:1; /* owned by the I2C core */ > > > > When more stuff is added to this bit field (which always happens at > > some point) updates to all members of the bit field will have to use > > the same root-adapter-locking, or we will suffer from RMW-races. So > > this feels like an invitation for future disaster. Maybe a comment > > about that to remind our future selves? Or perhaps the bit field > > should be avoided altogether? > > Changed to bool. Thanks! Does that help, given bool is smaller than the CPUs word size? Is it Alpha that cannot do atomic operations on bytes? Gr{oetje,eeting}s, Geert
On Wed, Dec 19, 2018 at 10:39:05AM +0100, Geert Uytterhoeven wrote: > Hi Wolfram, > > On Wed, Dec 19, 2018 at 12:34 AM Wolfram Sang <wsa@the-dreams.de> wrote: > > > > + unsigned int is_suspended:1; /* owned by the I2C core */ > > > > > > When more stuff is added to this bit field (which always happens at > > > some point) updates to all members of the bit field will have to use > > > the same root-adapter-locking, or we will suffer from RMW-races. So > > > this feels like an invitation for future disaster. Maybe a comment > > > about that to remind our future selves? Or perhaps the bit field > > > should be avoided altogether? > > > > Changed to bool. Thanks! > > Does that help, given bool is smaller than the CPUs word size? > Is it Alpha that cannot do atomic operations on bytes? Yup, I overestimated bools :( I guess good old unsigned long locked_flags; #define <PREFIX>_IS_SUSPENDED 0 set_bit(), clear_bit(), and test_bit() is it then.
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index 28460f6a60cc..9f89e258c8ff 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -1232,6 +1232,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap) if (!adap->lock_ops) adap->lock_ops = &i2c_adapter_lock_ops; + adap->is_suspended = false; rt_mutex_init(&adap->bus_lock); rt_mutex_init(&adap->mux_lock); mutex_init(&adap->userspace_clients_lock); diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 65b4eaed1d96..9852038ee3a7 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -680,6 +680,7 @@ struct i2c_adapter { int timeout; /* in jiffies */ int retries; struct device dev; /* the adapter device */ + unsigned int is_suspended:1; /* owned by the I2C core */ int nr; char name[48]; @@ -762,6 +763,14 @@ i2c_unlock_bus(struct i2c_adapter *adapter, unsigned int flags) adapter->lock_ops->unlock_bus(adapter, flags); } +static inline void i2c_mark_adapter_suspended(struct i2c_adapter *adap, + bool suspended) +{ + i2c_lock_bus(adap, I2C_LOCK_ROOT_ADAPTER); + adap->is_suspended = suspended; + i2c_unlock_bus(adap, I2C_LOCK_ROOT_ADAPTER); +} + /*flags for the client struct: */ #define I2C_CLIENT_PEC 0x04 /* Use Packet Error Checking */ #define I2C_CLIENT_TEN 0x10 /* we have a ten bit chip address */
Some drivers open code handling of suspended adapters. It should be handled by the core, though, to ensure generic handling. This patch adds the flag and an accessor function. Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com> --- drivers/i2c/i2c-core-base.c | 1 + include/linux/i2c.h | 9 +++++++++ 2 files changed, 10 insertions(+)