greybus: add a reference to pending operations
Grab an extra reference to an operation before sending it. Drop that reference at the end of its completion handling. It turns out gb_operation_get() got deleted along the way, so this re-introduces it. We're assuming we only get a reference when there's at least one in existence so we don't need a semaphore to protect it. Emphasize this by *not* returning a pointer to the referenced operation. Signed-off-by: Alex Elder <elder@linaro.org> Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
This commit is contained in:
Родитель
583c3117a4
Коммит
deb4b9efb3
|
@ -157,6 +157,7 @@ static void gb_operation_complete(struct gb_operation *operation)
|
|||
operation->callback(operation);
|
||||
else
|
||||
complete_all(&operation->completion);
|
||||
gb_operation_put(operation);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -409,6 +410,14 @@ gb_operation_create_incoming(struct gb_connection *connection,
|
|||
request_size, response_size);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get an additional reference on an operation.
|
||||
*/
|
||||
void gb_operation_get(struct gb_operation *operation)
|
||||
{
|
||||
kref_get(&operation->kref);
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroy a previously created operation.
|
||||
*/
|
||||
|
@ -429,6 +438,10 @@ static void _gb_operation_destroy(struct kref *kref)
|
|||
kmem_cache_free(gb_operation_cache, operation);
|
||||
}
|
||||
|
||||
/*
|
||||
* Drop a reference on an operation, and destroy it when the last
|
||||
* one is gone.
|
||||
*/
|
||||
void gb_operation_put(struct gb_operation *operation)
|
||||
{
|
||||
if (!WARN_ON(!operation))
|
||||
|
@ -454,11 +467,11 @@ int gb_operation_request_send(struct gb_operation *operation,
|
|||
return -ENOTCONN;
|
||||
|
||||
/*
|
||||
* XXX
|
||||
* I think the order of operations is going to be
|
||||
* significant, and if so, we may need a mutex to surround
|
||||
* setting the operation id and submitting the buffer.
|
||||
* First, get an extra reference on the operation.
|
||||
* It'll be dropped when the operation completes.
|
||||
*/
|
||||
gb_operation_get(operation);
|
||||
|
||||
operation->callback = callback;
|
||||
gb_pending_operation_insert(operation);
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ void gb_connection_recv(struct gb_connection *connection,
|
|||
struct gb_operation *gb_operation_create(struct gb_connection *connection,
|
||||
u8 type, size_t request_size,
|
||||
size_t response_size);
|
||||
struct gb_operation *gb_operation_get(struct gb_operation *operation);
|
||||
void gb_operation_get(struct gb_operation *operation);
|
||||
void gb_operation_put(struct gb_operation *operation);
|
||||
static inline void gb_operation_destroy(struct gb_operation *operation)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче