From: Roman Zippel <zippel@linux-m68k.org>
To: Kai Germaschewski <kai@tp1.ruhr-uni-bochum.de>
Cc: Alexander Viro <viro@math.psu.edu>,
Linus Torvalds <torvalds@transmeta.com>,
Patrick Mochel <mochel@osdl.org>, <linux-kernel@vger.kernel.org>
Subject: Re: [bk/patch] driver model update: device_unregister()
Date: Thu, 10 Oct 2002 20:04:36 +0200 (CEST) [thread overview]
Message-ID: <Pine.LNX.4.44.0210100107410.338-100000@serv> (raw)
In-Reply-To: <Pine.LNX.4.44.0210091704040.5883-100000@chaos.physics.uiowa.edu>
Hi,
On Wed, 9 Oct 2002, Kai Germaschewski wrote:
> So at this point, you decide to rather not have the user wait
> forever until his "rmmod net_pci" succeeds, but return -EBUSY right away.
> You do it by running MOD_INC_USE_COUNT in ::open(), and DEC again in
> ::close().
You don't really want to do this. Imagine what happens if you get
preempted before you had a chance to run MOD_INC_USE_COUNT.
> The current implementation gives you a way of knowing if unloading will
> succeed shortly (if not, it'll fail with -EBUSY). Yours doesn't AFAICS,
> and that's actually bad IMO, I think you actually have to try to see if
> the unload would succeed, and that's not pretty.
The unload path could look something like this:
if (mod->usecount())
return -EBUSY;
mod->state = cleanup;
if (mod->exit())
return -EBUSY;
(free module)
So this does what you want. The only problem is here that the exit call
can fail, because there are still users, so the module will stay in the
cleanup state. start/stop functions would give you better control over
this.
> And, done right, the API for the current implementation is so simple that
> I doubt you'll be able to come up with something with more ease-of-use.
The current API just hides the complexity, but it requires extra checks
all over the kernel, to test if an object belongs to a module and if the
module is running. My proposal would get rid of this.
Deciding whether when you can release a device object or a driver object
is pretty much the same problem and a common solution is IMO prefered. The
module code should work like the remaining kernel and not require extra
care everywhere.
The diff below shows how filesystem.c would change, which becomes simpler
as it doesn't has to care about the module state anymore.
bye, Roman
Index: fs/filesystems.c
===================================================================
RCS file: /home/other/cvs/linux/linux-2.5/fs/filesystems.c,v
retrieving revision 1.1.1.5
diff -u -p -r1.1.1.5 filesystems.c
--- fs/filesystems.c 16 Apr 2002 08:45:18 -0000 1.1.1.5
+++ fs/filesystems.c 10 Oct 2002 15:23:46 -0000
@@ -28,17 +28,17 @@
static struct file_system_type *file_systems;
static rwlock_t file_systems_lock = RW_LOCK_UNLOCKED;
-/* WARNING: This can be used only if we _already_ own a reference */
+/* WARNING: This can be used only if we _already_ own a reference
+ * or hold the file_systems_lock
+ */
void get_filesystem(struct file_system_type *fs)
{
- if (fs->owner)
- __MOD_INC_USE_COUNT(fs->owner);
+ atomic_inc(&fs->refcnt);
}
void put_filesystem(struct file_system_type *fs)
{
- if (fs->owner)
- __MOD_DEC_USE_COUNT(fs->owner);
+ atomic_dec(&fs->refcnt);
}
static struct file_system_type **find_filesystem(const char *name)
@@ -77,8 +77,10 @@ int register_filesystem(struct file_syst
p = find_filesystem(fs->name);
if (*p)
res = -EBUSY;
- else
+ else {
*p = fs;
+ get_filesystem(fs);
+ }
write_unlock(&file_systems_lock);
return res;
}
@@ -103,15 +105,15 @@ int unregister_filesystem(struct file_sy
tmp = &file_systems;
while (*tmp) {
if (fs == *tmp) {
+ put_filesystem(fs);
*tmp = fs->next;
fs->next = NULL;
- write_unlock(&file_systems_lock);
- return 0;
+ break;
}
tmp = &(*tmp)->next;
}
write_unlock(&file_systems_lock);
- return -EINVAL;
+ return atomic_read(&fs->refcnt) > 0 ? -EBUSY : 0;
}
static int fs_index(const char * __name)
@@ -145,8 +147,10 @@ static int fs_name(unsigned int index, c
read_lock(&file_systems_lock);
for (tmp = file_systems; tmp; tmp = tmp->next, index--)
- if (index <= 0 && try_inc_mod_count(tmp->owner))
- break;
+ if (index <= 0) {
+ get_filesystem(tmp)
+ break;
+ }
read_unlock(&file_systems_lock);
if (!tmp)
return -EINVAL;
@@ -216,14 +220,14 @@ struct file_system_type *get_fs_type(con
read_lock(&file_systems_lock);
fs = *(find_filesystem(name));
- if (fs && !try_inc_mod_count(fs->owner))
- fs = NULL;
+ if (fs)
+ get_filesystem(fs);
read_unlock(&file_systems_lock);
if (!fs && (request_module(name) == 0)) {
read_lock(&file_systems_lock);
fs = *(find_filesystem(name));
- if (fs && !try_inc_mod_count(fs->owner))
- fs = NULL;
+ if (fs)
+ put_filesystem(fs);
read_unlock(&file_systems_lock);
}
return fs;
next prev parent reply other threads:[~2002-10-10 17:59 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-10-09 0:57 Patrick Mochel
2002-10-09 0:57 ` Patrick Mochel
2002-10-09 0:57 ` Patrick Mochel
2002-10-09 0:57 ` Patrick Mochel
2002-10-09 1:04 ` Alexander Viro
2002-10-09 16:38 ` Patrick Mochel
2002-10-09 17:14 ` Linus Torvalds
2002-10-09 17:24 ` Patrick Mochel
2002-10-09 17:26 ` Patrick Mochel
2002-10-09 17:41 ` Linus Torvalds
2002-10-09 17:46 ` Patrick Mochel
2002-10-09 17:50 ` Linus Torvalds
2002-10-10 21:19 ` Rob Landley
2002-10-09 18:01 ` Jeff Muizlelaar
2002-10-09 17:33 ` Alexander Viro
2002-10-09 17:45 ` Linus Torvalds
2002-10-09 17:47 ` Alexander Viro
2002-10-09 17:55 ` Linus Torvalds
2002-10-09 18:00 ` Alexander Viro
2002-10-09 18:47 ` Linus Torvalds
2002-10-09 19:02 ` Alexander Viro
2002-10-09 19:16 ` Linus Torvalds
2002-10-09 19:26 ` Alexander Viro
2002-10-09 19:47 ` Linus Torvalds
2002-10-09 20:11 ` Alexander Viro
2002-10-09 21:45 ` Roman Zippel
2002-10-09 22:31 ` Kai Germaschewski
2002-10-10 18:04 ` Roman Zippel [this message]
2002-10-10 18:49 ` Kai Germaschewski
2002-10-11 13:48 ` Roman Zippel
2002-10-09 23:49 ` Patrick Mochel
2002-10-10 7:11 ` Mike Anderson
2002-10-09 20:42 ` Andries Brouwer
2002-10-15 22:18 ` Daniel Phillips
2002-10-09 18:02 ` Patrick Mochel
2002-10-09 18:04 ` Alexander Viro
2002-10-09 0:57 ` Patrick Mochel
[not found] <Pine.LNX.4.44.0210111725240.14124-100000@chaos.physics.uiowa.edu>
2002-10-12 0:47 ` Roman Zippel
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=Pine.LNX.4.44.0210100107410.338-100000@serv \
--to=zippel@linux-m68k.org \
--cc=kai@tp1.ruhr-uni-bochum.de \
--cc=linux-kernel@vger.kernel.org \
--cc=mochel@osdl.org \
--cc=torvalds@transmeta.com \
--cc=viro@math.psu.edu \
/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
all inboxes | Powered by JetHome®