]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blobdiff - src/patches/suse-2.6.27.31/patches.arch/s390-12-01-cio-reprobe-deadlock-fix.patch
Move xen patchset to new version's subdir.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.arch / s390-12-01-cio-reprobe-deadlock-fix.patch
diff --git a/src/patches/suse-2.6.27.31/patches.arch/s390-12-01-cio-reprobe-deadlock-fix.patch b/src/patches/suse-2.6.27.31/patches.arch/s390-12-01-cio-reprobe-deadlock-fix.patch
new file mode 100644 (file)
index 0000000..3411702
--- /dev/null
@@ -0,0 +1,59 @@
+From: Gerald Schaefer <geraldsc@de.ibm.com>
+Subject: cio: incomplete device initialization on LPAR
+References: bnc#487755,LTC#52366
+
+Symptom:     Random CCW devices are not usable after IPL. Sysfs shows
+             subchannel directories without links to CCW devices. This occurs
+             on LPARs with DASDs.
+Problem:     The DASD device driver triggers the subchannel reprobe function
+             during PAV initialization. Subchannel reprobing blocks the kslowcrw
+             workqueue until all outstanding device recognition requests have
+             finished processing. Device recognition uses kslowcrw to finish
+             processing which leads to a workqueue deadlock.
+Solution:    Move the waiting portion of subchannel reprobing to the cio
+             workqueue.
+
+Acked-by: John Jolly <jjolly@suse.de>
+
+---
+ drivers/s390/cio/css.c |   19 ++++++++++++++++---
+ 1 file changed, 16 insertions(+), 3 deletions(-)
+
+Index: linux-sles11/drivers/s390/cio/css.c
+===================================================================
+--- linux-sles11.orig/drivers/s390/cio/css.c
++++ linux-sles11/drivers/s390/cio/css.c
+@@ -509,6 +509,17 @@ static int reprobe_subchannel(struct sub
+       return ret;
+ }
++static void reprobe_after_idle(struct work_struct *unused)
++{
++      /* Make sure initial subchannel scan is done. */
++      wait_event(ccw_device_init_wq,
++                 atomic_read(&ccw_device_init_count) == 0);
++      if (need_reprobe)
++              css_schedule_reprobe();
++}
++
++static DECLARE_WORK(reprobe_idle_work, reprobe_after_idle);
++
+ /* Work function used to reprobe all unregistered subchannels. */
+ static void reprobe_all(struct work_struct *unused)
+ {
+@@ -516,10 +527,12 @@ static void reprobe_all(struct work_stru
+       CIO_MSG_EVENT(4, "reprobe start\n");
+-      need_reprobe = 0;
+       /* Make sure initial subchannel scan is done. */
+-      wait_event(ccw_device_init_wq,
+-                 atomic_read(&ccw_device_init_count) == 0);
++      if (atomic_read(&ccw_device_init_count) != 0) {
++              queue_work(ccw_device_work, &reprobe_idle_work);
++              return;
++      }
++      need_reprobe = 0;
+       ret = for_each_subchannel_staged(NULL, reprobe_subchannel, NULL);
+       CIO_MSG_EVENT(4, "reprobe done (rc=%d, need_reprobe=%d)\n", ret,