All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Ardelean, Alexandru" <alexandru.Ardelean@analog.com>
To: "jic23@kernel.org" <jic23@kernel.org>
Cc: "linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"linux-iio@vger.kernel.org" <linux-iio@vger.kernel.org>
Subject: Re: [PATCH 02/10] iio: imu: adis: add unlocked read/write function versions
Date: Tue, 8 Oct 2019 08:47:48 +0000	[thread overview]
Message-ID: <e61409aba34810d66906cece5dff0bb78c5e9385.camel@analog.com> (raw)
In-Reply-To: <944b74b85c2ff7853651b5df1b4557154fafa99b.camel@analog.com>

On Tue, 2019-10-08 at 06:54 +0000, Ardelean, Alexandru wrote:
> [External]
> 
> On Mon, 2019-10-07 at 22:16 +0100, Jonathan Cameron wrote:
> > On Sun, 6 Oct 2019 10:12:01 +0100
> > Jonathan Cameron <jic23@kernel.org> wrote:
> > 
> > > On Thu, 26 Sep 2019 14:18:04 +0300
> > > Alexandru Ardelean <alexandru.ardelean@analog.com> wrote:
> > > 
> > > > This will allow more flexible control to group reads & writes into
> > > > a
> > > > single
> > > > lock (particularly the state_lock).
> > > > 
> > > > The end-goal is to remove the indio_dev->mlock usage, and the
> > > > simplest fix
> > > > would have been to just add another lock, which would not be a good
> > > > idea on
> > > > the long-run.
> > > > 
> > > > Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>  
> > > Applied to the togreg branch of iio.git and pushed out as testing
> > > etc.
> > > 
> > > Jonathan
> > > 
> > 0-day found a potential issue (kind of) in the read functions.
> > 
> > > > ---
> > > >  drivers/iio/imu/adis.c       |  34 +++++------
> > > >  include/linux/iio/imu/adis.h | 114
> > > > ++++++++++++++++++++++++++++++++++-
> > > >  2 files changed, 128 insertions(+), 20 deletions(-)
> > > > 
> > > > diff --git a/drivers/iio/imu/adis.c b/drivers/iio/imu/adis.c
> > > > index 3c2d896e3a96..4f3be011c898 100644
> > > > --- a/drivers/iio/imu/adis.c
> > > > +++ b/drivers/iio/imu/adis.c
> > > > @@ -26,7 +26,14 @@
> > > >  #define ADIS_MSC_CTRL_DATA_RDY_DIO2	BIT(0)
> > > >  #define ADIS_GLOB_CMD_SW_RESET		BIT(7)
> > > >  
> > > > -int adis_write_reg(struct adis *adis, unsigned int reg,
> > > > +/**
> > > > + * __adis_write_reg() - write N bytes to register (unlocked
> > > > version)
> > > > + * @adis: The adis device
> > > > + * @reg: The address of the lower of the two registers
> > > > + * @value: The value to write to device (up to 4 bytes)
> > > > + * @size: The size of the @value (in bytes)
> > > > + */
> > > > +int __adis_write_reg(struct adis *adis, unsigned int reg,
> > > >  	unsigned int value, unsigned int size)
> > > >  {
> > > >  	unsigned int page = reg / ADIS_PAGE_SIZE;
> > > > @@ -70,8 +77,6 @@ int adis_write_reg(struct adis *adis, unsigned
> > > > int
> > > > reg,
> > > >  		},
> > > >  	};
> > > >  
> > > > -	mutex_lock(&adis->state_lock);
> > > > -
> > > >  	spi_message_init(&msg);
> > > >  
> > > >  	if (adis->current_page != page) {
> > > > @@ -96,8 +101,7 @@ int adis_write_reg(struct adis *adis, unsigned
> > > > int
> > > > reg,
> > > >  		adis->tx[3] = value & 0xff;
> > > >  		break;
> > > >  	default:
> > > > -		ret = -EINVAL;
> > > > -		goto out_unlock;
> > > > +		return -EINVAL;
> > > >  	}
> > > >  
> > > >  	xfers[size].cs_change = 0;
> > > > @@ -113,20 +117,18 @@ int adis_write_reg(struct adis *adis,
> > > > unsigned
> > > > int reg,
> > > >  		adis->current_page = page;
> > > >  	}
> > > >  
> > > > -out_unlock:
> > > > -	mutex_unlock(&adis->state_lock);
> > > > -
> > > >  	return ret;
> > > >  }
> > > > -EXPORT_SYMBOL_GPL(adis_write_reg);
> > > > +EXPORT_SYMBOL_GPL(__adis_write_reg);
> > > >  
> > > >  /**
> > > > - * adis_read_reg() - read 2 bytes from a 16-bit register
> > > > + * __adis_read_reg() - read N bytes from register (unlocked
> > > > version)
> > > >   * @adis: The adis device
> > > >   * @reg: The address of the lower of the two registers
> > > >   * @val: The value read back from the device
> > > > + * @size: The size of the @val buffer
> > > >   */
> > > > -int adis_read_reg(struct adis *adis, unsigned int reg,
> > > > +int __adis_read_reg(struct adis *adis, unsigned int reg,
> > > >  	unsigned int *val, unsigned int size)
> > > >  {
> > > >  	unsigned int page = reg / ADIS_PAGE_SIZE;
> > > > @@ -188,15 +190,14 @@ int adis_read_reg(struct adis *adis, unsigned
> > > > int reg,
> > > >  		spi_message_add_tail(&xfers[3], &msg);
> > > >  		break;
> > > >  	default:
> > > > -		ret = -EINVAL;
> > > > -		goto out_unlock;
> > > > +		return -EINVAL;
> > > >  	}
> > > >  
> > > >  	ret = spi_sync(adis->spi, &msg);
> > > >  	if (ret) {
> > > >  		dev_err(&adis->spi->dev, "Failed to read register
> > > > 0x%02X:
> > > > %d\n",
> > > >  				reg, ret);
> > > > -		goto out_unlock;
> > > > +		return ret;
> > > >  	} else {
> > > >  		adis->current_page = page;
> > > >  	}
> > > > @@ -210,12 +211,9 @@ int adis_read_reg(struct adis *adis, unsigned
> > > > int reg,
> > > >  		break;
> > > >  	}
> > > >  
> > > > -out_unlock:
> > > > -	mutex_unlock(&adis->state_lock);
> > > > -
> > > >  	return ret;
> > > >  }
> > > > -EXPORT_SYMBOL_GPL(adis_read_reg);
> > > > +EXPORT_SYMBOL_GPL(__adis_read_reg);
> > > >  
> > > >  #ifdef CONFIG_DEBUG_FS
> > > >  
> > > > diff --git a/include/linux/iio/imu/adis.h
> > > > b/include/linux/iio/imu/adis.h
> > > > index 3ed5eceaac2d..3a028c40e04e 100644
> > > > --- a/include/linux/iio/imu/adis.h
> > > > +++ b/include/linux/iio/imu/adis.h
> > > > @@ -75,11 +75,121 @@ int adis_init(struct adis *adis, struct
> > > > iio_dev
> > > > *indio_dev,
> > > >  	struct spi_device *spi, const struct adis_data *data);
> > > >  int adis_reset(struct adis *adis);
> > > >  
> > > > -int adis_write_reg(struct adis *adis, unsigned int reg,
> > > > +int __adis_write_reg(struct adis *adis, unsigned int reg,
> > > >  	unsigned int val, unsigned int size);
> > > > -int adis_read_reg(struct adis *adis, unsigned int reg,
> > > > +int __adis_read_reg(struct adis *adis, unsigned int reg,
> > > >  	unsigned int *val, unsigned int size);
> > > >  
> > > > +/**
> > > > + * __adis_write_reg_8() - Write single byte to a register
> > > > (unlocked
> > > > version)
> > > > + * @adis: The adis device
> > > > + * @reg: The address of the register to be written
> > > > + * @value: The value to write
> > > > + */
> > > > +static inline int __adis_write_reg_8(struct adis *adis, unsigned
> > > > int
> > > > reg,
> > > > +	uint8_t val)
> > > > +{
> > > > +	return __adis_write_reg(adis, reg, val, 1);
> > > > +}
> > > > +
> > > > +/**
> > > > + * __adis_write_reg_16() - Write 2 bytes to a pair of registers
> > > > (unlocked version)
> > > > + * @adis: The adis device
> > > > + * @reg: The address of the lower of the two registers
> > > > + * @value: Value to be written
> > > > + */
> > > > +static inline int __adis_write_reg_16(struct adis *adis, unsigned
> > > > int reg,
> > > > +	uint16_t val)
> > > > +{
> > > > +	return __adis_write_reg(adis, reg, val, 2);
> > > > +}
> > > > +
> > > > +/**
> > > > + * __adis_write_reg_32() - write 4 bytes to four registers
> > > > (unlocked
> > > > version)
> > > > + * @adis: The adis device
> > > > + * @reg: The address of the lower of the four register
> > > > + * @value: Value to be written
> > > > + */
> > > > +static inline int __adis_write_reg_32(struct adis *adis, unsigned
> > > > int reg,
> > > > +	uint32_t val)
> > > > +{
> > > > +	return __adis_write_reg(adis, reg, val, 4);
> > > > +}
> > > > +
> > > > +/**
> > > > + * __adis_read_reg_16() - read 2 bytes from a 16-bit register
> > > > (unlocked version)
> > > > + * @adis: The adis device
> > > > + * @reg: The address of the lower of the two registers
> > > > + * @val: The value read back from the device
> > > > + */
> > > > +static inline int __adis_read_reg_16(struct adis *adis, unsigned
> > > > int
> > > > reg,
> > > > +	uint16_t *val)
> > > > +{
> > > > +	unsigned int tmp;
> > > > +	int ret;
> > > > +
> > > > +	ret = __adis_read_reg(adis, reg, &tmp, 2);
> > Zero day isn't happy that this can use tmp without it actually being
> > set
> > in the
> > __adis_read_reg.
> > 
> > I've added
> > 	if (ret)
> > 		return ret;
> > > > +	*val = tmp;
> > > > +
> > > > +	return ret;
> > and changed this to return 0;
> > 
> > Same in the 32bit case below.
> > 
> > Hmm. There are quite a few sparse warnings in the adis16400 if anyone
> > fancies
> > cleaning them up ;)
> 
> Well, I've been planning to setup sparse as part of our CI.
> I guess this is another nudge in that direction.

I did find some warnings.
But they seem to be reported by GCC 8.
Not sure if GCC 7 reported them.
I re-installed my laptop [changed to another one], so maybe my default is
now 8; or maybe I did not notice this initially when I built it and picked
it up from our master branch.

Sparse reports nothing for the IMU drivers.
Should I try something newer?

sparse --version
0.6.0 (Ubuntu: 0.6.0-3)

-----------------------------------------------------------------
ARCH=arm CROSS_COMPILE=~/work/linux/gcc-linaro-5.5.0-2017.10-x86_64_arm-
linux-gnueabi/bin/arm-linux-gnueabi- make C=2 drivers/iio/imu/
  CHECK   scripts/mod/empty.c
  CALL    scripts/checksyscalls.sh
  CALL    scripts/atomic/check-atomics.sh
  CHECK   drivers/iio/imu/adis16400.c
  CHECK   drivers/iio/imu/adis16460.c
  CHECK   drivers/iio/imu/adis16480.c
  CHECK   drivers/iio/imu/adis.c
  CHECK   drivers/iio/imu/adis_trigger.c
  CHECK   drivers/iio/imu/adis_buffer.c
-----------------------------------------------------------------

> 
> Thanks
> Alex
> 
> > Thanks,
> > 
> > Jonathan
> > 
> > > > +}
> > > > +
> > > > +/**
> > > > + * __adis_read_reg_32() - read 4 bytes from a 32-bit register
> > > > (unlocked version)
> > > > + * @adis: The adis device
> > > > + * @reg: The address of the lower of the two registers
> > > > + * @val: The value read back from the device
> > > > + */
> > > > +static inline int __adis_read_reg_32(struct adis *adis, unsigned
> > > > int
> > > > reg,
> > > > +	uint32_t *val)
> > > > +{
> > > > +	unsigned int tmp;
> > > > +	int ret;
> > > > +
> > > > +	ret = __adis_read_reg(adis, reg, &tmp, 4);
> > > > +	*val = tmp;
> > > > +
> > > > +	return ret;
> > > > +}
> > > > +
> > > > +/**
> > > > + * adis_write_reg() - write N bytes to register
> > > > + * @adis: The adis device
> > > > + * @reg: The address of the lower of the two registers
> > > > + * @value: The value to write to device (up to 4 bytes)
> > > > + * @size: The size of the @value (in bytes)
> > > > + */
> > > > +static inline int adis_write_reg(struct adis *adis, unsigned int
> > > > reg,
> > > > +	unsigned int val, unsigned int size)
> > > > +{
> > > > +	int ret;
> > > > +
> > > > +	mutex_lock(&adis->state_lock);
> > > > +	ret = __adis_write_reg(adis, reg, val, size);
> > > > +	mutex_unlock(&adis->state_lock);
> > > > +
> > > > +	return ret;
> > > > +}
> > > > +
> > > > +/**
> > > > + * adis_read_reg() - read N bytes from register
> > > > + * @adis: The adis device
> > > > + * @reg: The address of the lower of the two registers
> > > > + * @val: The value read back from the device
> > > > + * @size: The size of the @val buffer
> > > > + */
> > > > +static int adis_read_reg(struct adis *adis, unsigned int reg,
> > > > +	unsigned int *val, unsigned int size)
> > > > +{
> > > > +	int ret;
> > > > +
> > > > +	mutex_lock(&adis->state_lock);
> > > > +	ret = __adis_read_reg(adis, reg, val, size);
> > > > +	mutex_unlock(&adis->state_lock);
> > > > +
> > > > +	return ret;
> > > > +}
> > > > +
> > > >  /**
> > > >   * adis_write_reg_8() - Write single byte to a register
> > > >   * @adis: The adis device  

  reply	other threads:[~2019-10-08  8:47 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-26 11:18 [PATCH 00/10] iio: imu: adis: cleanup lock usage Alexandru Ardelean
2019-09-26 11:18 ` [PATCH 01/10] iio: imu: adis: rename txrx_lock -> state_lock Alexandru Ardelean
2019-10-06  8:53   ` Jonathan Cameron
2019-10-06  9:06     ` Jonathan Cameron
2019-10-07 10:18       ` Ardelean, Alexandru
2019-09-26 11:18 ` [PATCH 02/10] iio: imu: adis: add unlocked read/write function versions Alexandru Ardelean
2019-10-06  9:12   ` Jonathan Cameron
2019-10-07 21:16     ` Jonathan Cameron
2019-10-08  6:54       ` Ardelean, Alexandru
2019-10-08  8:47         ` Ardelean, Alexandru [this message]
2019-10-08  8:58           ` Ardelean, Alexandru
2019-10-12 13:40             ` Jonathan Cameron
2019-09-26 11:18 ` [PATCH 03/10] iio: imu: adis[16480]: group RW into a single lock in adis_enable_irq() Alexandru Ardelean
2019-10-06  9:13   ` Jonathan Cameron
2019-09-26 11:18 ` [PATCH 04/10] iio: imu: adis: create an unlocked version of adis_check_status() Alexandru Ardelean
2019-10-06  9:13   ` Jonathan Cameron
2019-09-26 11:18 ` [PATCH 05/10] iio: imu: adis: create an unlocked version of adis_reset() Alexandru Ardelean
2019-10-06  9:19   ` Jonathan Cameron
2019-09-26 11:18 ` [PATCH 06/10] iio: imu: adis: protect initial startup routine with state lock Alexandru Ardelean
2019-10-06  9:20   ` Jonathan Cameron
2019-09-26 11:18 ` [PATCH 07/10] iio: imu: adis: group single conversion under a single " Alexandru Ardelean
2019-10-06  9:20   ` Jonathan Cameron
2019-09-26 11:18 ` [PATCH 08/10] iio: imu: adis16400: rework locks using ADIS library's " Alexandru Ardelean
2019-10-06  9:20   ` Jonathan Cameron
2019-09-26 11:18 ` [PATCH 09/10] iio: gyro: adis16136: " Alexandru Ardelean
2019-10-06  9:22   ` Jonathan Cameron
2019-09-26 11:18 ` [PATCH 10/10] iio: imu: adis16480: use state lock for filter freq set Alexandru Ardelean
2019-10-06  9:24   ` Jonathan Cameron

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=e61409aba34810d66906cece5dff0bb78c5e9385.camel@analog.com \
    --to=alexandru.ardelean@analog.com \
    --cc=jic23@kernel.org \
    --cc=linux-iio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.