Skip to content

Commit

Permalink
[S390] cio: prevent workqueue deadlock
Browse files Browse the repository at this point in the history
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: Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
  • Loading branch information
Peter Oberparleiter authored and Martin Schwidefsky committed Mar 26, 2009
1 parent 0cc1106 commit 56e25e9
Showing 1 changed file with 16 additions and 3 deletions.
19 changes: 16 additions & 3 deletions drivers/s390/cio/css.c
Original file line number Diff line number Diff line change
Expand Up @@ -533,17 +533,30 @@ 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)
{
int ret;

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,
Expand Down

0 comments on commit 56e25e9

Please sign in to comment.