greybus: operation: fix operation look-up race
Make sure to fully initialise the operation before adding it to the active list when sending a request. The operation should be fully initialised before adding it to the active list to avoid racing with operation look up when receiving a response, something which could potentially lead to a match against some earlier (or intermediate) value of the id field. Signed-off-by: Johan Hovold <johan@hovoldconsulting.com> Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
parent
7f1b67cd53
commit
3325a4ad71
|
@ -642,16 +642,6 @@ int gb_operation_request_send(struct gb_operation *operation,
|
||||||
|
|
||||||
if (!callback)
|
if (!callback)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/*
|
|
||||||
* First, get an extra reference on the operation.
|
|
||||||
* It'll be dropped when the operation completes.
|
|
||||||
*/
|
|
||||||
gb_operation_get(operation);
|
|
||||||
ret = gb_operation_get_active(operation);
|
|
||||||
if (ret)
|
|
||||||
goto err_put;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Record the callback function, which is executed in
|
* Record the callback function, which is executed in
|
||||||
* non-atomic (workqueue) context when the final result
|
* non-atomic (workqueue) context when the final result
|
||||||
|
@ -668,9 +658,17 @@ int gb_operation_request_send(struct gb_operation *operation,
|
||||||
header = operation->request->header;
|
header = operation->request->header;
|
||||||
header->operation_id = cpu_to_le16(operation->id);
|
header->operation_id = cpu_to_le16(operation->id);
|
||||||
|
|
||||||
/* All set, send the request */
|
|
||||||
gb_operation_result_set(operation, -EINPROGRESS);
|
gb_operation_result_set(operation, -EINPROGRESS);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get an extra reference on the operation. It'll be dropped when the
|
||||||
|
* operation completes.
|
||||||
|
*/
|
||||||
|
gb_operation_get(operation);
|
||||||
|
ret = gb_operation_get_active(operation);
|
||||||
|
if (ret)
|
||||||
|
goto err_put;
|
||||||
|
|
||||||
ret = gb_message_send(operation->request, gfp);
|
ret = gb_message_send(operation->request, gfp);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_put_active;
|
goto err_put_active;
|
||||||
|
|
Loading…
Reference in New Issue