lkml.org 
[lkml]   [1998]   [Feb]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: sound <-> kerneld
On Thu, Feb 05, 1998 at 10:29:34AM +0000, Alan Cox wrote:
> > 1. access the sound driver.. in my case "sb" is loaded, which depends
> > on sound, which is loaded and registers the device.
> > 2. one minute after this '(if not using the device), kerneld tries
> > to unload modules automatically, i.e. sb in this case, since
> > it's unused (sound itself, though, is used)
> > 3. now everybody (non-root) has to wait for another minute until
> > sound itself get's unloaded, no sound operation is possible.
>
> Thats interesting. Thats really a kerneld flaw. It should be figuring
> it out it partially unloaded a module set and restore the rest. Equally
> it can't do that as it wont see the next request.

Attached is a kernel patch that fixes this deficiency.

In addition, I've got a new version of modutils to release that,
among other things does closure on aliases so that `alias sound sb'
actually works right. But ftp.redhat.com doesn't seem to be
responding this evening, so it is currently living at

ftp://ftp.cygnus.com/pub/home/rth/modutils-2.1.85.tar.gz

Expect it to migrate to the usual locations shortly.


r~
--- 2.1.85/include/linux/module.h Sun Nov 2 14:23:27 1997
+++ 2.1.85-axp/include/linux/module.h Fri Feb 6 00:29:08 1998
@@ -94,6 +94,7 @@ struct module_info
#define MOD_AUTOCLEAN 4
#define MOD_VISITED 8
#define MOD_USED_ONCE 16
+#define MOD_JUST_FREED 32

/* Values for query_module's which. */

--- 2.1.85/kernel/module.c Sun Jan 11 21:51:02 1998
+++ 2.1.85-axp/kernel/module.c Fri Feb 6 00:43:45 1998
@@ -54,7 +54,7 @@ struct module *module_list = &kernel_mod
static long get_mod_name(const char *user_name, char **buf);
static void put_mod_name(char *buf);
static struct module *find_module(const char *name);
-static void free_module(struct module *);
+static void free_module(struct module *, int tag_freed);


/*
@@ -363,6 +363,7 @@ sys_delete_module(const char *name_user)
struct module *mod, *next;
char *name;
long error = -EPERM;
+ int something_changed;

lock_kernel();
if (!suser())
@@ -386,25 +387,35 @@ sys_delete_module(const char *name_user)
if (mod->refs != NULL || __MOD_IN_USE(mod))
goto out;

- free_module(mod);
+ free_module(mod, 0);
error = 0;
goto out;
}

/* Do automatic reaping */
+restart:
+ something_changed = 0;
for (mod = module_list; mod != &kernel_module; mod = next) {
next = mod->next;
- if (mod->refs == NULL &&
- ((mod->flags
- & (MOD_AUTOCLEAN|MOD_RUNNING|MOD_DELETED|MOD_USED_ONCE))
- == (MOD_AUTOCLEAN|MOD_RUNNING|MOD_USED_ONCE)) &&
- !__MOD_IN_USE(mod)) {
- if (mod->flags & MOD_VISITED)
+ if (mod->refs == NULL
+ && (mod->flags & MOD_AUTOCLEAN)
+ && (mod->flags & MOD_RUNNING)
+ && !(mod->flags & MOD_DELETED)
+ && (mod->flags & MOD_USED_ONCE)
+ && !__MOD_IN_USE(mod)) {
+ if ((mod->flags & MOD_VISITED)
+ && !(mod->flags & MOD_JUST_FREED)) {
mod->flags &= ~MOD_VISITED;
- else
- free_module(mod);
+ } else {
+ free_module(mod, 1);
+ something_changed = 1;
+ }
}
}
+ if (something_changed)
+ goto restart;
+ for (mod = module_list; mod != &kernel_module; mod = mod->next)
+ mod->flags &= ~MOD_JUST_FREED;
error = 0;
out:
unlock_kernel();
@@ -764,7 +775,7 @@ find_module(const char *name)
*/

static void
-free_module(struct module *mod)
+free_module(struct module *mod, int tag_freed)
{
struct module_ref *dep;
unsigned i;
@@ -786,6 +797,8 @@ free_module(struct module *mod)
for (pp = &dep->dep->refs; *pp != dep; pp = &(*pp)->next_ref)
continue;
*pp = dep->next_ref;
+ if (tag_freed && dep->dep->refs == NULL)
+ dep->dep->flags |= MOD_JUST_FREED;
}

/* And from the main module list. */
\
 
 \ /
  Last update: 2005-03-22 13:41    [W:0.339 / U:0.120 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site