[COMMON] media: mfc: avoid the kernel panic in specific scenario
authorAyoung Sim <a.sim@samsung.com>
Thu, 23 Aug 2018 08:10:04 +0000 (17:10 +0900)
committerhskang <hs1218.kang@samsung.com>
Sun, 9 Sep 2018 21:39:19 +0000 (06:39 +0900)
We do not support DRC(Dynamic Resolution Change)
and seeking overlapped scenario.
However, in this case, we avoid the kernel panic.

wait_state is changed as below.
DRC detected -> WAIT_DECODING -> g_fmt -> WAIT_DPB_FLUSH
-> stramoff(dst) -> WAIT_NONE -> decoding(INIT_BUF, NAL_START)

Change-Id: I81280249a962e2b3d4532b74ad247674441e4789
Signed-off-by: Ayoung Sim <a.sim@samsung.com>
drivers/media/platform/exynos/mfc/mfc_data_struct.h
drivers/media/platform/exynos/mfc/mfc_dec_v4l2.c
drivers/media/platform/exynos/mfc/mfc_dec_vb2.c
drivers/media/platform/exynos/mfc/mfc_isr.c

index ac55858e4e2e75fc2eb59eb998ae2fd83d62f00d..5140316c92dc1c67fc751810282a12467c7d9fec 100644 (file)
@@ -132,7 +132,7 @@ enum mfc_queue_state {
 enum mfc_dec_wait_state {
        WAIT_NONE = 0,
        WAIT_DECODING,
-       WAIT_INITBUF_DONE,
+       WAIT_DPB_FLUSH,
 };
 
 /**
index 2d045d42afa99aa26423e59709114526d4cefeac..fe2730862371c775e58b8a6eea42eeade1c1fe62 100644 (file)
@@ -284,12 +284,16 @@ static int mfc_dec_g_fmt_vid_cap_mplane(struct file *file, void *priv,
        if (ctx->state == MFCINST_GOT_INST ||
            ctx->state == MFCINST_RES_CHANGE_FLUSH ||
            ctx->state == MFCINST_RES_CHANGE_END) {
-               /* If the MFC is parsing the header,
-                * so wait until it is finished */
-               if (mfc_wait_for_done_ctx(ctx,
-                               MFC_REG_R2H_CMD_SEQ_DONE_RET)) {
-                               mfc_err_dev("header parsing failed\n");
-                               return -EAGAIN;
+               /* If there is no source buffer to parsing, we can't SEQ_START */
+               if ((ctx->wait_state == WAIT_DECODING) &&
+                       mfc_is_queue_count_same(&ctx->buf_queue_lock, &ctx->src_buf_queue, 0)) {
+                       mfc_err_dev("There is no source buffer to parsing, keep previous resolution\n");
+                       return -EAGAIN;
+               }
+               /* If the MFC is parsing the header, so wait until it is finished */
+               if (mfc_wait_for_done_ctx(ctx, MFC_REG_R2H_CMD_SEQ_DONE_RET)) {
+                       mfc_err_dev("header parsing failed\n");
+                       return -EAGAIN;
                }
        }
 
@@ -353,6 +357,11 @@ static int mfc_dec_g_fmt_vid_cap_mplane(struct file *file, void *priv,
                }
        }
 
+       if (ctx->wait_state == WAIT_DECODING) {
+               ctx->wait_state = WAIT_DPB_FLUSH;
+               mfc_debug(2, "wait DPB flush for decoding(INIT_BUFFER)\n");
+       }
+
        mfc_debug_leave();
 
        return 0;
index bf83abfbbfa0f09815862f5a0c1ee32a526aec99..fc24322ae065f07ea8bbaa0162b991de1c309363 100644 (file)
@@ -365,10 +365,9 @@ static void __mfc_dec_dst_stop_streaming(struct mfc_ctx *ctx)
                index++;
        }
 
-       if (ctx->wait_state == WAIT_INITBUF_DONE ||
-                       ctx->wait_state == WAIT_DECODING) {
+       if (ctx->wait_state == WAIT_DPB_FLUSH) {
                ctx->wait_state = WAIT_NONE;
-               mfc_debug(2, "Decoding can be started now\n");
+               mfc_debug(2, "Decoding(INIT_BUFFER) can be started now\n");
        }
 }
 
index c9470fec711cc6dcebd131077e84222ffb894383..7892589366db481f3fd9fb89825dd60c9305807b 100644 (file)
@@ -1466,10 +1466,6 @@ static int __mfc_irq_ctx(struct mfc_ctx *ctx, unsigned int reason, unsigned int
 
                mfc_change_state(ctx, MFCINST_RUNNING);
                if (ctx->type == MFCINST_DECODER) {
-                       if (ctx->wait_state == WAIT_DECODING) {
-                               ctx->wait_state = WAIT_INITBUF_DONE;
-                               mfc_debug(2, "INIT_BUFFER has done, but can't start decoding\n");
-                       }
                        if (ctx->is_dpb_realloc)
                                ctx->is_dpb_realloc = 0;
                }