diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-03-27 23:54:12 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-03-27 23:54:12 +0000 |
commit | d3e71cb08747743fce908122bab08b479eb403a5 (patch) | |
tree | cbec6948fdbdee9af81cf3ecfb504070d2745d7b /kernel | |
parent | fe7ff1706e323d0e5ed83972960a1ecc1ee538b3 (diff) |
Merge with Linux 2.3.99-pre3.
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/Makefile | 5 | ||||
-rw-r--r-- | kernel/ksyms.c | 21 | ||||
-rw-r--r-- | kernel/ptrace.c | 4 | ||||
-rw-r--r-- | kernel/sched.c | 7 | ||||
-rw-r--r-- | kernel/signal.c | 94 | ||||
-rw-r--r-- | kernel/sysctl.c | 69 |
6 files changed, 120 insertions, 80 deletions
diff --git a/kernel/Makefile b/kernel/Makefile index bec392fca..2a4f548af 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -7,9 +7,6 @@ # # Note 2! The CFLAGS definitions are now in the main makefile... -.S.s: - $(CPP) $(CPPFLAGS) -traditional $< -o $*.s - O_TARGET := kernel.o O_OBJS = sched.o dma.o fork.o exec_domain.o panic.o printk.o sys.o \ module.o exit.o itimer.o info.o time.o softirq.o resource.o \ @@ -29,7 +26,7 @@ ifeq ($(CONFIG_MODULES),y) OX_OBJS += ksyms.o endif -ifdef CONFIG_PM +ifeq ($(CONFIG_PM),y) OX_OBJS += pm.o endif diff --git a/kernel/ksyms.c b/kernel/ksyms.c index a6748e70c..ad11eafea 100644 --- a/kernel/ksyms.c +++ b/kernel/ksyms.c @@ -207,6 +207,7 @@ EXPORT_SYMBOL(posix_unblock_lock); EXPORT_SYMBOL(locks_mandatory_area); EXPORT_SYMBOL(dput); EXPORT_SYMBOL(is_root_busy); +EXPORT_SYMBOL(have_submounts); EXPORT_SYMBOL(prune_dcache); EXPORT_SYMBOL(shrink_dcache_sb); EXPORT_SYMBOL(shrink_dcache_parent); @@ -324,12 +325,20 @@ EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax); EXPORT_SYMBOL(proc_doulongvec_minmax); /* interrupt handling */ +EXPORT_SYMBOL(add_timer); +EXPORT_SYMBOL(del_timer); EXPORT_SYMBOL(request_irq); EXPORT_SYMBOL(free_irq); + +/* The notion of irq probe/assignment is foreign to S/390 */ + +#if !defined(CONFIG_ARCH_S390) EXPORT_SYMBOL(probe_irq_on); EXPORT_SYMBOL(probe_irq_off); -EXPORT_SYMBOL(add_timer); -EXPORT_SYMBOL(del_timer); +EXPORT_SYMBOL(autoirq_setup); +EXPORT_SYMBOL(autoirq_report); +#endif + #ifdef __SMP__ EXPORT_SYMBOL(del_timer_sync); #endif @@ -366,10 +375,6 @@ EXPORT_SYMBOL(lock_kiovec); EXPORT_SYMBOL(unlock_kiovec); EXPORT_SYMBOL(brw_kiovec); -/* autoirq from drivers/net/auto_irq.c */ -EXPORT_SYMBOL(autoirq_setup); -EXPORT_SYMBOL(autoirq_report); - /* dma handling */ EXPORT_SYMBOL(request_dma); EXPORT_SYMBOL(free_dma); @@ -439,8 +444,8 @@ EXPORT_SYMBOL(setup_arg_pages); EXPORT_SYMBOL(copy_strings_kernel); EXPORT_SYMBOL(do_execve); EXPORT_SYMBOL(flush_old_exec); -EXPORT_SYMBOL(open_dentry); -EXPORT_SYMBOL(read_exec); +EXPORT_SYMBOL(kernel_read); +EXPORT_SYMBOL(open_exec); /* Miscellaneous access points */ EXPORT_SYMBOL(si_meminfo); diff --git a/kernel/ptrace.c b/kernel/ptrace.c index c3f75124f..a87858804 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -44,9 +44,9 @@ repeat: mapnr = pte_pagenr(*pgtable); if (write && (!pte_write(*pgtable) || !pte_dirty(*pgtable))) goto fault_in_page; - if (mapnr >= max_mapnr) - return 0; page = mem_map + mapnr; + if ((mapnr >= max_mapnr) || PageReserved(page)) + return 0; flush_cache_page(vma, addr); if (write) { diff --git a/kernel/sched.c b/kernel/sched.c index e1dbc62ba..c0ac80395 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -618,6 +618,11 @@ handle_softirq: goto handle_softirq_back; handle_tq_scheduler: + /* + * do not run the task queue with disabled interrupts, + * cli() wouldn't work on SMP + */ + sti(); run_task_queue(&tq_scheduler); goto tq_scheduler_back; @@ -630,7 +635,7 @@ move_rr_last: scheduling_in_interrupt: printk("Scheduling in interrupt\n"); - *(int *)0 = 0; + BUG(); return; } diff --git a/kernel/signal.c b/kernel/signal.c index 55017e2f6..0958af05c 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -90,7 +90,7 @@ flush_signal_handlers(struct task_struct *t) * Dequeue a signal and return the element to the caller, which is * expected to free it. * - * All callers of must be holding current->sigmask_lock. + * All callers must be holding current->sigmask_lock. */ int @@ -149,19 +149,19 @@ printk("SIG dequeue (%s:%d): %d ", current->comm, current->pid, kmem_cache_free(signal_queue_cachep,q); atomic_dec(&nr_queued_signals); - /* then see if this signal is still pending. */ - q = *pp; - while (q) { - if (q->info.si_signo == sig) { - reset = 0; - break; - } - q = q->next; - } + /* Then see if this signal is still pending. + (Non rt signals may not be queued twice.) + */ + if (sig >= SIGRTMIN) + for (q = *pp; q; q = q->next) + if (q->info.si_signo == sig) { + reset = 0; + break; + } + } else { - /* Ok, it wasn't in the queue. It must have - been sent either by a non-rt mechanism and - we ran out of queue space. So zero out the + /* Ok, it wasn't in the queue. We must have + been out of queue space. So zero out the info. */ info->si_signo = sig; info->si_errno = 0; @@ -170,9 +170,10 @@ printk("SIG dequeue (%s:%d): %d ", current->comm, current->pid, info->si_uid = 0; } - if (reset) + if (reset) { sigdelset(¤t->signal, sig); - recalc_sigpending(current); + recalc_sigpending(current); + } /* XXX: Once POSIX.1b timers are in, if si_code == SI_TIMER, we need to xchg out the timer overrun values. */ @@ -196,6 +197,43 @@ printk(" %d -> %d\n", signal_pending(current), sig); } /* + * Remove signal sig from queue and from t->signal. + * Returns 1 if sig was found in t->signal. + * + * All callers must be holding t->sigmask_lock. + */ +static int rm_sig_from_queue(int sig, struct task_struct *t) +{ + struct signal_queue *q, **pp; + + if (sig >= SIGRTMIN) { + printk(KERN_CRIT "SIG: rm_sig_from_queue() doesn't support rt signals\n"); + return 0; + } + + if (!sigismember(&t->signal, sig)) + return 0; + + sigdelset(&t->signal, sig); + + pp = &t->sigqueue; + q = t->sigqueue; + + /* Find the one we're interested in ... + It may appear only once. */ + for ( ; q ; pp = &q->next, q = q->next) + if (q->info.si_signo == sig) + break; + if (q) { + if ((*pp = q->next) == NULL) + t->sigqueue_tail = pp; + kmem_cache_free(signal_queue_cachep,q); + atomic_dec(&nr_queued_signals); + } + return 1; +} + +/* * Determine whether a signal should be posted or not. * * Signals with SIG_IGN can be ignored, except for the @@ -273,18 +311,16 @@ printk("SIG queue (%s:%d): %d ", t->comm, t->pid, sig); if (t->state == TASK_STOPPED) wake_up_process(t); t->exit_code = 0; - sigdelsetmask(&t->signal, (sigmask(SIGSTOP)|sigmask(SIGTSTP)| - sigmask(SIGTTOU)|sigmask(SIGTTIN))); - /* Inflict this corner case with recalculations, not mainline */ - recalc_sigpending(t); + if (rm_sig_from_queue(SIGSTOP, t) || rm_sig_from_queue(SIGTSTP, t) || + rm_sig_from_queue(SIGTTOU, t) || rm_sig_from_queue(SIGTTIN, t)) + recalc_sigpending(t); break; case SIGSTOP: case SIGTSTP: case SIGTTIN: case SIGTTOU: /* If we're stopping again, cancel SIGCONT */ - sigdelset(&t->signal, SIGCONT); - /* Inflict this corner case with recalculations, not mainline */ - recalc_sigpending(t); + if (rm_sig_from_queue(SIGCONT, t)) + recalc_sigpending(t); break; } @@ -338,8 +374,12 @@ printk("SIG queue (%s:%d): %d ", t->comm, t->pid, sig); q->info = *info; break; } - } else { - /* Queue overflow, we have to abort. */ + } else if (sig >= SIGRTMIN && info && (unsigned long)info != 1 + && info->si_code < 0) { + /* + * Queue overflow, abort. We may abort if the signal was rt + * and sent by user using something other than kill(). + */ ret = -EAGAIN; goto out; } @@ -406,7 +446,7 @@ force_sig_info(int sig, struct siginfo *info, struct task_struct *t) } /* - * kill_pg() sends a signal to a process group: this is what the tty + * kill_pg_info() sends a signal to a process group: this is what the tty * control characters do (^C, ^Z etc) */ @@ -437,7 +477,7 @@ kill_pg_info(int sig, struct siginfo *info, pid_t pgrp) } /* - * kill_sl() sends a signal to the session leader: this is used + * kill_sl_info() sends a signal to the session leader: this is used * to send SIGHUP to the controlling process of a terminal when * the connection is lost. */ @@ -484,7 +524,7 @@ kill_proc_info(int sig, struct siginfo *info, pid_t pid) } /* - * kill_something() interprets pid in interesting ways just like kill(2). + * kill_something_info() interprets pid in interesting ways just like kill(2). * * POSIX specifies that kill(-1,sig) is unspecified, but what we have * is probably wrong. Should make it like BSD or SYSV. diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 4e654fa3a..35883ed4c 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -14,6 +14,8 @@ * Added proc_doulongvec_minmax, 09/08/99, Carlos H. Bauer. * Changed linked lists to use list.h instead of lists.h, 02/24/00, Bill * Wendling. + * The list_for_each() macro wasn't appropriate for the sysctl loop. + * Removed it and replaced it with older style, 03/23/00, Bill Wendling */ #include <linux/config.h> @@ -84,9 +86,9 @@ static int parse_table(int *, int, void *, size_t *, void *, size_t, static int proc_doutsstring(ctl_table *table, int write, struct file *filp, void *buffer, size_t *lenp); - static ctl_table root_table[]; -static LIST_HEAD(root_table_header); +static struct ctl_table_header root_table_header = + { root_table, LIST_HEAD_INIT(root_table_header.ctl_entry) }; static ctl_table kern_table[]; static ctl_table vm_table[]; @@ -99,7 +101,6 @@ static ctl_table debug_table[]; static ctl_table dev_table[]; extern ctl_table random_table[]; - /* /proc declarations: */ #ifdef CONFIG_PROC_FS @@ -108,14 +109,12 @@ static ssize_t proc_readsys(struct file *, char *, size_t, loff_t *); static ssize_t proc_writesys(struct file *, const char *, size_t, loff_t *); static int proc_sys_permission(struct inode *, int); -struct file_operations proc_sys_file_operations = -{ +struct file_operations proc_sys_file_operations = { read: proc_readsys, write: proc_writesys, }; -static struct inode_operations proc_sys_inode_operations = -{ +static struct inode_operations proc_sys_inode_operations = { permission: proc_sys_permission, }; @@ -124,6 +123,7 @@ extern struct proc_dir_entry *proc_sys_root; static void register_proc_table(ctl_table *, struct proc_dir_entry *); static void unregister_proc_table(ctl_table *, struct proc_dir_entry *); #endif + extern int inodes_stat[]; extern int dentry_stat[]; @@ -294,39 +294,33 @@ void __init sysctl_init(void) register_proc_table(root_table, proc_sys_root); init_irq_proc(); #endif - } -int do_sysctl (int *name, int nlen, - void *oldval, size_t *oldlenp, +int do_sysctl(int *name, int nlen, void *oldval, size_t *oldlenp, void *newval, size_t newlen) { - int error; struct list_head *tmp; - void *context; - + if (nlen == 0 || nlen >= CTL_MAXNAME) return -ENOTDIR; - - if (oldval) - { + if (oldval) { int old_len; - if (!oldlenp) - return -EFAULT; - if(get_user(old_len, oldlenp)) + if (!oldlenp || get_user(old_len, oldlenp)) return -EFAULT; } - list_for_each(tmp, &root_table_header) { + tmp = &root_table_header.ctl_entry; + do { struct ctl_table_header *head = list_entry(tmp, struct ctl_table_header, ctl_entry); - context = NULL; - error = parse_table(name, nlen, oldval, oldlenp, - newval, newlen, head->ctl_table, &context); + void *context = NULL; + int error = parse_table(name, nlen, oldval, oldlenp, + newval, newlen, head->ctl_table, + &context); if (context) kfree(context); if (error != -ENOTDIR) return error; - } + } while (tmp != &root_table_header.ctl_entry); return -ENOTDIR; } @@ -335,7 +329,7 @@ extern asmlinkage long sys_sysctl(struct __sysctl_args *args) struct __sysctl_args tmp; int error; - if(copy_from_user(&tmp, args, sizeof(tmp))) + if (copy_from_user(&tmp, args, sizeof(tmp))) return -EFAULT; lock_kernel(); @@ -345,9 +339,10 @@ extern asmlinkage long sys_sysctl(struct __sysctl_args *args) return error; } - -/* ctl_perm does NOT grant the superuser all rights automatically, because - some sysctl variables are readonly even to root. */ +/* + * ctl_perm does NOT grant the superuser all rights automatically, because + * some sysctl variables are readonly even to root. + */ static int test_perm(int mode, int op) { @@ -370,17 +365,16 @@ static int parse_table(int *name, int nlen, void *newval, size_t newlen, ctl_table *table, void **context) { - int error; repeat: if (!nlen) return -ENOTDIR; for ( ; table->ctl_name; table++) { int n; - if(get_user(n,name)) + if (get_user(n, name)) return -EFAULT; - if (n == table->ctl_name || - table->ctl_name == CTL_ANY) { + if (n == table->ctl_name || table->ctl_name == CTL_ANY) { + int error; if (table->child) { if (ctl_perm(table, 001)) return -EPERM; @@ -389,8 +383,8 @@ repeat: table, name, nlen, oldval, oldlenp, newval, newlen, context); - if (error) - return error; + if (error) + return error; } name++; nlen--; @@ -465,9 +459,9 @@ struct ctl_table_header *register_sysctl_table(ctl_table * table, tmp->ctl_table = table; INIT_LIST_HEAD(&tmp->ctl_entry); if (insert_at_head) - list_add(&tmp->ctl_entry, &root_table_header); + list_add(&tmp->ctl_entry, &root_table_header.ctl_entry); else - list_add_tail(&tmp->ctl_entry, &root_table_header); + list_add_tail(&tmp->ctl_entry, &root_table_header.ctl_entry); #ifdef CONFIG_PROC_FS register_proc_table(table, proc_sys_root); #endif @@ -694,6 +688,7 @@ static int proc_doutsstring(ctl_table *table, int write, struct file *filp, #define OP_OR 2 #define OP_MAX 3 #define OP_MIN 4 + static int do_proc_dointvec(ctl_table *table, int write, struct file *filp, void *buffer, size_t *lenp, int conv, int op) { @@ -812,7 +807,6 @@ int proc_dointvec_bset(ctl_table *table, int write, struct file *filp, (current->pid == 1) ? OP_SET : OP_AND); } - int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp, void *buffer, size_t *lenp) { @@ -911,7 +905,6 @@ int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp, return 0; } - /* * an unsigned long function version */ |