aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-01-26 12:47:43 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-01-26 12:47:43 -0500
commit1e70c7f7a9d4a3d2cc78b40e1d7768d99cd79899 (patch)
tree1218c32008412e57314f8f9db8d3b4912e2ecb25
parent810ee58de26c9c1255d716b1db7344c4a1093fec (diff)
parent1d4a7f1c4faf53eb9e822743ec8a70b3019a26d2 (diff)
Merge branch 'timers-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'timers-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: hrtimers: fix inconsistent lock state on resume in hres_timers_resume time-sched.c: tick_nohz_update_jiffies should be static locking, hpet: annotate false positive warning kernel/fork.c: unused variable 'ret' itimers: remove the per-cpu-ish-ness
-rw-r--r--arch/x86/kernel/hpet.c2
-rw-r--r--include/linux/init_task.h6
-rw-r--r--include/linux/sched.h29
-rw-r--r--include/linux/workqueue.h6
-rw-r--r--kernel/fork.c16
-rw-r--r--kernel/hrtimer.c4
-rw-r--r--kernel/posix-cpu-timers.c70
-rw-r--r--kernel/sched_stats.h33
-rw-r--r--kernel/time/tick-sched.c2
9 files changed, 57 insertions, 111 deletions
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index cd759ad90690..bb2e0f0975ae 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -628,7 +628,7 @@ static int hpet_cpuhp_notify(struct notifier_block *n,
628 628
629 switch (action & 0xf) { 629 switch (action & 0xf) {
630 case CPU_ONLINE: 630 case CPU_ONLINE:
631 INIT_DELAYED_WORK(&work.work, hpet_work); 631 INIT_DELAYED_WORK_ON_STACK(&work.work, hpet_work);
632 init_completion(&work.complete); 632 init_completion(&work.complete);
633 /* FIXME: add schedule_work_on() */ 633 /* FIXME: add schedule_work_on() */
634 schedule_delayed_work_on(cpu, &work.work, 0); 634 schedule_delayed_work_on(cpu, &work.work, 0);
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index 2f3c2d4ef73b..ea0ea1a4c36f 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -48,6 +48,12 @@ extern struct fs_struct init_fs;
48 .posix_timers = LIST_HEAD_INIT(sig.posix_timers), \ 48 .posix_timers = LIST_HEAD_INIT(sig.posix_timers), \
49 .cpu_timers = INIT_CPU_TIMERS(sig.cpu_timers), \ 49 .cpu_timers = INIT_CPU_TIMERS(sig.cpu_timers), \
50 .rlim = INIT_RLIMITS, \ 50 .rlim = INIT_RLIMITS, \
51 .cputime = { .totals = { \
52 .utime = cputime_zero, \
53 .stime = cputime_zero, \
54 .sum_exec_runtime = 0, \
55 .lock = __SPIN_LOCK_UNLOCKED(sig.cputime.totals.lock), \
56 }, }, \
51} 57}
52 58
53extern struct nsproxy init_nsproxy; 59extern struct nsproxy init_nsproxy;
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 4cae9b81a1f8..c20943eabb4c 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -450,6 +450,7 @@ struct task_cputime {
450 cputime_t utime; 450 cputime_t utime;
451 cputime_t stime; 451 cputime_t stime;
452 unsigned long long sum_exec_runtime; 452 unsigned long long sum_exec_runtime;
453 spinlock_t lock;
453}; 454};
454/* Alternate field names when used to cache expirations. */ 455/* Alternate field names when used to cache expirations. */
455#define prof_exp stime 456#define prof_exp stime
@@ -465,7 +466,7 @@ struct task_cputime {
465 * used for thread group CPU clock calculations. 466 * used for thread group CPU clock calculations.
466 */ 467 */
467struct thread_group_cputime { 468struct thread_group_cputime {
468 struct task_cputime *totals; 469 struct task_cputime totals;
469}; 470};
470 471
471/* 472/*
@@ -2180,24 +2181,30 @@ static inline int spin_needbreak(spinlock_t *lock)
2180 * Thread group CPU time accounting. 2181 * Thread group CPU time accounting.
2181 */ 2182 */
2182 2183
2183extern int thread_group_cputime_alloc(struct task_struct *); 2184static inline
2184extern void thread_group_cputime(struct task_struct *, struct task_cputime *); 2185void thread_group_cputime(struct task_struct *tsk, struct task_cputime *times)
2185
2186static inline void thread_group_cputime_init(struct signal_struct *sig)
2187{ 2186{
2188 sig->cputime.totals = NULL; 2187 struct task_cputime *totals = &tsk->signal->cputime.totals;
2188 unsigned long flags;
2189
2190 spin_lock_irqsave(&totals->lock, flags);
2191 *times = *totals;
2192 spin_unlock_irqrestore(&totals->lock, flags);
2189} 2193}
2190 2194
2191static inline int thread_group_cputime_clone_thread(struct task_struct *curr) 2195static inline void thread_group_cputime_init(struct signal_struct *sig)
2192{ 2196{
2193 if (curr->signal->cputime.totals) 2197 sig->cputime.totals = (struct task_cputime){
2194 return 0; 2198 .utime = cputime_zero,
2195 return thread_group_cputime_alloc(curr); 2199 .stime = cputime_zero,
2200 .sum_exec_runtime = 0,
2201 };
2202
2203 spin_lock_init(&sig->cputime.totals.lock);
2196} 2204}
2197 2205
2198static inline void thread_group_cputime_free(struct signal_struct *sig) 2206static inline void thread_group_cputime_free(struct signal_struct *sig)
2199{ 2207{
2200 free_percpu(sig->cputime.totals);
2201} 2208}
2202 2209
2203/* 2210/*
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index b36291130f22..47151c8495aa 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -118,6 +118,12 @@ struct execute_work {
118 init_timer(&(_work)->timer); \ 118 init_timer(&(_work)->timer); \
119 } while (0) 119 } while (0)
120 120
121#define INIT_DELAYED_WORK_ON_STACK(_work, _func) \
122 do { \
123 INIT_WORK(&(_work)->work, (_func)); \
124 init_timer_on_stack(&(_work)->timer); \
125 } while (0)
126
121#define INIT_DELAYED_WORK_DEFERRABLE(_work, _func) \ 127#define INIT_DELAYED_WORK_DEFERRABLE(_work, _func) \
122 do { \ 128 do { \
123 INIT_WORK(&(_work)->work, (_func)); \ 129 INIT_WORK(&(_work)->work, (_func)); \
diff --git a/kernel/fork.c b/kernel/fork.c
index bf0cef8bbdf2..242a706e7721 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -817,17 +817,17 @@ static void posix_cpu_timers_init_group(struct signal_struct *sig)
817static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) 817static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
818{ 818{
819 struct signal_struct *sig; 819 struct signal_struct *sig;
820 int ret;
821 820
822 if (clone_flags & CLONE_THREAD) { 821 if (clone_flags & CLONE_THREAD) {
823 ret = thread_group_cputime_clone_thread(current); 822 atomic_inc(&current->signal->count);
824 if (likely(!ret)) { 823 atomic_inc(&current->signal->live);
825 atomic_inc(&current->signal->count); 824 return 0;
826 atomic_inc(&current->signal->live);
827 }
828 return ret;
829 } 825 }
830 sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL); 826 sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL);
827
828 if (sig)
829 posix_cpu_timers_init_group(sig);
830
831 tsk->signal = sig; 831 tsk->signal = sig;
832 if (!sig) 832 if (!sig)
833 return -ENOMEM; 833 return -ENOMEM;
@@ -864,8 +864,6 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
864 memcpy(sig->rlim, current->signal->rlim, sizeof sig->rlim); 864 memcpy(sig->rlim, current->signal->rlim, sizeof sig->rlim);
865 task_unlock(current->group_leader); 865 task_unlock(current->group_leader);
866 866
867 posix_cpu_timers_init_group(sig);
868
869 acct_init_pacct(&sig->pacct); 867 acct_init_pacct(&sig->pacct);
870 868
871 tty_audit_fork(sig); 869 tty_audit_fork(sig);
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index 2dc30c59c5fd..f33afb0407bc 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -614,7 +614,9 @@ void clock_was_set(void)
614 */ 614 */
615void hres_timers_resume(void) 615void hres_timers_resume(void)
616{ 616{
617 /* Retrigger the CPU local events: */ 617 WARN_ONCE(!irqs_disabled(),
618 KERN_INFO "hres_timers_resume() called with IRQs enabled!");
619
618 retrigger_next_event(NULL); 620 retrigger_next_event(NULL);
619} 621}
620 622
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
index 157de3a47832..fa07da94d7be 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -10,76 +10,6 @@
10#include <linux/kernel_stat.h> 10#include <linux/kernel_stat.h>
11 11
12/* 12/*
13 * Allocate the thread_group_cputime structure appropriately and fill in the
14 * current values of the fields. Called from copy_signal() via
15 * thread_group_cputime_clone_thread() when adding a second or subsequent