]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.31/patches.arch/s390-05-06-stp-etr-mutex.patch
Disable build of xen kernel.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.arch / s390-05-06-stp-etr-mutex.patch
1 From: Gerald Schaefer <geraldsc@de.ibm.com>
2 Subject: stp/etr: serialize work.
3 References: bnc#450096
4
5 Symptom: Oops when setting stp online.
6 Problem: The stp/etr work function dispatched with schedule_work()
7 can be run twice on different cpus because run_workqueue
8 clears the WORK_STRUCT_PENDING bit before it executes the
9 function.
10 Solution: Serialize the etr and stp work functions with a mutex.
11
12 Acked-by: John Jolly <jjolly@suse.de>
13 ---
14 arch/s390/kernel/time.c | 23 ++++++++++++++++++-----
15 1 file changed, 18 insertions(+), 5 deletions(-)
16
17 Index: linux-2.6.27/arch/s390/kernel/time.c
18 ===================================================================
19 --- linux-2.6.27.orig/arch/s390/kernel/time.c
20 +++ linux-2.6.27/arch/s390/kernel/time.c
21 @@ -441,6 +441,7 @@ static struct timer_list etr_timer;
22
23 static void etr_timeout(unsigned long dummy);
24 static void etr_work_fn(struct work_struct *work);
25 +static DEFINE_MUTEX(etr_work_mutex);
26 static DECLARE_WORK(etr_work, etr_work_fn);
27
28 /*
29 @@ -950,6 +951,9 @@ static void etr_work_fn(struct work_stru
30 struct etr_aib aib;
31 int sync_port;
32
33 + /* prevent multiple execution. */
34 + mutex_lock(&etr_work_mutex);
35 +
36 /* Create working copy of etr_eacr. */
37 eacr = etr_eacr;
38
39 @@ -965,7 +969,7 @@ static void etr_work_fn(struct work_stru
40 del_timer_sync(&etr_timer);
41 etr_update_eacr(eacr);
42 clear_bit(CLOCK_SYNC_ETR, &clock_sync_flags);
43 - return;
44 + goto out_unlock;
45 }
46
47 /* Store aib to get the current ETR status word. */
48 @@ -1052,7 +1056,7 @@ static void etr_work_fn(struct work_stru
49 eacr.es || sync_port < 0) {
50 etr_update_eacr(eacr);
51 etr_set_tolec_timeout(now);
52 - return;
53 + goto out_unlock;
54 }
55
56 /*
57 @@ -1080,6 +1084,8 @@ static void etr_work_fn(struct work_stru
58 etr_set_sync_timeout();
59 } else
60 etr_set_tolec_timeout(now);
61 +out_unlock:
62 + mutex_unlock(&etr_work_mutex);
63 }
64
65 /*
66 @@ -1368,6 +1374,7 @@ static struct stp_sstpi stp_info;
67 static void *stp_page;
68
69 static void stp_work_fn(struct work_struct *work);
70 +static DEFINE_MUTEX(stp_work_mutex);
71 static DECLARE_WORK(stp_work, stp_work_fn);
72
73 static int __init early_parse_stp(char *p)
74 @@ -1517,24 +1524,30 @@ static void stp_work_fn(struct work_stru
75 struct clock_sync_data stp_sync;
76 int rc;
77
78 + /* prevent multiple execution. */
79 + mutex_lock(&stp_work_mutex);
80 +
81 if (!stp_online) {
82 chsc_sstpc(stp_page, STP_OP_CTRL, 0x0000);
83 - return;
84 + goto out_unlock;
85 }
86
87 rc = chsc_sstpc(stp_page, STP_OP_CTRL, 0xb0e0);
88 if (rc)
89 - return;
90 + goto out_unlock;
91
92 rc = chsc_sstpi(stp_page, &stp_info, sizeof(struct stp_sstpi));
93 if (rc || stp_info.c == 0)
94 - return;
95 + goto out_unlock;
96
97 memset(&stp_sync, 0, sizeof(stp_sync));
98 get_online_cpus();
99 atomic_set(&stp_sync.cpus, num_online_cpus() - 1);
100 stop_machine(stp_sync_clock, &stp_sync, &cpu_online_map);
101 put_online_cpus();
102 +
103 +out_unlock:
104 + mutex_unlock(&stp_work_mutex);
105 }
106
107 /*