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

Commit b4c70721 authored by Sebastian Ott's avatar Sebastian Ott Committed by Martin Schwidefsky
Browse files

[S390] cio: make wait_events interruptible



Make the potentially long blocking wait_event's used by the cio
settle mechanism interruptible.

Signed-off-by: default avatarSebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent b4563e89
Loading
Loading
Loading
Loading
+12 −6
Original line number Diff line number Diff line
@@ -1016,19 +1016,22 @@ static int css_settle(struct device_driver *drv, void *unused)
	struct css_driver *cssdrv = to_cssdriver(drv);

	if (cssdrv->settle)
		cssdrv->settle();
		return cssdrv->settle();
	return 0;
}

static inline void css_complete_work(void)
static inline int css_complete_work(void)
{
	int ret;

	/* Wait for the evaluation of subchannels to finish. */
	wait_event(css_eval_wq, atomic_read(&css_eval_scheduled) == 0);
	ret = wait_event_interruptible(css_eval_wq,
				       atomic_read(&css_eval_scheduled) == 0);
	if (ret)
		return -EINTR;
	flush_workqueue(cio_work_q);
	/* Wait for the subchannel type specific initialization to finish */
	ret = bus_for_each_drv(&css_bus_type, NULL, NULL, css_settle);
	return bus_for_each_drv(&css_bus_type, NULL, NULL, css_settle);
}


@@ -1049,10 +1052,13 @@ subsys_initcall_sync(channel_subsystem_init_sync);
static ssize_t cio_settle_write(struct file *file, const char __user *buf,
				size_t count, loff_t *ppos)
{
	int ret;

	/* Handle pending CRW's. */
	crw_wait_for_channel_report();
	css_complete_work();
	return count;
	ret = css_complete_work();

	return ret ? ret : count;
}

static const struct file_operations cio_settle_proc_fops = {
+1 −1
Original line number Diff line number Diff line
@@ -95,7 +95,7 @@ struct css_driver {
	int (*freeze)(struct subchannel *);
	int (*thaw) (struct subchannel *);
	int (*restore)(struct subchannel *);
	void (*settle)(void);
	int (*settle)(void);
	const char *name;
};

+8 −3
Original line number Diff line number Diff line
@@ -158,11 +158,16 @@ static int io_subchannel_prepare(struct subchannel *sch)
	return 0;
}

static void io_subchannel_settle(void)
static int io_subchannel_settle(void)
{
	wait_event(ccw_device_init_wq,
	int ret;

	ret = wait_event_interruptible(ccw_device_init_wq,
				atomic_read(&ccw_device_init_count) == 0);
	if (ret)
		return -EINTR;
	flush_workqueue(cio_work_q);
	return 0;
}

static struct css_driver io_subchannel_driver = {