[PATCH] RCU in kernel/intermodule.c

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

This patch, compiled against version 2.6.12-rc1, implements RCU mechanism in
intermodule functions.



Signed-off-by: Luca Falavigna <[email protected]>

- --- ./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-----

-
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/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux