diff options
| author | Linus Torvalds <torvalds@athlon.transmeta.com> | 2002-02-04 17:56:46 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@athlon.transmeta.com> | 2002-02-04 17:56:46 -0800 |
| commit | 5d12a58c4049a4839abbbdf87dd189505513b1b6 (patch) | |
| tree | 3bbde32337e8ec19cf556a0e1f53b037e01e3122 /kernel | |
| parent | 1644c00da2252cb979743060056b2e2778884e99 (diff) | |
v2.4.1.1 -> v2.4.1.2
- driver sync up with Alan
- Andrew Morton: wakeup cleanup and race fix
- Paul Mackerras: macintosh driver updates.
- don't trust "page_count()" on reserved pages!
- Russell King: fix serious IDE multimode write bug!
- me, Jens, others: fix elevator problem
- ARM, MIPS and cris architecture updates
- alpha updates: better page clear/copy, avoid kernel lock in execve
- USB and firewire updates
- ISDN updates
- Irda updates
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/printk.c | 3 | ||||
| -rw-r--r-- | kernel/sched.c | 76 | ||||
| -rw-r--r-- | kernel/sysctl.c | 3 |
3 files changed, 33 insertions, 49 deletions
diff --git a/kernel/printk.c b/kernel/printk.c index 4a459b6051d8..e04c3e6c6457 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -125,9 +125,8 @@ int do_syslog(int type, char * buf, int len) unsigned long i, j, limit, count; int do_clear = 0; char c; - int error = -EPERM; + int error = 0; - error = 0; switch (type) { case 0: /* Close log */ break; diff --git a/kernel/sched.c b/kernel/sched.c index ec1f463d0286..1df69dab41b4 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -326,9 +326,10 @@ static inline void move_first_runqueue(struct task_struct * p) * "current->state = TASK_RUNNING" to mark yourself runnable * without the overhead of this. */ -inline void wake_up_process(struct task_struct * p) +static inline int try_to_wake_up(struct task_struct * p, int synchronous) { unsigned long flags; + int success = 0; /* * We want the common case fall through straight, thus the goto. @@ -338,25 +339,17 @@ inline void wake_up_process(struct task_struct * p) if (task_on_runqueue(p)) goto out; add_to_runqueue(p); - reschedule_idle(p); + if (!synchronous) + reschedule_idle(p); + success = 1; out: spin_unlock_irqrestore(&runqueue_lock, flags); + return success; } -static inline void wake_up_process_synchronous(struct task_struct * p) +inline int wake_up_process(struct task_struct * p) { - unsigned long flags; - - /* - * We want the common case fall through straight, thus the goto. - */ - spin_lock_irqsave(&runqueue_lock, flags); - p->state = TASK_RUNNING; - if (task_on_runqueue(p)) - goto out; - add_to_runqueue(p); -out: - spin_unlock_irqrestore(&runqueue_lock, flags); + return try_to_wake_up(p, 0); } static void process_timeout(unsigned long __data) @@ -689,64 +682,59 @@ scheduling_in_interrupt: return; } +/* + * The core wakeup function. Non-exclusive wakeups (nr_exclusive == 0) just wake everything + * up. If it's an exclusive wakeup (nr_exclusive == small +ve number) then we wake all the + * non-exclusive tasks and one exclusive task. + * + * There are circumstances in which we can try to wake a task which has already + * started to run but is not in state TASK_RUNNING. try_to_wake_up() returns zero + * in this (rare) case, and we handle it by contonuing to scan the queue. + */ 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 task_struct *p; - unsigned long flags; - if (!q) - goto out; - - wq_write_lock_irqsave(&q->lock, flags); - -#if WAITQUEUE_DEBUG CHECK_MAGIC_WQHEAD(q); -#endif - head = &q->task_list; -#if WAITQUEUE_DEBUG - if (!head->next || !head->prev) - WQ_BUG(); -#endif + WQ_CHECK_LIST_HEAD(head); tmp = head->next; while (tmp != head) { unsigned int state; wait_queue_t *curr = list_entry(tmp, wait_queue_t, task_list); tmp = tmp->next; - -#if WAITQUEUE_DEBUG CHECK_MAGIC(curr->__magic); -#endif p = curr->task; state = p->state; if (state & mode) { -#if WAITQUEUE_DEBUG - curr->__waker = (long)__builtin_return_address(0); -#endif - if (sync) - wake_up_process_synchronous(p); - else - wake_up_process(p); - if ((curr->flags & WQ_FLAG_EXCLUSIVE) && !--nr_exclusive) + WQ_NOTE_WAKER(curr); + if (try_to_wake_up(p, sync) && curr->flags && !--nr_exclusive) break; } } - wq_write_unlock_irqrestore(&q->lock, flags); -out: - return; } void __wake_up(wait_queue_head_t *q, unsigned int mode, int nr) { - __wake_up_common(q, mode, nr, 0); + if (q) { + unsigned long flags; + wq_read_lock_irqsave(&q->lock, flags); + __wake_up_common(q, mode, nr, 0); + wq_read_unlock_irqrestore(&q->lock, flags); + } } void __wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr) { - __wake_up_common(q, mode, nr, 1); + if (q) { + unsigned long flags; + wq_read_lock_irqsave(&q->lock, flags); + __wake_up_common(q, mode, nr, 1); + wq_read_unlock_irqrestore(&q->lock, flags); + } } #define SLEEP_ON_VAR \ diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 1c22d7838dd2..95fc9e9fb7bc 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -130,9 +130,6 @@ 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[]; - /* The default sysctl tables: */ static ctl_table root_table[] = { |
