lkml.org 
[lkml]   [2005]   [Mar]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[8/9] [RFC] Steps to fixing the driver model locking

ChangeSet@1.2237, 2005-03-21 12:00:18-08:00, mochel@digitalimplant.org
[driver core] Add a klist to struct bus_type for its drivers.


- Use it in bus_for_each_drv().
- Use the klist spinlock instead of the bus rwsem.



Signed-off-by: Patrick Mochel <mochel@digitalimplant.org>

diff -Nru a/drivers/base/bus.c b/drivers/base/bus.c
--- a/drivers/base/bus.c 2005-03-21 12:30:27 -08:00
+++ b/drivers/base/bus.c 2005-03-21 12:30:27 -08:00
@@ -135,30 +135,6 @@
decl_subsys(bus, &ktype_bus, NULL);


-static int __bus_for_each_drv(struct bus_type *bus, struct device_driver *start,
- void * data, int (*fn)(struct device_driver *, void *))
-{
- struct list_head *head;
- struct device_driver *drv;
- int error = 0;
-
- if (!(bus = get_bus(bus)))
- return -EINVAL;
-
- head = &bus->drivers.list;
- drv = list_prepare_entry(start, head, kobj.entry);
- list_for_each_entry_continue(drv, head, kobj.entry) {
- get_driver(drv);
- error = fn(drv, data);
- put_driver(drv);
- if (error)
- break;
- }
- put_bus(bus);
- return error;
-}
-
-
static struct device * next_device(struct klist_iter * i)
{
struct klist_node * n = klist_next(i);
@@ -203,6 +179,14 @@
return error;
}

+
+
+static struct device_driver * next_driver(struct klist_iter * i)
+{
+ struct klist_node * n = klist_next(i);
+ return n ? container_of(n, struct device_driver, knode_bus) : NULL;
+}
+
/**
* bus_for_each_drv - driver iterator
* @bus: bus we're dealing with.
@@ -226,12 +210,19 @@
int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
void * data, int (*fn)(struct device_driver *, void *))
{
- int ret;
+ struct klist_iter i;
+ struct device_driver * drv;
+ int error = 0;

- down_read(&bus->subsys.rwsem);
- ret = __bus_for_each_drv(bus, start, data, fn);
- up_read(&bus->subsys.rwsem);
- return ret;
+ if (!bus)
+ return -EINVAL;
+
+ klist_iter_init_node(&bus->klist_drivers, &i,
+ start ? &start->knode_bus : NULL);
+ while ((drv = next_driver(&i)) && !error)
+ error = fn(drv, data);
+ klist_iter_exit(&i);
+ return error;
}


@@ -377,6 +368,7 @@
down_write(&bus->subsys.rwsem);
driver_attach(drv);
up_write(&bus->subsys.rwsem);
+ klist_add_tail(&bus->klist_drivers, &drv->knode_bus);
module_add_driver(drv->owner, drv);

driver_add_attrs(bus, drv);
@@ -398,6 +390,7 @@
{
if (drv->bus) {
driver_remove_attrs(drv->bus, drv);
+ klist_remove(&drv->knode_bus);
down_write(&drv->bus->subsys.rwsem);
pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name);
driver_detach(drv);
@@ -537,6 +530,7 @@
goto bus_drivers_fail;

klist_init(&bus->klist_devices);
+ klist_init(&bus->klist_drivers);
bus_add_attrs(bus);

pr_debug("bus type '%s' registered\n", bus->name);
diff -Nru a/include/linux/device.h b/include/linux/device.h
--- a/include/linux/device.h 2005-03-21 12:30:27 -08:00
+++ b/include/linux/device.h 2005-03-21 12:30:27 -08:00
@@ -54,6 +54,7 @@
struct kset drivers;
struct kset devices;
struct klist klist_devices;
+ struct klist klist_drivers;

struct bus_attribute * bus_attrs;
struct device_attribute * dev_attrs;
@@ -106,6 +107,7 @@
struct completion unloaded;
struct kobject kobj;
struct list_head devices;
+ struct klist_node knode_bus;

struct module * owner;

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
\
 
 \ /
  Last update: 2005-03-22 14:11    [W:0.047 / U:0.040 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site