Skip to content

Commit 2aa2627

Browse files
etienne-lmsfourmone
authored andcommitted
optee: refactor call queue code
Move the call queue handling logic off to a new file to allow for its use in other translation units cleanly. Signed-off-by: Hernan Gatta <hegatta@microsoft.com> Acked-by: Etienne Carriere <etienne.carriere@linaro.org> [etienne: picked commit from linaro-swg/linux#72] Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org> Change-Id: Ifbd281a8be32921d8273ba8683c53d5b19334b66
1 parent 0cca4d0 commit 2aa2627

4 files changed

Lines changed: 100 additions & 85 deletions

File tree

drivers/tee/optee/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# SPDX-License-Identifier: GPL-2.0
22
obj-$(CONFIG_OPTEE) += optee.o
33
optee-objs += core.o
4+
optee-objs += call_queue.o
45
optee-objs += call.o
56
optee-objs += rpc.o
67
optee-objs += supp.o

drivers/tee/optee/call.c

Lines changed: 0 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -17,91 +17,6 @@
1717
#define CREATE_TRACE_POINTS
1818
#include "optee_trace.h"
1919

20-
struct optee_call_waiter {
21-
struct list_head list_node;
22-
struct completion c;
23-
};
24-
25-
static void optee_cq_wait_init(struct optee_call_queue *cq,
26-
struct optee_call_waiter *w)
27-
{
28-
/*
29-
* We're preparing to make a call to secure world. In case we can't
30-
* allocate a thread in secure world we'll end up waiting in
31-
* optee_cq_wait_for_completion().
32-
*
33-
* Normally if there's no contention in secure world the call will
34-
* complete and we can cleanup directly with optee_cq_wait_final().
35-
*/
36-
mutex_lock(&cq->mutex);
37-
38-
/*
39-
* We add ourselves to the queue, but we don't wait. This
40-
* guarantees that we don't lose a completion if secure world
41-
* returns busy and another thread just exited and try to complete
42-
* someone.
43-
*/
44-
init_completion(&w->c);
45-
list_add_tail(&w->list_node, &cq->waiters);
46-
47-
mutex_unlock(&cq->mutex);
48-
}
49-
50-
static void optee_cq_wait_for_completion(struct optee_call_queue *cq,
51-
struct optee_call_waiter *w)
52-
{
53-
wait_for_completion(&w->c);
54-
55-
mutex_lock(&cq->mutex);
56-
57-
/* Move to end of list to get out of the way for other waiters */
58-
list_del(&w->list_node);
59-
reinit_completion(&w->c);
60-
list_add_tail(&w->list_node, &cq->waiters);
61-
62-
mutex_unlock(&cq->mutex);
63-
}
64-
65-
static void optee_cq_complete_one(struct optee_call_queue *cq)
66-
{
67-
struct optee_call_waiter *w;
68-
69-
list_for_each_entry(w, &cq->waiters, list_node) {
70-
if (!completion_done(&w->c)) {
71-
complete(&w->c);
72-
break;
73-
}
74-
}
75-
}
76-
77-
static void optee_cq_wait_final(struct optee_call_queue *cq,
78-
struct optee_call_waiter *w)
79-
{
80-
/*
81-
* We're done with the call to secure world. The thread in secure
82-
* world that was used for this call is now available for some
83-
* other task to use.
84-
*/
85-
mutex_lock(&cq->mutex);
86-
87-
/* Get out of the list */
88-
list_del(&w->list_node);
89-
90-
/* Wake up one eventual waiting task */
91-
optee_cq_complete_one(cq);
92-
93-
/*
94-
* If we're completed we've got a completion from another task that
95-
* was just done with its call to secure world. Since yet another
96-
* thread now is available in secure world wake up another eventual
97-
* waiting task.
98-
*/
99-
if (completion_done(&w->c))
100-
optee_cq_complete_one(cq);
101-
102-
mutex_unlock(&cq->mutex);
103-
}
104-
10520
/* Requires the filpstate mutex to be held */
10621
static struct optee_session *find_session(struct optee_context_data *ctxdata,
10722
u32 session_id)

drivers/tee/optee/call_queue.c

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/*
3+
* Copyright (c) 2015, Linaro Limited
4+
*/
5+
6+
#include "optee_private.h"
7+
8+
void optee_cq_wait_init(struct optee_call_queue *cq,
9+
struct optee_call_waiter *w)
10+
{
11+
/*
12+
* We're preparing to make a call to secure world. In case we can't
13+
* allocate a thread in secure world we'll end up waiting in
14+
* optee_cq_wait_for_completion().
15+
*
16+
* Normally if there's no contention in secure world the call will
17+
* complete and we can cleanup directly with optee_cq_wait_final().
18+
*/
19+
mutex_lock(&cq->mutex);
20+
21+
/*
22+
* We add ourselves to the queue, but we don't wait. This
23+
* guarantees that we don't lose a completion if secure world
24+
* returns busy and another thread just exited and try to complete
25+
* someone.
26+
*/
27+
init_completion(&w->c);
28+
list_add_tail(&w->list_node, &cq->waiters);
29+
30+
mutex_unlock(&cq->mutex);
31+
}
32+
33+
void optee_cq_wait_for_completion(struct optee_call_queue *cq,
34+
struct optee_call_waiter *w)
35+
{
36+
wait_for_completion(&w->c);
37+
38+
mutex_lock(&cq->mutex);
39+
40+
/* Move to end of list to get out of the way for other waiters */
41+
list_del(&w->list_node);
42+
reinit_completion(&w->c);
43+
list_add_tail(&w->list_node, &cq->waiters);
44+
45+
mutex_unlock(&cq->mutex);
46+
}
47+
48+
void optee_cq_complete_one(struct optee_call_queue *cq)
49+
{
50+
struct optee_call_waiter *w;
51+
52+
list_for_each_entry(w, &cq->waiters, list_node) {
53+
if (!completion_done(&w->c)) {
54+
complete(&w->c);
55+
break;
56+
}
57+
}
58+
}
59+
60+
void optee_cq_wait_final(struct optee_call_queue *cq,
61+
struct optee_call_waiter *w)
62+
{
63+
/*
64+
* We're done with the call to secure world. The thread in secure
65+
* world that was used for this call is now available for some
66+
* other task to use.
67+
*/
68+
mutex_lock(&cq->mutex);
69+
70+
/* Get out of the list */
71+
list_del(&w->list_node);
72+
73+
/* Wake up one eventual waiting task */
74+
optee_cq_complete_one(cq);
75+
76+
/*
77+
* If we're completed we've got a completion from another task that
78+
* was just done with its call to secure world. Since yet another
79+
* thread now is available in secure world wake up another eventual
80+
* waiting task.
81+
*/
82+
if (completion_done(&w->c))
83+
optee_cq_complete_one(cq);
84+
85+
mutex_unlock(&cq->mutex);
86+
}

drivers/tee/optee/optee_private.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,11 @@ struct optee_rpc_param {
120120
u32 a7;
121121
};
122122

123+
struct optee_call_waiter {
124+
struct list_head list_node;
125+
struct completion c;
126+
};
127+
123128
/* Holds context that is preserved during one STD call */
124129
struct optee_call_ctx {
125130
/* information about pages list used in last allocation */
@@ -186,6 +191,14 @@ void optee_fill_pages_list(u64 *dst, struct page **pages, int num_pages,
186191
int optee_enumerate_devices(u32 func);
187192
void optee_unregister_devices(void);
188193

194+
void optee_cq_wait_init(struct optee_call_queue *cq,
195+
struct optee_call_waiter *w);
196+
void optee_cq_wait_for_completion(struct optee_call_queue *cq,
197+
struct optee_call_waiter *w);
198+
void optee_cq_complete_one(struct optee_call_queue *cq);
199+
void optee_cq_wait_final(struct optee_call_queue *cq,
200+
struct optee_call_waiter *w);
201+
189202
/*
190203
* Small helpers
191204
*/

0 commit comments

Comments
 (0)