Re: [PATCH] Don't use a klist for drivers' set-of-devices

2005-08-17 Thread Bartlomiej Zolnierkiewicz
Hi,

On 8/17/05, Alan Stern <[EMAIL PROTECTED]> wrote:
> On Tue, 16 Aug 2005, Dmitry Torokhov wrote:
> 
> > Alan,
> >
> > I am sorry I don't have time to properly review the patch at
> > themoment, just a couple of comments about serio - I would not look at
> > serio for examples of typical use as it was trying very hard to work
> > around the original driver model limitation that prevented drivers to
> > register childern on the same bus from their probe function. I think
> > now that that limitation is lifted serio implemenation can be
> > simplified.
> 
> Okay.  The same comments may apply to the other users of
> device_bind_driver.  Apart from a couple in the USB stack that I can
> handle already, those users are:
> 
> drivers/pnp/card.c
> drivers/input/serio/serio.c
> drivers/input/gameport/gameport.c
> 
> Presumably the gameport code is very similar to the serio code.
> Interestingly, callers of device_release_driver include:
> 
> drivers/pnp/card.c
> drivers/input/serio/serio.c
> drivers/input/gameport/gameport.c
> drivers/ide/ide-proc.c
> drivers/ieee1394/nodemgr.c
> 
> It's not obvious (to me) why ide-proc.c and nodemgr.c call one but not the
> other.

ide-proc.c calls device_attach() instead of device_bind_driver()

"driver" interface in ide-proc.c will be scheduled for removal
since proper bind/unbind sysfs interface is available now.

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


Re: [PATCH] Don't use a klist for drivers' set-of-devices

2005-08-17 Thread Alan Stern
On Tue, 16 Aug 2005, Dmitry Torokhov wrote:

> Alan,
> 
> I am sorry I don't have time to properly review the patch at
> themoment, just a couple of comments about serio - I would not look at
> serio for examples of typical use as it was trying very hard to work
> around the original driver model limitation that prevented drivers to
> register childern on the same bus from their probe function. I think
> now that that limitation is lifted serio implemenation can be
> simplified.

Okay.  The same comments may apply to the other users of
device_bind_driver.  Apart from a couple in the USB stack that I can
handle already, those users are:

drivers/pnp/card.c
drivers/input/serio/serio.c
drivers/input/gameport/gameport.c

Presumably the gameport code is very similar to the serio code.  
Interestingly, callers of device_release_driver include:

drivers/pnp/card.c
drivers/input/serio/serio.c
drivers/input/gameport/gameport.c
drivers/ide/ide-proc.c
drivers/ieee1394/nodemgr.c

It's not obvious (to me) why ide-proc.c and nodemgr.c call one but not the 
other.

Anyway, I appreciate you taking the time to comment on this work.  When 
you've had a chance to read through that patch, let me know what you 
think.

Alan Stern

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


Re: [PATCH] Don't use a klist for drivers' set-of-devices

2005-08-16 Thread Dmitry Torokhov
On 8/15/05, Alan Stern <[EMAIL PROTECTED]> wrote:

> On the face of it, neither is particularly more attractive than the other.
> However, reading through the various places that call these routines (for
> example, drivers/input/serio/serio.c or drivers/pnp/card.c) revealed a
> pattern.  In most cases, the callers of device_bind_driver _really_ want
> something that functions more like driver_probe_device but without the
> matching step.  The callers are invoking the probe methods by hand rather
> than relying on the driver core to do so.  There's maybe only one place
> where a caller actually does want the device bound to the driver without
> doing a probe.
> 

Alan,

I am sorry I don't have time to properly review the patch at
themoment, just a couple of comments about serio - I would not look at
serio for examples of typical use as it was trying very hard to work
around the original driver model limitation that prevented drivers to
register childern on the same bus from their probe function. I think
now that that limitation is lifted serio implemenation can be
simplified.

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


Re: [PATCH] Don't use a klist for drivers' set-of-devices

2005-08-15 Thread Alan Stern
Dmitry, Pat, Greg, and everyone else:

This is a revised version of the patch I sent in last week -- not yet a
submission, more of an RFC.  It turns out that removing the driver's list
of bound devices isn't practical, because there are times when a device
not yet on the bus's overall klist will be bound (this happens whenever a
new device is registered, for instance).

Anyway, in this new version the locking is greatly simplified and the
requirements are made much more explicit in the comments.  This code will
not be subject to deadlock when a driver's probe routine registers a child
device that uses the same driver, or when a remove routine unregisters
a child device from the same driver.  I think this version is okay, but
please look it over and see if anything looks amiss.

The next step will be to clean up the races inherent in device_bind_driver 
and device_release_driver.  There are two obvious approaches:

Pass the driver as an argument rather than trusting the value
stored in dev->driver.

Require the caller to lock dev->sem.

On the face of it, neither is particularly more attractive than the other.  
However, reading through the various places that call these routines (for
example, drivers/input/serio/serio.c or drivers/pnp/card.c) revealed a
pattern.  In most cases, the callers of device_bind_driver _really_ want
something that functions more like driver_probe_device but without the
matching step.  The callers are invoking the probe methods by hand rather
than relying on the driver core to do so.  There's maybe only one place
where a caller actually does want the device bound to the driver without
doing a probe.

This suggests it might be a good idea to split driver_probe_device into 
two pieces, one for matching and one for probing & binding.  The second 
piece could then be used instead of device_bind_driver.

Another thing became apparent as well.  All of the places that use these
routines currently rely on the bus subsystem's rwsem for synchronization.  
Obviously this is bad, because that rwsem is on its way out.  I don't know
enough about all those different drivers to be able to tell whether they
lock the rwsem merely because the old API required it or because they
really do need some mutual exclusion.  Still, this suggests that it might
be best to require the callers to lock dev->sem -- i.e., use dev->sem sort
of as a replacement for the bus rwsem.

Comments?

Alan Stern



Index: usb-2.6/drivers/base/dd.c
===
--- usb-2.6.orig/drivers/base/dd.c
+++ usb-2.6/drivers/base/dd.c
@@ -21,31 +21,61 @@
 #include "base.h"
 #include "power/power.h"
 
-#define to_drv(node) container_of(node, struct device_driver, kobj.entry)
 
+/*
+ * @dev must be guaranteed not to be unregistered, in the process
+ * of registration, or else pinned by its knode_bus.
+ * The caller must hold @dev->sem.
+ */
+static int __device_bind_driver(struct device * dev)
+{
+   struct device_driver * drv = dev->driver;
+   int ret;
+
+   down(&drv->devlist_mutex);
+
+   /* Make sure that drv is registered */
+   if (klist_node_attached(&drv->knode_bus)) {
+   pr_debug("bound device '%s' to driver '%s'\n",
+dev->bus_id, dev->driver->name);
+   list_add_tail(&dev->node_driver, &dev->driver->devlist);
+   sysfs_create_link(&dev->driver->kobj, &dev->kobj,
+ kobject_name(&dev->kobj));
+   sysfs_create_link(&dev->kobj, &dev->driver->kobj, "driver");
+   ret = 0;
+   } else
+   ret = -EIDRM;
+
+   up(&drv->devlist_mutex);
+   return ret;
+}
 
 /**
  * device_bind_driver - bind a driver to one device.
  * @dev:   device.
  *
  * Allow manual attachment of a driver to a device.
- * Caller must have already set @dev->driver.
  *
- * Note that this does not modify the bus reference count
- * nor take the bus's rwsem. Please verify those are accounted
- * for before calling this. (It is ok to call with no other effort
- * from a driver's probe() method.)
- *
- * This function must be called with @dev->sem held.
- */
-void device_bind_driver(struct device * dev)
-{
-   pr_debug("bound device '%s' to driver '%s'\n",
-dev->bus_id, dev->driver->name);
-   klist_add_tail(&dev->driver->klist_devices, &dev->knode_driver);
-   sysfs_create_link(&dev->driver->kobj, &dev->kobj,
- kobject_name(&dev->kobj));
-   sysfs_create_link(&dev->kobj, &dev->driver->kobj, "driver");
+ * Caller must have already set @dev->driver.
+ * @dev must be guaranteed not to be unregistered, in the process
+ * of registration, or else pinned by its knode_bus.
+ */
+int device_bind_driver(struct device * dev)
+{
+   struct device_driver *drv = dev->driver;
+   int ret;
+
+   /* Make sure dev hasn't been u

Re: [PATCH] Don't use a klist for drivers' set-of-devices

2005-08-12 Thread Alan Stern
On Thu, 11 Aug 2005, Dmitry Torokhov wrote:

> Hmm, so what do I do in the following scenario - I have a serio port
> (AUX) that has a synaptics touchpad bound to it which is driven by
> psmouse driver. psmouse driver registers a child port (synaptics
> pass-through) during probe call. The child port is also driven by
> psmouse module - but it looks like it will deadlock when binding.

Dmitry's point is well founded.  Greg, I want to retract that klist patch 
(as536).  I'll send in a revised version before long.

It looks like the best approach will simply be to eliminate the driver's
list of bound devices altogether.  That should make Christoph happy -- no
klist, no list, no nothing!  :-)  The list hardly ever gets used, mainly
when the driver is unloaded.  We can already get the same effect by
iterating over the bus's list of devices and skipping everything not bound
to the driver.

This will eliminate a whole set of races and make the code more 
transparent (I hope).

Alan Stern

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


Re: [PATCH] Don't use a klist for drivers' set-of-devices

2005-08-11 Thread Alan Stern
On Thu, 11 Aug 2005, Dmitry Torokhov wrote:

> Hmm, so what do I do in the following scenario - I have a serio port
> (AUX) that has a synaptics touchpad bound to it which is driven by
> psmouse driver. psmouse driver registers a child port (synaptics
> pass-through) during probe call. The child port is also driven by
> psmouse module - but it looks like it will deadlock when binding.
> 
> Am I missing something here?

I hate to say this, but you are right.  Can you suggest a way around this 
problem?  Perhaps arranging things so that the devlist_mutex is held only 
during the actual __device_bind_driver call and not during probe...  But 
there are so many tricky interactions and possible races that this 
requires a lot of thought.  I'll get back to you.

Alan Stern

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


Re: [PATCH] Don't use a klist for drivers' set-of-devices

2005-08-11 Thread Dmitry Torokhov
On 8/11/05, Alan Stern <[EMAIL PROTECTED]> wrote:
> On Thu, 11 Aug 2005, Christoph Hellwig wrote:
> 
> > On Thu, Aug 11, 2005 at 11:24:23AM -0700, Greg KH wrote:
> > > > This patch (as536) simplifies the driver-model core by replacing the 
> > > > klist
> > > > used to store the set of devices bound to a driver with a regular list
> > > > protected by a mutex.  It turns out that even with a klist, there are 
> > > > too
> > > > many opportunities for races for the list to be used safely by more than
> > > > one thread at a time.  And given that only one thread uses the list at 
> > > > any
> > > > moment, there's no need to add all the extra overhead of making it a
> > > > klist.
> > >
> > > Hm, but that was the whole reason to go to a klist in the first place.
> >
> > And shows once more that the klist approach was totally misguided.
> 
> I'll let Pat answer Christoph's comment.
> 
> Do note that the bus's list of devices and the bus's list of registered
> drivers are still klists.  Only the driver's list of bound devices gets
> reverted to a normal list.
>

Hmm, so what do I do in the following scenario - I have a serio port
(AUX) that has a synaptics touchpad bound to it which is driven by
psmouse driver. psmouse driver registers a child port (synaptics
pass-through) during probe call. The child port is also driven by
psmouse module - but it looks like it will deadlock when binding.

Am I missing something here?

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


Re: [PATCH] Don't use a klist for drivers' set-of-devices

2005-08-11 Thread Alan Stern
On Thu, 11 Aug 2005, Christoph Hellwig wrote:

> On Thu, Aug 11, 2005 at 11:24:23AM -0700, Greg KH wrote:
> > > This patch (as536) simplifies the driver-model core by replacing the 
> > > klist 
> > > used to store the set of devices bound to a driver with a regular list 
> > > protected by a mutex.  It turns out that even with a klist, there are too 
> > > many opportunities for races for the list to be used safely by more than 
> > > one thread at a time.  And given that only one thread uses the list at 
> > > any 
> > > moment, there's no need to add all the extra overhead of making it a 
> > > klist.
> > 
> > Hm, but that was the whole reason to go to a klist in the first place.
> 
> And shows once more that the klist approach was totally misguided.

I'll let Pat answer Christoph's comment.

Do note that the bus's list of devices and the bus's list of registered
drivers are still klists.  Only the driver's list of bound devices gets
reverted to a normal list.

Alan Stern

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


Re: [PATCH] Don't use a klist for drivers' set-of-devices

2005-08-11 Thread Christoph Hellwig
On Thu, Aug 11, 2005 at 11:24:23AM -0700, Greg KH wrote:
> > This patch (as536) simplifies the driver-model core by replacing the klist 
> > used to store the set of devices bound to a driver with a regular list 
> > protected by a mutex.  It turns out that even with a klist, there are too 
> > many opportunities for races for the list to be used safely by more than 
> > one thread at a time.  And given that only one thread uses the list at any 
> > moment, there's no need to add all the extra overhead of making it a 
> > klist.
> 
> Hm, but that was the whole reason to go to a klist in the first place.

And shows once more that the klist approach was totally misguided.

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


Re: [PATCH] Don't use a klist for drivers' set-of-devices

2005-08-11 Thread Greg KH
On Wed, Aug 10, 2005 at 04:56:08PM -0400, Alan Stern wrote:
> Greg and Pat:
> 
> This patch (as536) simplifies the driver-model core by replacing the klist 
> used to store the set of devices bound to a driver with a regular list 
> protected by a mutex.  It turns out that even with a klist, there are too 
> many opportunities for races for the list to be used safely by more than 
> one thread at a time.  And given that only one thread uses the list at any 
> moment, there's no need to add all the extra overhead of making it a 
> klist.

Hm, but that was the whole reason to go to a klist in the first place.

> This version of the patch addresses the concerns raised earlier by Pat:  
> the list and mutex have been given more succinct names, and the obscure
> special-case code in device_attach has been replaced with a FIXME comment.  
> Note that the new iterators in driver.c could easily be changed to use
> list_for_each_entry_safe and list_for_each_entry, if the functions didn't
> offer the feature of starting in the middle of the list.  If no callers
> use that feature, it should be removed.

Pat, any opinions on this patch?

thanks,

greg k-h
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] Don't use a klist for drivers' set-of-devices

2005-08-10 Thread Alan Stern
Greg and Pat:

This patch (as536) simplifies the driver-model core by replacing the klist 
used to store the set of devices bound to a driver with a regular list 
protected by a mutex.  It turns out that even with a klist, there are too 
many opportunities for races for the list to be used safely by more than 
one thread at a time.  And given that only one thread uses the list at any 
moment, there's no need to add all the extra overhead of making it a 
klist.

This version of the patch addresses the concerns raised earlier by Pat:  
the list and mutex have been given more succinct names, and the obscure
special-case code in device_attach has been replaced with a FIXME comment.  
Note that the new iterators in driver.c could easily be changed to use
list_for_each_entry_safe and list_for_each_entry, if the functions didn't
offer the feature of starting in the middle of the list.  If no callers
use that feature, it should be removed.

I still think the APIs for device_bind_driver and device_release_driver
need to be changed, because they each rely on dev->drv not changing at a
time when no protecting locks are held.  They will have to be fixed up in
a later patch.

Alan Stern



Signed-off-by: Alan Stern <[EMAIL PROTECTED]>

Index: usb-2.6/drivers/base/dd.c
===
--- usb-2.6.orig/drivers/base/dd.c
+++ usb-2.6/drivers/base/dd.c
@@ -24,28 +24,37 @@
 #define to_drv(node) container_of(node, struct device_driver, kobj.entry)
 
 
+/*
+ * The caller must hold both @dev->drv->devlist_mutex and
+ * @dev->sem (acquired in that order).
+ */
+static void __device_bind_driver(struct device * dev)
+{
+   pr_debug("bound device '%s' to driver '%s'\n",
+dev->bus_id, dev->driver->name);
+   list_add_tail(&dev->node_driver, &dev->driver->devlist);
+   sysfs_create_link(&dev->driver->kobj, &dev->kobj,
+ kobject_name(&dev->kobj));
+   sysfs_create_link(&dev->kobj, &dev->driver->kobj, "driver");
+}
+
 /**
  * device_bind_driver - bind a driver to one device.
  * @dev:   device.
  *
  * Allow manual attachment of a driver to a device.
  * Caller must have already set @dev->driver.
- *
- * Note that this does not modify the bus reference count
- * nor take the bus's rwsem. Please verify those are accounted
- * for before calling this. (It is ok to call with no other effort
- * from a driver's probe() method.)
- *
- * This function must be called with @dev->sem held.
  */
 void device_bind_driver(struct device * dev)
 {
-   pr_debug("bound device '%s' to driver '%s'\n",
-dev->bus_id, dev->driver->name);
-   klist_add_tail(&dev->driver->klist_devices, &dev->knode_driver);
-   sysfs_create_link(&dev->driver->kobj, &dev->kobj,
- kobject_name(&dev->kobj));
-   sysfs_create_link(&dev->kobj, &dev->driver->kobj, "driver");
+   struct device_driver *drv = dev->driver;
+
+   down(&drv->devlist_mutex);
+   down(&dev->sem);
+   if (dev->driver == drv)
+   __device_bind_driver(dev);
+   up(&dev->sem);
+   up(&drv->devlist_mutex);
 }
 
 /**
@@ -59,16 +68,21 @@ void device_bind_driver(struct device * 
  * because we don't know the format of the ID structures, nor what
  * is to be considered a match and what is not.
  *
- *
  * This function returns 1 if a match is found, an error if one
  * occurs (that is not -ENODEV or -ENXIO), and 0 otherwise.
  *
- * This function must be called with @dev->sem held.
+ * The caller must hold @drv->devlist_mutex.
  */
 int driver_probe_device(struct device_driver * drv, struct device * dev)
 {
int ret = 0;
 
+   down(&dev->sem);
+   if (dev->driver) {
+   ret = -EBUSY;
+   goto Done;
+   }
+
if (drv->bus->match && !drv->bus->match(dev, drv))
goto Done;
 
@@ -82,7 +96,7 @@ int driver_probe_device(struct device_dr
goto ProbeFailed;
}
}
-   device_bind_driver(dev);
+   __device_bind_driver(dev);
ret = 1;
pr_debug("%s: Bound Device %s to Driver %s\n",
 drv->bus->name, dev->bus_id, drv->name);
@@ -102,13 +116,20 @@ int driver_probe_device(struct device_dr
   drv->name, dev->bus_id, ret);
}
  Done:
+   up(&dev->sem);
return ret;
 }
 
 static int __device_attach(struct device_driver * drv, void * data)
 {
struct device * dev = data;
-   return driver_probe_device(drv, dev);
+   int ret;
+
+   down(&drv->devlist_mutex);
+   ret = driver_probe_device(drv, dev);
+   up(&drv->devlist_mutex);
+
+   return ret;
 }
 
 /**
@@ -124,15 +145,21 @@ static int __device_attach(struct device
  */
 int device_attach(struct device * dev)
 {
-   int ret = 0;
+   int ret = 1;
+   struct device_driver * drv;
 
-   down(&dev