From e8b48d1586abd62dd1749520dccd4bac784ce680 Mon Sep 17 00:00:00 2001 From: Alex Elder Date: Thu, 20 Nov 2014 15:37:06 -0600 Subject: [PATCH] greybus: fix a timeout race Whenever we send a request message we start a timer to ensure the we don't wait too long for the matching response to arrive. Currently we set up the timeout *after* sending the message, but that is subject to a race--the response could arrive (and the timeout prematurely disabled) before the timeout is even set up. Set up the timeout before sending the message. Signed-off-by: Alex Elder Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/operation.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/staging/greybus/operation.c b/drivers/staging/greybus/operation.c index e6474253eae2..3e3fc73a881c 100644 --- a/drivers/staging/greybus/operation.c +++ b/drivers/staging/greybus/operation.c @@ -447,13 +447,20 @@ int gb_operation_request_send(struct gb_operation *operation, */ operation->callback = callback; gb_pending_operation_insert(operation); + + /* + * We impose a time limit for requests to complete. We need + * to set the timer before we send the request though, so we + * don't lose a race with the receipt of the resposne. + */ + timeout = msecs_to_jiffies(OPERATION_TIMEOUT_DEFAULT); + schedule_delayed_work(&operation->timeout_work, timeout); + + /* All set, send the request */ ret = gb_message_send(&operation->request, GFP_KERNEL); if (ret) return ret; - /* We impose a time limit for requests to complete. */ - timeout = msecs_to_jiffies(OPERATION_TIMEOUT_DEFAULT); - schedule_delayed_work(&operation->timeout_work, timeout); if (!callback) ret = gb_operation_wait(operation);