]>
Commit | Line | Data |
---|---|---|
1 | From: Gerald Schaefer <geraldsc@de.ibm.com> | |
2 | Subject: kernel: appldata vtimer bug with cpu hotplug | |
3 | References: bnc#487755,LTC#52680 | |
4 | ||
5 | Symptom: Kernel BUG on SLES 11 with cpu hotplug and appldata timer enabled. | |
6 | On older distributions, the appldata interval will not expire | |
7 | correctly instead (interval may be longer after cpu hotplug). | |
8 | Problem: The mod_virt_timer() function will add a one-shot timer for new | |
9 | cpus, not an interval timer. Also, on SLES 11 there is a misplaced | |
10 | BUG_ON() statement in that function. | |
11 | Solution: Work around by adding a new vtimer for cpus that get online, | |
12 | before modifying it. | |
13 | ||
14 | Acked-by: John Jolly <jjolly@suse.de> | |
15 | --- | |
16 | arch/s390/appldata/appldata_base.c | 11 ++++++++++- | |
17 | 1 file changed, 10 insertions(+), 1 deletion(-) | |
18 | ||
19 | Index: linux-sles11/arch/s390/appldata/appldata_base.c | |
20 | =================================================================== | |
21 | --- linux-sles11.orig/arch/s390/appldata/appldata_base.c | |
22 | +++ linux-sles11/arch/s390/appldata/appldata_base.c | |
23 | @@ -478,13 +478,22 @@ void appldata_unregister_ops(struct appl | |
24 | ||
25 | static void __cpuinit appldata_online_cpu(int cpu) | |
26 | { | |
27 | + u64 per_cpu_interval; | |
28 | + | |
29 | init_virt_timer(&per_cpu(appldata_timer, cpu)); | |
30 | per_cpu(appldata_timer, cpu).function = appldata_timer_function; | |
31 | per_cpu(appldata_timer, cpu).data = (unsigned long) | |
32 | &appldata_work; | |
33 | atomic_inc(&appldata_expire_count); | |
34 | spin_lock(&appldata_timer_lock); | |
35 | - __appldata_vtimer_setup(APPLDATA_MOD_TIMER); | |
36 | + if (appldata_timer_active) { | |
37 | + per_cpu_interval = (u64) (appldata_interval * 1000 / | |
38 | + num_online_cpus()) * TOD_MICRO; | |
39 | + per_cpu(appldata_timer, cpu).expires = per_cpu_interval; | |
40 | + smp_call_function_single(cpu, add_virt_timer_periodic, | |
41 | + &per_cpu(appldata_timer, cpu), 1); | |
42 | + __appldata_vtimer_setup(APPLDATA_MOD_TIMER); | |
43 | + } | |
44 | spin_unlock(&appldata_timer_lock); | |
45 | } | |
46 |