All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [RFC PATCH 1/2] i2c: smbus: Allow throttling of transfers to client devices
@ 2020-09-15  6:12 kernel test robot
  0 siblings, 0 replies; 2+ messages in thread
From: kernel test robot @ 2020-09-15  6:12 UTC (permalink / raw)
  To: kbuild

[-- Attachment #1: Type: text/plain, Size: 7039 bytes --]

CC: kbuild-all(a)lists.01.org
In-Reply-To: <20200914122811.3295678-2-andrew@aj.id.au>
References: <20200914122811.3295678-2-andrew@aj.id.au>
TO: Andrew Jeffery <andrew@aj.id.au>

Hi Andrew,

[FYI, it's a private test report for your RFC patch.]
[auto build test WARNING on wsa/i2c/for-next]
[also build test WARNING on hwmon/hwmon-next v5.9-rc5 next-20200914]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Andrew-Jeffery/Throttle-I2C-transfers-to-UCD9000-devices/20200915-012501
base:   https://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git i2c/for-next
:::::: branch date: 13 hours ago
:::::: commit date: 13 hours ago
config: mips-randconfig-s031-20200913 (attached as .config)
compiler: mips-linux-gcc (GCC) 9.3.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # apt-get install sparse
        # sparse version: v0.6.2-191-g10164920-dirty
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=mips 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>


sparse warnings: (new ones prefixed by >>)

>> drivers/i2c/i2c-core-smbus.c:552:12: sparse: sparse: context imbalance in 'i2c_smbus_throttle_enter' - wrong count at exit
>> drivers/i2c/i2c-core-smbus.c:592:9: sparse: sparse: context imbalance in 'i2c_smbus_throttle_exit' - wrong count at exit
>> drivers/i2c/i2c-core-smbus.c:595:12: sparse: sparse: context imbalance in 'i2c_smbus_throttle_xfer' - wrong count at exit

# https://github.com/0day-ci/linux/commit/28892a041b063ffb23690eb11e5764ac0e675823
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Andrew-Jeffery/Throttle-I2C-transfers-to-UCD9000-devices/20200915-012501
git checkout 28892a041b063ffb23690eb11e5764ac0e675823
vim +/i2c_smbus_throttle_enter +552 drivers/i2c/i2c-core-smbus.c

eef5ba1aa148ca Peter Rosin    2018-06-20  551  
28892a041b063f Andrew Jeffery 2020-09-14 @552  static int i2c_smbus_throttle_enter(const struct i2c_client *client)
28892a041b063f Andrew Jeffery 2020-09-14  553  		__acquires(&priv->throttle_lock)
28892a041b063f Andrew Jeffery 2020-09-14  554  {
28892a041b063f Andrew Jeffery 2020-09-14  555  	struct i2c_client_priv *priv;
28892a041b063f Andrew Jeffery 2020-09-14  556  	ktime_t earliest;
28892a041b063f Andrew Jeffery 2020-09-14  557  	int rc;
28892a041b063f Andrew Jeffery 2020-09-14  558  
28892a041b063f Andrew Jeffery 2020-09-14  559  	priv = to_i2c_client_priv(client);
28892a041b063f Andrew Jeffery 2020-09-14  560  
28892a041b063f Andrew Jeffery 2020-09-14  561  	if (i2c_in_atomic_xfer_mode()) {
28892a041b063f Andrew Jeffery 2020-09-14  562  		if (!mutex_trylock(&priv->throttle_lock))
28892a041b063f Andrew Jeffery 2020-09-14  563  			return -EAGAIN;
28892a041b063f Andrew Jeffery 2020-09-14  564  	} else {
28892a041b063f Andrew Jeffery 2020-09-14  565  		rc = mutex_lock_interruptible(&priv->throttle_lock);
28892a041b063f Andrew Jeffery 2020-09-14  566  		if (rc)
28892a041b063f Andrew Jeffery 2020-09-14  567  			return rc;
28892a041b063f Andrew Jeffery 2020-09-14  568  	}
28892a041b063f Andrew Jeffery 2020-09-14  569  	earliest = ktime_add_us(priv->last, priv->delay_us);
28892a041b063f Andrew Jeffery 2020-09-14  570  
28892a041b063f Andrew Jeffery 2020-09-14  571  	if (priv->delay_us && ktime_before(ktime_get(), earliest)) {
28892a041b063f Andrew Jeffery 2020-09-14  572  		if (i2c_in_atomic_xfer_mode()) {
28892a041b063f Andrew Jeffery 2020-09-14  573  			mutex_unlock(&priv->throttle_lock);
28892a041b063f Andrew Jeffery 2020-09-14  574  			return -EAGAIN;
28892a041b063f Andrew Jeffery 2020-09-14  575  		}
28892a041b063f Andrew Jeffery 2020-09-14  576  
28892a041b063f Andrew Jeffery 2020-09-14  577  		usleep_range(priv->delay_us, 2 * priv->delay_us);
28892a041b063f Andrew Jeffery 2020-09-14  578  	}
28892a041b063f Andrew Jeffery 2020-09-14  579  
28892a041b063f Andrew Jeffery 2020-09-14  580  	return 0;
28892a041b063f Andrew Jeffery 2020-09-14  581  }
28892a041b063f Andrew Jeffery 2020-09-14  582  
28892a041b063f Andrew Jeffery 2020-09-14  583  static void i2c_smbus_throttle_exit(const struct i2c_client *client)
28892a041b063f Andrew Jeffery 2020-09-14  584  		__releases(&priv->throttle_lock)
28892a041b063f Andrew Jeffery 2020-09-14  585  {
28892a041b063f Andrew Jeffery 2020-09-14  586  	struct i2c_client_priv *priv;
28892a041b063f Andrew Jeffery 2020-09-14  587  
28892a041b063f Andrew Jeffery 2020-09-14  588  	priv = to_i2c_client_priv(client);
28892a041b063f Andrew Jeffery 2020-09-14  589  
28892a041b063f Andrew Jeffery 2020-09-14  590  	if (priv->delay_us)
28892a041b063f Andrew Jeffery 2020-09-14  591  		priv->last = ktime_get();
28892a041b063f Andrew Jeffery 2020-09-14 @592  	mutex_unlock(&priv->throttle_lock);
28892a041b063f Andrew Jeffery 2020-09-14  593  }
28892a041b063f Andrew Jeffery 2020-09-14  594  
28892a041b063f Andrew Jeffery 2020-09-14 @595  static s32 i2c_smbus_throttle_xfer(const struct i2c_client *client,
28892a041b063f Andrew Jeffery 2020-09-14  596  				   char read_write, u8 command, int protocol,
28892a041b063f Andrew Jeffery 2020-09-14  597  				   union i2c_smbus_data *data)
28892a041b063f Andrew Jeffery 2020-09-14  598  {
28892a041b063f Andrew Jeffery 2020-09-14  599  	s32 res;
28892a041b063f Andrew Jeffery 2020-09-14  600  
28892a041b063f Andrew Jeffery 2020-09-14  601  	res = i2c_smbus_throttle_enter(client);
28892a041b063f Andrew Jeffery 2020-09-14  602  	if (res)
28892a041b063f Andrew Jeffery 2020-09-14  603  		return res;
28892a041b063f Andrew Jeffery 2020-09-14  604  
28892a041b063f Andrew Jeffery 2020-09-14  605  	res = __i2c_lock_bus_helper(client->adapter);
28892a041b063f Andrew Jeffery 2020-09-14  606  	if (!res)
28892a041b063f Andrew Jeffery 2020-09-14  607  		res = __i2c_smbus_xfer(client->adapter, client->addr,
28892a041b063f Andrew Jeffery 2020-09-14  608  				       client->flags, read_write, command,
28892a041b063f Andrew Jeffery 2020-09-14  609  				       protocol, data);
28892a041b063f Andrew Jeffery 2020-09-14  610  	i2c_unlock_bus(client->adapter, I2C_LOCK_SEGMENT);
28892a041b063f Andrew Jeffery 2020-09-14  611  
28892a041b063f Andrew Jeffery 2020-09-14  612  	i2c_smbus_throttle_exit(client);
28892a041b063f Andrew Jeffery 2020-09-14  613  
28892a041b063f Andrew Jeffery 2020-09-14  614  	return res;
28892a041b063f Andrew Jeffery 2020-09-14  615  }
28892a041b063f Andrew Jeffery 2020-09-14  616  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 31785 bytes --]

^ permalink raw reply	[flat|nested] 2+ messages in thread
* [RFC PATCH 0/2] Throttle I2C transfers to UCD9000 devices
@ 2020-09-14 12:28 Andrew Jeffery
  2020-09-14 12:28 ` [RFC PATCH 1/2] i2c: smbus: Allow throttling of transfers to client devices Andrew Jeffery
  0 siblings, 1 reply; 2+ messages in thread
From: Andrew Jeffery @ 2020-09-14 12:28 UTC (permalink / raw)
  To: linux-hwmon, linux-i2c; +Cc: linux, jdelvare, wsa, joel, linux-kernel

Hello,

While working with system designs making use of TI's UCD90320 Power
Sequencer we've found that communication with the device isn't terribly
reliable.

It appears that back-to-back transfers where commands addressed to the
device are put onto the bus with intervals between STOP and START in the
neighbourhood of 250us or less can cause bad behaviour. This primarily
happens during driver probe while scanning the device to determine its
capabilities.

We have observed the device causing excessive clock stretches and bus
lockups, and also corruption of the device's volatile state (requiring it
to be reset).  The latter is particularly disruptive in that the controlled
rails are brought down either by:

1. The corruption causing a fault condition, or
2. Asserting the device's reset line to recover

A further observation is that pacing transfers to the device appears to
mitigate the bad behaviour. We're in discussion with TI to better
understand the limitations and at least get the behaviour documented.

This short series implements the mitigation in terms of a throttle in the
i2c_client associated with the device's driver. Before the first
communication with the device in the probe() of ucd9000 we configure the
i2c_client to throttle transfers with a minimum of a 1ms delay (with the
delay exposed as a module parameter).

The series is RFC for several reasons:

The first is to sus out feelings on the general direction. The problem is
pretty unfortunate - are there better ways to implement the mitigation?

If there aren't, then:

I'd like thoughts on whether we want to account for i2c-dev clients.
Implementing throttling in i2c_client feels like a solution-by-proxy as the
throttling is really a property of the targeted device, but we don't have a
coherent representation between platform devices and devices associated
with i2c-dev clients. At the moment we'd have to resort to address-based
lookups for platform data stashed in the transfer functions.

Next is that I've only implemented throttling for SMBus devices. I don't
yet have a use-case for throttling non-SMBus devices so I'm not sure it's
worth poking at it, but would appreciate thoughts there.

Further, I've had a bit of a stab at dealing with atomic transfers that's
not been tested. Hopefully it makes sense.

Finally I'm also interested in feedback on exposing the control in a little
more general manner than having to implement a module parameter in all
drivers that want to take advantage of throttling. This isn't a big problem
at the moment, but if anyone has thoughts there then I'm happy to poke at
those too.

Please review!

Andrew

Andrew Jeffery (2):
  i2c: smbus: Allow throttling of transfers to client devices
  hwmon: (pmbus/ucd9000) Throttle SMBus transfers to avoid poor
    behaviour

 drivers/hwmon/pmbus/ucd9000.c |   6 ++
 drivers/i2c/i2c-core-base.c   |   8 +-
 drivers/i2c/i2c-core-smbus.c  | 149 +++++++++++++++++++++++++++-------
 drivers/i2c/i2c-core.h        |  22 +++++
 include/linux/i2c.h           |   3 +
 5 files changed, 157 insertions(+), 31 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2020-09-15  6:12 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-15  6:12 [RFC PATCH 1/2] i2c: smbus: Allow throttling of transfers to client devices kernel test robot
  -- strict thread matches above, loose matches on Subject: below --
2020-09-14 12:28 [RFC PATCH 0/2] Throttle I2C transfers to UCD9000 devices Andrew Jeffery
2020-09-14 12:28 ` [RFC PATCH 1/2] i2c: smbus: Allow throttling of transfers to client devices Andrew Jeffery

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.