]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
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, |