linuxdriver: check supplicant status before send message [1/1]
authorPengguang Zhu <pengguang.zhu@amlogic.com>
Thu, 16 May 2019 06:07:13 +0000 (14:07 +0800)
committerPengguang Zhu <pengguang.zhu@amlogic.com>
Thu, 16 May 2019 07:51:12 +0000 (15:51 +0800)
PD#TV-5392

Problem:
when playing netflix movies, press power button, TV can not
power down and console hang.
previous commit will check supplicant status, but there is gap
that thread will scheduled and meanwhile the supplicant status
may change.

Solution:
move the status check before wait_for_completion

Verify:
TXLX + Android P

Change-Id: I445619192a1c6cf047a3fe51f3660dad7aa39601
Signed-off-by: Pengguang Zhu <pengguang.zhu@amlogic.com>
optee/supp.c

index d4f4a34dbb6ed8c172bb54e758df34306ea30ce9..de1b5f9f02f68948b0b9a7ca3ed4475223f1acc2 100755 (executable)
@@ -88,14 +88,12 @@ u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params,
 {
        struct optee *optee = tee_get_drvdata(ctx->teedev);
        struct optee_supp *supp = &optee->supp;
-       struct optee_supp_req *req = NULL;
+       struct optee_supp_req *req = kzalloc(sizeof(*req), GFP_KERNEL);
        bool interruptable;
        u32 ret;
+       int id;
+       struct optee_supp_req *req_tmp;
 
-       if (!supp->ctx)
-               return TEEC_ERROR_COMMUNICATION;
-
-       req = kzalloc(sizeof(*req), GFP_KERNEL);
        if (!req)
                return TEEC_ERROR_OUT_OF_MEMORY;
 
@@ -113,6 +111,23 @@ 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);
 
+       if (!supp->ctx) {
+               mutex_lock(&supp->mutex);
+               if (req->in_queue) {
+                       list_del(&req->link);
+               } else {
+                       idr_for_each_entry(&supp->idr, req_tmp, id) {
+                               if (req == req_tmp)
+                                       idr_remove(&supp->idr, id);
+                       }
+               }
+               mutex_unlock(&supp->mutex);
+
+               kfree(req);
+
+               return TEEC_ERROR_COMMUNICATION;
+       }
+
        /*
         * Wait for supplicant to process and return result, once we've
         * returned from wait_for_completion(&req->c) successfully we have