diff --git a/kernel/daedalus_v4l2_main.c b/kernel/daedalus_v4l2_main.c index 6dfd6cf..f3830a5 100644 --- a/kernel/daedalus_v4l2_main.c +++ b/kernel/daedalus_v4l2_main.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -680,8 +681,18 @@ static void daedalus_device_run(void *priv) * trigger MEDIA_REQUEST_STATE_COMPLETE. vb2-core's normal * buf_done path unbinds the buffer's req_obj but leaves the * control object bound — the driver has to complete it. + * + * Take our own reference via media_request_get so the + * pointer stays valid even if vb2 releases its reference + * concurrently (e.g. via MEDIA_IOC_REQUEST_REINIT or a + * process kill triggering buf_request_complete from the + * cancel path). Released by media_request_put in + * daedalus_complete_resp_frame. Matches the cedrus / + * rkvdec refcount pattern. */ inf->req = src_buf->vb2_buf.req_obj.req; + if (inf->req) + media_request_get(inf->req); mutex_lock(&dev->inflight_lock); list_add_tail(&inf->list, &dev->inflight); @@ -833,6 +844,15 @@ void daedalus_complete_resp_frame(u32 cookie, v4l2_m2m_buf_done_and_job_finish(dev->m2m_dev, inf->ctx->m2m_ctx, state); + /* + * Release our reference taken in device_run; safe to do + * AFTER buf_done_and_job_finish (which dropped the vb2 + * reference) because we still hold this one. If the + * refcount hits zero here, media-core releases the request. + */ + if (inf->req) + media_request_put(inf->req); + kfree(inf); }