Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 56e25e97 authored by Peter Oberparleiter's avatar Peter Oberparleiter Committed by Martin Schwidefsky
Browse files

[S390] cio: prevent workqueue deadlock



Subchannel reprobing can block the kslowcrw workqueue indefinitely
while waiting for device recognition to finish which is also scheduled
to run on kslowcrw. Prevent this deadlock by moving the waiting
portion of subchannel reprobing to the cio workqueue.

Signed-off-by: default avatarPeter Oberparleiter <peter.oberparleiter@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 0cc11065
Loading
Loading
Loading
Loading
+16 −3
Original line number Diff line number Diff line
@@ -533,6 +533,17 @@ static int reprobe_subchannel(struct subchannel_id schid, void *data)
	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)
{
@@ -540,10 +551,12 @@ static void reprobe_all(struct work_struct *unused)

	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,