Files
BPI-CM9-Linux/aml-patches/aml-comp/kernel/aml-6.12/common_drivers/0002-video-display-add-protect-for-NULL-pointer-1-1.patch
T

745 lines
27 KiB
Diff

From 79c89cfdef8e9f3b2cbc53dbbd29e00635bf0023 Mon Sep 17 00:00:00 2001
From: "zongren.yin" <[email protected]>
Date: Mon, 26 Oct 2026 19:54:27 +0800
Subject: [PATCH 2/4] video display: add protect for NULL pointer [1/1]
PD#SWPL-
Problem:
Solution:
Fixed conflicts:
Verify:
t
Change-Id: Id8e88ef66bec35727344edf5d25df208f457baaf
Signed-off-by: zongren.yin <[email protected]>
---
drivers/drm/meson_plane.c | 9 +-
drivers/drm/vpu-hw/meson_vpu_video_wrapper.c | 73 ++++-
.../videodisplay/videodisplay_process.c | 286 +++++++++++++++++-
3 files changed, 340 insertions(+), 28 deletions(-)
diff --git a/drivers/drm/meson_plane.c b/drivers/drm/meson_plane.c
index 99b2e068f7..3f50b73f74 100644
--- a/drivers/drm/meson_plane.c
+++ b/drivers/drm/meson_plane.c
@@ -3463,10 +3463,17 @@ void meson_video_plane_async_update(struct drm_plane *plane,
return;
mvbs = meson_vpu_block_get_new_state(&mvv->base, state);
- if (!mvbs)
+ if (!mvbs) {
+ DRM_ERROR("async_update: plane%d get video new state failed\n",
+ video_plane->plane_index);
return;
+ }
mvvs = to_video_state(mvbs);
+ DRM_DEBUG_DRIVER("async_update: plane%d fb(%px) mvvs_new(%px) dmabuf(%px,%px)\n",
+ video_plane->plane_index, new_state->fb, mvvs,
+ mvvs->slices[0].dmabuf[0], mvvs->slices[0].dmabuf[1]);
+
DRM_DEBUG_DRIVER("plane_index=%d,crtc=%px,crtc_index=%d,fb=%px,src=%dx%d,dst=%dx%d\n",
plane->index, new_state->crtc,
crtc_index, new_state->fb,
diff --git a/drivers/drm/vpu-hw/meson_vpu_video_wrapper.c b/drivers/drm/vpu-hw/meson_vpu_video_wrapper.c
index 42f2bc0ae6..e92fbd718a 100644
--- a/drivers/drm/vpu-hw/meson_vpu_video_wrapper.c
+++ b/drivers/drm/vpu-hw/meson_vpu_video_wrapper.c
@@ -191,6 +191,11 @@ void video_dummy_data_set(u64 crtc_bgcolor, bool crtc_bgcolor_flag)
set_post_blend_dummy_data(vpp_index, 1 << 24 | y << 16 | u << 8 | v, alpha);
}
+static bool meson_dmabuf_is_stale(struct dma_buf *dmabuf)
+{
+ return dmabuf && !dmabuf->file;
+}
+
static void meson_vpu_update_video_info(struct meson_vpu_video_layer_info *plane_info,
struct meson_vpu_slice_state *mvss)
{
@@ -198,6 +203,11 @@ static void meson_vpu_update_video_info(struct meson_vpu_video_layer_info *plane
mvss->dmabuf[0], mvss->dmabuf[1],
plane_info->dmabuf[0], plane_info->dmabuf[1]);
+ if (meson_dmabuf_is_stale(mvss->dmabuf[0]) || meson_dmabuf_is_stale(mvss->dmabuf[1]))
+ DRM_INFO("%s: overwrite stale mvss dmabuf(%px,%px) with plane_info(%px,%px)\n",
+ __func__, mvss->dmabuf[0], mvss->dmabuf[1],
+ plane_info->dmabuf[0], plane_info->dmabuf[1]);
+
mvss->src_x = plane_info->src_x;
mvss->src_y = plane_info->src_y;
mvss->src_w = plane_info->src_w;
@@ -218,11 +228,8 @@ static void meson_vpu_update_video_info(struct meson_vpu_video_layer_info *plane
mvss->fb_size[1] = plane_info->fb_size[1];
mvss->vf = plane_info->vf;
mvss->is_uvm = plane_info->is_uvm;
- if (mvss->dmabuf[0] != plane_info->dmabuf[0] &&
- plane_info->dmabuf[0]) {
- mvss->dmabuf[0] = plane_info->dmabuf[0];
- mvss->dmabuf[1] = plane_info->dmabuf[1];
- }
+ mvss->dmabuf[0] = plane_info->dmabuf[0];
+ mvss->dmabuf[1] = plane_info->dmabuf[1];
mvss->crtc_index = plane_info->crtc_index;
mvss->rotation = plane_info->rotation;
mvss->signal_fmt = video_signal_fmt_cov(plane_info->signal_fmt);
@@ -304,6 +311,13 @@ static void video_set_state_for_uvm(struct meson_vpu_block *vblk,
return;
}
+ if (meson_dmabuf_is_stale(mvss->dmabuf[0]) ||
+ meson_dmabuf_is_stale(mvss->dmabuf[1])) {
+ DRM_ERROR("%s: stale dmabuf(%px,%px) file released, skip uvm set_state.\n",
+ video->base.name, mvss->dmabuf[0], mvss->dmabuf[1]);
+ return;
+ }
+
memset(vf_info, 0, sizeof(*vf_info));
src_h = mvss->src_h;
byte_stride = mvss->byte_stride;
@@ -494,6 +508,13 @@ static void video_set_state_for_non_uvm(struct meson_vpu_block *vblk,
return;
}
+ if (meson_dmabuf_is_stale(mvss->dmabuf[0]) ||
+ meson_dmabuf_is_stale(mvss->dmabuf[1])) {
+ DRM_ERROR("%s: stale dmabuf(%px,%px) file released, skip non-uvm set_state.\n",
+ video->base.name, mvss->dmabuf[0], mvss->dmabuf[1]);
+ return;
+ }
+
memset(vf_info, 0, sizeof(*vf_info));
src_h = mvss->src_h;
byte_stride = mvss->byte_stride;
@@ -581,10 +602,14 @@ static void video_set_state(struct meson_vpu_block *vblk,
video_set_state_for_non_uvm(vblk, mvss, vf_info);
}
+ DRM_INFO("set_state: %s mvvs(%px) dmabuf(%px,%px) is_uvm(%d) vf(%px) num(%d)\n",
+ video->base.name, mvvs, mvss->dmabuf[0], mvss->dmabuf[1],
+ mvss->is_uvm, mvss->vf, num_frame);
+
#ifdef CONFIG_AMLOGIC_VIDEO_DISPLAY
if (video->slice_mode && mvvs->num_of_video == VIDEO_MAX_SLICE)
video_display_set_multiframe(vblk->index, info_para, num_frame, 0);
- else
+ else if (info_para[0]->dmabuf[0])
video_display_setframe(vblk->index, info_para[0], 0);
#endif
@@ -644,11 +669,19 @@ static void video_disable_work_func(struct work_struct *works)
num_frame = mvvs->num_of_video;
for (i = 0; i < num_frame; i++) {
mvss = &mvvs->slices[i];
- if (mvss->dmabuf[0]) {
+ if (mvss->dmabuf[0] && meson_dmabuf_is_stale(mvss->dmabuf[0])) {
+ DRM_ERROR("%s: stale dmabuf[0](%px) file released, skip put.\n",
+ worker->video->base.name, mvss->dmabuf[0]);
+ mvss->dmabuf[0] = NULL;
+ } else if (mvss->dmabuf[0]) {
dma_buf_put(mvss->dmabuf[0]);
mvss->dmabuf[0] = NULL;
}
- if (mvss->dmabuf[1]) {
+ if (mvss->dmabuf[1] && meson_dmabuf_is_stale(mvss->dmabuf[1])) {
+ DRM_ERROR("%s: stale dmabuf[1](%px) file released, skip put.\n",
+ worker->video->base.name, mvss->dmabuf[1]);
+ mvss->dmabuf[1] = NULL;
+ } else if (mvss->dmabuf[1]) {
dma_buf_put(mvss->dmabuf[1]);
mvss->dmabuf[1] = NULL;
}
@@ -696,10 +729,18 @@ static void video_hw_disable(struct meson_vpu_block *vblk,
num_frame = mvvs->num_of_video;
for (i = 0; i < num_frame; i++) {
mvss = &mvvs->slices[i];
- if (mvss->dmabuf[0])
+ if (mvss->dmabuf[0] && meson_dmabuf_is_stale(mvss->dmabuf[0])) {
+ DRM_ERROR("%s: stale dmabuf[0](%px) file released, skip get.\n",
+ video->base.name, mvss->dmabuf[0]);
+ } else if (mvss->dmabuf[0]) {
get_dma_buf(mvss->dmabuf[0]);
- if (mvss->dmabuf[1])
+ }
+ if (mvss->dmabuf[1] && meson_dmabuf_is_stale(mvss->dmabuf[1])) {
+ DRM_ERROR("%s: stale dmabuf[1](%px) file released, skip get.\n",
+ video->base.name, mvss->dmabuf[1]);
+ } else if (mvss->dmabuf[1]) {
get_dma_buf(mvss->dmabuf[1]);
+ }
DRM_INFO("dmabuf(%px %px), release_fence(%px),present_fence(%px),\n"
"video_name(%s),frame_cnt(%llu)\n",
@@ -730,11 +771,19 @@ static void video_hw_disable(struct meson_vpu_block *vblk,
#endif
for (i = 0; i < num_frame; i++) {
mvss = &mvvs->slices[i];
- if (mvss->dmabuf[0]) {
+ if (mvss->dmabuf[0] && meson_dmabuf_is_stale(mvss->dmabuf[0])) {
+ DRM_ERROR("%s: stale dmabuf[0](%px) file released, skip put.\n",
+ video->base.name, mvss->dmabuf[0]);
+ mvss->dmabuf[0] = NULL;
+ } else if (mvss->dmabuf[0]) {
dma_buf_put(mvss->dmabuf[0]);
mvss->dmabuf[0] = NULL;
}
- if (mvss->dmabuf[1]) {
+ if (mvss->dmabuf[1] && meson_dmabuf_is_stale(mvss->dmabuf[1])) {
+ DRM_ERROR("%s: stale dmabuf[1](%px) file released, skip put.\n",
+ video->base.name, mvss->dmabuf[1]);
+ mvss->dmabuf[1] = NULL;
+ } else if (mvss->dmabuf[1]) {
dma_buf_put(mvss->dmabuf[1]);
mvss->dmabuf[1] = NULL;
}
diff --git a/drivers/media/video_processor/videodisplay/videodisplay_process.c b/drivers/media/video_processor/videodisplay/videodisplay_process.c
index 1425bf552d..f09e87093f 100644
--- a/drivers/media/video_processor/videodisplay/videodisplay_process.c
+++ b/drivers/media/video_processor/videodisplay/videodisplay_process.c
@@ -766,6 +766,18 @@ static void detect_vf_type(struct frame_info_t *frame_info, bool *is_dec_vf_ptr,
pr_info("is_dec_vf or is_v4l_vf err.\n");
return;
}
+ if (!frame_info) {
+ pr_err("%s: frame_info is NULL.\n", __func__);
+ *is_dec_vf_ptr = false;
+ *is_v4l_vf_ptr = false;
+ return;
+ }
+ if (!frame_info->dmabuf[0]) {
+ pr_err("%s: frame_info(%px)->dmabuf[0] is NULL.\n", __func__, frame_info);
+ *is_dec_vf_ptr = false;
+ *is_v4l_vf_ptr = false;
+ return;
+ }
if (frame_info->source_type == SOURCE_HWC_CREAT_ION) {
*is_dec_vf_ptr = false;
*is_v4l_vf_ptr = false;
@@ -1146,8 +1158,13 @@ static void display_q_uninit(struct videodisplay_dev *dev)
dma_buf_put((struct dma_buf *)file_vf);
if (file_vf_ext)
dma_buf_put((struct dma_buf *)file_vf_ext);
- dma_fence_signal(vd_prepare->release_fence[0]);
- dma_fence_put(vd_prepare->release_fence[0]);
+ if (vd_prepare->release_fence[0]) {
+ dma_fence_signal(vd_prepare->release_fence[0]);
+ dma_fence_put(vd_prepare->release_fence[0]);
+ } else {
+ pr_err("%s: release_fence[0] is NULL, frame_index=%d.\n",
+ __func__, vf->frame_index);
+ }
}
dev->fput_count++;
@@ -1166,7 +1183,26 @@ static void vd_get_input_dmabufs(struct frames_info_t *frames_info)
if (frames_info->frame_count != 1)
return;
+ if (frames_info->layer_index >= MAX_COMPOSER_COUNT) {
+ pr_err("%s: layer_index(%d) overflow.\n",
+ __func__, frames_info->layer_index);
+ return;
+ }
+
frame_info = &frames_info->frame_info[frames_info->layer_index];
+ if (!frame_info->dmabuf[0]) {
+ pr_err("%s: frame_info(%px)->dmabuf[0] is NULL.\n",
+ __func__, frame_info);
+ return;
+ }
+ if (!frame_info->dmabuf[0]->file ||
+ (frame_info->dmabuf[1] && !frame_info->dmabuf[1]->file)) {
+ pr_err("%s: stale dmabuf(%px,%px) file released, skip get.\n",
+ __func__, frame_info->dmabuf[0], frame_info->dmabuf[1]);
+ frame_info->dmabuf[0] = NULL;
+ frame_info->dmabuf[1] = NULL;
+ return;
+ }
get_dma_buf(frame_info->dmabuf[0]);
if (frame_info->dmabuf[1])
get_dma_buf(frame_info->dmabuf[1]);
@@ -1179,7 +1215,23 @@ static void vd_put_input_dmabufs(struct frames_info_t *frames_info)
if (frames_info->frame_count != 1)
return;
+ if (frames_info->layer_index >= MAX_COMPOSER_COUNT) {
+ pr_err("%s: layer_index(%d) overflow.\n",
+ __func__, frames_info->layer_index);
+ return;
+ }
+
frame_info = &frames_info->frame_info[frames_info->layer_index];
+ if (!frame_info->dmabuf[0])
+ return;
+ if (!frame_info->dmabuf[0]->file ||
+ (frame_info->dmabuf[1] && !frame_info->dmabuf[1]->file)) {
+ pr_err("%s: stale dmabuf(%px,%px) file released, skip put.\n",
+ __func__, frame_info->dmabuf[0], frame_info->dmabuf[1]);
+ frame_info->dmabuf[0] = NULL;
+ frame_info->dmabuf[1] = NULL;
+ return;
+ }
dma_buf_put(frame_info->dmabuf[0]);
if (frame_info->dmabuf[1])
dma_buf_put(frame_info->dmabuf[1]);
@@ -1202,11 +1254,20 @@ static void receive_q_uninit(struct videodisplay_dev *dev)
__func__, kfifo_len(&dev->receive_q));
if (kfifo_get(&dev->receive_q, &received_frames)) {
num = received_frames->frames_info.layer_index;
+ if (num >= MAX_COMPOSER_COUNT) {
+ pr_err("%s: layer_index(%d) overflow.\n", __func__, num);
+ num = 0;
+ }
release_fence = received_frames->frames_info.frame_info[num].release_fence;
present_fence = received_frames->frames_info.frame_info[num].present_fence;
vd_put_input_dmabufs(&received_frames->frames_info);
- dma_fence_signal(release_fence);
- dma_fence_put(release_fence);
+ if (release_fence) {
+ dma_fence_signal(release_fence);
+ dma_fence_put(release_fence);
+ } else {
+ pr_err("%s: release_fence is NULL, layer_index=%d.\n",
+ __func__, num);
+ }
if (present_fence) {
dma_fence_signal(present_fence);
dma_fence_put(present_fence);
@@ -1291,8 +1352,13 @@ static void ready_q_uninit(struct videodisplay_dev *dev)
dma_buf_put((struct dma_buf *)file_vf);
if (vf->file_vf_ext)
dma_buf_put((struct dma_buf *)vf->file_vf_ext);
- dma_fence_put(vd_prepare->release_fence[0]);
- dma_fence_signal(vd_prepare->release_fence[0]);
+ if (vd_prepare->release_fence[0]) {
+ dma_fence_signal(vd_prepare->release_fence[0]);
+ dma_fence_put(vd_prepare->release_fence[0]);
+ } else {
+ pr_err("%s: release_fence[0] is NULL, frame_index=%d.\n",
+ __func__, vf->frame_index);
+ }
}
dev->fput_count++;
@@ -1689,8 +1755,9 @@ static struct vframe_s *vd_get_vf_from_buf(struct videodisplay_dev *dev, struct
vd_print(dev->index, PRINT_OTHER, "vf is from decoder.\n");
vf = dmabuf_get_vframe(buf);
if (!vf) {
- vd_print(dev->index, PRINT_ERROR, "get vframe from decoder failed.\n");
- return vf;
+ pr_err("%s: dmabuf_get_vframe return NULL, buf=%px.\n",
+ __func__, buf);
+ return NULL;
}
vd_print(dev->index, PRINT_OTHER,
"vframe_type = 0x%x, vframe_flag = 0x%x.\n",
@@ -1791,7 +1858,9 @@ static int video_wait_dma_fence(struct videodisplay_dev *dev,
timestamp = local_clock();
ret = dma_fence_wait_timeout(fence_file, false, msecs_to_jiffies(3000));
if (ret == 0) {
- vd_print(dev->index, PRINT_ERROR, "fence wait timeout\n");
+ vd_print(dev->index, PRINT_ERROR,
+ "%s: fence(%px) wait timeout.\n", __func__, fence_file);
+ dma_fence_put(fence_file);
return 0;
}
@@ -1882,7 +1951,8 @@ static void vframe_do_mosaic_22(struct videodisplay_dev *dev,
u32 pic_w, pic_h;
if (IS_ERR_OR_NULL(dev) || IS_ERR_OR_NULL(received_frames)) {
- vd_print(dev->index, PRINT_ERROR, "%s: invalid param.\n", __func__);
+ pr_err("%s: invalid param, dev=%px, received_frames=%px.\n",
+ __func__, dev, received_frames);
return;
}
@@ -1904,6 +1974,7 @@ static void vframe_do_mosaic_22(struct videodisplay_dev *dev,
vc_private = vd_private_q_pop(dev);
if (!vc_private) {
vd_print(dev->index, PRINT_ERROR, "%s: get vc_private failed.\n", __func__);
+ vd_prepare_data_q_put(dev, vd_prepare);
return;
}
@@ -1916,6 +1987,11 @@ static void vframe_do_mosaic_22(struct videodisplay_dev *dev,
if (video_wait_dma_fence(dev, frame_info->input_fence) == 0)
continue;
}
+ if (!frame_info->dmabuf[0]) {
+ pr_err("%s: mosaic frame_info[%d]->dmabuf[0] is NULL.\n",
+ __func__, i);
+ continue;
+ }
get_dma_buf(frame_info->dmabuf[0]);
if (frame_info->dmabuf[1])
@@ -2067,6 +2143,11 @@ static void empty_ready_queue(struct videodisplay_dev *dev)
repeat_count, frame_index);
video_timeline_increase(dev, repeat_count + 1);
if (!is_composer) {
+ if (!file_vf) {
+ pr_err("%s: vf(%px) file_vf is NULL, frame_index=%d.\n",
+ __func__, vf, frame_index);
+ continue;
+ }
for (i = 0; i <= repeat_count; i++) {
fput(file_vf);
total_put_count++;
@@ -2817,6 +2898,8 @@ static inline int vd_perform_pulldown(struct videodisplay_dev *dev, struct vfram
/* Dont do anything if we have invalid data */
if (!vf || !vf->vc_private)
return -1;
+ if (vf->vc_private->vsync_index == 0)
+ return -1;
if (vf->vf_vrr_param.qms_plus_en || vf->vf_vrr_param.qms_en)
return -1;
@@ -2901,6 +2984,11 @@ static inline int vd_perform_pulldown(struct videodisplay_dev *dev, struct vfram
"patten_undetected: already hold:%d, need expire\n",
dev->cur_hold_count);
*expired = true;
+ } else if (!vf->vc_private) {
+ vd_print(dev->index, PRINT_ERROR,
+ "patten_undetected: vf(%px) vc_private is NULL.\n",
+ vf);
+ *expired = true;
} else {
expected_disp_vsync =
vf->vc_private->vsync_index - dev->last_vsync_index;
@@ -2928,6 +3016,11 @@ static inline int vd_perform_pulldown(struct videodisplay_dev *dev, struct vfram
"patten_undetected: already hold:%d, need expire\n",
dev->cur_hold_count);
*expired = true;
+ } else if (!vf->vc_private) {
+ vd_print(dev->index, PRINT_ERROR,
+ "patten_undetected: vf(%px) vc_private is NULL.\n",
+ vf);
+ *expired = true;
} else {
expected_disp_vsync =
vf->vc_private->vsync_index - dev->last_vsync_index;
@@ -2949,6 +3042,13 @@ static inline int vd_perform_pulldown(struct videodisplay_dev *dev, struct vfram
expected_disp_vsync = vf->vc_private->vsync_index - dev->last_vsync_index;
if (dev->is_tunnel_mode) {
+ if (!vf->vc_private) {
+ vd_print(dev->index, PRINT_ERROR,
+ "%s: tunnel mode vf(%px) vc_private is NULL.\n",
+ __func__, vf);
+ return -1;
+ }
+ expected_disp_vsync = vf->vc_private->vsync_index - dev->last_vsync_index;
vd_print(dev->index, PRINT_PATTERN,
"tunnel mode patten:%d: expected_disp_vsync:%d, patten_trace:%d\n",
dev->pattern_detected, expected_disp_vsync, patten_trace[dev->index]);
@@ -3261,6 +3361,11 @@ static int videodisplay_drop_frame(struct videodisplay_dev *dev,
struct timeval cur_time;
unsigned long time = 0;
+ if (!vf || !dmabuf) {
+ pr_err("%s: invalid param, vf=%px, dmabuf=%px.\n", __func__, vf, dmabuf);
+ return false;
+ }
+
if (vd_drop_org_i == 0)
return false;
@@ -3835,27 +3940,67 @@ static void vframe_display(struct videodisplay_dev *dev,
frames_info = &received_frames->frames_info;
num = frames_info->layer_index;
+ if (num >= MAX_COMPOSER_COUNT) {
+ pr_err("%s: received_frames(%px) layer_index(%d) overflow.\n",
+ __func__, received_frames, num);
+ return;
+ }
frame_info = &frames_info->frame_info[num];
time_us64 = received_frames->time_us64;
+ if (!frame_info->dmabuf[0]) {
+ pr_err("%s: frame_info(%px)->dmabuf[0] is NULL, frame_index=%d.\n",
+ __func__, frame_info, num);
+ if (frame_info->release_fence) {
+ dma_fence_signal(frame_info->release_fence);
+ dma_fence_put(frame_info->release_fence);
+ }
+ atomic_set(&received_frames->on_use, false);
+ return;
+ }
+
#ifdef CONFIG_AMLOGIC_MEDIA_DEINTERLACE
enable_prelink = dim_get_pre_link();
#endif
detect_vf_type(frame_info, &is_dec_vf, &is_v4l_vf);
+ get_dma_buf(frame_info->dmabuf[0]);
+ if (frame_info->dmabuf[1])
+ get_dma_buf(frame_info->dmabuf[1]);
if (dev->last_file == (struct file *)frame_info->dmabuf[0])
is_repeat_vf = true;
if (is_repeat_vf) {
vd_prepare = dev->vd_prepare_last;
+ if (!vd_prepare) {
+ pr_err("%s: dev(%px) vd_prepare_last is NULL for repeat frame, dmabuf=%px.\n",
+ __func__, dev, frame_info->dmabuf[0]);
+ dma_buf_put(frame_info->dmabuf[0]);
+ if (frame_info->dmabuf[1])
+ dma_buf_put(frame_info->dmabuf[1]);
+ if (frame_info->release_fence) {
+ dma_fence_signal(frame_info->release_fence);
+ dma_fence_put(frame_info->release_fence);
+ }
+ atomic_set(&received_frames->on_use, false);
+ dev->last_file = NULL;
+ return;
+ }
} else {
vd_prepare = vd_prepare_data_q_get(dev);
if (!vd_prepare) {
- vd_print(dev->index, PRINT_ERROR, "get prepare_data failed.\n");
+ pr_err("%s: dev(%px) vd_prepare_data_q_get return NULL, dmabuf=%px.\n",
+ __func__, dev, frame_info->dmabuf[0]);
dma_buf_put(frame_info->dmabuf[0]);
if (frame_info->dmabuf[1])
dma_buf_put(frame_info->dmabuf[1]);
+ if (frame_info->release_fence) {
+ dma_fence_signal(frame_info->release_fence);
+ dma_fence_put(frame_info->release_fence);
+ }
+ atomic_set(&received_frames->on_use, false);
+ dev->last_file = NULL;
return;
}
@@ -3866,6 +4011,13 @@ static void vframe_display(struct videodisplay_dev *dev,
dma_buf_put(frame_info->dmabuf[0]);
if (frame_info->dmabuf[1])
dma_buf_put(frame_info->dmabuf[1]);
+ if (frame_info->release_fence) {
+ dma_fence_signal(frame_info->release_fence);
+ dma_fence_put(frame_info->release_fence);
+ }
+ atomic_set(&received_frames->on_use, false);
+ vd_prepare_data_q_put(dev, vd_prepare);
+ dev->last_file = NULL;
return;
}
@@ -4156,7 +4308,18 @@ static void vframe_display(struct videodisplay_dev *dev,
dev->last_file = (struct file *)frame_info->dmabuf[0];
vf->vc_private = vd_private_q_pop(dev);
if (!vf->vc_private) {
- vd_print(dev->index, PRINT_ERROR, "vc_private is NULL.\n");
+ pr_err("%s: dev(%px) vd_private_q_pop return NULL, vf=%px, frame_index=%d.\n",
+ __func__, dev, vf, vf->frame_index);
+ dma_buf_put(frame_info->dmabuf[0]);
+ if (frame_info->dmabuf[1])
+ dma_buf_put(frame_info->dmabuf[1]);
+ if (frame_info->release_fence) {
+ dma_fence_signal(frame_info->release_fence);
+ dma_fence_put(frame_info->release_fence);
+ }
+ vd_prepare_data_q_put(dev, vd_prepare);
+ dev->last_file = NULL;
+ atomic_set(&received_frames->on_use, false);
return;
}
vf->vc_private->present_fence = frame_info->present_fence;
@@ -4214,6 +4377,21 @@ static void vframe_display(struct videodisplay_dev *dev,
if (!kfifo_put(&dev->ready_q, (const struct vframe_s *)vf)) {
vd_print(dev->index, PRINT_ERROR, "%s: put to ready_q failed.\n", __func__);
+ dma_buf_put(frame_info->dmabuf[0]);
+ if (frame_info->dmabuf[1])
+ dma_buf_put(frame_info->dmabuf[1]);
+ if (frame_info->release_fence) {
+ dma_fence_signal(frame_info->release_fence);
+ dma_fence_put(frame_info->release_fence);
+ }
+ if (vf->vc_private) {
+ vd_private_q_recycle(dev, vf->vc_private);
+ vf->vc_private = NULL;
+ }
+ vd_prepare_data_q_put(dev, vd_prepare);
+ dev->last_file = NULL;
+ dev->vd_prepare_last = NULL;
+ atomic_set(&received_frames->on_use, false);
return;
}
vf_notify_receiver(dev->vf_provider_name,
@@ -4288,10 +4466,36 @@ static void video_display_task(struct videodisplay_dev *dev)
dev->is_drm_enable = received_frames->is_drm;
num = received_frames->frames_info.layer_index;
+ if (num >= MAX_COMPOSER_COUNT ||
+ received_frames->frames_info.frame_count > MAX_COMPOSER_COUNT) {
+ pr_err("%s: received_frames(%px) invalid, layer_index=%d, frame_count=%d.\n",
+ __func__, received_frames,
+ received_frames->frames_info.layer_index,
+ received_frames->frames_info.frame_count);
+ if (received_frames->frames_info.frame_count >= 1 &&
+ received_frames->frames_info.frame_count <= MAX_COMPOSER_COUNT) {
+ fence_file = received_frames->frames_info.frame_info[0].release_fence;
+ if (fence_file) {
+ dma_fence_signal(fence_file);
+ dma_fence_put(fence_file);
+ }
+ }
+ atomic_set(&received_frames->on_use, false);
+ return;
+ }
fence_file = received_frames->frames_info.frame_info[num].input_fence;
if (video_wait_dma_fence(dev, fence_file) == 0) {
+ vd_print(dev->index, PRINT_ERROR,
+ "%s: input fence(%px) wait timeout, drop frame layer=%d count=%d.\n",
+ __func__, fence_file, num,
+ received_frames->frames_info.frame_count);
vd_put_input_dmabufs(&received_frames->frames_info);
+ fence_file = received_frames->frames_info.frame_info[num].release_fence;
+ if (fence_file) {
+ dma_fence_signal(fence_file);
+ dma_fence_put(fence_file);
+ }
atomic_set(&received_frames->on_use, false);
return;
}
@@ -4299,6 +4503,11 @@ static void video_display_task(struct videodisplay_dev *dev)
if (!detect_vf_usage(dev, received_frames, &need_composer, &do_mosaic_22)) {
vd_print(dev->index, PRINT_ERROR, "%s: fail to get vf usage.\n", __func__);
vd_put_input_dmabufs(&received_frames->frames_info);
+ fence_file = received_frames->frames_info.frame_info[num].release_fence;
+ if (fence_file) {
+ dma_fence_signal(fence_file);
+ dma_fence_put(fence_file);
+ }
atomic_set(&received_frames->on_use, false);
return;
}
@@ -4314,6 +4523,7 @@ static void video_display_task(struct videodisplay_dev *dev)
} else {
vd_print(dev->index, PRINT_INFO, "task: do display.\n");
vframe_display(dev, received_frames);
+ vd_put_input_dmabufs(&received_frames->frames_info);
}
}
@@ -4380,6 +4590,8 @@ static int video_display_thread(void *data)
}
if (kfifo_len(&dev->receive_q) > 0)
receive_q_uninit(dev);
+ vd_print(dev->index, PRINT_OTHER, "thread: stopped, receive_q len=%d\n",
+ kfifo_len(&dev->receive_q));
dev->thread_stopped = 1;
return 0;
}
@@ -4803,6 +5015,10 @@ static void vd_vf_put(struct vframe_s *vf, void *op_arg)
vf->canvas0_config[0].phy_addr,
vf->width,
vf->height);
+ if (!vf->enhance_vf) {
+ pr_err("%s: vf(%px) enhance_vf is NULL.\n", __func__, vf);
+ return;
+ }
vf = vf->enhance_vf;
display_vf = vf->enhance_vf;
vf->rendered = display_vf->rendered;
@@ -4939,8 +5155,13 @@ static void vd_vf_put(struct vframe_s *vf, void *op_arg)
dma_buf_put((struct dma_buf *)vf->file_vf);
if (vf->file_vf_ext)
dma_buf_put((struct dma_buf *)vf->file_vf_ext);
- dma_fence_signal(vd_prepare->release_fence[0]);
- dma_fence_put(vd_prepare->release_fence[0]);
+ if (vd_prepare->release_fence[0]) {
+ dma_fence_signal(vd_prepare->release_fence[0]);
+ dma_fence_put(vd_prepare->release_fence[0]);
+ } else {
+ pr_err("%s: release_fence[0] is NULL, frame_index=%d.\n",
+ __func__, vf->frame_index);
+ }
dev->fput_count++;
total_put_count++;
}
@@ -5345,7 +5566,9 @@ static int video_display_uninit(struct videodisplay_dev *dev)
dev->fget_count,
dev->fput_count);
}
- video_timeline_increase(dev, dev->fence_creat_count - dev->fence_release_count);
+ if (dev->fence_creat_count > dev->fence_release_count)
+ video_timeline_increase(dev,
+ dev->fence_creat_count - dev->fence_release_count);
dev->is_sideband = false;
dev->need_empty_ready = false;
dev_array[dev->index] = NULL;
@@ -5569,6 +5792,13 @@ int vd_set_frames(int index, struct frames_info_t *frames_info)
return -EINVAL;
}
+ pr_info("vd:%d %s: count=%d, layer=%d, dmabuf=(%px,%px), fi=%px\n",
+ index, __func__, frames_info->frame_count,
+ frames_info->layer_index,
+ frames_info->frame_info[frames_info->layer_index].dmabuf[0],
+ frames_info->frame_info[frames_info->layer_index].dmabuf[1],
+ frames_info);
+
vd_print(dev->index, PRINT_AXIS, "********src frame param********.\n");
vd_print(dev->index, PRINT_INFO,
"%s: count:%d, index:%d, z:%d, .\n",
@@ -5671,6 +5901,12 @@ int vd_mbd_setframe(int layer_index, struct mbd_video_frame_info_t *frame_info)
if (!dev)
return -1;
+ if (!frame_info->buffer_info) {
+ pr_err("%s: layer_index(%d) frame_info->buffer_info is NULL.\n",
+ __func__, layer_index);
+ return -EINVAL;
+ }
+
dev->received_count++;
vd_print(layer_index, PRINT_OTHER | PRINT_PATTERN,
"%s: total receive_count is %lld.\n",
@@ -5681,6 +5917,11 @@ int vd_mbd_setframe(int layer_index, struct mbd_video_frame_info_t *frame_info)
if (is_repeat_vf) {
vd_prepare = dev->vd_prepare_last;
+ if (!vd_prepare) {
+ pr_err("%s: layer_index(%d) vd_prepare_last is NULL for repeat frame.\n",
+ __func__, layer_index);
+ return -ENOENT;
+ }
} else {
vd_prepare = vd_prepare_data_q_get(dev);
if (!vd_prepare) {
@@ -5735,6 +5976,21 @@ int vd_mbd_setframe(int layer_index, struct mbd_video_frame_info_t *frame_info)
}
vf->vc_private = vd_private_q_pop(dev);
+ if (!vf->vc_private) {
+ pr_err("%s: layer_index(%d) vd_private_q_pop return NULL.\n",
+ __func__, layer_index);
+ vd_prepare_data_q_put(dev, vd_prepare);
+ dev->vd_prepare_last = NULL;
+ return -ENOENT;
+ }
+ if (!frame_info->lock_buffer_cb || !frame_info->unlock_buffer_cb) {
+ pr_err("%s: layer_index(%d) mbd lock/unlock_buffer_cb is NULL, buffer_info=%px.\n",
+ __func__, layer_index, frame_info->buffer_info);
+ vd_prepare_data_q_put(dev, vd_prepare);
+ vd_private_q_recycle(dev, vf->vc_private);
+ vf->vc_private = NULL;
+ return -EINVAL;
+ }
vf->vc_private->lock_buffer_cb = frame_info->lock_buffer_cb;
vf->vc_private->unlock_buffer_cb = frame_info->unlock_buffer_cb;
vf->vc_private->lock_buffer_cb((void *)frame_info->buffer_info);
--
2.55.0