summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@athlon.transmeta.com>2002-02-04 18:14:02 -0800
committerLinus Torvalds <torvalds@athlon.transmeta.com>2002-02-04 18:14:02 -0800
commit236e6127ad942fa9712f83a2d441e0ba7c3fc190 (patch)
treec57f86b605bcd3b1c08d28a8de945cca83e4152b /kernel
parent7216d3e927c3b6c5d28e5ffaa54afbb34649debb (diff)
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
Diffstat (limited to 'kernel')
-rw-r--r--kernel/fork.c18
-rw-r--r--kernel/kmod.c19
-rw-r--r--kernel/ksyms.c1
-rw-r--r--kernel/module.c23
4 files changed, 30 insertions, 31 deletions
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;