Skip to content

Commit

Permalink
tee: optee: Fix RPC call break system sleep operation.
Browse files Browse the repository at this point in the history
The system sleep can be break when freezer try to freeze tasks
who are waitting for unreachable conditions.

All RPC calls waiting on tee-supplicant results are unreachable
conditions when tee-supplicant be frozen.

And TEE wait queue sleep becomes to unreachable condition on
the corresponding wakeup process be frozen.

By introduce freezer help functions tell to freezer ignoring tasks
which can help to avoid freezer wakeup those tasks and wait them call
into try_to_freeze(), the wait of those tasks are constantly timeout
because they are waitting on unreachable conditions.

This patch utilize freezer help functions to enclose those potential
unreachable conditions boundaries to avoid breaking system sleep.

Signed-off-by: Shown Han <Shown.Han@armchina.com>
  • Loading branch information
Shown Han authored and Shown Han committed Jan 19, 2021
1 parent 436d15c commit 18c7ae7
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 0 deletions.
6 changes: 6 additions & 0 deletions drivers/tee/optee/call.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,14 @@ static void optee_cq_wait_init(struct optee_call_queue *cq,
static void optee_cq_wait_for_completion(struct optee_call_queue *cq,
struct optee_call_waiter *w)
{
/* Tell freezers to ignore the current task. */
freezer_do_not_count();

wait_for_completion(&w->c);

/* Tell freezer to stop ignoring current task. */
freezer_count();

mutex_lock(&cq->mutex);

/* Move to end of list to get out of the way for other waiters */
Expand Down
1 change: 1 addition & 0 deletions drivers/tee/optee/optee_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <linux/semaphore.h>
#include <linux/tee_drv.h>
#include <linux/types.h>
#include <linux/freezer.h>
#include "optee_msg.h"

#define OPTEE_MAX_ARG_SIZE 1024
Expand Down
6 changes: 6 additions & 0 deletions drivers/tee/optee/rpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,13 @@ static void wq_sleep(struct optee_wait_queue *wq, u32 key)
struct wq_entry *w = wq_entry_get(wq, key);

if (w) {
/* Tell freezers to ignore the current task. */
freezer_do_not_count();

wait_for_completion(&w->c);

/* Tell freezer to stop ignoring current task. */
freezer_count();
mutex_lock(&wq->mu);
list_del(&w->link);
mutex_unlock(&wq->mu);
Expand Down
7 changes: 7 additions & 0 deletions drivers/tee/optee/supp.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params,
/* Tell an eventual waiter there's a new request */
complete(&supp->reqs_c);


/* Tell freezers to ignore the current task. */
freezer_do_not_count();

/*
* Wait for supplicant to process and return result, once we've
* returned from wait_for_completion(&req->c) successfully we have
Expand Down Expand Up @@ -143,6 +147,9 @@ u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params,
}
}

/* Tell freezer to stop ignoring current task. */
freezer_count();

ret = req->ret;
kfree(req);

Expand Down

0 comments on commit 18c7ae7

Please sign in to comment.