diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-06-12 15:55:18 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-06-12 15:55:18 -0400 |
commit | 1b3cba8e60c67c968d108ac55c77e32c1928dec3 (patch) | |
tree | 79ce35debeb7e203558d884efd03c7cf160cceaa | |
parent | 14a73f54798f39854e521fb596da7d50b7566bbd (diff) | |
parent | 7a232e0350940d2664f4de5cc3f0f443bae5062d (diff) |
Merge branch 'sched-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'sched-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
sched: 64-bit: fix arithmetics overflow
sched: fair group: fix overflow(was: fix divide by zero)
sched: fix TASK_WAKEKILL vs SIGKILL race
-rw-r--r-- | include/linux/sched.h | 13 | ||||
-rw-r--r-- | kernel/sched.c | 22 |
2 files changed, 27 insertions, 8 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h index ae0be3c62375..c5d3f847ca8d 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -2026,6 +2026,19 @@ static inline int fatal_signal_pending(struct task_struct *p) | |||
2026 | return signal_pending(p) && __fatal_signal_pending(p); | 2026 | return signal_pending(p) && __fatal_signal_pending(p); |
2027 | } | 2027 | } |
2028 | 2028 | ||
2029 | static inline int signal_pending_state(long state, struct task_struct *p) | ||
2030 | { | ||
2031 | if (!(state & (TASK_INTERRUPTIBLE | TASK_WAKEKILL))) | ||
2032 | return 0; | ||
2033 | if (!signal_pending(p)) | ||
2034 | return 0; | ||
2035 | |||
2036 | if (state & (__TASK_STOPPED | __TASK_TRACED)) | ||
2037 | return 0; | ||
2038 | |||
2039 | return (state & TASK_INTERRUPTIBLE) || __fatal_signal_pending(p); | ||
2040 | } | ||
2041 | |||
2029 | static inline int need_resched(void) | 2042 | static inline int need_resched(void) |
2030 | { | 2043 | { |
2031 | return unlikely(test_thread_flag(TIF_NEED_RESCHED)); | 2044 | return unlikely(test_thread_flag(TIF_NEED_RESCHED)); |
diff --git a/kernel/sched.c b/kernel/sched.c index bfb8ad8ed171..eaf6751e7612 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -312,12 +312,15 @@ static DEFINE_SPINLOCK(task_group_lock); | |||
312 | #endif | 312 | #endif |
313 | 313 | ||
314 | /* | 314 | /* |
315 | * A weight of 0, 1 or ULONG_MAX can cause arithmetics problems. | 315 | * A weight of 0 or 1 can cause arithmetics problems. |
316 | * A weight of a cfs_rq is the sum of weights of which entities | ||
317 | * are queued on this cfs_rq, so a weight of a entity should not be | ||
318 | * too large, so as the shares value of a task group. | ||
316 | * (The default weight is 1024 - so there's no practical | 319 | * (The default weight is 1024 - so there's no practical |
317 | * limitation from this.) | 320 | * limitation from this.) |
318 | */ | 321 | */ |
319 | #define MIN_SHARES 2 | 322 | #define MIN_SHARES 2 |
320 | #define MAX_SHARES (ULONG_MAX - 1) | 323 | #define MAX_SHARES (1UL << 18) |
321 | 324 | ||
322 | static int init_task_group_load = INIT_TASK_GROUP_LOAD; | 325 | static int init_task_group_load = INIT_TASK_GROUP_LOAD; |
323 | #endif | 326 | #endif |
@@ -1337,8 +1340,13 @@ calc_delta_mine(unsigned long delta_exec, unsigned long weight, | |||
1337 | { | 1340 | { |
1338 | u64 tmp; | 1341 | u64 tmp; |
1339 | 1342 | ||
1340 | if (!lw->inv_weight) | 1343 | if (!lw->inv_weight) { |
1341 | lw->inv_weight = 1 + (WMULT_CONST-lw->weight/2)/(lw->weight+1); | 1344 | if (BITS_PER_LONG > 32 && unlikely(lw->weight >= WMULT_CONST)) |
1345 | lw->inv_weight = 1; | ||
1346 | else | ||
1347 | lw->inv_weight = 1 + (WMULT_CONST-lw->weight/2) | ||
1348 | / (lw->weight+1); | ||
1349 | } | ||
1342 | 1350 | ||
1343 | tmp = (u64)delta_exec * weight; | 1351 | tmp = (u64)delta_exec * weight; |
1344 | /* | 1352 | /* |
@@ -4159,12 +4167,10 @@ need_resched_nonpreemptible: | |||
4159 | clear_tsk_need_resched(prev); | 4167 | clear_tsk_need_resched(prev); |
4160 | 4168 | ||
4161 | if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) { | 4169 | if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) { |
4162 | if (unlikely((prev->state & TASK_INTERRUPTIBLE) && | 4170 | if (unlikely(signal_pending_state(prev->state, prev))) |
4163 | signal_pending(prev))) { | ||
4164 | prev->state = TASK_RUNNING; | 4171 | prev->state = TASK_RUNNING; |
4165 | } else { | 4172 | else |
4166 | deactivate_task(rq, prev, 1); | 4173 | deactivate_task(rq, prev, 1); |
4167 | } | ||
4168 | switch_count = &prev->nvcsw; | 4174 | switch_count = &prev->nvcsw; |
4169 | } | 4175 | } |
4170 | 4176 | ||