[PATCH] media: vivid: initialize control update work items early

Hyeonjun Hong posted 1 patch 1 week, 1 day ago
drivers/media/test-drivers/vivid/vivid-core.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
[PATCH] media: vivid: initialize control update work items early
Posted by Hyeonjun Hong 1 week, 1 day ago
vivid_create_instance() installs the v4l2_device release callback long
before it initializes the update_hdmi_ctrl_work and update_svid_ctrl_work
items. If any of the error paths in between is taken, dropping the last
v4l2_device reference calls vivid_dev_release(), which cancels both work
items while their work->func is still NULL. __flush_work() then trips
WARN_ON(!work->func) and taints the kernel.

Reproduced by asking for an HDMI input while disabling both the video
and the metadata capture nodes, which vivid_detect_feature_set() rejects
with -EINVAL:

  $ modprobe vivid node_types=0xc1d3c

  WARNING: kernel/workqueue.c:4400 at __flush_work+0x9a7/0xc20
  cancel_work_sync+0x90/0xc0
  vivid_dev_release+0x1e/0x170 [vivid]
  v4l2_device_put+0x80/0xb0
  vivid_probe+0x257c/0xa3e0 [vivid]

Two such warnings are printed, one per work item.

Initialize both work items right after the vivid_dev structure is
allocated, so that vivid_dev_release() can cancel them from any error
path.

Fixes: d7c969f37515 ("media: vivid: Add 'Is Connected To' menu controls")
Assisted-by: LLM
Signed-off-by: Hyeonjun Hong <hyeonjunhong330@gmail.com>
---
 drivers/media/test-drivers/vivid/vivid-core.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/test-drivers/vivid/vivid-core.c b/drivers/media/test-drivers/vivid/vivid-core.c
index c042d92db175..ea0b5ae6f437 100644
--- a/drivers/media/test-drivers/vivid/vivid-core.c
+++ b/drivers/media/test-drivers/vivid/vivid-core.c
@@ -1820,6 +1820,8 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
 		return -ENOMEM;
 
 	dev->inst = inst;
+	INIT_WORK(&dev->update_hdmi_ctrl_work, update_hdmi_ctrls_work_handler);
+	INIT_WORK(&dev->update_svid_ctrl_work, update_svid_ctrls_work_handler);
 
 #ifdef CONFIG_MEDIA_CONTROLLER
 	dev->v4l2_dev.mdev = &dev->mdev;
@@ -1913,8 +1915,6 @@ static int vivid_create_instance(struct platform_device *pdev, int inst)
 	dev->edid_max_blocks = dev->edid_blocks = 2;
 	memcpy(dev->edid, vivid_hdmi_edid, sizeof(vivid_hdmi_edid));
 	dev->radio_rds_init_time = ktime_get();
-	INIT_WORK(&dev->update_hdmi_ctrl_work, update_hdmi_ctrls_work_handler);
-	INIT_WORK(&dev->update_svid_ctrl_work, update_svid_ctrls_work_handler);
 	for (int j = 0, k = 0; j < dev->num_inputs; ++j)
 		if (dev->input_type[j] == HDMI)
 			dev->hdmi_index_to_input_index[k++] = j;
-- 
2.34.1