aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sched.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sched.c')
-rw-r--r--kernel/sched.c101
1 files changed, 78 insertions, 23 deletions
diff --git a/kernel/sched.c b/kernel/sched.c
index cc1f81b50b82..0d8905a1b8ca 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -1921,11 +1921,8 @@ unsigned long wait_task_inactive(struct task_struct *p, long match_state)
1921 running = task_running(rq, p); 1921 running = task_running(rq, p);
1922 on_rq = p->se.on_rq; 1922 on_rq = p->se.on_rq;
1923 ncsw = 0; 1923 ncsw = 0;
1924 if (!match_state || p->state == match_state) { 1924 if (!match_state || p->state == match_state)
1925 ncsw = p->nivcsw + p->nvcsw; 1925 ncsw = p->nvcsw | LONG_MIN; /* sets MSB */
1926 if (unlikely(!ncsw))
1927 ncsw = 1;
1928 }
1929 task_rq_unlock(rq, &flags); 1926 task_rq_unlock(rq, &flags);
1930 1927
1931 /* 1928 /*
@@ -4627,6 +4624,15 @@ __wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr_exclusive)
4627} 4624}
4628EXPORT_SYMBOL_GPL(__wake_up_sync); /* For internal use only */ 4625EXPORT_SYMBOL_GPL(__wake_up_sync); /* For internal use only */
4629 4626
4627/**
4628 * complete: - signals a single thread waiting on this completion
4629 * @x: holds the state of this particular completion
4630 *
4631 * This will wake up a single thread waiting on this completion. Threads will be
4632 * awakened in the same order in which they were queued.
4633 *
4634 * See also complete_all(), wait_for_completion() and related routines.
4635 */
4630void complete(struct completion *x) 4636void complete(struct completion *x)
4631{ 4637{
4632 unsigned long flags; 4638 unsigned long flags;
@@ -4638,6 +4644,12 @@ void complete(struct completion *x)
4638} 4644}
4639EXPORT_SYMBOL(complete); 4645EXPORT_SYMBOL(complete);
4640 4646
4647/**
4648 * complete_all: - signals all threads waiting on this completion
4649 * @x: holds the state of this particular completion
4650 *
4651 * This will wake up all threads waiting on this particular completion event.
4652 */
4641void complete_all(struct completion *x) 4653void complete_all(struct completion *x)
4642{ 4654{
4643 unsigned long flags; 4655 unsigned long flags;
@@ -4658,10 +4670,7 @@ do_wait_for_common(struct completion *x, long timeout, int state)
4658 wait.flags |= WQ_FLAG_EXCLUSIVE; 4670 wait.flags |= WQ_FLAG_EXCLUSIVE;
4659 __add_wait_queue_tail(&x->wait, &wait); 4671 __add_wait_queue_tail(&x->wait, &wait);
4660 do { 4672 do {
4661 if ((state == TASK_INTERRUPTIBLE && 4673 if (signal_pending_state(state, current)) {
4662 signal_pending(current)) ||
4663 (state == TASK_KILLABLE &&
4664 fatal_signal_pending(current))) {
4665 timeout = -ERESTARTSYS; 4674 timeout = -ERESTARTSYS;
4666 break; 4675 break;
4667 } 4676 }
@@ -4689,12 +4698,31 @@ wait_for_common(struct completion *x, long timeout, int state)
4689 return timeout; 4698 return timeout;
4690} 4699}
4691 4700
4701/**
4702 * wait_for_completion: - waits for completion of a task
4703 * @x: holds the state of this particular completion
4704 *
4705 * This waits to be signaled for completion of a specific task. It is NOT
4706 * interruptible and there is no timeout.
4707 *
4708 * See also similar routines (i.e. wait_for_completion_timeout()) with timeout
4709 * and interrupt capability. Also see complete().
4710 */
4692void __sched wait_for_completion(struct completion *x) 4711void __sched wait_for_completion(struct completion *x)
4693{ 4712{
4694 wait_for_common(x, MAX_SCHEDULE_TIMEOUT, TASK_UNINTERRUPTIBLE); 4713 wait_for_common(x, MAX_SCHEDULE_TIMEOUT, TASK_UNINTERRUPTIBLE);
4695} 4714}
4696EXPORT_SYMBOL(wait_for_completion); 4715EXPORT_SYMBOL(wait_for_completion);
4697 4716
4717/**
4718 * wait_for_completion_timeout: - waits for completion of a task (w/timeout)
4719 * @x: holds the state of this particular completion
4720 * @timeout: timeout value in jiffies
4721 *
4722 * This waits for either a completion of a specific task to be signaled or for a
4723 * specified timeout to expire. The timeout is in jiffies. It is not
4724 * interruptible.
4725 */
4698unsigned long __sched 4726unsigned long __sched
4699wait_for_completion_timeout(struct completion *x, unsigned long timeout) 4727wait_for_completion_timeout(struct completion *x, unsigned long timeout)
4700{ 4728{
@@ -4702,6 +4730,13 @@ wait_for_completion_timeout(struct completion *x, unsigned long timeout)
4702} 4730}
4703EXPORT_SYMBOL(wait_for_completion_timeout); 4731EXPORT_SYMBOL(wait_for_completion_timeout);
4704 4732
4733/**
4734 * wait_for_completion_interruptible: - waits for completion of a task (w/intr)
4735 * @x: holds the state of this particular completion
4736 *
4737 * This waits for completion of a specific task to be signaled. It is
4738 * interruptible.
4739 */
4705int __sched wait_for_completion_interruptible(struct completion *x) 4740int __sched wait_for_completion_interruptible(struct completion *x)
4706{ 4741{
4707 long t = wait_for_common(x, MAX_SCHEDULE_TIMEOUT, TASK_INTERRUPTIBLE); 4742 long t = wait_for_common(x, MAX_SCHEDULE_TIMEOUT, TASK_INTERRUPTIBLE);
@@ -4711,6 +4746,14 @@ int __sched wait_for_completion_interruptible(struct completion *x)
4711} 4746}
4712EXPORT_SYMBOL(wait_for_completion_interruptible); 4747EXPORT_SYMBOL(wait_for_completion_interruptible);
4713 4748
4749/**
4750 * wait_for_completion_interruptible_timeout: - waits for completion (w/(to,intr))
4751 * @x: holds the state of this particular completion
4752 * @timeout: timeout value in jiffies
4753 *
4754 * This waits for either a completion of a specific task to be signaled or for a
4755 * specified timeout to expire. It is interruptible. The timeout is in jiffies.
4756 */
4714unsigned long __sched 4757unsigned long __sched
4715wait_for_completion_interruptible_timeout(struct completion *x, 4758wait_for_completion_interruptible_timeout(struct completion *x,
4716 unsigned long timeout) 4759 unsigned long timeout)
@@ -4719,6 +4762,13 @@ wait_for_completion_interruptible_timeout(struct completion *x,
4719} 4762}
4720EXPORT_SYMBOL(wait_for_completion_interruptible_timeout); 4763EXPORT_SYMBOL(wait_for_completion_interruptible_timeout);
4721 4764
4765/**
4766 * wait_for_completion_killable: - waits for completion of a task (killable)
4767 * @x: holds the state of this particular completion
4768 *
4769 * This waits to be signaled for completion of a specific task. It can be
4770 * interrupted by a kill signal.
4771 */
4722int __sched wait_for_completion_killable(struct completion *x) 4772int __sched wait_for_completion_killable(struct completion *x)
4723{ 4773{
4724 long t = wait_for_common(x, MAX_SCHEDULE_TIMEOUT, TASK_KILLABLE); 4774 long t = wait_for_common(x, MAX_SCHEDULE_TIMEOUT, TASK_KILLABLE);
@@ -8242,20 +8292,25 @@ void __might_sleep(char *file, int line)
8242#ifdef in_atomic 8292#ifdef in_atomic
8243 static unsigned long prev_jiffy; /* ratelimiting */ 8293 static unsigned long prev_jiffy; /* ratelimiting */
8244 8294
8245 if ((in_atomic() || irqs_disabled()) && 8295 if ((!in_atomic() && !irqs_disabled()) ||
8246 system_state == SYSTEM_RUNNING && !oops_in_progress) { 8296 system_state != SYSTEM_RUNNING || oops_in_progress)
8247 if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy) 8297 return;
8248 return; 8298 if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy)
8249 prev_jiffy = jiffies; 8299 return;
8250 printk(KERN_ERR "BUG: sleeping function called from invalid" 8300 prev_jiffy = jiffies;
8251 " context at %s:%d\n", file, line); 8301
8252 printk("in_atomic():%d, irqs_disabled():%d\n", 8302 printk(KERN_ERR
8253 in_atomic(), irqs_disabled()); 8303 "BUG: sleeping function called from invalid context at %s:%d\n",
8254 debug_show_held_locks(current); 8304 file, line);
8255 if (irqs_disabled()) 8305 printk(KERN_ERR
8256 print_irqtrace_events(current); 8306 "in_atomic(): %d, irqs_disabled(): %d, pid: %d, name: %s\n",
8257 dump_stack(); 8307 in_atomic(), irqs_disabled(),
8258 } 8308 current->pid, current->comm);
8309
8310 debug_show_held_locks(current);
8311 if (irqs_disabled())
8312 print_irqtrace_events(current);
8313 dump_stack();
8259#endif 8314#endif
8260} 8315}
8261EXPORT_SYMBOL(__might_sleep); 8316EXPORT_SYMBOL(__might_sleep);