summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1998-09-19 19:15:08 +0000
committerRalf Baechle <ralf@linux-mips.org>1998-09-19 19:15:08 +0000
commit03ba4131783cc9e872f8bb26a03f15bc11f27564 (patch)
tree88db8dba75ae06ba3bad08e42c5e52efc162535c /kernel
parent257730f99381dd26e10b832fce4c94cae7ac1176 (diff)
- Merge with Linux 2.1.121.
- Bugfixes.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/capability.c1
-rw-r--r--kernel/fork.c71
-rw-r--r--kernel/kmod.c2
-rw-r--r--kernel/module.c8
-rw-r--r--kernel/panic.c11
-rw-r--r--kernel/printk.c2
-rw-r--r--kernel/resource.c2
-rw-r--r--kernel/sched.c14
-rw-r--r--kernel/signal.c21
-rw-r--r--kernel/sysctl.c8
10 files changed, 74 insertions, 66 deletions
diff --git a/kernel/capability.c b/kernel/capability.c
index 60d4ed6b5..b2a8d43a1 100644
--- a/kernel/capability.c
+++ b/kernel/capability.c
@@ -147,7 +147,6 @@ asmlinkage int sys_capset(cap_user_header_t header, const cap_user_data_t data)
return -EINVAL;
}
- /* may want to set other processes at some point -- for now demand 0 */
if (get_user(pid, &header->pid))
return -EFAULT;
diff --git a/kernel/fork.c b/kernel/fork.c
index 5a577abe3..856934441 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -29,8 +29,10 @@
#include <asm/mmu_context.h>
#include <asm/uaccess.h>
-int nr_tasks=1;
-int nr_running=1;
+/* The idle tasks do not count.. */
+int nr_tasks=0;
+int nr_running=0;
+
unsigned long int total_forks=0; /* Handle normal Linux uptimes. */
int last_pid=0;
@@ -125,7 +127,7 @@ int alloc_uid(struct task_struct *p)
return 0;
}
-__initfunc(void uidcache_init(void))
+void __init uidcache_init(void)
{
int i;
@@ -356,8 +358,9 @@ static inline int copy_fs(unsigned long clone_flags, struct task_struct * tsk)
return 0;
}
-/* return value is only accurate by +-sizeof(long)*8 fds */
-/* XXX make this architecture specific */
+/*
+ * Copy a fd_set and compute the maximum fd it contains.
+ */
static inline int __copy_fdset(unsigned long *d, unsigned long *src)
{
int i;
@@ -411,7 +414,6 @@ static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
new_fds = (struct file **) kmalloc(size, GFP_KERNEL);
if (!new_fds)
goto out_release;
- memset((void *) new_fds, 0, size);
atomic_set(&newf->count, 1);
newf->max_fds = NR_OPEN;
@@ -421,13 +423,15 @@ static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
old_fds = oldf->fd;
for (; i != 0; i--) {
- struct file * f = *old_fds;
- old_fds++;
+ struct file *f = *old_fds++;
*new_fds = f;
if (f)
f->f_count++;
new_fds++;
}
+ /* This is long word aligned thus could use a optimized version */
+ memset(new_fds, 0, (char *)newf->fd + size - (char *)new_fds);
+
tsk->files = newf;
error = 0;
out:
@@ -554,19 +558,6 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs)
p->lock_depth = -1; /* -1 = no lock */
p->start_time = jiffies;
- {
- /* This makes it visible to the rest of the system */
- unsigned long flags;
- write_lock_irqsave(&tasklist_lock, flags);
- SET_LINKS(p);
- hash_pid(p);
- write_unlock_irqrestore(&tasklist_lock, flags);
- }
-
- nr_tasks++;
- if (p->user)
- atomic_inc(&p->user->count);
-
retval = -ENOMEM;
/* copy all the process information */
if (copy_files(clone_flags, p))
@@ -596,9 +587,23 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs)
current->counter >>= 1;
p->counter = current->counter;
- /* Ok, add it to the run-queues, let it rip! */
+ /*
+ * Ok, add it to the run-queues and make it
+ * visible to the rest of the system.
+ *
+ * Let it rip!
+ */
retval = p->pid;
if (retval) {
+ write_lock_irq(&tasklist_lock);
+ SET_LINKS(p);
+ hash_pid(p);
+ write_unlock_irq(&tasklist_lock);
+
+ nr_tasks++;
+ if (p->user)
+ atomic_inc(&p->user->count);
+
p->next_run = NULL;
p->prev_run = NULL;
wake_up_process(p); /* do this last */
@@ -622,37 +627,19 @@ bad_fork_cleanup:
if (p->binfmt && p->binfmt->module)
__MOD_DEC_USE_COUNT(p->binfmt->module);
- {
- unsigned long flags;
- write_lock_irqsave(&tasklist_lock, flags);
- unhash_pid(p);
- REMOVE_LINKS(p);
- write_unlock_irqrestore(&tasklist_lock, flags);
- }
-
- if (p->user)
- atomic_dec(&p->user->count);
- nr_tasks--;
add_free_taskslot(p->tarray_ptr);
bad_fork_free:
free_task_struct(p);
goto bad_fork;
}
-static void files_ctor(void *fp, kmem_cache_t *cachep, unsigned long flags)
-{
- struct files_struct *f = fp;
-
- memset(f, 0, sizeof(*f));
-}
-
-__initfunc(void filescache_init(void))
+void __init filescache_init(void)
{
files_cachep = kmem_cache_create("files_cache",
sizeof(struct files_struct),
0,
SLAB_HWCACHE_ALIGN,
- files_ctor, NULL);
+ NULL, NULL);
if (!files_cachep)
panic("Cannot create files cache");
}
diff --git a/kernel/kmod.c b/kernel/kmod.c
index ec0d85d32..4a7e3ebda 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -116,7 +116,7 @@ int request_module(const char * module_name)
/* Block everything but SIGKILL/SIGSTOP */
spin_lock_irq(&current->sigmask_lock);
tmpsig = current->blocked;
- siginitset(&current->blocked, ~(sigmask(SIGKILL)|sigmask(SIGSTOP)));
+ siginitsetinv(&current->blocked, sigmask(SIGKILL) | sigmask(SIGSTOP));
recalc_sigpending(current);
spin_unlock_irq(&current->sigmask_lock);
diff --git a/kernel/module.c b/kernel/module.c
index 5225c6709..e367a747c 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -288,10 +288,6 @@ sys_init_module(const char *name_user, struct module *mod_user)
goto err3;
}
- /* On some machines it is necessary to do something here
- to make the I and D caches consistent. */
- flush_icache_range((unsigned long)mod, (unsigned long)mod + mod->size);
-
/* Ok, that's about all the sanity we can stomach; copy the rest. */
if (copy_from_user(mod+1, mod_user+1, mod->size-sizeof(*mod))) {
@@ -299,6 +295,10 @@ sys_init_module(const char *name_user, struct module *mod_user)
goto err3;
}
+ /* On some machines it is necessary to do something here
+ to make the I and D caches consistent. */
+ flush_icache_range((unsigned long)mod, (unsigned long)mod + mod->size);
+
/* Update module references. */
mod->next = mod_tmp.next;
mod->refs = NULL;
diff --git a/kernel/panic.c b/kernel/panic.c
index 4ba287e05..140c6bad2 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -20,6 +20,10 @@
#include <linux/sysrq.h>
#include <linux/interrupt.h>
+#ifdef __alpha__
+#include <asm/machvec.h>
+#endif
+
asmlinkage void sys_sync(void); /* it's really int */
extern void unblank_console(void);
extern int C_A_D;
@@ -28,7 +32,7 @@ int panic_timeout = 0;
struct notifier_block *panic_notifier_list = NULL;
-__initfunc(void panic_setup(char *str, int *ints))
+void __init panic_setup(char *str, int *ints)
{
if (ints[0] == 1)
panic_timeout = ints[1];
@@ -76,7 +80,10 @@ NORET_TYPE void panic(const char * fmt, ...)
#ifdef __sparc__
printk("Press L1-A to return to the boot prom\n");
#endif
-
+#ifdef __alpha__
+ if (alpha_using_srm)
+ halt();
+#endif
sti();
for(;;) {
CHECK_EMERGENCY_SYNC
diff --git a/kernel/printk.c b/kernel/printk.c
index 2998dbede..0d8287fef 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -58,7 +58,7 @@ static int preferred_console = -1;
/*
* Setup a list of consoles. Called from init/main.c
*/
-__initfunc(void console_setup(char *str, int *ints))
+void __init console_setup(char *str, int *ints)
{
struct console_cmdline *c;
char name[sizeof(c->name)];
diff --git a/kernel/resource.c b/kernel/resource.c
index dc23b159b..2d6b56eb0 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -182,7 +182,7 @@ unsigned long occupy_region(unsigned long base, unsigned long end,
#endif
/* Called from init/main.c to reserve IO ports. */
-__initfunc(void reserve_setup(char *str, int *ints))
+void __init reserve_setup(char *str, int *ints)
{
int i;
diff --git a/kernel/sched.c b/kernel/sched.c
index 1b76fee50..a9a7a6b64 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -430,9 +430,6 @@ int del_timer(struct timer_list * timer)
ret = detach_timer(timer);
timer->next = timer->prev = 0;
spin_unlock_irqrestore(&timerlist_lock, flags);
-
- /* Make sure the timer isn't running in parallell.. */
- synchronize_bh();
return ret;
}
@@ -847,8 +844,7 @@ static unsigned long count_active_tasks(void)
read_lock(&tasklist_lock);
for_each_task(p) {
- if (p->pid &&
- (p->state == TASK_RUNNING ||
+ if ((p->state == TASK_RUNNING ||
p->state == TASK_UNINTERRUPTIBLE ||
p->state == TASK_SWAPPING))
nr += FIXED_1;
@@ -1588,11 +1584,13 @@ asmlinkage int sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp)
static void show_task(int nr,struct task_struct * p)
{
unsigned long free = 0;
+ int state;
static const char * stat_nam[] = { "R", "S", "D", "Z", "T", "W" };
printk("%-8s %3d ", p->comm, (p == current) ? -nr : nr);
- if (((unsigned) p->state) < sizeof(stat_nam)/sizeof(char *))
- printk(stat_nam[p->state]);
+ state = p->state ? ffz(~p->state) + 1 : 0;
+ if (((unsigned) state) < sizeof(stat_nam)/sizeof(char *))
+ printk(stat_nam[state]);
else
printk(" ");
#if (BITS_PER_LONG == 32)
@@ -1673,7 +1671,7 @@ void show_state(void)
read_unlock(&tasklist_lock);
}
-__initfunc(void sched_init(void))
+void __init sched_init(void)
{
/*
* We have to do a little magic to get the first
diff --git a/kernel/signal.c b/kernel/signal.c
index ff5ec0a8d..1aded9117 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -18,6 +18,7 @@
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/slab.h>
+#include <linux/init.h>
#include <asm/uaccess.h>
@@ -35,8 +36,10 @@
static kmem_cache_t *signal_queue_cachep;
-void
-signals_init(void)
+static int nr_queued_signals;
+static int max_queued_signals = 1024;
+
+void __init signals_init(void)
{
signal_queue_cachep =
kmem_cache_create("signal_queue",
@@ -64,6 +67,7 @@ flush_signals(struct task_struct *t)
while (q) {
n = q->next;
kmem_cache_free(signal_queue_cachep, q);
+ nr_queued_signals--;
q = n;
}
}
@@ -160,7 +164,8 @@ printk("SIG dequeue (%s:%d): %d ", current->comm, current->pid,
current->sigqueue_tail = pp;
*info = q->info;
kmem_cache_free(signal_queue_cachep,q);
-
+ nr_queued_signals--;
+
/* then see if this signal is still pending. */
q = *pp;
while (q) {
@@ -300,9 +305,14 @@ printk("SIG queue (%s:%d): %d ", t->comm, t->pid, sig);
make sure at least one signal gets delivered and don't
pass on the info struct. */
- struct signal_queue *q = (struct signal_queue *)
- kmem_cache_alloc(signal_queue_cachep, GFP_KERNEL);
+ struct signal_queue *q = 0;
+ if (nr_queued_signals < max_queued_signals) {
+ q = (struct signal_queue *)
+ kmem_cache_alloc(signal_queue_cachep, GFP_KERNEL);
+ nr_queued_signals++;
+ }
+
if (q) {
q->next = NULL;
*t->sigqueue_tail = q;
@@ -825,6 +835,7 @@ do_sigaction(int sig, const struct k_sigaction *act, struct k_sigaction *oact)
else {
*pp = q->next;
kmem_cache_free(signal_queue_cachep, q);
+ nr_queued_signals--;
}
q = *pp;
}
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 95db16576..132739310 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -25,6 +25,7 @@
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/init.h>
+#include <linux/fs.h>
#include <asm/bitops.h>
#include <asm/uaccess.h>
@@ -94,6 +95,7 @@ struct file_operations proc_sys_file_operations =
NULL, /* ioctl */
NULL, /* mmap */
NULL, /* no special open code */
+ NULL, /* no special flush code */
NULL, /* no special release code */
NULL /* can't fsync */
};
@@ -228,6 +230,10 @@ static ctl_table fs_table[] = {
0444, NULL, &proc_dointvec},
{FS_MAXFILE, "file-max", &max_files, sizeof(int),
0644, NULL, &proc_dointvec},
+ {FS_NRSUPER, "super-nr", &nr_super_blocks, sizeof(int),
+ 0444, NULL, &proc_dointvec},
+ {FS_MAXSUPER, "super-max", &max_super_blocks, sizeof(int),
+ 0644, NULL, &proc_dointvec},
{FS_NRDQUOT, "dquot-nr", &nr_dquots, 2*sizeof(int),
0444, NULL, &proc_dointvec},
{FS_MAXDQUOT, "dquot-max", &max_dquots, sizeof(int),
@@ -246,7 +252,7 @@ static ctl_table dev_table[] = {
};
-__initfunc(void sysctl_init(void))
+void __init sysctl_init(void)
{
#ifdef CONFIG_PROC_FS
register_proc_table(root_table, &proc_sys_root);