greybus: fix a timeout race
authorAlex Elder <elder@linaro.org>
Thu, 20 Nov 2014 21:37:06 +0000 (15:37 -0600)
committerGreg Kroah-Hartman <greg@kroah.com>
Fri, 21 Nov 2014 20:18:38 +0000 (12:18 -0800)
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 <elder@linaro.org>
Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
drivers/staging/greybus/operation.c

index e647425..3e3fc73 100644 (file)
@@ -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);