Re: [patch] Real-Time Preemption, -RT-2.6.10-rc2-mm1-V0.7.28-1

From: Ingo Molnar
Date: Thu Nov 18 2004 - 15:10:44 EST



* Rui Nuno Capela <rncbc@xxxxxxxxx> wrote:

> I'm still seeing this sometimes (not everytime) on my P4/UP laptop
> while shutting down ALSA modules. This isn't the same as the lockup
> I've been reporting lately (that happens on my P4/SMT desktop) but may
> be remotely related.

could you (and Christian) try the patch below, ontop of a current-ish
tree - does the unload crash still occur? (this is an earlier cleanup
patch from Thomas Gleixner, but it could fix a real PREEMPT_RT bug in
this particular case.)

Ingo

--- linux/drivers/base/driver.c.orig
+++ linux/drivers/base/driver.c
@@ -79,14 +79,13 @@ void put_driver(struct device_driver * d
* since most of the things we have to do deal with the bus
* structures.
*
- * The one interesting aspect is that we initialize @drv->unload_sem
- * to a locked state here. It will be unlocked when the driver
- * reference count reaches 0.
+ * We init the completion strcut here. When the reference
+ * count reaches zero, complete() is called from bus_release().
*/
int driver_register(struct device_driver * drv)
{
INIT_LIST_HEAD(&drv->devices);
- init_MUTEX_LOCKED(&drv->unload_sem);
+ init_completion(&drv->unload_done);
return bus_add_driver(drv);
}

@@ -97,18 +96,16 @@ int driver_register(struct device_driver
*
* Again, we pass off most of the work to the bus-level call.
*
- * Though, once that is done, we attempt to take @drv->unload_sem.
- * This will block until the driver refcount reaches 0, and it is
- * released. Only modular drivers will call this function, and we
+ * Though, once that is done, we wait until the driver refcount
+ * reaches 0, and complete() is called in bus_release().
+ * Only modular drivers will call this function, and we
* have to guarantee that it won't complete, letting the driver
* unload until all references are gone.
*/
-
void driver_unregister(struct device_driver * drv)
{
bus_remove_driver(drv);
- down(&drv->unload_sem);
- up(&drv->unload_sem);
+ wait_for_completion(&drv->unload_done);
}

/**
--- linux/drivers/base/bus.c.orig
+++ linux/drivers/base/bus.c
@@ -65,7 +65,7 @@ static struct sysfs_ops driver_sysfs_ops
static void driver_release(struct kobject * kobj)
{
struct device_driver * drv = to_driver(kobj);
- up(&drv->unload_sem);
+ complete(&drv->unload_done);
}

static struct kobj_type ktype_driver = {
--- linux/include/linux/device.h.orig
+++ linux/include/linux/device.h
@@ -102,7 +102,7 @@ struct device_driver {
char * name;
struct bus_type * bus;

- struct semaphore unload_sem;
+ struct completion unload_done;
struct kobject kobj;
struct list_head devices;

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