diff options
Diffstat (limited to 'kernel/sched.c')
-rw-r--r-- | kernel/sched.c | 100 |
1 files changed, 68 insertions, 32 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index 1b59e265273b..ce1056e9b02a 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -693,6 +693,7 @@ static inline int cpu_of(struct rq *rq) | |||
693 | #define this_rq() (&__get_cpu_var(runqueues)) | 693 | #define this_rq() (&__get_cpu_var(runqueues)) |
694 | #define task_rq(p) cpu_rq(task_cpu(p)) | 694 | #define task_rq(p) cpu_rq(task_cpu(p)) |
695 | #define cpu_curr(cpu) (cpu_rq(cpu)->curr) | 695 | #define cpu_curr(cpu) (cpu_rq(cpu)->curr) |
696 | #define raw_rq() (&__raw_get_cpu_var(runqueues)) | ||
696 | 697 | ||
697 | inline void update_rq_clock(struct rq *rq) | 698 | inline void update_rq_clock(struct rq *rq) |
698 | { | 699 | { |
@@ -2637,9 +2638,32 @@ void sched_fork(struct task_struct *p, int clone_flags) | |||
2637 | set_task_cpu(p, cpu); | 2638 | set_task_cpu(p, cpu); |
2638 | 2639 | ||
2639 | /* | 2640 | /* |
2640 | * Make sure we do not leak PI boosting priority to the child: | 2641 | * Make sure we do not leak PI boosting priority to the child. |
2641 | */ | 2642 | */ |
2642 | p->prio = current->normal_prio; | 2643 | p->prio = current->normal_prio; |
2644 | |||
2645 | /* | ||
2646 | * Revert to default priority/policy on fork if requested. | ||
2647 | */ | ||
2648 | if (unlikely(p->sched_reset_on_fork)) { | ||
2649 | if (p->policy == SCHED_FIFO || p->policy == SCHED_RR) | ||
2650 | p->policy = SCHED_NORMAL; | ||
2651 | |||
2652 | if (p->normal_prio < DEFAULT_PRIO) | ||
2653 | p->prio = DEFAULT_PRIO; | ||
2654 | |||
2655 | if (PRIO_TO_NICE(p->static_prio) < 0) { | ||
2656 | p->static_prio = NICE_TO_PRIO(0); | ||
2657 | set_load_weight(p); | ||
2658 | } | ||
2659 | |||
2660 | /* | ||
2661 | * We don't need the reset flag anymore after the fork. It has | ||
2662 | * fulfilled its duty: | ||
2663 | */ | ||
2664 | p->sched_reset_on_fork = 0; | ||
2665 | } | ||
2666 | |||
2643 | if (!rt_prio(p->prio)) | 2667 | if (!rt_prio(p->prio)) |
2644 | p->sched_class = &fair_sched_class; | 2668 | p->sched_class = &fair_sched_class; |
2645 | 2669 | ||
@@ -6123,17 +6147,25 @@ static int __sched_setscheduler(struct task_struct *p, int policy, | |||
6123 | unsigned long flags; | 6147 | unsigned long flags; |
6124 | const struct sched_class *prev_class = p->sched_class; | 6148 | const struct sched_class *prev_class = p->sched_class; |
6125 | struct rq *rq; | 6149 | struct rq *rq; |
6150 | int reset_on_fork; | ||
6126 | 6151 | ||
6127 | /* may grab non-irq protected spin_locks */ | 6152 | /* may grab non-irq protected spin_locks */ |
6128 | BUG_ON(in_interrupt()); | 6153 | BUG_ON(in_interrupt()); |
6129 | recheck: | 6154 | recheck: |
6130 | /* double check policy once rq lock held */ | 6155 | /* double check policy once rq lock held */ |
6131 | if (policy < 0) | 6156 | if (policy < 0) { |
6157 | reset_on_fork = p->sched_reset_on_fork; | ||
6132 | policy = oldpolicy = p->policy; | 6158 | policy = oldpolicy = p->policy; |
6133 | else if (policy != SCHED_FIFO && policy != SCHED_RR && | 6159 | } else { |
6134 | policy != SCHED_NORMAL && policy != SCHED_BATCH && | 6160 | reset_on_fork = !!(policy & SCHED_RESET_ON_FORK); |
6135 | policy != SCHED_IDLE) | 6161 | policy &= ~SCHED_RESET_ON_FORK; |
6136 | return -EINVAL; | 6162 | |
6163 | if (policy != SCHED_FIFO && policy != SCHED_RR && | ||
6164 | policy != SCHED_NORMAL && policy != SCHED_BATCH && | ||
6165 | policy != SCHED_IDLE) | ||
6166 | return -EINVAL; | ||
6167 | } | ||
6168 | |||
6137 | /* | 6169 | /* |
6138 | * Valid priorities for SCHED_FIFO and SCHED_RR are | 6170 | * Valid priorities for SCHED_FIFO and SCHED_RR are |
6139 | * 1..MAX_USER_RT_PRIO-1, valid priority for SCHED_NORMAL, | 6171 | * 1..MAX_USER_RT_PRIO-1, valid priority for SCHED_NORMAL, |
@@ -6177,6 +6209,10 @@ recheck: | |||
6177 | /* can't change other user's priorities */ | 6209 | /* can't change other user's priorities */ |
6178 | if (!check_same_owner(p)) | 6210 | if (!check_same_owner(p)) |
6179 | return -EPERM; | 6211 | return -EPERM; |
6212 | |||
6213 | /* Normal users shall not reset the sched_reset_on_fork flag */ | ||
6214 | if (p->sched_reset_on_fork && !reset_on_fork) | ||
6215 | return -EPERM; | ||
6180 | } | 6216 | } |
6181 | 6217 | ||
6182 | if (user) { | 6218 | if (user) { |
@@ -6220,6 +6256,8 @@ recheck: | |||
6220 | if (running) | 6256 | if (running) |
6221 | p->sched_class->put_prev_task(rq, p); | 6257 | p->sched_class->put_prev_task(rq, p); |
6222 | 6258 | ||
6259 | p->sched_reset_on_fork = reset_on_fork; | ||
6260 | |||
6223 | oldprio = p->prio; | 6261 | oldprio = p->prio; |
6224 | __setscheduler(rq, p, policy, param->sched_priority); | 6262 | __setscheduler(rq, p, policy, param->sched_priority); |
6225 | 6263 | ||
@@ -6336,14 +6374,15 @@ SYSCALL_DEFINE1(sched_getscheduler, pid_t, pid) | |||
6336 | if (p) { | 6374 | if (p) { |
6337 | retval = security_task_getscheduler(p); | 6375 | retval = security_task_getscheduler(p); |
6338 | if (!retval) | 6376 | if (!retval) |
6339 | retval = p->policy; | 6377 | retval = p->policy |
6378 | | (p->sched_reset_on_fork ? SCHED_RESET_ON_FORK : 0); | ||
6340 | } | 6379 | } |
6341 | read_unlock(&tasklist_lock); | 6380 | read_unlock(&tasklist_lock); |
6342 | return retval; | 6381 | return retval; |
6343 | } | 6382 | } |
6344 | 6383 | ||
6345 | /** | 6384 | /** |
6346 | * sys_sched_getscheduler - get the RT priority of a thread | 6385 | * sys_sched_getparam - get the RT priority of a thread |
6347 | * @pid: the pid in question. | 6386 | * @pid: the pid in question. |
6348 | * @param: structure containing the RT priority. | 6387 | * @param: structure containing the RT priority. |
6349 | */ | 6388 | */ |
@@ -6571,19 +6610,9 @@ static inline int should_resched(void) | |||
6571 | 6610 | ||
6572 | static void __cond_resched(void) | 6611 | static void __cond_resched(void) |
6573 | { | 6612 | { |
6574 | #ifdef CONFIG_DEBUG_SPINLOCK_SLEEP | 6613 | add_preempt_count(PREEMPT_ACTIVE); |
6575 | __might_sleep(__FILE__, __LINE__); | 6614 | schedule(); |
6576 | #endif | 6615 | sub_preempt_count(PREEMPT_ACTIVE); |
6577 | /* | ||
6578 | * The BKS might be reacquired before we have dropped | ||
6579 | * PREEMPT_ACTIVE, which could trigger a second | ||
6580 | * cond_resched() call. | ||
6581 | */ | ||
6582 | do { | ||
6583 | add_preempt_count(PREEMPT_ACTIVE); | ||
6584 | schedule(); | ||
6585 | sub_preempt_count(PREEMPT_ACTIVE); | ||
6586 | } while (need_resched()); | ||
6587 | } | 6616 | } |
6588 | 6617 | ||
6589 | int __sched _cond_resched(void) | 6618 | int __sched _cond_resched(void) |
@@ -6597,14 +6626,14 @@ int __sched _cond_resched(void) | |||
6597 | EXPORT_SYMBOL(_cond_resched); | 6626 | EXPORT_SYMBOL(_cond_resched); |
6598 | 6627 | ||
6599 | /* | 6628 | /* |
6600 | * cond_resched_lock() - if a reschedule is pending, drop the given lock, | 6629 | * __cond_resched_lock() - if a reschedule is pending, drop the given lock, |
6601 | * call schedule, and on return reacquire the lock. | 6630 | * call schedule, and on return reacquire the lock. |
6602 | * | 6631 | * |
6603 | * This works OK both with and without CONFIG_PREEMPT. We do strange low-level | 6632 | * This works OK both with and without CONFIG_PREEMPT. We do strange low-level |
6604 | * operations here to prevent schedule() from being called twice (once via | 6633 | * operations here to prevent schedule() from being called twice (once via |
6605 | * spin_unlock(), once by hand). | 6634 | * spin_unlock(), once by hand). |
6606 | */ | 6635 | */ |
6607 | int cond_resched_lock(spinlock_t *lock) | 6636 | int __cond_resched_lock(spinlock_t *lock) |
6608 | { | 6637 | { |
6609 | int resched = should_resched(); | 6638 | int resched = should_resched(); |
6610 | int ret = 0; | 6639 | int ret = 0; |
@@ -6620,9 +6649,9 @@ int cond_resched_lock(spinlock_t *lock) | |||
6620 | } | 6649 | } |
6621 | return ret; | 6650 | return ret; |
6622 | } | 6651 | } |
6623 | EXPORT_SYMBOL(cond_resched_lock); | 6652 | EXPORT_SYMBOL(__cond_resched_lock); |
6624 | 6653 | ||
6625 | int __sched cond_resched_softirq(void) | 6654 | int __sched __cond_resched_softirq(void) |
6626 | { | 6655 | { |
6627 | BUG_ON(!in_softirq()); | 6656 | BUG_ON(!in_softirq()); |
6628 | 6657 | ||
@@ -6634,7 +6663,7 @@ int __sched cond_resched_softirq(void) | |||
6634 | } | 6663 | } |
6635 | return 0; | 6664 | return 0; |
6636 | } | 6665 | } |
6637 | EXPORT_SYMBOL(cond_resched_softirq); | 6666 | EXPORT_SYMBOL(__cond_resched_softirq); |
6638 | 6667 | ||
6639 | /** | 6668 | /** |
6640 | * yield - yield the current processor to other threads. | 6669 | * yield - yield the current processor to other threads. |
@@ -6658,7 +6687,7 @@ EXPORT_SYMBOL(yield); | |||
6658 | */ | 6687 | */ |
6659 | void __sched io_schedule(void) | 6688 | void __sched io_schedule(void) |
6660 | { | 6689 | { |
6661 | struct rq *rq = &__raw_get_cpu_var(runqueues); | 6690 | struct rq *rq = raw_rq(); |
6662 | 6691 | ||
6663 | delayacct_blkio_start(); | 6692 | delayacct_blkio_start(); |
6664 | atomic_inc(&rq->nr_iowait); | 6693 | atomic_inc(&rq->nr_iowait); |
@@ -6670,7 +6699,7 @@ EXPORT_SYMBOL(io_schedule); | |||
6670 | 6699 | ||
6671 | long __sched io_schedule_timeout(long timeout) | 6700 | long __sched io_schedule_timeout(long timeout) |
6672 | { | 6701 | { |
6673 | struct rq *rq = &__raw_get_cpu_var(runqueues); | 6702 | struct rq *rq = raw_rq(); |
6674 | long ret; | 6703 | long ret; |
6675 | 6704 | ||
6676 | delayacct_blkio_start(); | 6705 | delayacct_blkio_start(); |
@@ -7625,7 +7654,7 @@ static int __init migration_init(void) | |||
7625 | migration_call(&migration_notifier, CPU_ONLINE, cpu); | 7654 | migration_call(&migration_notifier, CPU_ONLINE, cpu); |
7626 | register_cpu_notifier(&migration_notifier); | 7655 | register_cpu_notifier(&migration_notifier); |
7627 | 7656 | ||
7628 | return err; | 7657 | return 0; |
7629 | } | 7658 | } |
7630 | early_initcall(migration_init); | 7659 | early_initcall(migration_init); |
7631 | #endif | 7660 | #endif |
@@ -9398,13 +9427,20 @@ void __init sched_init(void) | |||
9398 | } | 9427 | } |
9399 | 9428 | ||
9400 | #ifdef CONFIG_DEBUG_SPINLOCK_SLEEP | 9429 | #ifdef CONFIG_DEBUG_SPINLOCK_SLEEP |
9401 | void __might_sleep(char *file, int line) | 9430 | static inline int preempt_count_equals(int preempt_offset) |
9431 | { | ||
9432 | int nested = preempt_count() & ~PREEMPT_ACTIVE; | ||
9433 | |||
9434 | return (nested == PREEMPT_INATOMIC_BASE + preempt_offset); | ||
9435 | } | ||
9436 | |||
9437 | void __might_sleep(char *file, int line, int preempt_offset) | ||
9402 | { | 9438 | { |
9403 | #ifdef in_atomic | 9439 | #ifdef in_atomic |
9404 | static unsigned long prev_jiffy; /* ratelimiting */ | 9440 | static unsigned long prev_jiffy; /* ratelimiting */ |
9405 | 9441 | ||
9406 | if ((!in_atomic() && !irqs_disabled()) || | 9442 | if ((preempt_count_equals(preempt_offset) && !irqs_disabled()) || |
9407 | system_state != SYSTEM_RUNNING || oops_in_progress) | 9443 | system_state != SYSTEM_RUNNING || oops_in_progress) |
9408 | return; | 9444 | return; |
9409 | if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy) | 9445 | if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy) |
9410 | return; | 9446 | return; |