From 236e6127ad942fa9712f83a2d441e0ba7c3fc190 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 4 Feb 2002 18:14:02 -0800 Subject: v2.4.4 -> v2.4.4.1 - Al Viro: clean up driver "invalidate_device()" mess - Andries Brouwer: make sd.c work with USB Dane-Elec CompactFlash Card Reader - me: fix nasty lazy kernel page table update problem - me: undo fork changes. Too many user-level bugs and unresolved issues. - Peter Anvin: iso9660 cleanups - Alan Cox: big merge - Johannes Erdfelt: UHCI pci DMA setup fix --- kernel/fork.c | 18 ++++++++---------- kernel/kmod.c | 19 +++++++++---------- kernel/ksyms.c | 1 + kernel/module.c | 23 ++++++++++++----------- 4 files changed, 30 insertions(+), 31 deletions(-) (limited to 'kernel') diff --git a/kernel/fork.c b/kernel/fork.c index 74b3ee7ca8cd..feed49eb35bc 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -666,17 +666,15 @@ int do_fork(unsigned long clone_flags, unsigned long stack_start, p->pdeath_signal = 0; /* - * Give the parent's dynamic priority entirely to the child. The - * total amount of dynamic priorities in the system doesn't change - * (more scheduling fairness), but the child will run first, which - * is especially useful in avoiding a lot of copy-on-write faults - * if the child for a fork() just wants to do a few simple things - * and then exec(). This is only important in the first timeslice. - * In the long run, the scheduling behavior is unchanged. + * "share" dynamic priority between parent and child, thus the + * total amount of dynamic priorities in the system doesnt change, + * more scheduling fairness. This is only important in the first + * timeslice, on the long run the scheduling behaviour is unchanged. */ - p->counter = current->counter; - current->counter = 0; - current->need_resched = 1; + p->counter = (current->counter + 1) >> 1; + current->counter >>= 1; + if (!current->counter) + current->need_resched = 1; /* * Ok, add it to the run-queues and make it diff --git a/kernel/kmod.c b/kernel/kmod.c index ac840a901f1a..c1774226e111 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c @@ -157,19 +157,18 @@ static int exec_modprobe(void * module_name) } /** - * request_module - try to load a kernel module - * @module_name: Name of module + * request_module - try to load a kernel module + * @module_name: Name of module * - * Load a module using the user mode module loader. The function returns - * zero on success or a negative errno code on failure. Note that a - * successful module load does not mean the module did not then unload - * and exit on an error of its own. Callers must check that the service - * they requested is now available not blindly invoke it. + * Load a module using the user mode module loader. The function returns + * zero on success or a negative errno code on failure. Note that a + * successful module load does not mean the module did not then unload + * and exit on an error of its own. Callers must check that the service + * they requested is now available not blindly invoke it. * - * If module auto-loading support is disabled then this function - * becomes a no-operation. + * If module auto-loading support is disabled then this function + * becomes a no-operation. */ - int request_module(const char * module_name) { pid_t pid; diff --git a/kernel/ksyms.c b/kernel/ksyms.c index 5fcbe2d34109..b28f65e9fd5f 100644 --- a/kernel/ksyms.c +++ b/kernel/ksyms.c @@ -174,6 +174,7 @@ EXPORT_SYMBOL(files_lock); EXPORT_SYMBOL(check_disk_change); EXPORT_SYMBOL(__invalidate_buffers); EXPORT_SYMBOL(invalidate_inodes); +EXPORT_SYMBOL(invalidate_device); EXPORT_SYMBOL(invalidate_inode_pages); EXPORT_SYMBOL(truncate_inode_pages); EXPORT_SYMBOL(fsync_dev); diff --git a/kernel/module.c b/kernel/module.c index 36023bce008f..a80e9596cd03 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -554,8 +554,8 @@ sys_init_module(const char *name_user, struct module *mod_user) put_mod_name(name); /* Initialize the module. */ - mod->flags |= MOD_INITIALIZING; atomic_set(&mod->uc.usecount,1); + mod->flags |= MOD_INITIALIZING; if (mod->init && (error = mod->init()) != 0) { atomic_set(&mod->uc.usecount,0); mod->flags &= ~MOD_INITIALIZING; @@ -613,11 +613,6 @@ sys_delete_module(const char *name_user) if (name_user) { if ((error = get_mod_name(name_user, &name)) < 0) goto out; - if (error == 0) { - error = -EINVAL; - put_mod_name(name); - goto out; - } error = -ENOENT; if ((mod = find_module(name)) == NULL) { put_mod_name(name); @@ -847,7 +842,6 @@ qm_symbols(struct module *mod, char *buf, size_t bufsize, size_t *ret) bufsize -= len; space += len; } - if (put_user(i, ret)) return -EFAULT; else @@ -876,8 +870,11 @@ qm_info(struct module *mod, char *buf, size_t bufsize, size_t *ret) info.addr = (unsigned long)mod; info.size = mod->size; info.flags = mod->flags; + + /* usecount is one too high here - report appropriately to + compensate for locking */ info.usecount = (mod_member_present(mod, can_unload) - && mod->can_unload ? -1 : atomic_read(&mod->uc.usecount)); + && mod->can_unload ? -1 : atomic_read(&mod->uc.usecount)-1); if (copy_to_user(buf, &info, sizeof(struct module_info))) return -EFAULT; @@ -909,15 +906,17 @@ sys_query_module(const char *name_user, int which, char *buf, size_t bufsize, goto out; } err = -ENOENT; - if (namelen == 0) - mod = &kernel_module; - else if ((mod = find_module(name)) == NULL) { + if ((mod = find_module(name)) == NULL) { put_mod_name(name); goto out; } put_mod_name(name); } + /* __MOD_ touches the flags. We must avoid that */ + + atomic_inc(&mod->uc.usecount); + switch (which) { case 0: @@ -942,6 +941,8 @@ sys_query_module(const char *name_user, int which, char *buf, size_t bufsize, err = -EINVAL; break; } + atomic_dec(&mod->uc.usecount); + out: unlock_kernel(); return err; -- cgit v1.2.3