RCU in kernel/intermodule.c
PATCH 1/1 RCU in kernel/intermodule.c
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
This patch, compiled against version 2.6.12-rc1, implements RCU mechanism in intermodule functions.
- --- ./kernel/intermodule.c.orig 2005-04-01 19:25:26.000000000 +0000
+++ ./kernel/intermodule.c 2005-04-02 02:46:22.000000000 +0000
@@ -3,7 +3,7 @@
/* Written by Keith Owens <[email protected]> Oct 2000 */ #include <linux/module.h>
#include <linux/kmod.h>
- -#include <linux/spinlock.h>
+#include <linux/rcupdate.h>
#include <linux/list.h>
#include <linux/slab.h>
@@ -14,7 +14,6 @@
*/
static struct list_head ime_list = LIST_HEAD_INIT(ime_list);
- -static DEFINE_SPINLOCK(ime_lock);
static int kmalloc_failed;
struct inter_module_entry {
@@ -22,8 +21,17 @@ struct inter_module_entry {
const char *im_name;
struct module *owner;
const void *userdata;
+ struct rcu_head rcu;
};
+static void inter_module_free(struct rcu_head *rcu)
+{
+ struct inter_module_entry *ime;
+
+ ime = container_of(rcu, struct inter_module_entry, rcu);
+ kfree(ime);
+}
+
/**
* inter_module_register - register a new set of inter module data.
* @im_name: an arbitrary string to identify the data, must be unique
@@ -36,7 +44,6 @@ struct inter_module_entry {
*/
void inter_module_register(const char *im_name, struct module *owner, const
void *userdata)
{
- - struct list_head *tmp;
struct inter_module_entry *ime, *ime_new;
if (!(ime_new = kmalloc(sizeof(*ime), GFP_KERNEL))) {
@@ -52,19 +59,15 @@ void inter_module_register(const char *i
ime_new->owner = owner;
ime_new->userdata = userdata;
- - spin_lock(&ime_lock);
- - list_for_each(tmp, &ime_list) {
- - ime = list_entry(tmp, struct inter_module_entry, list);
+ list_for_each_entry(ime, &ime_list, list) {
if (strcmp(ime->im_name, im_name) == 0) {
- - spin_unlock(&ime_lock);
kfree(ime_new);
/* Program logic error, fatal */
printk(KERN_ERR "inter_module_register: duplicate im_name '%s'", im_name); BUG();
}
}
- - list_add(&(ime_new->list), &ime_list);
- - spin_unlock(&ime_lock);
+ list_add_rcu(&ime_new->list, &ime_list);
}
/**
@@ -77,20 +80,15 @@ void inter_module_register(const char *i
*/
void inter_module_unregister(const char *im_name) {
- - struct list_head *tmp;
struct inter_module_entry *ime;
- - spin_lock(&ime_lock);
- - list_for_each(tmp, &ime_list) {
- - ime = list_entry(tmp, struct inter_module_entry, list);
+ list_for_each_entry(ime, &ime_list, list) {
if (strcmp(ime->im_name, im_name) == 0) {
- - list_del(&(ime->list));
- - spin_unlock(&ime_lock);
- - kfree(ime);
+ list_del_rcu(&(ime->list));
+ call_rcu(&ime->rcu, inter_module_free);
return;
}
}
- - spin_unlock(&ime_lock);
if (kmalloc_failed) {
printk(KERN_ERR
"inter_module_unregister: no entry for '%s', "
@@ -115,20 +113,18 @@ void inter_module_unregister(const char
*/
static const void *inter_module_get(const char *im_name)
{
- - struct list_head *tmp;
struct inter_module_entry *ime;
const void *result = NULL;
- - spin_lock(&ime_lock);
- - list_for_each(tmp, &ime_list) {
- - ime = list_entry(tmp, struct inter_module_entry, list);
+ rcu_read_lock();
+ list_for_each_entry_rcu(ime, &ime_list, list) {
if (strcmp(ime->im_name, im_name) == 0) {
if (try_module_get(ime->owner))
result = ime->userdata;
break;
}
}
- - spin_unlock(&ime_lock);
+ rcu_read_unlock();
return(result);
}
@@ -158,20 +154,18 @@ const void *inter_module_get_request(con
*/
void inter_module_put(const char *im_name)
{
- - struct list_head *tmp;
struct inter_module_entry *ime;
- - spin_lock(&ime_lock);
- - list_for_each(tmp, &ime_list) {
- - ime = list_entry(tmp, struct inter_module_entry, list);
+ rcu_read_lock();
+ list_for_each_entry(ime, &ime_list, list) {
if (strcmp(ime->im_name, im_name) == 0) {
if (ime->owner)
module_put(ime->owner);
- - spin_unlock(&ime_lock);
+ rcu_read_unlock();
return;
}
}
- - spin_unlock(&ime_lock);
+ rcu_read_unlock();
printk(KERN_ERR "inter_module_put: no entry for '%s'", im_name); BUG();
}
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
iQEVAwUBQk6BzMzkDT3RfMB6AQI+BggAu476KZ3UOURm+IOBJyFnrtpaC9OgA2/c 5Q5A3Rvl0RZkuv3xCZino9eMNOqhC7HOSbvS7OfOwuhSe6my8F2eSImQb8H0rGCa T1TGa5FdO0IDDlX0pDkFX5h2fv9bcoyCMlWC2UI8c9x12jpWaU/rBQASBn+Wg58F aeszrjaRWrXuXU47y6FucWbegc0X2eU7b+1sPMCRlA9X3f6agCOcgrmpZdjyrJm3 0Q5IpEW3AR/Aicbe4+n1mIj5LOahSQNU+lFq/yNgaNKPpOfBc9+dgyfpVAt2jSb/ UEC2PWqLcVFar+JSTbI6EYDyasb4dfFQtds/pIXo1POh6rAPboTiXA== =Rm4E
-----END PGP SIGNATURE-----
Quoted 5 lines · Luca Falavigna
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1This patch, compiled against version 2.6.12-rc1, implements RCU mechanism in intermodule functions.
There's no point as these functions are going to go away soon.
Review line 6
Quoted 8 lines · Luca Falavigna
-----BEGIN PGP SIGNED MESSAGE-----
- ---./kernel/intermodule.c.orig2005-04-01 19:25:26.000000000 +0000
+++./kernel/intermodule.c2005-04-02 02:46:22.000000000 +0000(quoted diff) +0
-1@@ -3,7 +3,7 @@ /* Written by Keith Owens <[email protected]> Oct 2000 */ #include <linux/module.h> #include <linux/kmod.h> - -#include <linux/spinlock.h>
^ Ugh, mangled patch
Review line 8
Quoted 3 lines
(quoted diff) +1
-0+#include <linux/rcupdate.h> #include <linux/list.h> #include <linux/slab.h>
Please don't sign patches with PGP, it mangles them and makes them much harder to apply.
Also, the intermodule stuff is slated for removal, as soon as MTD and such are fixed; the interface has been deprecated for a while.
Cheers,
Kyle Moffett
-----BEGIN GEEK CODE BLOCK-----
Version: 3.12
GCM/CS/IT/U d- s++: a18 C++++>$ UB/L/X/*++++(+)>$ P+++(++++)>$ L++++(+++) E W++(+) N+++(++) o? K? w--- O? M++ V? PS+() PE+(-) Y+ PGP+++ t+(+++) 5 X R? tv-(--) b++++(++) DI+ D+ G e->++++$ h!*()>++$ r !y?(-) ------END GEEK CODE BLOCK------
Quoted 2 lines · Kyle Moffett
Also, the intermodule stuff is slated for removal, as soon as MTD and such are fixed; the interface has been deprecated for a while.
Actually 'just' mtd now iirc. agpgart was the penultimate user which got fixed a few months back.
Dave