Commit 309ad9e0 authored by Dafna Hirschfeld's avatar Dafna Hirschfeld

x

parent cd711719
From 3eab7992c2c0298ba5404233ff3aab75e5976395 Mon Sep 17 00:00:00 2001
From: Shuah Khan <skhan@linuxfoundation.org>
Date: Thu, 15 Aug 2019 13:42:13 -0600
Subject: [PATCH 2/4] media: vimc: Fix gpf in rmmod path when stream is active
If vimc module is removed while streaming is in progress, sensor subdev
unregister runs into general protection fault when it tries to unregister
media entities. This is a common subdev problem related to releasing
pads from v4l2_device_unregister_subdev() before calling unregister.
Unregister references pads during unregistering subdev.
The sd release handler is the right place for releasing all sd resources
including pads. The release handlers currently release all resources
except the pads.
Fix v4l2_device_unregister_subdev() not release pads and release pads
from the sd_int_op release handlers.
kernel: [ 4136.715839] general protection fault: 0000 [#1] SMP PTI
kernel: [ 4136.715847] CPU: 2 PID: 1972 Comm: bash Not tainted 5.3.0-rc2+ #4
kernel: [ 4136.715850] Hardware name: Dell Inc. OptiPlex 790/0HY9JP, BIOS A18 09/24/2013
kernel: [ 4136.715858] RIP: 0010:media_gobj_destroy.part.16+0x1f/0x60
kernel: [ 4136.715863] Code: ff 66 2e 0f 1f 84 00 00 00 00 00 66 66 66 66 90 55 48 89 fe 48 89 e5 53 48 89 fb 48 c7 c7 00 7f cf b0 e8 24 fa ff ff 48 8b 03 <48> 83 80 a0 00 00 00 01 48 8b 43 18 48 8b 53 10 48 89 42 08 48 89
kernel: [ 4136.715866] RSP: 0018:ffff9b2248fe3cb0 EFLAGS: 00010246
kernel: [ 4136.715870] RAX: bcf2bfbfa0d63c2f RBX: ffff88c3eb37e9c0 RCX: 00000000802a0018
kernel: [ 4136.715873] RDX: ffff88c3e4f6a078 RSI: ffff88c3eb37e9c0 RDI: ffffffffb0cf7f00
kernel: [ 4136.715876] RBP: ffff9b2248fe3cb8 R08: 0000000001000002 R09: ffffffffb0492b00
kernel: [ 4136.715879] R10: ffff9b2248fe3c28 R11: 0000000000000001 R12: 0000000000000038
kernel: [ 4136.715881] R13: ffffffffc09a1628 R14: ffff88c3e4f6a028 R15: fffffffffffffff2
kernel: [ 4136.715885] FS: 00007f8389647740(0000) GS:ffff88c465500000(0000) knlGS:0000000000000000
kernel: [ 4136.715888] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
kernel: [ 4136.715891] CR2: 000055d008f80fd8 CR3: 00000001996ec005 CR4: 00000000000606e0
kernel: [ 4136.715894] Call Trace:
kernel: [ 4136.715903] media_gobj_destroy+0x14/0x20
kernel: [ 4136.715908] __media_device_unregister_entity+0xb3/0xe0
kernel: [ 4136.715915] media_device_unregister_entity+0x30/0x40
kernel: [ 4136.715920] v4l2_device_unregister_subdev+0xa8/0xe0
kernel: [ 4136.715928] vimc_ent_sd_unregister+0x1e/0x30 [vimc]
kernel: [ 4136.715933] vimc_sen_rm+0x16/0x20 [vimc]
kernel: [ 4136.715938] vimc_remove+0x3e/0xa0 [vimc]
kernel: [ 4136.715945] platform_drv_remove+0x25/0x50
kernel: [ 4136.715951] device_release_driver_internal+0xe0/0x1b0
kernel: [ 4136.715956] device_driver_detach+0x14/0x20
kernel: [ 4136.715960] unbind_store+0xd1/0x130
kernel: [ 4136.715965] drv_attr_store+0x27/0x40
kernel: [ 4136.715971] sysfs_kf_write+0x48/0x60
kernel: [ 4136.715976] kernfs_fop_write+0x128/0x1b0
kernel: [ 4136.715982] __vfs_write+0x1b/0x40
kernel: [ 4136.715987] vfs_write+0xc3/0x1d0
kernel: [ 4136.715993] ksys_write+0xaa/0xe0
kernel: [ 4136.715999] __x64_sys_write+0x1a/0x20
kernel: [ 4136.716005] do_syscall_64+0x5a/0x130
kernel: [ 4136.716010] entry_SYSCALL_64_after_hwframe+0x4
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
---
drivers/media/platform/vimc/vimc-common.c | 3 +--
drivers/media/platform/vimc/vimc-debayer.c | 1 +
drivers/media/platform/vimc/vimc-scaler.c | 1 +
drivers/media/platform/vimc/vimc-sensor.c | 1 +
4 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/vimc/vimc-common.c b/drivers/media/platform/vimc/vimc-common.c
index 7e1ae0b12f1e..a3120f4f7a90 100644
--- a/drivers/media/platform/vimc/vimc-common.c
+++ b/drivers/media/platform/vimc/vimc-common.c
@@ -375,7 +375,7 @@ int vimc_ent_sd_register(struct vimc_ent_device *ved,
{
int ret;
- /* Allocate the pads */
+ /* Allocate the pads. Should be released from the sd_int_op release */
ved->pads = vimc_pads_init(num_pads, pads_flag);
if (IS_ERR(ved->pads))
return PTR_ERR(ved->pads);
@@ -424,7 +424,6 @@ EXPORT_SYMBOL_GPL(vimc_ent_sd_register);
void vimc_ent_sd_unregister(struct vimc_ent_device *ved, struct v4l2_subdev *sd)
{
media_entity_cleanup(ved->ent);
- vimc_pads_cleanup(ved->pads);
v4l2_device_unregister_subdev(sd);
}
EXPORT_SYMBOL_GPL(vimc_ent_sd_unregister);
diff --git a/drivers/media/platform/vimc/vimc-debayer.c b/drivers/media/platform/vimc/vimc-debayer.c
index 0bf97f8c05d5..586073cca065 100644
--- a/drivers/media/platform/vimc/vimc-debayer.c
+++ b/drivers/media/platform/vimc/vimc-debayer.c
@@ -479,6 +479,7 @@ static void vimc_deb_release(struct v4l2_subdev *sd)
struct vimc_deb_device *vdeb =
container_of(sd, struct vimc_deb_device, sd);
+ vimc_pads_cleanup(vdeb->ved.pads);
kfree(vdeb);
}
diff --git a/drivers/media/platform/vimc/vimc-scaler.c b/drivers/media/platform/vimc/vimc-scaler.c
index 53bb8c5a8e14..b4d1717a26e8 100644
--- a/drivers/media/platform/vimc/vimc-scaler.c
+++ b/drivers/media/platform/vimc/vimc-scaler.c
@@ -338,6 +338,7 @@ static void vimc_sca_release(struct v4l2_subdev *sd)
struct vimc_sca_device *vsca =
container_of(sd, struct vimc_sca_device, sd);
+ vimc_pads_cleanup(vsca->ved.pads);
kfree(vsca);
}
diff --git a/drivers/media/platform/vimc/vimc-sensor.c b/drivers/media/platform/vimc/vimc-sensor.c
index c54bfdafd027..57cacb2f2bd3 100644
--- a/drivers/media/platform/vimc/vimc-sensor.c
+++ b/drivers/media/platform/vimc/vimc-sensor.c
@@ -291,6 +291,7 @@ static void vimc_sen_release(struct v4l2_subdev *sd)
v4l2_ctrl_handler_free(&vsen->hdl);
tpg_free(&vsen->tpg);
+ vimc_pads_cleanup(vsen->ved.pads);
kfree(vsen);
}
--
2.17.1
From 509e997762b1648040b482994ff6ac9ca7fbde19 Mon Sep 17 00:00:00 2001
From: Dafna Hirschfeld <dafna3@gmail.com>
Date: Sat, 17 Aug 2019 05:00:12 -0700
Subject: [PATCH 4/4] debugs
---
drivers/media/platform/vimc/vimc-configfs.c | 16 ++++++++++++++--
drivers/media/platform/vimc/vimc-core.c | 11 +++++++++++
2 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/vimc/vimc-configfs.c b/drivers/media/platform/vimc/vimc-configfs.c
index f35b829cdf7e..48fee7579419 100644
--- a/drivers/media/platform/vimc/vimc-configfs.c
+++ b/drivers/media/platform/vimc/vimc-configfs.c
@@ -122,6 +122,8 @@ static void vimc_cfs_device_unplug(struct vimc_cfs_device *cfs)
static int vimc_cfs_device_plug(struct vimc_cfs_device *cfs)
{
struct vimc_link *link;
+ struct vimc_entity *ent;
+ int i = 0;
cg_dbg(&cfs->gdev, "Plugging device\n");
@@ -131,6 +133,14 @@ static int vimc_cfs_device_plug(struct vimc_cfs_device *cfs)
return -EINVAL;
}
+ pr_info("%s: start cfs=%px &cfs->pdata.ents=%px\n", __func__, cfs, &cfs->pdata.ents);
+ list_for_each_entry(ent, &cfs->pdata.ents, list) {
+ i++;
+ pr_info("%s: start i=%d ent=%px\n", __func__, i, ent);
+ if (i>10)
+ return -EINVAL;
+ }
+
list_for_each_entry(link, &cfs->pdata.links, list) {
if (vimc_cfs_link_set_ents(cfs, link)) {
cg_err(&cfs->gdev, "could not validate link\n");
@@ -367,7 +377,7 @@ static struct config_group *vimc_cfs_ent_make_group(struct config_group *group,
goto syntax_error;
}
list_for_each_entry(ent, &cfs->pdata.ents, list) {
- if (!strncmp(ent->name, ent_name, strlen(ent->name))) {
+ if (!strncmp(ent->name, ent_name, sizeof(ent->name))) {
cg_err(&cfs->gdev, "entity `%s` already exist\n",
ent->name);
goto syntax_error;
@@ -381,7 +391,7 @@ static struct config_group *vimc_cfs_ent_make_group(struct config_group *group,
strscpy(c_ent->ent.drv_name, name, drv_namelen + 1);
strscpy(c_ent->ent.name, ent_name, sizeof(c_ent->ent.name));
- cg_dbg(&cfs->gdev, "New entity %s:%s\n",
+ cg_dbg(&cfs->gdev, "new entity %s:%s\n",
c_ent->ent.drv_name, c_ent->ent.name);
@@ -545,12 +555,14 @@ static struct config_group *vimc_cfs_dev_make_group(
{
struct vimc_cfs_device *cfs = kzalloc(sizeof(*cfs), GFP_KERNEL);
+ pr_info("%s: start cfs=%px &cfs->pdata=%px\n", __func__, cfs, &cfs->pdata);
if (!cfs)
return ERR_PTR(-ENOMEM);
/* Configure platform data */
INIT_LIST_HEAD(&cfs->pdata.ents);
INIT_LIST_HEAD(&cfs->pdata.links);
+ pr_info("%s: start cfs=%px &cfs->pdata.ents=%px\n", __func__, cfs, &cfs->pdata.ents);
/* Configure configfs group */
config_group_init_type_name(&cfs->gdev, name, &vimc_cfs_dev_type);
diff --git a/drivers/media/platform/vimc/vimc-core.c b/drivers/media/platform/vimc/vimc-core.c
index a829918ca40f..8a98fd21fc47 100644
--- a/drivers/media/platform/vimc/vimc-core.c
+++ b/drivers/media/platform/vimc/vimc-core.c
@@ -185,12 +185,23 @@ static int vimc_probe(struct platform_device *pdev)
{
const struct vimc_platform_data_core *pdata = pdev->dev.platform_data;
struct vimc_device *vimc;
+ struct vimc_entity *ent;
int ret = 0;
+ int i = 0;
dev_dbg(&pdev->dev, "probe\n");
vimc = devm_kzalloc(&pdev->dev, sizeof(*vimc),
GFP_KERNEL);
+
+ list_for_each_entry(ent, &pdata->ents, list) {
+ i++;
+ pr_info("%s: start i=%d ent=%px %s:%s\n", __func__, i, ent,
+ ent->drv_name, ent->name);
+ if (i>10)
+ return -EINVAL;
+ }
+
memset(&vimc->mdev, 0, sizeof(vimc->mdev));
/* Link the media device within the v4l2_device */
--
2.17.1
......@@ -7,8 +7,6 @@ version=$1
mkdir -p /lib/modules/$version/kernel/drivers/media/platform/vimc ; cp drivers/media/platform/vimc/vimc.ko /lib/modules/$version/kernel/drivers/media/platform/vimc ; true /lib/modules/$version/kernel/drivers/media/platform/vimc/vimc.ko ; scripts/sign-file "sha512" "certs/signing_key.pem" certs/signing_key.x509 /lib/modules/$version/kernel/drivers/media/platform/vimc/vimc.ko ; true /lib/modules/$version/kernel/drivers/media/platform/vimc/vimc.ko
mkdir -p /lib/modules/$version/kernel/drivers/media ; cp drivers/media/media.ko /lib/modules/$version/kernel/drivers/media ; true /lib/modules/$version/kernel/drivers/media/media.ko ; scripts/sign-file "sha512" "certs/signing_key.pem" certs/signing_key.x509 /lib/modules/$version/kernel/drivers/media/media.ko && true /lib/modules/$version/kernel/drivers/media/media.ko
mkdir -p /lib/modules/$version/kernel/drivers/media/platform/vicodec
cp drivers/media/platform/vicodec/vicodec.ko /lib/modules/$version/kernel/drivers/media/platform/vicodec
true /lib/modules/$version/kernel/drivers/media/platform/vicodec/vicodec.ko
......
#!/bin/bash
set -i
set -x
echo "file drivers/media/platform/vimc/* +p" > /sys/kernel/debug/dynamic_debug/control
echo 15 > /proc/sys/kernel/printk
mount -t configfs none /configfs
rmdir /configfs/vimc/mdev/entities/*
rmdir /configfs/vimc/mdev/links/*
rmdir /configfs/vimc/mdev
modprobe -vr vimc
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment