mirror of https://gitee.com/openkylin/linux.git
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: Greg Kroah-Hartman <gregkh@google.com> Signed-off-by: Johan Hovold <johan@hovoldconsulting.com> Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
parent
5c1ac69455
commit
85109f7ddd
|
@ -528,14 +528,12 @@ EXPORT_SYMBOL_GPL(gb_operation_get);
|
||||||
static void _gb_operation_destroy(struct kref *kref)
|
static void _gb_operation_destroy(struct kref *kref)
|
||||||
{
|
{
|
||||||
struct gb_operation *operation;
|
struct gb_operation *operation;
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
operation = container_of(kref, struct gb_operation, kref);
|
operation = container_of(kref, struct gb_operation, kref);
|
||||||
|
|
||||||
/* XXX Make sure it's not in flight */
|
/* XXX Make sure it's not in flight */
|
||||||
spin_lock_irqsave(&gb_operations_lock, flags);
|
|
||||||
list_del(&operation->links);
|
list_del(&operation->links);
|
||||||
spin_unlock_irqrestore(&gb_operations_lock, flags);
|
spin_unlock(&gb_operations_lock);
|
||||||
|
|
||||||
if (operation->response)
|
if (operation->response)
|
||||||
gb_operation_message_free(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)
|
void gb_operation_put(struct gb_operation *operation)
|
||||||
{
|
{
|
||||||
if (!WARN_ON(!operation))
|
if (WARN_ON(!operation))
|
||||||
kref_put(&operation->kref, _gb_operation_destroy);
|
return;
|
||||||
|
|
||||||
|
kref_put_spinlock_irqsave(&operation->kref, _gb_operation_destroy,
|
||||||
|
&gb_operations_lock);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(gb_operation_put);
|
EXPORT_SYMBOL_GPL(gb_operation_put);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue