From: James S. <jsi...@us...> - 2001-10-19 21:19:44
|
Update of /cvsroot/linux-mips/linux/kernel In directory usw-pr-cvs1:/tmp/cvs-serv13849/kernel Modified Files: exit.c printk.c sched.c signal.c sys.c Log Message: Synced to 2.4.10. Index: exit.c =================================================================== RCS file: /cvsroot/linux-mips/linux/kernel/exit.c,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- exit.c 2001/09/25 03:36:36 1.6 +++ exit.c 2001/10/19 21:19:40 1.7 @@ -10,6 +10,7 @@ #include <linux/smp_lock.h> #include <linux/module.h> #include <linux/completion.h> +#include <linux/personality.h> #include <linux/tty.h> #ifdef CONFIG_BSD_PROCESS_ACCT #include <linux/acct.h> Index: printk.c =================================================================== RCS file: /cvsroot/linux-mips/linux/kernel/printk.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- printk.c 2001/09/04 11:25:25 1.5 +++ printk.c 2001/10/19 21:19:40 1.6 @@ -12,6 +12,8 @@ * Modified for sysctl support, 1/8/97, Chris Horn. * Fixed SMP synchronization, 08/08/99, Manfred Spraul * man...@co... + * Rewrote bits to get rid of console_lock + * 01Mar01 Andrew Morton <an...@uo...> */ #include <linux/mm.h> @@ -20,14 +22,14 @@ #include <linux/smp_lock.h> #include <linux/console.h> #include <linux/init.h> +#include <linux/module.h> +#include <linux/interrupt.h> /* For in_interrupt() */ #include <asm/uaccess.h> -#define LOG_BUF_LEN (16384) +#define LOG_BUF_LEN (16384) /* This must be a power of two */ #define LOG_BUF_MASK (LOG_BUF_LEN-1) -static char buf[1024]; - /* printk's without a loglevel use this.. */ #define DEFAULT_MESSAGE_LOGLEVEL 4 /* KERN_WARNING */ @@ -35,7 +37,6 @@ #define MINIMUM_CONSOLE_LOGLEVEL 1 /* Minimum loglevel we let people use */ #define DEFAULT_CONSOLE_LOGLEVEL 7 /* anything MORE serious than KERN_DEBUG */ -unsigned long log_size; DECLARE_WAIT_QUEUE_HEAD(log_wait); /* Keep together for sysctl support */ @@ -44,15 +45,41 @@ int minimum_console_loglevel = MINIMUM_CONSOLE_LOGLEVEL; int default_console_loglevel = DEFAULT_CONSOLE_LOGLEVEL; -spinlock_t console_lock = SPIN_LOCK_UNLOCKED; +int oops_in_progress; +/* + * console_sem protects the console_drivers list, and also + * provides serialisation for access to the entire console + * driver system. + */ +static DECLARE_MUTEX(console_sem); struct console *console_drivers; + +/* + * logbuf_lock protects log_buf, log_start, log_end, con_start and logged_chars + * It is also used in interesting ways to provide interlocking in + * release_console_sem(). + */ +static spinlock_t logbuf_lock = SPIN_LOCK_UNLOCKED; + static char log_buf[LOG_BUF_LEN]; -static unsigned long log_start; -static unsigned long logged_chars; +#define LOG_BUF(idx) (log_buf[(idx) & LOG_BUF_MASK]) + +/* + * The indices into log_buf are not constrained to LOG_BUF_LEN - they + * must be masked before subscripting + */ +static unsigned long log_start; /* Index into log_buf: next char to be read by syslog() */ +static unsigned long con_start; /* Index into log_buf: next char to be sent to consoles */ +static unsigned long log_end; /* Index into log_buf: most-recently-written-char + 1 */ +static unsigned long logged_chars; /* Number of chars produced since last read+clear operation */ + struct console_cmdline console_cmdline[MAX_CMDLINECONSOLES]; static int preferred_console = -1; +/* Flag: console code may call schedule() */ +static int console_may_schedule; + /* * Setup a list of consoles. Called from init/main.c */ @@ -120,6 +147,7 @@ * 6 -- Disable printk's to console * 7 -- Enable printk's to console * 8 -- Set level of messages printed to console + * 9 -- Return number of unread characters in the log buffer */ int do_syslog(int type, char * buf, int len) { @@ -143,22 +171,21 @@ error = verify_area(VERIFY_WRITE,buf,len); if (error) goto out; - error = wait_event_interruptible(log_wait, log_size); + error = wait_event_interruptible(log_wait, (log_start - log_end)); if (error) goto out; i = 0; - spin_lock_irq(&console_lock); - while (log_size && i < len) { - c = log_buf[log_start & LOG_BUF_MASK]; + spin_lock_irq(&logbuf_lock); + while ((log_start != log_end) && i < len) { + c = LOG_BUF(log_start); log_start++; - log_size--; - spin_unlock_irq(&console_lock); + spin_unlock_irq(&logbuf_lock); __put_user(c,buf); buf++; i++; - spin_lock_irq(&console_lock); + spin_lock_irq(&logbuf_lock); } - spin_unlock_irq(&console_lock); + spin_unlock_irq(&logbuf_lock); error = i; break; case 4: /* Read/clear last kernel messages */ @@ -177,12 +204,12 @@ count = len; if (count > LOG_BUF_LEN) count = LOG_BUF_LEN; - spin_lock_irq(&console_lock); + spin_lock_irq(&logbuf_lock); if (count > logged_chars) count = logged_chars; if (do_clear) logged_chars = 0; - limit = log_start + log_size; + limit = log_end; /* * __put_user() could sleep, and while we sleep * printk() could overwrite the messages @@ -191,14 +218,14 @@ */ for(i=0;i < count;i++) { j = limit-1-i; - if (j+LOG_BUF_LEN < log_start+log_size) + if (j+LOG_BUF_LEN < log_end) break; - c = log_buf[ j & LOG_BUF_MASK ]; - spin_unlock_irq(&console_lock); + c = LOG_BUF(j); + spin_unlock_irq(&logbuf_lock); __put_user(c,&buf[count-1-i]); - spin_lock_irq(&console_lock); + spin_lock_irq(&logbuf_lock); } - spin_unlock_irq(&console_lock); + spin_unlock_irq(&logbuf_lock); error = i; if(i != count) { int offset = count-error; @@ -211,31 +238,36 @@ break; case 5: /* Clear ring buffer */ - spin_lock_irq(&console_lock); + spin_lock_irq(&logbuf_lock); logged_chars = 0; - spin_unlock_irq(&console_lock); + spin_unlock_irq(&logbuf_lock); break; case 6: /* Disable logging to console */ - spin_lock_irq(&console_lock); + spin_lock_irq(&logbuf_lock); console_loglevel = minimum_console_loglevel; - spin_unlock_irq(&console_lock); + spin_unlock_irq(&logbuf_lock); break; case 7: /* Enable logging to console */ - spin_lock_irq(&console_lock); + spin_lock_irq(&logbuf_lock); console_loglevel = default_console_loglevel; - spin_unlock_irq(&console_lock); + spin_unlock_irq(&logbuf_lock); break; - case 8: + case 8: /* Set level of messages printed to console */ error = -EINVAL; if (len < 1 || len > 8) goto out; if (len < minimum_console_loglevel) len = minimum_console_loglevel; - spin_lock_irq(&console_lock); + spin_lock_irq(&logbuf_lock); console_loglevel = len; - spin_unlock_irq(&console_lock); + spin_unlock_irq(&logbuf_lock); error = 0; break; + case 9: /* Number of chars in the log buffer */ + spin_lock_irq(&logbuf_lock); + error = log_end - log_start; + spin_unlock_irq(&logbuf_lock); + break; default: error = -EINVAL; break; @@ -251,98 +283,250 @@ return do_syslog(type, buf, len); } -asmlinkage int printk(const char *fmt, ...) +/* + * Call the console drivers on a range of log_buf + */ +static void __call_console_drivers(unsigned long start, unsigned long end) { - va_list args; - int i; - char *msg, *p, *buf_end; - int line_feed; - static signed char msg_level = -1; - long flags; + struct console *con; - spin_lock_irqsave(&console_lock, flags); - va_start(args, fmt); - i = vsprintf(buf + 3, fmt, args); /* hopefully i < sizeof(buf)-4 */ - buf_end = buf + 3 + i; - va_end(args); - for (p = buf + 3; p < buf_end; p++) { - msg = p; - if (msg_level < 0) { - if ( - p[0] != '<' || - p[1] < '0' || - p[1] > '7' || - p[2] != '>' - ) { - p -= 3; - p[0] = '<'; - p[1] = default_message_loglevel + '0'; - p[2] = '>'; - } else - msg += 3; - msg_level = p[1] - '0'; + for (con = console_drivers; con; con = con->next) { + if ((con->flags & CON_ENABLED) && con->write) + con->write(con, &LOG_BUF(start), end - start); + } +} + +/* + * Write out chars from start to end - 1 inclusive + */ +static void _call_console_drivers(unsigned long start, unsigned long end, int msg_log_level) +{ + if (msg_log_level < console_loglevel && console_drivers && start != end) { + if ((start & LOG_BUF_MASK) > (end & LOG_BUF_MASK)) { + /* wrapped write */ + __call_console_drivers(start & LOG_BUF_MASK, LOG_BUF_LEN); + __call_console_drivers(0, end & LOG_BUF_MASK); + } else { + __call_console_drivers(start, end); } - line_feed = 0; - for (; p < buf_end; p++) { - log_buf[(log_start+log_size) & LOG_BUF_MASK] = *p; - if (log_size < LOG_BUF_LEN) - log_size++; - else - log_start++; + } +} - logged_chars++; - if (*p == '\n') { - line_feed = 1; +/* + * Call the console drivers, asking them to write out + * log_buf[start] to log_buf[end - 1]. + * The console_sem must be held. + */ +static void call_console_drivers(unsigned long start, unsigned long end) +{ + unsigned long cur_index, start_print; + static int msg_level = -1; + + if (((long)(start - end)) > 0) + BUG(); + + cur_index = start; + start_print = start; + while (cur_index != end) { + if ( msg_level < 0 && + ((end - cur_index) > 2) && + LOG_BUF(cur_index + 0) == '<' && + LOG_BUF(cur_index + 1) >= '0' && + LOG_BUF(cur_index + 1) <= '7' && + LOG_BUF(cur_index + 2) == '>') + { + msg_level = LOG_BUF(cur_index + 1) - '0'; + cur_index += 3; + start_print = cur_index; + } + while (cur_index != end) { + char c = LOG_BUF(cur_index); + cur_index++; + + if (c == '\n') { + if (msg_level < 0) { + /* + * printk() has already given us loglevel tags in + * the buffer. This code is here in case the + * log buffer has wrapped right round and scribbled + * on those tags + */ + msg_level = default_message_loglevel; + } + _call_console_drivers(start_print, cur_index, msg_level); + msg_level = -1; + start_print = cur_index; break; } } - if (msg_level < console_loglevel && console_drivers) { - struct console *c = console_drivers; - while(c) { - if ((c->flags & CON_ENABLED) && c->write) - c->write(c, msg, p - msg + line_feed); - c = c->next; + } + _call_console_drivers(start_print, end, msg_level); +} + +static void emit_log_char(char c) +{ + LOG_BUF(log_end) = c; + log_end++; + if (log_end - log_start > LOG_BUF_LEN) + log_start = log_end - LOG_BUF_LEN; + if (log_end - con_start > LOG_BUF_LEN) + con_start = log_end - LOG_BUF_LEN; + if (logged_chars < LOG_BUF_LEN) + logged_chars++; +} + +/* + * This is printk. It can be called from any context. We want it to work. + * + * We try to grab the console_sem. If we succeed, it's easy - we log the output and + * call the console drivers. If we fail to get the semaphore we place the output + * into the log buffer and return. The current holder of the console_sem will + * notice the new output in release_console_sem() and will send it to the + * consoles before releasing the semaphore. + * + * One effect of this deferred printing is that code which calls printk() and + * then changes console_loglevel may break. This is because console_loglevel + * is inspected when the actual printing occurs. + */ +asmlinkage int printk(const char *fmt, ...) +{ + va_list args; + unsigned long flags; + int printed_len; + char *p; + static char printk_buf[1024]; + static int log_level_unknown = 1; + + if (oops_in_progress) { + /* If a crash is occurring, make sure we can't deadlock */ + spin_lock_init(&logbuf_lock); + /* And make sure that we print immediately */ + init_MUTEX(&console_sem); + } + + /* This stops the holder of console_sem just where we want him */ + spin_lock_irqsave(&logbuf_lock, flags); + + /* Emit the output into the temporary buffer */ + va_start(args, fmt); + printed_len = vsnprintf(printk_buf, sizeof(printk_buf), fmt, args); + va_end(args); + + /* + * Copy the output into log_buf. If the caller didn't provide + * appropriate log level tags, we insert them here + */ + for (p = printk_buf; *p; p++) { + if (log_level_unknown) { + if (p[0] != '<' || p[1] < '0' || p[1] > '7' || p[2] != '>') { + emit_log_char('<'); + emit_log_char(default_message_loglevel + '0'); + emit_log_char('>'); } + log_level_unknown = 0; } - if (line_feed) - msg_level = -1; + emit_log_char(*p); + if (*p == '\n') + log_level_unknown = 1; } - spin_unlock_irqrestore(&console_lock, flags); - wake_up_interruptible(&log_wait); - return i; + + if (!down_trylock(&console_sem)) { + /* + * We own the drivers. We can drop the spinlock and let + * release_console_sem() print the text + */ + spin_unlock_irqrestore(&logbuf_lock, flags); + console_may_schedule = 0; + release_console_sem(); + } else { + /* + * Someone else owns the drivers. We drop the spinlock, which + * allows the semaphore holder to proceed and to call the + * console drivers with the output which we just produced. + */ + spin_unlock_irqrestore(&logbuf_lock, flags); + } + return printed_len; } +EXPORT_SYMBOL(printk); -void console_print(const char *s) +/** + * acquire_console_sem - lock the console system for exclusive use. + * + * Acquires a semaphore which guarantees that the caller has + * exclusive access to the console system and the console_drivers list. + * + * Can sleep, returns nothing. + */ +void acquire_console_sem(void) { - struct console *c; + if (in_interrupt()) + BUG(); + down(&console_sem); + console_may_schedule = 1; +} +EXPORT_SYMBOL(acquire_console_sem); + +/** + * release_console_sem - unlock the console system + * + * Releases the semaphore which the caller holds on the console system + * and the console driver list. + * + * While the semaphore was held, console output may have been buffered + * by printk(). If this is the case, release_console_sem() emits + * the output prior to releasing the semaphore. + * + * If there is output waiting for klogd, we wake it up. + * + * release_console_sem() may be called from any context. + */ +void release_console_sem(void) +{ unsigned long flags; - int len = strlen(s); + unsigned long _con_start, _log_end; + unsigned long must_wake_klogd = 0; - spin_lock_irqsave(&console_lock, flags); - c = console_drivers; - while(c) { - if ((c->flags & CON_ENABLED) && c->write) - c->write(c, s, len); - c = c->next; + for ( ; ; ) { + spin_lock_irqsave(&logbuf_lock, flags); + must_wake_klogd |= log_start - log_end; + if (con_start == log_end) + break; /* Nothing to print */ + _con_start = con_start; + _log_end = log_end; + con_start = log_end; /* Flush */ + spin_unlock_irqrestore(&logbuf_lock, flags); + call_console_drivers(_con_start, _log_end); } - spin_unlock_irqrestore(&console_lock, flags); + console_may_schedule = 0; + up(&console_sem); + spin_unlock_irqrestore(&logbuf_lock, flags); + if (must_wake_klogd && !oops_in_progress) + wake_up_interruptible(&log_wait); } -void unblank_console(void) +/** console_conditional_schedule - yield the CPU if required + * + * If the console code is currently allowed to sleep, and + * if this CPU should yield the CPU to another task, do + * so here. + * + * Must be called within acquire_console_sem(). + */ +void console_conditional_schedule(void) { - struct console *c; - unsigned long flags; - - spin_lock_irqsave(&console_lock, flags); - c = console_drivers; - while(c) { - if ((c->flags & CON_ENABLED) && c->unblank) - c->unblank(); - c = c->next; + if (console_may_schedule && current->need_resched) { + set_current_state(TASK_RUNNING); + schedule(); } - spin_unlock_irqrestore(&console_lock, flags); } +void console_print(const char *s) +{ + printk(KERN_EMERG "%s", s); +} +EXPORT_SYMBOL(console_print); + /* * The console driver calls this routine during kernel initialization * to register the console printing procedure with printk() and to @@ -351,11 +535,7 @@ */ void register_console(struct console * console) { - int i, j,len; - int p; - char buf[16]; - signed char msg_level = -1; - char *q; + int i; unsigned long flags; /* @@ -402,7 +582,7 @@ * Put this console in the list - keep the * preferred driver at the head of the list. */ - spin_lock_irqsave(&console_lock, flags); + acquire_console_sem(); if ((console->flags & CON_CONSDEV) || console_drivers == NULL) { console->next = console_drivers; console_drivers = console; @@ -410,57 +590,28 @@ console->next = console_drivers->next; console_drivers->next = console; } - if ((console->flags & CON_PRINTBUFFER) == 0) - goto done; - /* - * Print out buffered log messages. - */ - p = log_start & LOG_BUF_MASK; - - for (i=0,j=0; i < log_size; i++) { - buf[j++] = log_buf[p]; - p = (p+1) & LOG_BUF_MASK; - if (buf[j-1] != '\n' && i < log_size - 1 && j < sizeof(buf)-1) - continue; - buf[j] = 0; - q = buf; - len = j; - if (msg_level < 0) { - if(buf[0] == '<' && - buf[1] >= '0' && - buf[1] <= '7' && - buf[2] == '>') { - msg_level = buf[1] - '0'; - q = buf + 3; - len -= 3; - } else - { - msg_level = default_message_loglevel; - } - } - if (msg_level < console_loglevel) - console->write(console, q, len); - if (buf[j-1] == '\n') - msg_level = -1; - j = 0; + if (console->flags & CON_PRINTBUFFER) { + /* + * release_cosole_sem() will print out the buffered messages for us. + */ + spin_lock_irqsave(&logbuf_lock, flags); + con_start = log_start; + spin_unlock_irqrestore(&logbuf_lock, flags); } -done: - spin_unlock_irqrestore(&console_lock, flags); + release_console_sem(); } - +EXPORT_SYMBOL(register_console); int unregister_console(struct console * console) { struct console *a,*b; - unsigned long flags; int res = 1; - spin_lock_irqsave(&console_lock, flags); + acquire_console_sem(); if (console_drivers == console) { console_drivers=console->next; res = 0; - } else - { + } else { for (a=console_drivers->next, b=console_drivers ; a; b=a, a=b->next) { if (a == console) { @@ -479,13 +630,15 @@ preferred_console = -1; - spin_unlock_irqrestore(&console_lock, flags); + release_console_sem(); return res; } +EXPORT_SYMBOL(unregister_console); -/* - * Write a message to a certain tty, not just the console. This is used for - * messages that need to be redirected to a specific tty. +/** + * tty_write_message - write a message to a certain tty, not just the console. + * + * This is used for messages that need to be redirected to a specific tty. * We don't put it into the syslog queue right now maybe in the future if * really needed. */ Index: sched.c =================================================================== RCS file: /cvsroot/linux-mips/linux/kernel/sched.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- sched.c 2001/09/26 16:50:30 1.1 +++ sched.c 2001/10/19 21:19:40 1.2 @@ -23,9 +23,11 @@ #include <linux/mm.h> #include <linux/init.h> #include <linux/smp_lock.h> +#include <linux/nmi.h> #include <linux/interrupt.h> #include <linux/kernel_stat.h> #include <linux/completion.h> +#include <linux/prefetch.h> #include <asm/uaccess.h> #include <asm/mmu_context.h> @@ -107,6 +109,7 @@ #define last_schedule(cpu) aligned_data[(cpu)].schedule_data.last_schedule struct kernel_stat kstat; +extern struct task_struct *child_reaper; #ifdef CONFIG_SMP @@ -245,7 +248,7 @@ */ oldest_idle = (cycles_t) -1; target_tsk = NULL; - max_prio = 1; + max_prio = 0; for (i = 0; i < smp_num_cpus; i++) { cpu = cpu_logical_map(i); @@ -291,7 +294,7 @@ struct task_struct *tsk; tsk = cpu_curr(this_cpu); - if (preemption_goodness(tsk, p, this_cpu) > 1) + if (preemption_goodness(tsk, p, this_cpu) > 0) tsk->need_resched = 1; #endif } @@ -534,6 +537,9 @@ struct list_head *tmp; int this_cpu, c; + + spin_lock_prefetch(&runqueue_lock); + if (!current->active_mm) BUG(); need_resched_back: prev = current; @@ -719,18 +725,16 @@ static inline void __wake_up_common (wait_queue_head_t *q, unsigned int mode, int nr_exclusive, const int sync) { - struct list_head *tmp, *head; + struct list_head *tmp; struct task_struct *p; CHECK_MAGIC_WQHEAD(q); - head = &q->task_list; - WQ_CHECK_LIST_HEAD(head); - tmp = head->next; - while (tmp != head) { + WQ_CHECK_LIST_HEAD(&q->task_list); + + list_for_each(tmp,&q->task_list) { unsigned int state; wait_queue_t *curr = list_entry(tmp, wait_queue_t, task_list); - tmp = tmp->next; CHECK_MAGIC(curr->__magic); p = curr->task; state = p->state; @@ -1050,7 +1054,7 @@ #if CONFIG_SMP int i; - // Substract non-idle processes running on other CPUs. + // Subtract non-idle processes running on other CPUs. for (i = 0; i < smp_num_cpus; i++) { int cpu = cpu_logical_map(i); if (aligned_data[cpu].schedule_data.curr != idle_task(cpu)) @@ -1173,7 +1177,7 @@ printk(" (NOTLB)\n"); #if defined(CONFIG_X86) || defined(CONFIG_SPARC64) || defined(CONFIG_ARM) || \ - defined(CONFIG_MIPS) + defined(CONFIG_ALPHA) || defined(CONFIG_MIPS) /* * This is very useful, but only works on ARM, x86, MIPS and sparc64 right * now @@ -1214,9 +1218,68 @@ printk(" task PC stack pid father child younger older\n"); #endif read_lock(&tasklist_lock); - for_each_task(p) + for_each_task(p) { + /* + * reset the NMI-timeout, listing all files on a slow + * console might take alot of time: + */ + touch_nmi_watchdog(); show_task(p); + } read_unlock(&tasklist_lock); +} + +/** + * reparent_to_init() - Reparent the calling kernel thread to the init task. + * + * If a kernel thread is launched as a result of a system call, or if + * it ever exits, it should generally reparent itself to init so that + * it is correctly cleaned up on exit. + * + * The various task state such as scheduling policy and priority may have + * been inherited fro a user process, so we reset them to sane values here. + * + * NOTE that reparent_to_init() gives the caller full capabilities. + */ +void reparent_to_init(void) +{ + struct task_struct *this_task = current; + + write_lock_irq(&tasklist_lock); + + /* Reparent to init */ + REMOVE_LINKS(this_task); + this_task->p_pptr = child_reaper; + this_task->p_opptr = child_reaper; + SET_LINKS(this_task); + + /* Set the exit signal to SIGCHLD so we signal init on exit */ + if (this_task->exit_signal != 0) { + printk(KERN_ERR "task `%s' exit_signal %d in " + __FUNCTION__ "\n", + this_task->comm, this_task->exit_signal); + } + this_task->exit_signal = SIGCHLD; + + /* We also take the runqueue_lock while altering task fields + * which affect scheduling decisions */ + spin_lock(&runqueue_lock); + + this_task->ptrace = 0; + this_task->nice = DEF_NICE; + this_task->policy = SCHED_OTHER; + /* cpus_allowed? */ + /* rt_priority? */ + /* signals? */ + this_task->cap_effective = CAP_INIT_EFF_SET; + this_task->cap_inheritable = CAP_INIT_INH_SET; + this_task->cap_permitted = CAP_FULL_SET; + this_task->keep_capabilities = 0; + memcpy(this_task->rlim, init_task.rlim, sizeof(*(this_task->rlim))); + this_task->user = INIT_USER; + + spin_unlock(&runqueue_lock); + write_unlock_irq(&tasklist_lock); } /* Index: signal.c =================================================================== RCS file: /cvsroot/linux-mips/linux/kernel/signal.c,v retrieving revision 1.1.1.1 retrieving revision 1.2 diff -u -d -r1.1.1.1 -r1.2 --- signal.c 2001/06/22 02:29:32 1.1.1.1 +++ signal.c 2001/10/19 21:19:40 1.2 @@ -243,16 +243,16 @@ #endif sig = next_signal(current, mask); - if (current->notifier) { - if (sigismember(current->notifier_mask, sig)) { - if (!(current->notifier)(current->notifier_data)) { - current->sigpending = 0; - return 0; + if (sig) { + if (current->notifier) { + if (sigismember(current->notifier_mask, sig)) { + if (!(current->notifier)(current->notifier_data)) { + current->sigpending = 0; + return 0; + } } } - } - if (sig) { if (!collect_signal(sig, ¤t->pending, info)) sig = 0; @@ -468,11 +468,6 @@ { t->sigpending = 1; - if (t->state & TASK_INTERRUPTIBLE) { - wake_up_process(t); - return; - } - #ifdef CONFIG_SMP /* * If the task is running on a different CPU @@ -489,6 +484,11 @@ smp_send_reschedule(t->processor); spin_unlock(&runqueue_lock); #endif /* CONFIG_SMP */ + + if (t->state & TASK_INTERRUPTIBLE) { + wake_up_process(t); + return; + } } static int deliver_signal(int sig, struct siginfo *info, struct task_struct *t) @@ -545,8 +545,6 @@ ret = deliver_signal(sig, info, t); out: spin_unlock_irqrestore(&t->sigmask_lock, flags); - if ((t->state & TASK_INTERRUPTIBLE) && signal_pending(t)) - wake_up_process(t); out_nolock: #if DEBUG_SIG printk(" %d -> %d\n", signal_pending(t), ret); Index: sys.c =================================================================== RCS file: /cvsroot/linux-mips/linux/kernel/sys.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- sys.c 2001/08/25 06:24:46 1.3 +++ sys.c 2001/10/19 21:19:40 1.4 @@ -39,6 +39,7 @@ */ int C_A_D = 1; +int cad_pid = 1; /* @@ -350,7 +351,7 @@ if (C_A_D) schedule_task(&cad_tq); else - kill_proc(1, SIGINT, 1); + kill_proc(cad_pid, SIGINT, 1); } @@ -1215,7 +1216,7 @@ switch (option) { case PR_SET_PDEATHSIG: sig = arg2; - if (sig > _NSIG) { + if (sig < 0 || sig > _NSIG) { error = -EINVAL; break; } |