From: Keith Owens <kaos@ocs.com.au>
To: David Woodhouse <dwmw2@infradead.org>
Cc: mtd@infradead.org, alan@lxorguk.ukuu.org.uk
Subject: Re: s/get_module_symbol/inter_module_xxx/ in MTD CVS.
Date: Tue, 14 Nov 2000 00:18:04 +1100 [thread overview]
Message-ID: <5017.974121484@ocs3.ocs-net> (raw)
In-Reply-To: Your message of "Mon, 13 Nov 2000 11:18:34 -0000." <18197.974114314@redhat.com>
On Mon, 13 Nov 2000 11:18:34 +0000,
David Woodhouse <dwmw2@infradead.org> wrote:
>kaos@ocs.com.au said:
>> I almost have it done, adding inter_module_xxx but keeping the old
>> get/put_module_symbol interfaces. I am not patching any code to use
>> inter_module_xxx, just making the interface available for 2.2/2.4
>> compatibility.
>
>You say 'keeping the old get/put...' but 2.2 didn't actually have
>put_module_symbol(). The patch to make it get_module_symbol() increase the
>use count was never included. Did you add put_module_symbol() or was this a
>typo?
2.4 thinking. No change to get_module_symbol, no addition of
put_module_symbol. Bug for bug compliant with existing 2.2 kernels.
Patch against 2.2.18-pre21.
Index: 18-pre21.1/kernel/module.c
--- 18-pre21.1/kernel/module.c Fri, 05 May 2000 00:28:16 +1000 kaos (linux-2.2/h/18_module.c 1.1.9.1 644)
+++ 18-pre21.1(w)/kernel/module.c Mon, 13 Nov 2000 22:29:46 +1100 kaos (linux-2.2/h/18_module.c 1.1.9.1 644)
@@ -6,6 +6,8 @@
#include <linux/smp_lock.h>
#include <asm/pgtable.h>
#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/kmod.h>
/*
* Originally by Anonymous (as far as I know...)
@@ -14,11 +16,12 @@
* Heavily modified by Bjorn Ekwall <bj0rn@blox.se> May 1994 (C)
* Rewritten by Richard Henderson <rth@tamu.edu> Dec 1996
* Add MOD_INITIALIZING Keith Owens <kaos@ocs.com.au> Nov 1999
+ * Backport inter_module_xxx from 2.4. Keith Owens <kaos@ocs.com.au> Oct 2000
*
* This source is covered by the GNU GPL, the same as all kernel sources.
*/
-#ifdef CONFIG_MODULES /* a *big* #ifdef block... */
+#ifdef CONFIG_MODULES
extern struct module_symbol __start___ksymtab[];
extern struct module_symbol __stop___ksymtab[];
@@ -47,6 +50,173 @@ static struct module kernel_module =
};
struct module *module_list = &kernel_module;
+
+#endif /* CONFIG_MODULES */
+
+/* inter_module functions are always available, even when the kernel is
+ * compiled without modules. Consumers of inter_module_xxx routines
+ * will always work, even when both are built into the kernel, this
+ * approach removes lots of #ifdefs in mainline code.
+ */
+
+static struct list_head ime_list = LIST_HEAD_INIT(ime_list);
+static spinlock_t ime_lock = SPIN_LOCK_UNLOCKED;
+static int kmalloc_failed;
+
+/**
+ * inter_module_register - register a new set of inter module data.
+ * @im_name: an arbitrary string to identify the data, must be unique
+ * @owner: module that is registering the data, always use THIS_MODULE
+ * @userdata: pointer to arbitrary userdata to be registered
+ *
+ * Description: Check that the im_name has not already been registered,
+ * complain if it has. For new data, add it to the inter_module_entry
+ * list.
+ */
+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))) {
+ /* Overloaded kernel, not fatal */
+ printk(KERN_ERR
+ "Aiee, inter_module_register: cannot kmalloc entry for '%s'\n",
+ im_name);
+ kmalloc_failed = 1;
+ return;
+ }
+ memset(ime_new, 0, sizeof(*ime_new));
+ ime_new->im_name = im_name;
+ 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);
+ if (strcmp(ime->im_name, im_name) == 0) {
+ spin_unlock(&ime_lock);
+ kfree(ime_new);
+ /* Program logic error, fatal */
+ panic("inter_module_register: duplicate im_name '%s'", im_name);
+ }
+ }
+ list_add(&(ime_new->list), &ime_list);
+ spin_unlock(&ime_lock);
+}
+
+/**
+ * inter_module_unregister - unregister a set of inter module data.
+ * @im_name: an arbitrary string to identify the data, must be unique
+ *
+ * Description: Check that the im_name has been registered, complain if
+ * it has not. For existing data, remove it from the
+ * inter_module_entry list.
+ */
+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);
+ if (strcmp(ime->im_name, im_name) == 0) {
+ list_del(&(ime->list));
+ spin_unlock(&ime_lock);
+ kfree(ime);
+ return;
+ }
+ }
+ spin_unlock(&ime_lock);
+ if (kmalloc_failed) {
+ printk(KERN_ERR
+ "inter_module_unregister: no entry for '%s', "
+ "probably caused by previous kmalloc failure\n",
+ im_name);
+ return;
+ }
+ else {
+ /* Program logic error, fatal */
+ panic("inter_module_unregister: no entry for '%s'", im_name);
+ }
+}
+
+/**
+ * inter_module_get - return arbitrary userdata from another module.
+ * @im_name: an arbitrary string to identify the data, must be unique
+ *
+ * Description: If the im_name has not been registered, return NULL.
+ * Try to increment the use count on the owning module, if that fails
+ * then return NULL. Otherwise return the userdata.
+ */
+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);
+ if (strcmp(ime->im_name, im_name) == 0) {
+ /* This should be try_inc_use_count but that function is
+ * not in 2.2 kernels. I am not opening that can of worms
+ * for 2.2. Keith Owens
+ */
+ __MOD_INC_USE_COUNT(ime->owner);
+ result = ime->userdata;
+ break;
+ }
+ }
+ spin_unlock(&ime_lock);
+ return(result);
+}
+
+/**
+ * inter_module_get_request - im get with automatic request_module.
+ * @im_name: an arbitrary string to identify the data, must be unique
+ * @modname: module that is expected to register im_name
+ *
+ * Description: If inter_module_get fails, do request_module then retry.
+ */
+const void *inter_module_get_request(const char *im_name, const char *modname)
+{
+ const void *result = inter_module_get(im_name);
+ if (!result) {
+ request_module(modname);
+ result = inter_module_get(im_name);
+ }
+ return(result);
+}
+
+/**
+ * inter_module_put - release use of data from another module.
+ * @im_name: an arbitrary string to identify the data, must be unique
+ *
+ * Description: If the im_name has not been registered, complain,
+ * otherwise decrement the use count on the owning module.
+ */
+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);
+ if (strcmp(ime->im_name, im_name) == 0) {
+ if (ime->owner)
+ __MOD_DEC_USE_COUNT(ime->owner);
+ spin_unlock(&ime_lock);
+ return;
+ }
+ }
+ spin_unlock(&ime_lock);
+ panic("inter_module_put: no entry for '%s'", im_name);
+}
+
+#if defined(CONFIG_MODULES) /* The rest of the source */
static long get_mod_name(const char *user_name, char **buf);
static void put_mod_name(char *buf);
Index: 18-pre21.1/kernel/ksyms.c
--- 18-pre21.1/kernel/ksyms.c Wed, 08 Nov 2000 11:39:15 +1100 kaos (linux-2.2/h/19_ksyms.c 1.2.1.3.3.1.3.1.1.1.1.5.1.2 644)
+++ 18-pre21.1(w)/kernel/ksyms.c Mon, 13 Nov 2000 22:19:34 +1100 kaos (linux-2.2/h/19_ksyms.c 1.2.1.3.3.1.3.1.1.1.1.5.1.2 644)
@@ -82,6 +82,11 @@ EXPORT_SYMBOL(hotplug_path);
#ifdef CONFIG_MODULES
EXPORT_SYMBOL(get_module_symbol);
#endif
+EXPORT_SYMBOL(inter_module_register);
+EXPORT_SYMBOL(inter_module_unregister);
+EXPORT_SYMBOL(inter_module_get);
+EXPORT_SYMBOL(inter_module_get_request);
+EXPORT_SYMBOL(inter_module_put);
EXPORT_SYMBOL(get_options);
/* process memory management */
Index: 18-pre21.1/include/linux/module.h
--- 18-pre21.1/include/linux/module.h Tue, 12 Sep 2000 13:37:17 +1100 kaos (linux-2.2/F/51_module.h 1.1.7.2 644)
+++ 18-pre21.1(w)/include/linux/module.h Tue, 14 Nov 2000 00:04:33 +1100 kaos (linux-2.2/F/51_module.h 1.1.7.2 644)
@@ -8,6 +8,7 @@
#define _LINUX_MODULE_H
#include <linux/config.h>
+#include <linux/list.h>
#ifdef __GENKSYMS__
# define _set_ver(sym) sym
@@ -140,6 +141,35 @@ struct module_info
#define __MODULE_STRING_1(x) #x
#define __MODULE_STRING(x) __MODULE_STRING_1(x)
+
+/* Generic inter module communication.
+ *
+ * NOTE: This interface is intended for small amounts of data that are
+ * passed between two objects and either or both of the objects
+ * might be compiled as modules. Do not over use this interface.
+ *
+ * If more than two objects need to communicate then you probably
+ * need a specific interface instead of abusing this generic
+ * interface. If both objects are *always* built into the kernel
+ * then a global extern variable is good enough, you do not need
+ * this interface.
+ *
+ * Keith Owens <kaos@ocs.com.au> 28 Oct 2000.
+ */
+
+#define HAVE_INTER_MODULE
+extern void inter_module_register(const char *, struct module *, const void *);
+extern void inter_module_unregister(const char *);
+extern const void *inter_module_get(const char *);
+extern const void *inter_module_get_request(const char *, const char *);
+extern void inter_module_put(const char *);
+
+struct inter_module_entry {
+ struct list_head list;
+ const char *im_name;
+ struct module *owner;
+ const void *userdata;
+};
/* Find a symbol exported by the kernel or another module */
#ifndef CONFIG_MODULES
Index: 18-pre21.1/Makefile
--- 18-pre21.1/Makefile Fri, 10 Nov 2000 22:07:33 +1100 kaos (linux-2.2/G/b/14_Makefile 1.3.2.2.1.1.1.5.1.3.6.1.5.1.1.1.1.16.1.6 644)
+++ 18-pre21.1(w)/Makefile Tue, 14 Nov 2000 00:13:18 +1100 kaos (linux-2.2/G/b/14_Makefile 1.3.2.2.1.1.1.5.1.3.6.1.5.1.1.1.1.16.1.6 644)
@@ -241,7 +241,7 @@ vmlinux: $(CONFIGURATION) init/main.o in
$(LIBS) \
--end-group \
-o vmlinux
- $(NM) vmlinux | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aU] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System.map
+ $(NM) vmlinux | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System.map
symlinks:
rm -f include/asm
To unsubscribe, send "unsubscribe mtd" to majordomo@infradead.org
next prev parent reply other threads:[~2000-11-13 13:18 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2000-11-13 11:06 s/get_module_symbol/inter_module_xxx/ in MTD CVS David Woodhouse
2000-11-13 11:12 ` Keith Owens
2000-11-13 11:18 ` David Woodhouse
2000-11-13 13:18 ` Keith Owens [this message]
2000-11-16 13:21 ` Alan Cox
2000-11-16 20:20 ` Keith Owens
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5017.974121484@ocs3.ocs-net \
--to=kaos@ocs.com.au \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=dwmw2@infradead.org \
--cc=mtd@infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.