* [PATCH 0/2] media: venus: close() fixes @ 2024-10-23 5:24 Sergey Senozhatsky 2024-10-23 5:24 ` [PATCH 1/2] media: venus: fix enc/dec destruction order Sergey Senozhatsky 2024-10-23 5:24 ` [PATCH 2/2] media: venus: sync with threaded IRQ during inst destruction Sergey Senozhatsky 0 siblings, 2 replies; 8+ messages in thread From: Sergey Senozhatsky @ 2024-10-23 5:24 UTC (permalink / raw) To: Stanimir Varbanov, Vikash Garodia Cc: Bryan O'Donoghue, linux-media, linux-kernel, Sergey Senozhatsky A couple of venus fixes for close() handling (both enc and dec). Sergey Senozhatsky (2): media: venus: fix enc/dec destruction order media: venus: sync with threaded IRQ during inst destruction drivers/media/platform/qcom/venus/vdec.c | 20 +++++++++++++++++--- drivers/media/platform/qcom/venus/venc.c | 19 ++++++++++++++++--- 2 files changed, 33 insertions(+), 6 deletions(-) -- 2.47.0.105.g07ac214952-goog ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/2] media: venus: fix enc/dec destruction order 2024-10-23 5:24 [PATCH 0/2] media: venus: close() fixes Sergey Senozhatsky @ 2024-10-23 5:24 ` Sergey Senozhatsky 2024-10-23 5:24 ` [PATCH 2/2] media: venus: sync with threaded IRQ during inst destruction Sergey Senozhatsky 1 sibling, 0 replies; 8+ messages in thread From: Sergey Senozhatsky @ 2024-10-23 5:24 UTC (permalink / raw) To: Stanimir Varbanov, Vikash Garodia Cc: Bryan O'Donoghue, linux-media, linux-kernel, Sergey Senozhatsky, Tomasz Figa We destroy mutex-es too early as they are still taken in v4l2_fh_exit()->v4l2_event_unsubscribe()->v4l2_ctrl_find(). We should destroy mutex-es right before kfree(). Also do not vdec_ctrl_deinit() before v4l2_fh_exit(). Suggested-by: Tomasz Figa <tfiga@google.com> Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org> --- drivers/media/platform/qcom/venus/vdec.c | 7 ++++--- drivers/media/platform/qcom/venus/venc.c | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c index 6252a6b3d4ba..0013c4704f03 100644 --- a/drivers/media/platform/qcom/venus/vdec.c +++ b/drivers/media/platform/qcom/venus/vdec.c @@ -1752,13 +1752,14 @@ static int vdec_close(struct file *file) cancel_work_sync(&inst->delayed_process_work); v4l2_m2m_ctx_release(inst->m2m_ctx); v4l2_m2m_release(inst->m2m_dev); - vdec_ctrl_deinit(inst); ida_destroy(&inst->dpb_ids); hfi_session_destroy(inst); - mutex_destroy(&inst->lock); - mutex_destroy(&inst->ctx_q_lock); v4l2_fh_del(&inst->fh); v4l2_fh_exit(&inst->fh); + vdec_ctrl_deinit(inst); + + mutex_destroy(&inst->lock); + mutex_destroy(&inst->ctx_q_lock); vdec_pm_put(inst, false); diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c index 322a7737e2c7..6a26a6592424 100644 --- a/drivers/media/platform/qcom/venus/venc.c +++ b/drivers/media/platform/qcom/venus/venc.c @@ -1519,14 +1519,14 @@ static int venc_close(struct file *file) v4l2_m2m_ctx_release(inst->m2m_ctx); v4l2_m2m_release(inst->m2m_dev); - venc_ctrl_deinit(inst); hfi_session_destroy(inst); - mutex_destroy(&inst->lock); - mutex_destroy(&inst->ctx_q_lock); v4l2_fh_del(&inst->fh); v4l2_fh_exit(&inst->fh); + venc_ctrl_deinit(inst); inst->enc_state = VENUS_ENC_STATE_DEINIT; + mutex_destroy(&inst->lock); + mutex_destroy(&inst->ctx_q_lock); venc_pm_put(inst, false); -- 2.47.0.105.g07ac214952-goog ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/2] media: venus: sync with threaded IRQ during inst destruction 2024-10-23 5:24 [PATCH 0/2] media: venus: close() fixes Sergey Senozhatsky 2024-10-23 5:24 ` [PATCH 1/2] media: venus: fix enc/dec destruction order Sergey Senozhatsky @ 2024-10-23 5:24 ` Sergey Senozhatsky 2024-10-24 4:58 ` Sergey Senozhatsky 1 sibling, 1 reply; 8+ messages in thread From: Sergey Senozhatsky @ 2024-10-23 5:24 UTC (permalink / raw) To: Stanimir Varbanov, Vikash Garodia Cc: Bryan O'Donoghue, linux-media, linux-kernel, Sergey Senozhatsky When destroy inst we should make sure that we don't race against threaded IRQ (or pending IRQ), otherwise we can concurrently kfree() inst context and inst itself. BUG: KASAN: slab-use-after-free in vb2_queue_error+0x80/0x90 Call trace: dump_backtrace+0x1c4/0x1f8 show_stack+0x38/0x60 dump_stack_lvl+0x168/0x1f0 print_report+0x170/0x4c8 kasan_report+0x94/0xd0 __asan_report_load2_noabort+0x20/0x30 vb2_queue_error+0x80/0x90 venus_helper_vb2_queue_error+0x54/0x78 venc_event_notify+0xec/0x158 hfi_event_notify+0x878/0xd20 hfi_process_msg_packet+0x27c/0x4e0 venus_isr_thread+0x258/0x6e8 hfi_isr_thread+0x70/0x90 venus_isr_thread+0x34/0x50 irq_thread_fn+0x88/0x130 irq_thread+0x160/0x2c0 kthread+0x294/0x328 ret_from_fork+0x10/0x20 Allocated by task 20291: kasan_set_track+0x4c/0x80 kasan_save_alloc_info+0x28/0x38 __kasan_kmalloc+0x84/0xa0 kmalloc_trace+0x7c/0x98 v4l2_m2m_ctx_init+0x74/0x280 venc_open+0x444/0x6d0 v4l2_open+0x19c/0x2a0 chrdev_open+0x374/0x3f0 do_dentry_open+0x710/0x10a8 vfs_open+0x88/0xa8 path_openat+0x1e6c/0x2700 do_filp_open+0x1a4/0x2e0 do_sys_openat2+0xe8/0x508 do_sys_open+0x15c/0x1a0 __arm64_sys_openat+0xa8/0xc8 invoke_syscall+0xdc/0x270 el0_svc_common+0x1ec/0x250 do_el0_svc+0x54/0x70 el0_svc+0x50/0xe8 el0t_64_sync_handler+0x48/0x120 el0t_64_sync+0x1a8/0x1b0 Guard inst destruction (both dec and enc) with hard and threaded IRQ synchronization. Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org> --- drivers/media/platform/qcom/venus/vdec.c | 13 +++++++++++++ drivers/media/platform/qcom/venus/venc.c | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c index 0013c4704f03..ff1823bc967c 100644 --- a/drivers/media/platform/qcom/venus/vdec.c +++ b/drivers/media/platform/qcom/venus/vdec.c @@ -1747,6 +1747,13 @@ static int vdec_close(struct file *file) { struct venus_inst *inst = to_inst(file); + /* + * Make sure we don't have pending IRQs and no threaded IRQ handler is + * running nor pending (synchronize_irq)), which can race with inst + * destruction. + */ + disable_irq(inst->core->irq); + vdec_pm_get(inst); cancel_work_sync(&inst->delayed_process_work); @@ -1763,6 +1770,12 @@ static int vdec_close(struct file *file) vdec_pm_put(inst, false); + /* + * inst is gone from the core->instances list, re-enable IRQ and + * threaded IRQ + */ + enable_irq(inst->core->irq); + kfree(inst); return 0; } diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c index 6a26a6592424..6575e84312fe 100644 --- a/drivers/media/platform/qcom/venus/venc.c +++ b/drivers/media/platform/qcom/venus/venc.c @@ -1515,6 +1515,13 @@ static int venc_close(struct file *file) { struct venus_inst *inst = to_inst(file); + /* + * Make sure we don't have pending IRQs and no threaded IRQ handler is + * running nor pending (synchronize_irq)), which can race with inst + * destruction. + */ + disable_irq(inst->core->irq); + venc_pm_get(inst); v4l2_m2m_ctx_release(inst->m2m_ctx); @@ -1530,6 +1537,12 @@ static int venc_close(struct file *file) venc_pm_put(inst, false); + /* + * inst is gone from the core->instances list, re-enable IRQ and + * threaded IRQ + */ + enable_irq(inst->core->irq); + kfree(inst); return 0; } -- 2.47.0.105.g07ac214952-goog ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2] media: venus: sync with threaded IRQ during inst destruction 2024-10-23 5:24 ` [PATCH 2/2] media: venus: sync with threaded IRQ during inst destruction Sergey Senozhatsky @ 2024-10-24 4:58 ` Sergey Senozhatsky 2024-10-24 5:13 ` Sergey Senozhatsky 0 siblings, 1 reply; 8+ messages in thread From: Sergey Senozhatsky @ 2024-10-24 4:58 UTC (permalink / raw) To: Sergey Senozhatsky Cc: Stanimir Varbanov, Vikash Garodia, Bryan O'Donoghue, linux-media, linux-kernel On (24/10/23 14:24), Sergey Senozhatsky wrote: > Guard inst destruction (both dec and enc) with hard and threaded > IRQ synchronization. Folks, please ignore this patch. Stand by for v2. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2] media: venus: sync with threaded IRQ during inst destruction 2024-10-24 4:58 ` Sergey Senozhatsky @ 2024-10-24 5:13 ` Sergey Senozhatsky 2024-10-24 5:18 ` Tomasz Figa 0 siblings, 1 reply; 8+ messages in thread From: Sergey Senozhatsky @ 2024-10-24 5:13 UTC (permalink / raw) To: Sergey Senozhatsky Cc: Stanimir Varbanov, Vikash Garodia, Bryan O'Donoghue, linux-media, linux-kernel On (24/10/24 13:58), Sergey Senozhatsky wrote: > Date: Thu, 24 Oct 2024 13:58:36 +0900 > From: Sergey Senozhatsky <senozhatsky@chromium.org> > To: Sergey Senozhatsky <senozhatsky@chromium.org> > Cc: Stanimir Varbanov <stanimir.k.varbanov@gmail.com>, Vikash Garodia > <quic_vgarodia@quicinc.com>, Bryan O'Donoghue > <bryan.odonoghue@linaro.org>, linux-media@vger.kernel.org, > linux-kernel@vger.kernel.org > Subject: Re: [PATCH 2/2] media: venus: sync with threaded IRQ during inst > destruction > Message-ID: <20241024045836.GJ1279924@google.com> > > On (24/10/23 14:24), Sergey Senozhatsky wrote: > > Guard inst destruction (both dec and enc) with hard and threaded > > IRQ synchronization. > > Folks, please ignore this patch. Stand by for v2. I think it probably should be something like this (both for dec and enc). --- @@ -1538,9 +1538,25 @@ static int venc_close(struct file *file) venc_pm_get(inst); + /* + * First, remove the inst from the ->instances list, so that + * to_instance() will return NULL. + */ + hfi_session_destroy(inst); + /* + * Second, make sure we don't have IRQ/IRQ-thread currently running or + * pending execution (disable_irq() calls synchronize_irq()), which + * can race with the inst destruction. + */ + disable_irq(inst->core->irq); + /* + * Lastly, inst is gone from the core->instances list and we don't + * have running/pending IRQ/IRQ-thread, proceed with the destruction + */ + enable_irq(inst->core->irq); + v4l2_m2m_ctx_release(inst->m2m_ctx); v4l2_m2m_release(inst->m2m_dev); - hfi_session_destroy(inst); v4l2_fh_del(&inst->fh); v4l2_fh_exit(&inst->fh); venc_ctrl_deinit(inst); ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2] media: venus: sync with threaded IRQ during inst destruction 2024-10-24 5:13 ` Sergey Senozhatsky @ 2024-10-24 5:18 ` Tomasz Figa 2024-10-24 5:46 ` Sergey Senozhatsky 0 siblings, 1 reply; 8+ messages in thread From: Tomasz Figa @ 2024-10-24 5:18 UTC (permalink / raw) To: Sergey Senozhatsky Cc: Stanimir Varbanov, Vikash Garodia, Bryan O'Donoghue, linux-media, linux-kernel Hi Sergey, On Thu, Oct 24, 2024 at 2:13 PM Sergey Senozhatsky <senozhatsky@chromium.org> wrote: > > On (24/10/24 13:58), Sergey Senozhatsky wrote: > > Date: Thu, 24 Oct 2024 13:58:36 +0900 > > From: Sergey Senozhatsky <senozhatsky@chromium.org> > > To: Sergey Senozhatsky <senozhatsky@chromium.org> > > Cc: Stanimir Varbanov <stanimir.k.varbanov@gmail.com>, Vikash Garodia > > <quic_vgarodia@quicinc.com>, Bryan O'Donoghue > > <bryan.odonoghue@linaro.org>, linux-media@vger.kernel.org, > > linux-kernel@vger.kernel.org > > Subject: Re: [PATCH 2/2] media: venus: sync with threaded IRQ during inst > > destruction > > Message-ID: <20241024045836.GJ1279924@google.com> > > > > On (24/10/23 14:24), Sergey Senozhatsky wrote: > > > Guard inst destruction (both dec and enc) with hard and threaded > > > IRQ synchronization. > > > > Folks, please ignore this patch. Stand by for v2. > > I think it probably should be something like this (both for dec and > enc). > > --- > > @@ -1538,9 +1538,25 @@ static int venc_close(struct file *file) > > venc_pm_get(inst); > > + /* > + * First, remove the inst from the ->instances list, so that > + * to_instance() will return NULL. > + */ > + hfi_session_destroy(inst); > + /* > + * Second, make sure we don't have IRQ/IRQ-thread currently running or > + * pending execution (disable_irq() calls synchronize_irq()), which > + * can race with the inst destruction. > + */ > + disable_irq(inst->core->irq); > + /* > + * Lastly, inst is gone from the core->instances list and we don't > + * have running/pending IRQ/IRQ-thread, proceed with the destruction > + */ > + enable_irq(inst->core->irq); > + Thanks a lot for looking into this. Wouldn't it be enough to just call synchronize_irq() at this point, since the instance was removed from the list already? I guess the question is if that's the only way the interrupt handler can get hold of the instance. Best, Tomasz > v4l2_m2m_ctx_release(inst->m2m_ctx); > v4l2_m2m_release(inst->m2m_dev); > - hfi_session_destroy(inst); > v4l2_fh_del(&inst->fh); > v4l2_fh_exit(&inst->fh); > venc_ctrl_deinit(inst); > ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2] media: venus: sync with threaded IRQ during inst destruction 2024-10-24 5:18 ` Tomasz Figa @ 2024-10-24 5:46 ` Sergey Senozhatsky 2024-10-24 6:05 ` Tomasz Figa 0 siblings, 1 reply; 8+ messages in thread From: Sergey Senozhatsky @ 2024-10-24 5:46 UTC (permalink / raw) To: Tomasz Figa Cc: Sergey Senozhatsky, Stanimir Varbanov, Vikash Garodia, Bryan O'Donoghue, linux-media, linux-kernel On (24/10/24 14:18), Tomasz Figa wrote: > > @@ -1538,9 +1538,25 @@ static int venc_close(struct file *file) > > > > venc_pm_get(inst); > > > > + /* > > + * First, remove the inst from the ->instances list, so that > > + * to_instance() will return NULL. > > + */ > > + hfi_session_destroy(inst); > > + /* > > + * Second, make sure we don't have IRQ/IRQ-thread currently running or > > + * pending execution (disable_irq() calls synchronize_irq()), which > > + * can race with the inst destruction. > > + */ > > + disable_irq(inst->core->irq); > > + /* > > + * Lastly, inst is gone from the core->instances list and we don't > > + * have running/pending IRQ/IRQ-thread, proceed with the destruction > > + */ > > + enable_irq(inst->core->irq); > > + > > Thanks a lot for looking into this. Wouldn't it be enough to just call > synchronize_irq() at this point, since the instance was removed from > the list already? I guess the question is if that's the only way the > interrupt handler can get hold of the instance. Good question. synchronize_irq() waits for IRQ-threads, so if inst is accessed only from IRQ-thread then we are fine. If, however, inst is also accessed from hard IRQ, then synchronize_irq() won't work, I guess, because it doesn't wait for "in flight hard IRQs". disable_irq() OTOH "waits for completion", so we cover in-flight hard IRQs too. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2] media: venus: sync with threaded IRQ during inst destruction 2024-10-24 5:46 ` Sergey Senozhatsky @ 2024-10-24 6:05 ` Tomasz Figa 0 siblings, 0 replies; 8+ messages in thread From: Tomasz Figa @ 2024-10-24 6:05 UTC (permalink / raw) To: Sergey Senozhatsky Cc: Stanimir Varbanov, Vikash Garodia, Bryan O'Donoghue, linux-media, linux-kernel On Thu, Oct 24, 2024 at 2:46 PM Sergey Senozhatsky <senozhatsky@chromium.org> wrote: > > On (24/10/24 14:18), Tomasz Figa wrote: > > > @@ -1538,9 +1538,25 @@ static int venc_close(struct file *file) > > > > > > venc_pm_get(inst); > > > > > > + /* > > > + * First, remove the inst from the ->instances list, so that > > > + * to_instance() will return NULL. > > > + */ > > > + hfi_session_destroy(inst); > > > + /* > > > + * Second, make sure we don't have IRQ/IRQ-thread currently running or > > > + * pending execution (disable_irq() calls synchronize_irq()), which > > > + * can race with the inst destruction. > > > + */ > > > + disable_irq(inst->core->irq); > > > + /* > > > + * Lastly, inst is gone from the core->instances list and we don't > > > + * have running/pending IRQ/IRQ-thread, proceed with the destruction > > > + */ > > > + enable_irq(inst->core->irq); > > > + > > > > Thanks a lot for looking into this. Wouldn't it be enough to just call > > synchronize_irq() at this point, since the instance was removed from > > the list already? I guess the question is if that's the only way the > > interrupt handler can get hold of the instance. > > Good question. > > synchronize_irq() waits for IRQ-threads, so if inst is accessed only from > IRQ-thread then we are fine. If, however, inst is also accessed from hard > IRQ, then synchronize_irq() won't work, I guess, because it doesn't wait > for "in flight hard IRQs". disable_irq() OTOH "waits for completion", so > we cover in-flight hard IRQs too. Looking at the code, synchronize_irq() internally also calls synchronize_hardirq() and that in turn waits for the IRQD_IRQ_INPROGESS flag to be cleared before returning [1]. The flag is set by handle_irq_event() before most of the IRQ handling is run and cleared at the end of the function [2], which makes me believe that it would actually ensure all the hardirq and threaded IRQ handlers would be waited for. [1] https://elixir.bootlin.com/linux/v6.11.5/source/kernel/irq/manage.c#L38 [2] https://elixir.bootlin.com/linux/v6.11.5/source/kernel/irq/handle.c#L202 Although I guess it would be the best if someone confirmed that, because with all the IRQ handling complexities of SMP, nothing can be certain today. :P Best, Tomasz ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2024-10-24 6:06 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2024-10-23 5:24 [PATCH 0/2] media: venus: close() fixes Sergey Senozhatsky 2024-10-23 5:24 ` [PATCH 1/2] media: venus: fix enc/dec destruction order Sergey Senozhatsky 2024-10-23 5:24 ` [PATCH 2/2] media: venus: sync with threaded IRQ during inst destruction Sergey Senozhatsky 2024-10-24 4:58 ` Sergey Senozhatsky 2024-10-24 5:13 ` Sergey Senozhatsky 2024-10-24 5:18 ` Tomasz Figa 2024-10-24 5:46 ` Sergey Senozhatsky 2024-10-24 6:05 ` Tomasz Figa
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox