aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-06-12 15:55:18 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-06-12 15:55:18 -0400
commit1b3cba8e60c67c968d108ac55c77e32c1928dec3 (patch)
tree79ce35debeb7e203558d884efd03c7cf160cceaa
parent14a73f54798f39854e521fb596da7d50b7566bbd (diff)
parent7a232e0350940d2664f4de5cc3f0f443bae5062d (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.h13
-rw-r--r--kernel/sched.c22
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
2029static 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
2029static inline int need_resched(void) 2042static 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
322static int init_task_group_load = INIT_TASK_GROUP_LOAD; 325static 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