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)
|
||||
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
|
||||
* 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_id = cpu_to_le16(operation->id);
|
||||
|
||||
/* All set, send the request */
|
||||
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);
|
||||
if (ret)
|
||||
goto err_put_active;
|
||||
|
|
Loading…
Reference in New Issue