]> git.ipfire.org Git - ipfire-2.x.git/blob - src/patches/suse-2.6.27.31/patches.arch/s390-12-01-cio-reprobe-deadlock-fix.patch
Add a patch to fix Intel E100 wake-on-lan problems.
[ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.arch / s390-12-01-cio-reprobe-deadlock-fix.patch
1 From: Gerald Schaefer <geraldsc@de.ibm.com>
2 Subject: cio: incomplete device initialization on LPAR
3 References: bnc#487755,LTC#52366
4
5 Symptom: Random CCW devices are not usable after IPL. Sysfs shows
6 subchannel directories without links to CCW devices. This occurs
7 on LPARs with DASDs.
8 Problem: The DASD device driver triggers the subchannel reprobe function
9 during PAV initialization. Subchannel reprobing blocks the kslowcrw
10 workqueue until all outstanding device recognition requests have
11 finished processing. Device recognition uses kslowcrw to finish
12 processing which leads to a workqueue deadlock.
13 Solution: Move the waiting portion of subchannel reprobing to the cio
14 workqueue.
15
16 Acked-by: John Jolly <jjolly@suse.de>
17
18 ---
19 drivers/s390/cio/css.c | 19 ++++++++++++++++---
20 1 file changed, 16 insertions(+), 3 deletions(-)
21
22 Index: linux-sles11/drivers/s390/cio/css.c
23 ===================================================================
24 --- linux-sles11.orig/drivers/s390/cio/css.c
25 +++ linux-sles11/drivers/s390/cio/css.c
26 @@ -509,6 +509,17 @@ static int reprobe_subchannel(struct sub
27 return ret;
28 }
29
30 +static void reprobe_after_idle(struct work_struct *unused)
31 +{
32 + /* Make sure initial subchannel scan is done. */
33 + wait_event(ccw_device_init_wq,
34 + atomic_read(&ccw_device_init_count) == 0);
35 + if (need_reprobe)
36 + css_schedule_reprobe();
37 +}
38 +
39 +static DECLARE_WORK(reprobe_idle_work, reprobe_after_idle);
40 +
41 /* Work function used to reprobe all unregistered subchannels. */
42 static void reprobe_all(struct work_struct *unused)
43 {
44 @@ -516,10 +527,12 @@ static void reprobe_all(struct work_stru
45
46 CIO_MSG_EVENT(4, "reprobe start\n");
47
48 - need_reprobe = 0;
49 /* Make sure initial subchannel scan is done. */
50 - wait_event(ccw_device_init_wq,
51 - atomic_read(&ccw_device_init_count) == 0);
52 + if (atomic_read(&ccw_device_init_count) != 0) {
53 + queue_work(ccw_device_work, &reprobe_idle_work);
54 + return;
55 + }
56 + need_reprobe = 0;
57 ret = for_each_subchannel_staged(NULL, reprobe_subchannel, NULL);
58
59 CIO_MSG_EVENT(4, "reprobe done (rc=%d, need_reprobe=%d)\n", ret,