greybus: gb_operation: replace timeout workqueue

If an operation is issued and the response never comes back,
gb_operation_timeout() cancels the operation but never wakes up the
waiter in gb_operation_request_send().

This patch removes the timeout workqueue and changes the request wait to
wait_for_completion_interruptible_timeout(), with timeout set to
OPERATION_TIMEOUT_DEFAULT.

Signed-off-by: Perry Hung <perry@leaflabs.com>
Reviewed-by: Alex Elder <elder@linaro.org>
Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
This commit is contained in:
Perry Hung 2015-01-14 16:19:26 -05:00 committed by Greg Kroah-Hartman
parent 76590b1e88
commit 7bad4e85b8
2 changed files with 9 additions and 26 deletions

View File

@ -248,16 +248,6 @@ static void gb_operation_work(struct work_struct *work)
gb_operation_put(operation);
}
/*
* Timeout call for the operation.
*/
static void gb_operation_timeout(struct work_struct *work)
{
struct gb_operation *operation;
operation = container_of(work, struct gb_operation, timeout_work.work);
gb_operation_cancel(operation, -ETIMEDOUT);
}
/*
* Given a pointer to the header in a message sent on a given host
@ -533,7 +523,6 @@ gb_operation_create_common(struct gb_connection *connection, u8 type,
INIT_WORK(&operation->work, gb_operation_work);
operation->callback = NULL; /* set at submit time */
init_completion(&operation->completion);
INIT_DELAYED_WORK(&operation->timeout_work, gb_operation_timeout);
kref_init(&operation->kref);
spin_lock_irq(&gb_operations_lock);
@ -652,7 +641,6 @@ int gb_operation_request_send(struct gb_operation *operation,
{
struct gb_connection *connection = operation->connection;
struct gb_operation_msg_hdr *header;
unsigned long timeout;
unsigned int cycle;
if (connection->state != GB_CONNECTION_STATE_ENABLED)
@ -680,14 +668,6 @@ int gb_operation_request_send(struct gb_operation *operation,
header = operation->request->header;
header->operation_id = cpu_to_le16(operation->id);
/*
* We impose a time limit for requests to complete. We need
* to set the timer before we send the request though, so we
* don't lose a race with the receipt of the resposne.
*/
timeout = msecs_to_jiffies(OPERATION_TIMEOUT_DEFAULT);
schedule_delayed_work(&operation->timeout_work, timeout);
/* All set, send the request */
gb_operation_result_set(operation, -EINPROGRESS);
@ -703,15 +683,21 @@ int gb_operation_request_send(struct gb_operation *operation,
int gb_operation_request_send_sync(struct gb_operation *operation)
{
int ret;
unsigned long timeout;
ret = gb_operation_request_send(operation, gb_operation_sync_callback);
if (ret)
return ret;
/* Cancel the operation if interrupted */
ret = wait_for_completion_interruptible(&operation->completion);
if (ret < 0)
timeout = msecs_to_jiffies(OPERATION_TIMEOUT_DEFAULT);
ret = wait_for_completion_interruptible_timeout(&operation->completion, timeout);
if (ret < 0) {
/* Cancel the operation if interrupted */
gb_operation_cancel(operation, -ECANCELED);
} else if (ret == 0) {
/* Cancel the operation if op timed out */
gb_operation_cancel(operation, -ETIMEDOUT);
}
return gb_operation_result(operation);
}
@ -843,8 +829,6 @@ static void gb_connection_recv_response(struct gb_connection *connection,
return;
}
cancel_delayed_work(&operation->timeout_work);
message = operation->response;
message_size = sizeof(*message->header) + message->payload_size;
if (!errno && size != message_size) {

View File

@ -88,7 +88,6 @@ struct gb_operation {
struct work_struct work;
gb_operation_callback callback; /* If asynchronous */
struct completion completion; /* Used if no callback */
struct delayed_work timeout_work;
struct kref kref;
struct list_head links; /* connection->operations */