Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1437388 > unrolled thread

[PATCH 0/2] i2c-dev: Don't let userspace block adapter

Started byViresh Kumar <viresh.kumar@linaro.org>
First post2016-07-06 05:00 +0200
Last post2016-07-06 17:40 +0200
Articles 13 — 5 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH 0/2] i2c-dev: Don't let userspace block adapter Viresh Kumar <viresh.kumar@linaro.org> - 2016-07-06 05:00 +0200
    [PATCH 2/2] i2c-dev: Don't block the adapter from unregistering Viresh Kumar <viresh.kumar@linaro.org> - 2016-07-06 05:00 +0200
      Re: [PATCH 2/2] i2c-dev: Don't block the adapter from unregistering kbuild test robot <lkp@intel.com> - 2016-07-06 07:10 +0200
      Re: [PATCH 2/2] i2c-dev: Don't block the adapter from unregistering Wolfram Sang <wsa@the-dreams.de> - 2016-07-06 09:00 +0200
        Re: [PATCH 2/2] i2c-dev: Don't block the adapter from unregistering Viresh Kumar <viresh.kumar@linaro.org> - 2016-07-06 16:00 +0200
        Re: [PATCH 2/2] i2c-dev: Don't block the adapter from unregistering Jean Delvare <jdelvare@suse.de> - 2016-07-06 19:20 +0200
          Re: [PATCH 2/2] i2c-dev: Don't block the adapter from unregistering Viresh Kumar <viresh.kumar@linaro.org> - 2016-07-06 23:00 +0200
      Re: [PATCH 2/2] i2c-dev: Don't block the adapter from unregistering Viresh Kumar <viresh.kumar@linaro.org> - 2016-07-06 16:40 +0200
        Re: [PATCH 2/2] i2c-dev: Don't block the adapter from unregistering Lars-Peter Clausen <lars@metafoo.de> - 2016-07-06 16:50 +0200
          Re: [PATCH 2/2] i2c-dev: Don't block the adapter from unregistering Viresh Kumar <viresh.kumar@linaro.org> - 2016-07-06 17:40 +0200
          Re: [PATCH 2/2] i2c-dev: Don't block the adapter from unregistering Viresh Kumar <viresh.kumar@linaro.org> - 2016-07-06 17:40 +0200
    Re: [PATCH 0/2] i2c-dev: Don't let userspace block adapter Lars-Peter Clausen <lars@metafoo.de> - 2016-07-06 16:50 +0200
      Re: [PATCH 0/2] i2c-dev: Don't let userspace block adapter Viresh Kumar <viresh.kumar@linaro.org> - 2016-07-06 17:40 +0200

#1437388 — [PATCH 0/2] i2c-dev: Don't let userspace block adapter

FromViresh Kumar <viresh.kumar@linaro.org>
Date2016-07-06 05:00 +0200
Subject[PATCH 0/2] i2c-dev: Don't let userspace block adapter
Message-ID<rRLe9-3nf-3@gated-at.bofh.it>
Hi Wolfram/Jean,

I am part of the kernel team for Google's projectara [1], where we are
building a module smart phone.

This series tries to fix one of the problems we hit on our system as we
are required to hotplug pretty much every thing on the phone and so this
fixes hotplug issues with i2c-dev.

As described in the second patch, the current implementation of i2c-dev
file operations doesn't let the modules (hardware attached to the phone)
eject from the phone as the cleanup path for the module hasn't finished
yet (i2c adapter not removed).

We can't let the userspace block the kernel devices forever in such
cases.

I was able to test them on the ARA phone with kernel 3.10 only and not
mainline.

--
viresh

[1] https://atap.google.com/ara/

Viresh Kumar (2):
  i2c-dev: don't get i2c adapter via i2c_dev
  i2c-dev: Don't block the adapter from unregistering

 drivers/i2c/i2c-dev.c | 79 ++++++++++++++++++++++++++++++++++++++++++---------
 include/linux/i2c.h   |  1 +
 2 files changed, 67 insertions(+), 13 deletions(-)

-- 
2.7.4

[toc] | [next] | [standalone]


#1437389 — [PATCH 2/2] i2c-dev: Don't block the adapter from unregistering

FromViresh Kumar <viresh.kumar@linaro.org>
Date2016-07-06 05:00 +0200
Subject[PATCH 2/2] i2c-dev: Don't block the adapter from unregistering
Message-ID<rRLe9-3nf-17@gated-at.bofh.it>
In reply to#1437388
The i2c-dev calls i2c_get_adapter() from the .open() callback, which
doesn't let the adapter device unregister unless the .close() callback
is called.

On some platforms (like Google ARA), this doesn't let the modules
(hardware attached to the phone) eject from the phone as the cleanup
path for the module hasn't finished yet (i2c adapter not removed).

We can't let the userspace block the kernel forever in such cases.

Fix this by calling i2c_get_adapter() from all other file operations,
i.e.  read/write/ioctl, to make sure the adapter doesn't get away while
we are in the middle of a operation, but not otherwise. In .open() we
will release the adapter device before returning and so if there is no
data transfer in progress, then the i2c-dev doesn't block the adapter
from unregistering.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 drivers/i2c/i2c-dev.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++-----
 include/linux/i2c.h   |  1 +
 2 files changed, 66 insertions(+), 7 deletions(-)

diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
index 66f323fd3982..b2562603daa9 100644
--- a/drivers/i2c/i2c-dev.c
+++ b/drivers/i2c/i2c-dev.c
@@ -142,13 +142,25 @@ static ssize_t i2cdev_read(struct file *file, char __user *buf, size_t count,
 	int ret;
 
 	struct i2c_client *client = file->private_data;
+	struct i2c_adapter *adap;
+
+	adap = i2c_get_adapter(client->adapter_nr);
+	if (!adap)
+		return -ENODEV;
+
+	if (adap != client->adapter) {
+		ret = -EINVAL;
+		goto put_adapter;
+	}
 
 	if (count > 8192)
 		count = 8192;
 
 	tmp = kmalloc(count, GFP_KERNEL);
-	if (tmp == NULL)
-		return -ENOMEM;
+	if (tmp == NULL) {
+		ret = -ENOMEM;
+		goto put_adapter;
+	}
 
 	pr_debug("i2c-dev: i2c-%d reading %zu bytes.\n",
 		iminor(file_inode(file)), count);
@@ -157,6 +169,9 @@ static ssize_t i2cdev_read(struct file *file, char __user *buf, size_t count,
 	if (ret >= 0)
 		ret = copy_to_user(buf, tmp, count) ? -EFAULT : ret;
 	kfree(tmp);
+
+put_adapter:
+	i2c_put_adapter(adap);
 	return ret;
 }
 
@@ -166,19 +181,34 @@ static ssize_t i2cdev_write(struct file *file, const char __user *buf,
 	int ret;
 	char *tmp;
 	struct i2c_client *client = file->private_data;
+	struct i2c_adapter *adap;
+
+	adap = i2c_get_adapter(client->adapter_nr);
+	if (!adap)
+		return -ENODEV;
+
+	if (adap != client->adapter) {
+		ret = -EINVAL;
+		goto put_adapter;
+	}
 
 	if (count > 8192)
 		count = 8192;
 
 	tmp = memdup_user(buf, count);
-	if (IS_ERR(tmp))
-		return PTR_ERR(tmp);
+	if (IS_ERR(tmp)) {
+		ret = PTR_ERR(tmp);
+		goto put_adapter;
+	}
 
 	pr_debug("i2c-dev: i2c-%d writing %zu bytes.\n",
 		iminor(file_inode(file)), count);
 
 	ret = i2c_master_send(client, tmp, count);
 	kfree(tmp);
+
+put_adapter:
+	i2c_put_adapter(adap);
 	return ret;
 }
 
@@ -412,9 +442,9 @@ static noinline int i2cdev_ioctl_smbus(struct i2c_client *client,
 	return res;
 }
 
-static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+static long __i2cdev_ioctl(struct i2c_client *client, unsigned int cmd,
+			   unsigned long arg)
 {
-	struct i2c_client *client = file->private_data;
 	unsigned long funcs;
 
 	dev_dbg(&client->adapter->dev, "ioctl, cmd=0x%02x, arg=0x%02lx\n",
@@ -480,6 +510,28 @@ static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 	return 0;
 }
 
+static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	struct i2c_client *client = file->private_data;
+	struct i2c_adapter *adap;
+	unsigned long ret;
+
+	adap = i2c_get_adapter(client->adapter_nr);
+	if (!adap)
+		return -ENODEV;
+
+	if (adap != client->adapter) {
+		ret = -EINVAL;
+		goto put_adapter;
+	}
+
+	ret = __i2cdev_ioctl(client, cmd, arg);
+
+put_adapter:
+	i2c_put_adapter(adap);
+	return ret;
+}
+
 static int i2cdev_open(struct inode *inode, struct file *file)
 {
 	unsigned int minor = iminor(inode);
@@ -504,9 +556,16 @@ static int i2cdev_open(struct inode *inode, struct file *file)
 	}
 	snprintf(client->name, I2C_NAME_SIZE, "i2c-dev %d", adap->nr);
 
+	client->adapter_nr = minor;
 	client->adapter = adap;
 	file->private_data = client;
 
+	/*
+	 * Allow the adapter to unregister while userspace has opened the i2c
+	 * device.
+	 */
+	i2c_put_adapter(client->adapter);
+
 	return 0;
 }
 
@@ -514,7 +573,6 @@ static int i2cdev_release(struct inode *inode, struct file *file)
 {
 	struct i2c_client *client = file->private_data;
 
-	i2c_put_adapter(client->adapter);
 	kfree(client);
 	file->private_data = NULL;
 
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index fffdc270ca18..38c8fe8ca681 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -234,6 +234,7 @@ struct i2c_client {
 	struct i2c_adapter *adapter;	/* the adapter we sit on	*/
 	struct device dev;		/* the device structure		*/
 	int irq;			/* irq issued by device		*/
+	int adapter_nr;
 	struct list_head detected;
 #if IS_ENABLED(CONFIG_I2C_SLAVE)
 	i2c_slave_cb_t slave_cb;	/* callback for slave mode	*/
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1437412 — Re: [PATCH 2/2] i2c-dev: Don't block the adapter from unregistering

Fromkbuild test robot <lkp@intel.com>
Date2016-07-06 07:10 +0200
SubjectRe: [PATCH 2/2] i2c-dev: Don't block the adapter from unregistering
Message-ID<rRNfX-4Ur-5@gated-at.bofh.it>
In reply to#1437389

[Multipart message — attachments visible in raw view] — view raw

Hi,

[auto build test WARNING on wsa/i2c/for-next]
[also build test WARNING on v4.7-rc6 next-20160705]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Viresh-Kumar/i2c-dev-Don-t-let-userspace-block-adapter/20160706-110245
base:   https://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git i2c/for-next
reproduce: make htmldocs

All warnings (new ones prefixed by >>):

   include/linux/init.h:1: warning: no structured comments found
   kernel/sched/core.c:2079: warning: No description found for parameter 'cookie'
   kernel/sys.c:1: warning: no structured comments found
   drivers/dma-buf/seqno-fence.c:1: warning: no structured comments found
>> include/linux/i2c.h:242: warning: No description found for parameter 'adapter_nr'

vim +/adapter_nr +242 include/linux/i2c.h

d64f73be David Brownell  2007-07-12  226   * managing the device.
^1da177e Linus Torvalds  2005-04-16  227   */
^1da177e Linus Torvalds  2005-04-16  228  struct i2c_client {
2096b956 David Brownell  2007-05-01  229  	unsigned short flags;		/* div., see below		*/
5071860a Jean Delvare    2005-07-20  230  	unsigned short addr;		/* chip address - NOTE: 7bit	*/
^1da177e Linus Torvalds  2005-04-16  231  					/* addresses are stored in the	*/
5071860a Jean Delvare    2005-07-20  232  					/* _LOWER_ 7 bits		*/
2096b956 David Brownell  2007-05-01  233  	char name[I2C_NAME_SIZE];
^1da177e Linus Torvalds  2005-04-16  234  	struct i2c_adapter *adapter;	/* the adapter we sit on	*/
^1da177e Linus Torvalds  2005-04-16  235  	struct device dev;		/* the device structure		*/
8e29da9e Wolfram Sang    2008-07-01  236  	int irq;			/* irq issued by device		*/
42fc20b8 Viresh Kumar    2016-07-05  237  	int adapter_nr;
4735c98f Jean Delvare    2008-07-14  238  	struct list_head detected;
d5fd120e Jean Delvare    2015-01-26  239  #if IS_ENABLED(CONFIG_I2C_SLAVE)
4b1acc43 Wolfram Sang    2014-11-18  240  	i2c_slave_cb_t slave_cb;	/* callback for slave mode	*/
d5fd120e Jean Delvare    2015-01-26  241  #endif
^1da177e Linus Torvalds  2005-04-16 @242  };
^1da177e Linus Torvalds  2005-04-16  243  #define to_i2c_client(d) container_of(d, struct i2c_client, dev)
^1da177e Linus Torvalds  2005-04-16  244  
9b766b81 David Brownell  2008-01-27  245  extern struct i2c_client *i2c_verify_client(struct device *dev);
643dd09e Stephen Warren  2012-04-17  246  extern struct i2c_adapter *i2c_verify_adapter(struct device *dev);
9b766b81 David Brownell  2008-01-27  247  
a61fc683 Ben Gardner     2005-07-27  248  static inline struct i2c_client *kobj_to_i2c_client(struct kobject *kobj)
a61fc683 Ben Gardner     2005-07-27  249  {
d75d53cd Mark M. Hoffman 2007-07-12  250  	struct device * const dev = container_of(kobj, struct device, kobj);

:::::: The code at line 242 was first introduced by commit
:::::: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 Linux-2.6.12-rc2

:::::: TO: Linus Torvalds <torvalds@ppc970.osdl.org>
:::::: CC: Linus Torvalds <torvalds@ppc970.osdl.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[toc] | [prev] | [next] | [standalone]


#1437490 — Re: [PATCH 2/2] i2c-dev: Don't block the adapter from unregistering

FromWolfram Sang <wsa@the-dreams.de>
Date2016-07-06 09:00 +0200
SubjectRe: [PATCH 2/2] i2c-dev: Don't block the adapter from unregistering
Message-ID<rROYp-5Ma-1@gated-at.bofh.it>
In reply to#1437389

[Multipart message — attachments visible in raw view] — view raw

On Tue, Jul 05, 2016 at 07:57:07PM -0700, Viresh Kumar wrote:
> The i2c-dev calls i2c_get_adapter() from the .open() callback, which
> doesn't let the adapter device unregister unless the .close() callback
> is called.
> 
> On some platforms (like Google ARA), this doesn't let the modules
> (hardware attached to the phone) eject from the phone as the cleanup
> path for the module hasn't finished yet (i2c adapter not removed).
> 
> We can't let the userspace block the kernel forever in such cases.
> 
> Fix this by calling i2c_get_adapter() from all other file operations,
> i.e.  read/write/ioctl, to make sure the adapter doesn't get away while
> we are in the middle of a operation, but not otherwise. In .open() we
> will release the adapter device before returning and so if there is no
> data transfer in progress, then the i2c-dev doesn't block the adapter
> from unregistering.
> 
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>

I'd think Jean has more experience with I2C hotplugging approaches and
difficulties, so I'd be interested in his high level review.

However:

> @@ -234,6 +234,7 @@ struct i2c_client {
>  	struct i2c_adapter *adapter;	/* the adapter we sit on	*/
>  	struct device dev;		/* the device structure		*/
>  	int irq;			/* irq issued by device		*/
> +	int adapter_nr;
>  	struct list_head detected;

Adding something to *every* i2c_client for this corner case sounds
pretty expensive to me.

Regards,

   Wolfram

[toc] | [prev] | [next] | [standalone]


#1437743 — Re: [PATCH 2/2] i2c-dev: Don't block the adapter from unregistering

FromViresh Kumar <viresh.kumar@linaro.org>
Date2016-07-06 16:00 +0200
SubjectRe: [PATCH 2/2] i2c-dev: Don't block the adapter from unregistering
Message-ID<rRVwR-1tj-9@gated-at.bofh.it>
In reply to#1437490
On 06-07-16, 15:55, Wolfram Sang wrote:
> Adding something to *every* i2c_client for this corner case sounds
> pretty expensive to me.

I agree with you on that. I wanted to avoid it, but I couldn't :(

Lets see how Jean suggests to handle it.

-- 
viresh

[toc] | [prev] | [next] | [standalone]


#1437859 — Re: [PATCH 2/2] i2c-dev: Don't block the adapter from unregistering

FromJean Delvare <jdelvare@suse.de>
Date2016-07-06 19:20 +0200
SubjectRe: [PATCH 2/2] i2c-dev: Don't block the adapter from unregistering
Message-ID<rRYEq-3A0-15@gated-at.bofh.it>
In reply to#1437490
On Wed, 6 Jul 2016 15:55:24 +0900, Wolfram Sang wrote:
> On Tue, Jul 05, 2016 at 07:57:07PM -0700, Viresh Kumar wrote:
> > The i2c-dev calls i2c_get_adapter() from the .open() callback, which
> > doesn't let the adapter device unregister unless the .close() callback
> > is called.
> > 
> > On some platforms (like Google ARA), this doesn't let the modules
> > (hardware attached to the phone) eject from the phone as the cleanup
> > path for the module hasn't finished yet (i2c adapter not removed).
> > 
> > We can't let the userspace block the kernel forever in such cases.
> > 
> > Fix this by calling i2c_get_adapter() from all other file operations,
> > i.e.  read/write/ioctl, to make sure the adapter doesn't get away while
> > we are in the middle of a operation, but not otherwise. In .open() we
> > will release the adapter device before returning and so if there is no
> > data transfer in progress, then the i2c-dev doesn't block the adapter
> > from unregistering.
> > 
> > Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
> 
> I'd think Jean has more experience with I2C hotplugging approaches and
> difficulties, so I'd be interested in his high level review.

Well well... I don't like this patch at all to be honest.

My first question would be: what is keeping /dev/i2c-* open all the
time? Originally i2c-dev was developed with development and debugging
tools in mind (the i2c-tools suite.) The device nodes were never meant
to be kept open for more than a few seconds.

Do you have user-space i2c device drivers on your system? Which ones,
and why (I would expect all useful i2c devices to have a kernel
driver.) And why do they keep their i2c device node opened all the time?

Requesting and freeing the i2c adapter for every transaction is going
to add a lot of overhead to all existing tools :-(

It's not like every user can open i2c device nodes and block the
system. Only selected users should be able to open i2c device nodes
(only root by default) so they should be responsible for not
misbehaving.

-- 
Jean Delvare
SUSE L3 Support

[toc] | [prev] | [next] | [standalone]


#1437937 — Re: [PATCH 2/2] i2c-dev: Don't block the adapter from unregistering

FromViresh Kumar <viresh.kumar@linaro.org>
Date2016-07-06 23:00 +0200
SubjectRe: [PATCH 2/2] i2c-dev: Don't block the adapter from unregistering
Message-ID<rS25k-5DG-23@gated-at.bofh.it>
In reply to#1437859
On 06-07-16, 19:12, Jean Delvare wrote:
> Well well... I don't like this patch at all to be honest.

Sure, I didn't like it much as well. I just wanted people to comment on what
else we can do here. We don't really want to add out-of-mainline stuff here.

> My first question would be: what is keeping /dev/i2c-* open all the
> time? Originally i2c-dev was developed with development and debugging
> tools in mind (the i2c-tools suite.) The device nodes were never meant
> to be kept open for more than a few seconds.

We thought that buggy userspace shouldn't be allowed to get kernel into trouble.
Isn't that the case ?

In our case this is what happens:
- userspace opens the file descriptor
- we try to forcefully remove the module from phone (that doesn't talk to
  userspace to stop using the device).
- The module doesn't get ejected unless the app closes the fd.

> Do you have user-space i2c device drivers on your system? Which ones,

No. Its probably an app written by some of our module app developers.

> and why (I would expect all useful i2c devices to have a kernel
> driver.)

That's what we have.

> Requesting and freeing the i2c adapter for every transaction is going

Well, we are just finding it (taking a reference of it) and the dropping its
reference.

> to add a lot of overhead to all existing tools :-(

:(

> It's not like every user can open i2c device nodes and block the
> system. Only selected users should be able to open i2c device nodes
> (only root by default) so they should be responsible for not
> misbehaving.

Hmmm. The problem is that they weren't told when the module tries to go away and
so they don't know that they need to close the fd.

Also coming to the earlier thing, I though even the buggy userspace thing
shouldn't be allowed to block kernel device unregisteration.

-- 
viresh

[toc] | [prev] | [next] | [standalone]


#1437774 — Re: [PATCH 2/2] i2c-dev: Don't block the adapter from unregistering

FromViresh Kumar <viresh.kumar@linaro.org>
Date2016-07-06 16:40 +0200
SubjectRe: [PATCH 2/2] i2c-dev: Don't block the adapter from unregistering
Message-ID<rRW9A-1Wj-25@gated-at.bofh.it>
In reply to#1437389
On 06-07-16, 10:22, Peter Rosin wrote:
> On 2016-07-06 04:57, Viresh Kumar wrote:
> > The i2c-dev calls i2c_get_adapter() from the .open() callback, which
> > doesn't let the adapter device unregister unless the .close() callback
> > is called.
> > 
> > On some platforms (like Google ARA), this doesn't let the modules
> > (hardware attached to the phone) eject from the phone as the cleanup
> > path for the module hasn't finished yet (i2c adapter not removed).
> > 
> > We can't let the userspace block the kernel forever in such cases.
> > 
> > Fix this by calling i2c_get_adapter() from all other file operations,
> > i.e.  read/write/ioctl, to make sure the adapter doesn't get away while
> > we are in the middle of a operation, but not otherwise. In .open() we
> > will release the adapter device before returning and so if there is no
> > data transfer in progress, then the i2c-dev doesn't block the adapter
> > from unregistering.
> > 
> > Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
> > ---
> >  drivers/i2c/i2c-dev.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++-----
> >  include/linux/i2c.h   |  1 +
> >  2 files changed, 66 insertions(+), 7 deletions(-)
> > 
> > diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
> > index 66f323fd3982..b2562603daa9 100644
> > --- a/drivers/i2c/i2c-dev.c
> > +++ b/drivers/i2c/i2c-dev.c
> > @@ -142,13 +142,25 @@ static ssize_t i2cdev_read(struct file *file, char __user *buf, size_t count,
> >  	int ret;
> >  
> >  	struct i2c_client *client = file->private_data;
> > +	struct i2c_adapter *adap;
> > +
> > +	adap = i2c_get_adapter(client->adapter_nr);
> > +	if (!adap)
> > +		return -ENODEV;
> > +
> > +	if (adap != client->adapter) {
> > +		ret = -EINVAL;
> > +		goto put_adapter;
> > +	}
> 
> I don't see how this can work with the i2c-demux-pinctrl driver.
> I also wonder if/how other muxes handle this relaxed adapter
> lifetime thingy?

I would like to mention here that I am no I2C expert and have limited
knowledge of it :)

I haven't had a look at the muxes implementation earlier, now that I
looked at them, I see that they unregister/register the adapter,
perhaps while switching functionality.

I am not sure though, if this patch will break it or not. And I don't
have a way of testing it out.

> Out of curiosity, why would client->adapter change anyway?
> (that is, if not because of a demux-pinctrl op)

I didn't mean that it will change, and perhaps we can add a
WARN_ON(adap != client->adapter).

But, thinking about it again now, I think it is possible.

What about this sequence:

- i2c-adap-register (address P1)
- .open(), client->adapter = P1;
- .read/write/ioctl()..
- i2c-adap-unregister (adapter freed)
- i2c-adap-register with same adapter_nr (address P2);
- .read/write/ioctl().

Wouldn't the address differ here ?

-- 
viresh

[toc] | [prev] | [next] | [standalone]


#1437776 — Re: [PATCH 2/2] i2c-dev: Don't block the adapter from unregistering

FromLars-Peter Clausen <lars@metafoo.de>
Date2016-07-06 16:50 +0200
SubjectRe: [PATCH 2/2] i2c-dev: Don't block the adapter from unregistering
Message-ID<rRWjg-1ZJ-3@gated-at.bofh.it>
In reply to#1437774
On 07/06/2016 04:33 PM, Viresh Kumar wrote:
> On 06-07-16, 10:22, Peter Rosin wrote:
>> On 2016-07-06 04:57, Viresh Kumar wrote:
>>> The i2c-dev calls i2c_get_adapter() from the .open() callback, which
>>> doesn't let the adapter device unregister unless the .close() callback
>>> is called.
>>>
>>> On some platforms (like Google ARA), this doesn't let the modules
>>> (hardware attached to the phone) eject from the phone as the cleanup
>>> path for the module hasn't finished yet (i2c adapter not removed).
>>>
>>> We can't let the userspace block the kernel forever in such cases.
>>>
>>> Fix this by calling i2c_get_adapter() from all other file operations,
>>> i.e.  read/write/ioctl, to make sure the adapter doesn't get away while
>>> we are in the middle of a operation, but not otherwise. In .open() we
>>> will release the adapter device before returning and so if there is no
>>> data transfer in progress, then the i2c-dev doesn't block the adapter
>>> from unregistering.
>>>
>>> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
>>> ---
>>>  drivers/i2c/i2c-dev.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++-----
>>>  include/linux/i2c.h   |  1 +
>>>  2 files changed, 66 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
>>> index 66f323fd3982..b2562603daa9 100644
>>> --- a/drivers/i2c/i2c-dev.c
>>> +++ b/drivers/i2c/i2c-dev.c
>>> @@ -142,13 +142,25 @@ static ssize_t i2cdev_read(struct file *file, char __user *buf, size_t count,
>>>  	int ret;
>>>  
>>>  	struct i2c_client *client = file->private_data;
>>> +	struct i2c_adapter *adap;
>>> +
>>> +	adap = i2c_get_adapter(client->adapter_nr);
>>> +	if (!adap)
>>> +		return -ENODEV;
>>> +
>>> +	if (adap != client->adapter) {
>>> +		ret = -EINVAL;
>>> +		goto put_adapter;
>>> +	}
>>
>> I don't see how this can work with the i2c-demux-pinctrl driver.
>> I also wonder if/how other muxes handle this relaxed adapter
>> lifetime thingy?
> 
> I would like to mention here that I am no I2C expert and have limited
> knowledge of it :)
> 
> I haven't had a look at the muxes implementation earlier, now that I
> looked at them, I see that they unregister/register the adapter,
> perhaps while switching functionality.
> 
> I am not sure though, if this patch will break it or not. And I don't
> have a way of testing it out.
> 
>> Out of curiosity, why would client->adapter change anyway?
>> (that is, if not because of a demux-pinctrl op)
> 
> I didn't mean that it will change, and perhaps we can add a
> WARN_ON(adap != client->adapter).
> 
> But, thinking about it again now, I think it is possible.
> 
> What about this sequence:
> 
> - i2c-adap-register (address P1)
> - .open(), client->adapter = P1;
> - .read/write/ioctl()..
> - i2c-adap-unregister (adapter freed)
> - i2c-adap-register with same adapter_nr (address P2);
> - .read/write/ioctl().
> 
> Wouldn't the address differ here ?

There is no guarantee that the address will be different. While it is
unlikely the memory allocated might give out the same address for the second
adapter if the first one has been freed.

[toc] | [prev] | [next] | [standalone]


#1437796 — Re: [PATCH 2/2] i2c-dev: Don't block the adapter from unregistering

FromViresh Kumar <viresh.kumar@linaro.org>
Date2016-07-06 17:40 +0200
SubjectRe: [PATCH 2/2] i2c-dev: Don't block the adapter from unregistering
Message-ID<rRX5D-2x0-1@gated-at.bofh.it>
In reply to#1437776
On 06-07-16, 16:43, Lars-Peter Clausen wrote:
> There is no guarantee that the address will be different. While it is
> unlikely the memory allocated might give out the same address for the second
> adapter if the first one has been freed.

Oh yeah, thanks for correcting me :)

-- 
viresh

[toc] | [prev] | [next] | [standalone]


#1437802 — Re: [PATCH 2/2] i2c-dev: Don't block the adapter from unregistering

FromViresh Kumar <viresh.kumar@linaro.org>
Date2016-07-06 17:40 +0200
SubjectRe: [PATCH 2/2] i2c-dev: Don't block the adapter from unregistering
Message-ID<rRX5E-2x0-21@gated-at.bofh.it>
In reply to#1437776
On 06-07-16, 17:04, Peter Rosin wrote:
> Exactly, so the stored address had better be correct, and in

No.

> that case there is no need for the new adapter_nr in every
> client, you could just go with client->adapter->nr instead.

client->adapter may be a dangling pointer at this point if the adapter
is freed, so we can't use that blindly for sure.

> Which just shows that the whole thing is fishy and that the
> adapter has to remain alive. BTW, is there any guarantee that
> adapter numbers will not get reused?

We are allocating them from idr and that will reuse them once they get
freed.

-- 
viresh

[toc] | [prev] | [next] | [standalone]


#1437775

FromLars-Peter Clausen <lars@metafoo.de>
Date2016-07-06 16:50 +0200
Message-ID<rRWjg-1ZJ-5@gated-at.bofh.it>
In reply to#1437388
On 07/06/2016 04:57 AM, Viresh Kumar wrote:
> Hi Wolfram/Jean,
> 
> I am part of the kernel team for Google's projectara [1], where we are
> building a module smart phone.
> 
> This series tries to fix one of the problems we hit on our system as we
> are required to hotplug pretty much every thing on the phone and so this
> fixes hotplug issues with i2c-dev.
> 
> As described in the second patch, the current implementation of i2c-dev
> file operations doesn't let the modules (hardware attached to the phone)
> eject from the phone as the cleanup path for the module hasn't finished
> yet (i2c adapter not removed).
> 
> We can't let the userspace block the kernel devices forever in such
> cases.
> 
> I was able to test them on the ARA phone with kernel 3.10 only and not
> mainline.

This sounds like you want hot-unplug. This is currently not support by the
I2C framework for adapters. A better approach compared to this series might
be to implement full hot-unplug support for I2C adapters. This will probably
also be useful for additional usecases.

[toc] | [prev] | [next] | [standalone]


#1437804

FromViresh Kumar <viresh.kumar@linaro.org>
Date2016-07-06 17:40 +0200
Message-ID<rRX5E-2x0-27@gated-at.bofh.it>
In reply to#1437775
On 06-07-16, 16:41, Lars-Peter Clausen wrote:
> On 07/06/2016 04:57 AM, Viresh Kumar wrote:
> > Hi Wolfram/Jean,
> > 
> > I am part of the kernel team for Google's projectara [1], where we are
> > building a module smart phone.
> > 
> > This series tries to fix one of the problems we hit on our system as we
> > are required to hotplug pretty much every thing on the phone and so this
> > fixes hotplug issues with i2c-dev.
> > 
> > As described in the second patch, the current implementation of i2c-dev
> > file operations doesn't let the modules (hardware attached to the phone)
> > eject from the phone as the cleanup path for the module hasn't finished
> > yet (i2c adapter not removed).
> > 
> > We can't let the userspace block the kernel devices forever in such
> > cases.
> > 
> > I was able to test them on the ARA phone with kernel 3.10 only and not
> > mainline.
> 
> This sounds like you want hot-unplug. This is currently not support by the
> I2C framework for adapters. A better approach compared to this series might
> be to implement full hot-unplug support for I2C adapters. This will probably
> also be useful for additional usecases.

Yeah, we need hot-unplug.

Hmm, doing that would require more knowledge of the framework and I am
afraid I don't have it right now, not that it can't be done :)

-- 
viresh

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web