Commit 85109f7d authored by Johan Hovold's avatar Johan Hovold Committed by Greg Kroah-Hartman

greybus: operation: fix operation-destroy race

Make sure to acquire the connection-list lock atomically when releasing
the final reference.

This allows the list to be traversed and references to be acquired
(while holding the lock) without racing with the destructor.
Suggested-by: default avatarGreg Kroah-Hartman <gregkh@google.com>
Signed-off-by: default avatarJohan Hovold <johan@hovoldconsulting.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@google.com>
parent 5c1ac694
......@@ -528,14 +528,12 @@ EXPORT_SYMBOL_GPL(gb_operation_get);
static void _gb_operation_destroy(struct kref *kref)
{
struct gb_operation *operation;
unsigned long flags;
operation = container_of(kref, struct gb_operation, kref);
/* XXX Make sure it's not in flight */
spin_lock_irqsave(&gb_operations_lock, flags);
list_del(&operation->links);
spin_unlock_irqrestore(&gb_operations_lock, flags);
spin_unlock(&gb_operations_lock);
if (operation->response)
gb_operation_message_free(operation->response);
......@@ -550,8 +548,11 @@ static void _gb_operation_destroy(struct kref *kref)
*/
void gb_operation_put(struct gb_operation *operation)
{
if (!WARN_ON(!operation))
kref_put(&operation->kref, _gb_operation_destroy);
if (WARN_ON(!operation))
return;
kref_put_spinlock_irqsave(&operation->kref, _gb_operation_destroy,
&gb_operations_lock);
}
EXPORT_SYMBOL_GPL(gb_operation_put);
......
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