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

Commit 3dfe8aaa authored by Bryan O'Donoghue's avatar Bryan O'Donoghue Committed by Greg Kroah-Hartman
Browse files

greybus: loopback: convert loopback wake/sleep to a waitqueue



Current code will incrementally poll for gb->type == 0 and sleep.
This type of polling strategy wastes cycles.

This patch changes the sleep strategy by introducing a wait-queue which
waits for gb->type != 0 or kthread_should_stop() to wake-up and work or
to wake-up and terminate.

Signed-off-by: default avatarBryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@google.com>
parent c2939f41
Loading
Loading
Loading
Loading
+17 −13
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ struct gb_loopback {
	u8 version_minor;

	struct task_struct *task;
	wait_queue_head_t wq;

	int type;
	u32 size;
@@ -113,22 +114,24 @@ static DEVICE_ATTR_RW(field)
static void gb_loopback_reset_stats(struct gb_loopback *gb);
static void gb_loopback_check_attr(struct gb_loopback *gb)
{
	if (gb->ms_wait > GB_LOOPBACK_MS_WAIT_MAX)
		gb->ms_wait = GB_LOOPBACK_MS_WAIT_MAX;
	if (gb->size > gb->size_max)
		gb->size = gb->size_max;
	gb->error = 0;
	gb->iteration_count = 0;
	gb_loopback_reset_stats(gb);

	switch (gb->type) {
	case GB_LOOPBACK_TYPE_PING:
	case GB_LOOPBACK_TYPE_TRANSFER:
	case GB_LOOPBACK_TYPE_SINK:
		wake_up(&gb->wq);
		break;
	default:
		gb->type = 0;
		break;
	}
	if (gb->ms_wait > GB_LOOPBACK_MS_WAIT_MAX)
		gb->ms_wait = GB_LOOPBACK_MS_WAIT_MAX;
	if (gb->size > gb->size_max)
		gb->size = gb->size_max;
	gb->error = 0;
	gb->iteration_count = 0;
	gb_loopback_reset_stats(gb);
}

/* Time to send and receive one message */
@@ -397,11 +400,12 @@ static int gb_loopback_fn(void *data)
	struct timeval tlat = {0, 0};
	struct gb_loopback *gb = (struct gb_loopback *)data;

	while (!kthread_should_stop()) {
		if (!gb->type) {
			msleep(1000);
			continue;
		}
	while (1) {
		if (!gb->type)
			wait_event_interruptible(gb->wq, gb->type ||
						 kthread_should_stop());
		if (kthread_should_stop())
			break;
		if (gb->iteration_max) {
			if (gb->iteration_count < gb->iteration_max) {
				gb->iteration_count++;
@@ -429,7 +433,6 @@ static int gb_loopback_fn(void *data)
		gb->ts = gb->te;
		if (gb->ms_wait)
			msleep(gb->ms_wait);

	}
	return 0;
}
@@ -463,6 +466,7 @@ static int gb_loopback_connection_init(struct gb_connection *connection)
	gb->size_max -= sizeof(struct gb_loopback_transfer_request);

	gb_loopback_reset_stats(gb);
	init_waitqueue_head(&gb->wq);
	gb->task = kthread_run(gb_loopback_fn, gb, "gb_loopback");
	if (IS_ERR(gb->task)) {
		retval = PTR_ERR(gb->task);