From: Greg KH <greg@kroah.com>
To: rusty@rustcorp.com.au
Cc: linux-kernel@vger.kernel.org
Subject: [RFC] add kobject to struct module
Date: Tue, 9 Sep 2003 15:24:21 -0700 [thread overview]
Message-ID: <20030909222421.GA7703@kroah.com> (raw)
Hi,
A while ago we had talked about adding a kobject to struct module. By
doing this we add support for module paramaters and other module info to
be exported in sysfs. So here's a patch that does this that is against
2.6.0-test4 (it applies with some fuzz, sorry.)
This patch adds basic kobject support to struct module, and it creates a
/sys/module directory which contains all of the individual modules.
Each module currently exports only one file, the module refcount:
$ tree /sys/module/
/sys/module/
|-- ehci_hcd
| `-- refcount
|-- hid
| `-- refcount
|-- parport
| `-- refcount
|-- parport_pc
| `-- refcount
|-- uhci_hcd
| `-- refcount
`-- usbcore
`-- refcount
I used the kobject reference count to add to the module reference count
to handle races if a user has a module owned sysfs file open, but this
reference is not exported to userspace, as that just confuses the
userspace tools a bunch (and I don't want to force people to upgrade
module-init-tools this late in the development cycle...)
Rusty, any comments? If this looks sane, I'll work on adding the
module_paramater support to the individual module directories.
thanks,
greg k-h
# Module: Add a kobject to struct module
#
# This gets us /sys/module to show all modules.
# Module attributes will happen next.
diff -Nru a/include/linux/module.h b/include/linux/module.h
--- a/include/linux/module.h Tue Sep 9 14:58:58 2003
+++ b/include/linux/module.h Tue Sep 9 14:58:58 2003
@@ -16,6 +16,7 @@
#include <linux/kmod.h>
#include <linux/elf.h>
#include <linux/stringify.h>
+#include <linux/kobject.h>
#include <asm/local.h>
#include <asm/module.h>
@@ -184,6 +185,8 @@
struct module
{
+ struct kobject kobj;
+
enum module_state state;
/* Member of list of modules */
diff -Nru a/kernel/module.c b/kernel/module.c
--- a/kernel/module.c Tue Sep 9 14:58:58 2003
+++ b/kernel/module.c Tue Sep 9 14:58:58 2003
@@ -613,6 +613,7 @@
for (i = 0; i < NR_CPUS; i++)
total += local_read(&mod->ref[i].count);
+ total += atomic_read(&mod->kobj.refcount);
return total;
}
EXPORT_SYMBOL(module_refcount);
@@ -656,6 +657,8 @@
down(&module_mutex);
}
+static void mod_kobject_remove(struct module *mod);
+
asmlinkage long
sys_delete_module(const char __user *name_user, unsigned int flags)
{
@@ -704,6 +707,10 @@
goto out;
}
}
+
+ /* unregister the kobject in this module */
+ mod_kobject_remove(mod);
+
/* Stop the machine so refcounts can't move: irqs disabled. */
DEBUGP("Stopping refcounts...\n");
ret = stop_refcounts();
@@ -743,7 +750,7 @@
struct module_use *use;
int printed_something = 0;
- seq_printf(m, " %u ", module_refcount(mod));
+ seq_printf(m, " %u ", module_refcount(mod) - atomic_read(&mod->kobj.refcount));
/* Always include a trailing , so userspace can differentiate
between this and the old multi-field proc format. */
@@ -1753,6 +1760,85 @@
else return ptr;
}
+/* sysfs stuff */
+struct module_attribute {
+ struct attribute attr;
+ ssize_t (*show)(struct module *mod, char *);
+ ssize_t (*store)(struct module *mod, const char *, size_t);
+};
+#define to_module_attr(n) container_of(n, struct module_attribute, attr);
+#define to_module(n) container_of(n, struct module, kobj)
+
+static ssize_t module_attr_show(struct kobject *kobj, struct attribute *attr, char *buf)
+{
+ struct module *slot = to_module(kobj);
+ struct module_attribute *attribute = to_module_attr(attr);
+ return attribute->show ? attribute->show(slot, buf) : 0;
+}
+
+static ssize_t module_attr_store(struct kobject *kobj, struct attribute *attr, const char *buf, size_t len)
+{
+ struct module *slot = to_module(kobj);
+ struct module_attribute *attribute = to_module_attr(attr);
+ return attribute->store ? attribute->store(slot, buf, len) : 0;
+}
+
+static struct sysfs_ops module_sysfs_ops = {
+ .show = module_attr_show,
+ .store = module_attr_store,
+};
+
+/* Huh? A release() function that doesn't do anything?
+ * This is here only because a module has another reference count that
+ * it uses to determine if it should be cleaned up or not. If the
+ * module wants to switch over to use the kobject reference instead of
+ * its own, then this release function needs to do some work.
+ */
+static void module_release(struct kobject *kobj)
+{
+}
+
+static struct kobj_type module_ktype = {
+ .sysfs_ops = &module_sysfs_ops,
+ .release = &module_release,
+};
+static decl_subsys(module, &module_ktype, NULL);
+
+static int __init module_subsys_init(void)
+{
+ return subsystem_register(&module_subsys);
+}
+core_initcall(module_subsys_init);
+
+static ssize_t show_mod_refcount(struct module *mod, char *buf)
+{
+ return sprintf(buf, "%d\n", module_refcount(mod) - atomic_read(&mod->kobj.refcount));
+}
+
+static struct module_attribute mod_refcount = {
+ .attr = {.name = "refcount", .mode = S_IRUGO},
+ .show = show_mod_refcount,
+};
+
+static int mod_kobject_init(struct module *mod)
+{
+ int retval;
+
+ memset(&mod->kobj, 0x00, sizeof(struct kobject));
+ kobject_set_name(&mod->kobj, mod->name);
+ kobj_set_kset_s(mod, module_subsys);
+ retval = kobject_register(&mod->kobj);
+ if (!retval)
+ retval = sysfs_create_file(&mod->kobj, &mod_refcount.attr);
+ return retval;
+}
+
+static void mod_kobject_remove(struct module *mod)
+{
+ sysfs_remove_file(&mod->kobj, &mod_refcount.attr);
+ kobject_unregister(&mod->kobj);
+}
+
/* This is where the real work happens */
asmlinkage long
sys_init_module(void __user *umod,
@@ -1816,6 +1902,8 @@
}
return ret;
}
+
+ mod_kobject_init(mod);
/* Now it's a first class citizen! */
down(&module_mutex);
next reply other threads:[~2003-09-09 22:24 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-09-09 22:24 Greg KH [this message]
2003-09-10 0:13 ` [RFC] add kobject to struct module Greg KH
2003-09-10 3:31 ` Rusty Russell
2003-09-10 4:11 ` Greg KH
2003-09-10 8:07 ` Rusty Russell
2003-09-10 15:26 ` Patrick Mochel
2003-09-11 1:13 ` Rusty Russell
2003-09-11 6:26 ` Greg KH
2003-09-11 8:18 ` Rusty Russell
2003-09-11 17:15 ` Greg KH
2004-02-24 23:29 ` Greg KH
2004-03-05 14:34 ` Rusty Russell
2004-05-07 21:28 ` Greg KH
2003-09-10 23:06 ` Greg KH
2003-09-11 2:33 ` Rusty Russell
2003-09-10 23:32 ` Russell King
2003-09-10 23:45 ` Greg KH
2003-09-11 0:04 ` Mike Fedyk
2003-09-11 0:21 ` Greg KH
2003-09-11 2:10 ` Rusty Russell
2003-09-11 2:04 ` Rusty Russell
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=20030909222421.GA7703@kroah.com \
--to=greg@kroah.com \
--cc=linux-kernel@vger.kernel.org \
--cc=rusty@rustcorp.com.au \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).