Commit 66928d6c authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

[PATCH] kmap: remove usage of rwsem from kobj_map.

This forces the caller to provide the lock, but as they all already had one, it's not a big change.
It also removes the now-unneeded cdev_subsys.  Thanks to Jon Corbet for reminding me about that.
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 9ddbb23b
......@@ -25,7 +25,7 @@ struct kobj_map {
int (*lock)(dev_t, void *);
void *data;
} *probes[255];
struct rw_semaphore *sem;
struct semaphore *sem;
};
int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range,
......@@ -53,7 +53,7 @@ int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range,
p->range = range;
p->data = data;
}
down_write(domain->sem);
down(domain->sem);
for (i = 0, p -= n; i < n; i++, p++, index++) {
struct probe **s = &domain->probes[index % 255];
while (*s && (*s)->range < range)
......@@ -61,7 +61,7 @@ int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range,
p->next = *s;
*s = p;
}
up_write(domain->sem);
up(domain->sem);
return 0;
}
......@@ -75,7 +75,7 @@ void kobj_unmap(struct kobj_map *domain, dev_t dev, unsigned long range)
if (n > 255)
n = 255;
down_write(domain->sem);
down(domain->sem);
for (i = 0; i < n; i++, index++) {
struct probe **s;
for (s = &domain->probes[index % 255]; *s; s = &(*s)->next) {
......@@ -88,7 +88,7 @@ void kobj_unmap(struct kobj_map *domain, dev_t dev, unsigned long range)
}
}
}
up_write(domain->sem);
up(domain->sem);
kfree(found);
}
......@@ -99,7 +99,7 @@ struct kobject *kobj_lookup(struct kobj_map *domain, dev_t dev, int *index)
unsigned long best = ~0UL;
retry:
down_read(domain->sem);
down(domain->sem);
for (p = domain->probes[MAJOR(dev) % 255]; p; p = p->next) {
struct kobject *(*probe)(dev_t, int *, void *);
struct module *owner;
......@@ -120,7 +120,7 @@ struct kobject *kobj_lookup(struct kobj_map *domain, dev_t dev, int *index)
module_put(owner);
continue;
}
up_read(domain->sem);
up(domain->sem);
kobj = probe(dev, index, data);
/* Currently ->owner protects _only_ ->probe() itself. */
module_put(owner);
......@@ -128,12 +128,11 @@ struct kobject *kobj_lookup(struct kobj_map *domain, dev_t dev, int *index)
return kobj;
goto retry;
}
up_read(domain->sem);
up(domain->sem);
return NULL;
}
struct kobj_map *kobj_map_init(kobj_probe_t *base_probe,
struct subsystem *s)
struct kobj_map *kobj_map_init(kobj_probe_t *base_probe, struct semaphore *sem)
{
struct kobj_map *p = kmalloc(sizeof(struct kobj_map), GFP_KERNEL);
struct probe *base = kmalloc(sizeof(struct probe), GFP_KERNEL);
......@@ -151,6 +150,6 @@ struct kobj_map *kobj_map_init(kobj_probe_t *base_probe,
base->get = base_probe;
for (i = 0; i < 255; i++)
p->probes[i] = base;
p->sem = &s->rwsem;
p->sem = sem;
return p;
}
......@@ -302,7 +302,7 @@ static struct kobject *base_probe(dev_t dev, int *part, void *data)
static int __init genhd_device_init(void)
{
bdev_map = kobj_map_init(base_probe, &block_subsys);
bdev_map = kobj_map_init(base_probe, &block_subsys_sem);
blk_dev_init();
subsystem_register(&block_subsys);
return 0;
......
......@@ -29,7 +29,7 @@ static struct kobj_map *cdev_map;
/* degrade to linked list for small systems */
#define MAX_PROBE_HASH (CONFIG_BASE_SMALL ? 1 : 255)
static DEFINE_RWLOCK(chrdevs_lock);
static DECLARE_MUTEX(chrdevs_lock);
static struct char_device_struct {
struct char_device_struct *next;
......@@ -55,13 +55,13 @@ int get_chrdev_list(char *page)
len = sprintf(page, "Character devices:\n");
read_lock(&chrdevs_lock);
down(&chrdevs_lock);
for (i = 0; i < ARRAY_SIZE(chrdevs) ; i++) {
for (cd = chrdevs[i]; cd; cd = cd->next)
len += sprintf(page+len, "%3d %s\n",
cd->major, cd->name);
}
read_unlock(&chrdevs_lock);
up(&chrdevs_lock);
return len;
}
......@@ -91,7 +91,7 @@ __register_chrdev_region(unsigned int major, unsigned int baseminor,
memset(cd, 0, sizeof(struct char_device_struct));
write_lock_irq(&chrdevs_lock);
down(&chrdevs_lock);
/* temporary */
if (major == 0) {
......@@ -126,10 +126,10 @@ __register_chrdev_region(unsigned int major, unsigned int baseminor,
}
cd->next = *cp;
*cp = cd;
write_unlock_irq(&chrdevs_lock);
up(&chrdevs_lock);
return cd;
out:
write_unlock_irq(&chrdevs_lock);
up(&chrdevs_lock);
kfree(cd);
return ERR_PTR(ret);
}
......@@ -140,7 +140,7 @@ __unregister_chrdev_region(unsigned major, unsigned baseminor, int minorct)
struct char_device_struct *cd = NULL, **cp;
int i = major_to_index(major);
write_lock_irq(&chrdevs_lock);
up(&chrdevs_lock);
for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next)
if ((*cp)->major == major &&
(*cp)->baseminor == baseminor &&
......@@ -150,7 +150,7 @@ __unregister_chrdev_region(unsigned major, unsigned baseminor, int minorct)
cd = *cp;
*cp = cd->next;
}
write_unlock_irq(&chrdevs_lock);
up(&chrdevs_lock);
return cd;
}
......@@ -381,8 +381,6 @@ void cdev_del(struct cdev *p)
}
static decl_subsys(cdev, NULL, NULL);
static void cdev_default_release(struct kobject *kobj)
{
struct cdev *p = container_of(kobj, struct cdev, kobj);
......@@ -435,13 +433,7 @@ static struct kobject *base_probe(dev_t dev, int *part, void *data)
void __init chrdev_init(void)
{
/*
* Keep cdev_subsys around because (and only because) the kobj_map code
* depends on the rwsem it contains. We don't make it public in sysfs,
* however.
*/
subsystem_init(&cdev_subsys);
cdev_map = kobj_map_init(base_probe, &cdev_subsys);
cdev_map = kobj_map_init(base_probe, &chrdevs_lock);
}
......
......@@ -7,6 +7,6 @@ int kobj_map(struct kobj_map *, dev_t, unsigned long, struct module *,
kobj_probe_t *, int (*)(dev_t, void *), void *);
void kobj_unmap(struct kobj_map *, dev_t, unsigned long);
struct kobject *kobj_lookup(struct kobj_map *, dev_t, int *);
struct kobj_map *kobj_map_init(kobj_probe_t *, struct subsystem *);
struct kobj_map *kobj_map_init(kobj_probe_t *, struct semaphore *);
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment