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

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
...@@ -31,6 +31,7 @@ struct gb_loopback { ...@@ -31,6 +31,7 @@ struct gb_loopback {
u8 version_minor; u8 version_minor;
struct task_struct *task; struct task_struct *task;
wait_queue_head_t wq;
int type; int type;
u32 size; u32 size;
...@@ -113,22 +114,24 @@ static DEVICE_ATTR_RW(field) ...@@ -113,22 +114,24 @@ static DEVICE_ATTR_RW(field)
static void gb_loopback_reset_stats(struct gb_loopback *gb); static void gb_loopback_reset_stats(struct gb_loopback *gb);
static void gb_loopback_check_attr(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) { switch (gb->type) {
case GB_LOOPBACK_TYPE_PING: case GB_LOOPBACK_TYPE_PING:
case GB_LOOPBACK_TYPE_TRANSFER: case GB_LOOPBACK_TYPE_TRANSFER:
case GB_LOOPBACK_TYPE_SINK: case GB_LOOPBACK_TYPE_SINK:
wake_up(&gb->wq);
break; break;
default: default:
gb->type = 0; gb->type = 0;
break; 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 */ /* Time to send and receive one message */
...@@ -397,11 +400,12 @@ static int gb_loopback_fn(void *data) ...@@ -397,11 +400,12 @@ static int gb_loopback_fn(void *data)
struct timeval tlat = {0, 0}; struct timeval tlat = {0, 0};
struct gb_loopback *gb = (struct gb_loopback *)data; struct gb_loopback *gb = (struct gb_loopback *)data;
while (!kthread_should_stop()) { while (1) {
if (!gb->type) { if (!gb->type)
msleep(1000); wait_event_interruptible(gb->wq, gb->type ||
continue; kthread_should_stop());
} if (kthread_should_stop())
break;
if (gb->iteration_max) { if (gb->iteration_max) {
if (gb->iteration_count < gb->iteration_max) { if (gb->iteration_count < gb->iteration_max) {
gb->iteration_count++; gb->iteration_count++;
...@@ -429,7 +433,6 @@ static int gb_loopback_fn(void *data) ...@@ -429,7 +433,6 @@ static int gb_loopback_fn(void *data)
gb->ts = gb->te; gb->ts = gb->te;
if (gb->ms_wait) if (gb->ms_wait)
msleep(gb->ms_wait); msleep(gb->ms_wait);
} }
return 0; return 0;
} }
...@@ -463,6 +466,7 @@ static int gb_loopback_connection_init(struct gb_connection *connection) ...@@ -463,6 +466,7 @@ static int gb_loopback_connection_init(struct gb_connection *connection)
gb->size_max -= sizeof(struct gb_loopback_transfer_request); gb->size_max -= sizeof(struct gb_loopback_transfer_request);
gb_loopback_reset_stats(gb); gb_loopback_reset_stats(gb);
init_waitqueue_head(&gb->wq);
gb->task = kthread_run(gb_loopback_fn, gb, "gb_loopback"); gb->task = kthread_run(gb_loopback_fn, gb, "gb_loopback");
if (IS_ERR(gb->task)) { if (IS_ERR(gb->task)) {
retval = PTR_ERR(gb->task); retval = PTR_ERR(gb->task);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment