Commit deb4b9ef authored by Alex Elder's avatar Alex Elder Committed by Greg Kroah-Hartman

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: default avatarAlex Elder <elder@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <greg@kroah.com>
parent 583c3117
...@@ -157,6 +157,7 @@ static void gb_operation_complete(struct gb_operation *operation) ...@@ -157,6 +157,7 @@ static void gb_operation_complete(struct gb_operation *operation)
operation->callback(operation); operation->callback(operation);
else else
complete_all(&operation->completion); complete_all(&operation->completion);
gb_operation_put(operation);
} }
/* /*
...@@ -409,6 +410,14 @@ gb_operation_create_incoming(struct gb_connection *connection, ...@@ -409,6 +410,14 @@ gb_operation_create_incoming(struct gb_connection *connection,
request_size, response_size); 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. * Destroy a previously created operation.
*/ */
...@@ -429,6 +438,10 @@ static void _gb_operation_destroy(struct kref *kref) ...@@ -429,6 +438,10 @@ static void _gb_operation_destroy(struct kref *kref)
kmem_cache_free(gb_operation_cache, operation); 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) void gb_operation_put(struct gb_operation *operation)
{ {
if (!WARN_ON(!operation)) if (!WARN_ON(!operation))
...@@ -454,11 +467,11 @@ int gb_operation_request_send(struct gb_operation *operation, ...@@ -454,11 +467,11 @@ int gb_operation_request_send(struct gb_operation *operation,
return -ENOTCONN; return -ENOTCONN;
/* /*
* XXX * First, get an extra reference on the operation.
* I think the order of operations is going to be * It'll be dropped when the operation completes.
* significant, and if so, we may need a mutex to surround
* setting the operation id and submitting the buffer.
*/ */
gb_operation_get(operation);
operation->callback = callback; operation->callback = callback;
gb_pending_operation_insert(operation); gb_pending_operation_insert(operation);
......
...@@ -88,7 +88,7 @@ void gb_connection_recv(struct gb_connection *connection, ...@@ -88,7 +88,7 @@ void gb_connection_recv(struct gb_connection *connection,
struct gb_operation *gb_operation_create(struct gb_connection *connection, struct gb_operation *gb_operation_create(struct gb_connection *connection,
u8 type, size_t request_size, u8 type, size_t request_size,
size_t response_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); void gb_operation_put(struct gb_operation *operation);
static inline void gb_operation_destroy(struct gb_operation *operation) static inline void gb_operation_destroy(struct gb_operation *operation)
{ {
......
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