Messages in this thread Patch in this message | | | Date | Fri, 6 Feb 1998 01:48:13 -0800 | From | Richard Henderson <> | Subject | Re: 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. */ | |