* [PATCH] [media] media-device: Don't call notify callbacks holding a spinlock
@ 2016-03-14 19:16 Mauro Carvalho Chehab
2016-03-14 19:19 ` [PATCH v2] " Mauro Carvalho Chehab
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Mauro Carvalho Chehab @ 2016-03-14 19:16 UTC (permalink / raw)
To: Linux Media Mailing List
Cc: Mauro Carvalho Chehab, Mauro Carvalho Chehab, Shuah Khan,
Javier Martinez Canillas, Laurent Pinchart, Hans Verkuil,
Prabhakar Lad
The notify routines may sleep. So, they can't be called in spinlock
context. Also, they may want to call other media routines that might
be spinning the spinlock, like creating a link.
This fixes the following bug:
[ 1839.510587] BUG: sleeping function called from invalid context at mm/slub.c:1289
[ 1839.510881] in_atomic(): 1, irqs_disabled(): 0, pid: 3479, name: modprobe
[ 1839.511157] 4 locks held by modprobe/3479:
[ 1839.511415] #0: (&dev->mutex){......}, at: [<ffffffff81ce8933>] __driver_attach+0xa3/0x160
[ 1839.512381] #1: (&dev->mutex){......}, at: [<ffffffff81ce8941>] __driver_attach+0xb1/0x160
[ 1839.512388] #2: (register_mutex#5){+.+.+.}, at: [<ffffffffa10596c7>] usb_audio_probe+0x257/0x1c90 [snd_usb_audio]
[ 1839.512401] #3: (&(&mdev->lock)->rlock){+.+.+.}, at: [<ffffffffa0e6051b>] media_device_register_entity+0x1cb/0x700 [media]
[ 1839.512412] CPU: 2 PID: 3479 Comm: modprobe Not tainted 4.5.0-rc3+ #49
[ 1839.512415] Hardware name: /NUC5i7RYB, BIOS RYBDWi35.86A.0350.2015.0812.1722 08/12/2015
[ 1839.512417] 0000000000000000 ffff8803b3f6f288 ffffffff81933901 ffff8803c4bae000
[ 1839.512422] ffff8803c4bae5c8 ffff8803b3f6f2b0 ffffffff811c6af5 ffff8803c4bae000
[ 1839.512427] ffffffff8285d7f6 0000000000000509 ffff8803b3f6f2f0 ffffffff811c6ce5
[ 1839.512432] Call Trace:
[ 1839.512436] [<ffffffff81933901>] dump_stack+0x85/0xc4
[ 1839.512440] [<ffffffff811c6af5>] ___might_sleep+0x245/0x3a0
[ 1839.512443] [<ffffffff811c6ce5>] __might_sleep+0x95/0x1a0
[ 1839.512446] [<ffffffff8155aade>] kmem_cache_alloc_trace+0x20e/0x300
[ 1839.512451] [<ffffffffa0e66e3d>] ? media_add_link+0x4d/0x140 [media]
[ 1839.512455] [<ffffffffa0e66e3d>] media_add_link+0x4d/0x140 [media]
[ 1839.512459] [<ffffffffa0e69931>] media_create_pad_link+0xa1/0x600 [media]
[ 1839.512463] [<ffffffffa0fe11b3>] au0828_media_graph_notify+0x173/0x360 [au0828]
[ 1839.512467] [<ffffffffa0e68a6a>] ? media_gobj_create+0x1ba/0x480 [media]
[ 1839.512471] [<ffffffffa0e606fb>] media_device_register_entity+0x3ab/0x700 [media]
Tested with an HVR-950Q, under the following testcases:
1) load au0828 driver first, and then snd-usb-audio;
2) load snd-usb-audio driver first, and then au0828;
3) loading both drivers, and then connecting the device.
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
---
drivers/media/i2c/tvp5150.c | 39 ++++++++++++++++++++++-------------
drivers/media/media-device.c | 5 +++--
drivers/media/v4l2-core/v4l2-common.c | 8 +++++++
include/media/v4l2-subdev.h | 4 ++++
4 files changed, 40 insertions(+), 16 deletions(-)
diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c
index ff18444e19e4..14004fd7d0fb 100644
--- a/drivers/media/i2c/tvp5150.c
+++ b/drivers/media/i2c/tvp5150.c
@@ -1208,6 +1208,28 @@ static int tvp5150_registered_async(struct v4l2_subdev *sd)
return 0;
}
+static int __maybe_unused tvp5150_pad_init(struct v4l2_subdev *sd)
+{
+ struct tvp5150 *core = to_tvp5150(sd);
+ int res;
+
+#if defined(CONFIG_MEDIA_CONTROLLER)
+ core->pads[DEMOD_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK;
+ core->pads[DEMOD_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE;
+ core->pads[DEMOD_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE;
+
+ sd->entity.function = MEDIA_ENT_F_ATV_DECODER;
+
+ res = media_entity_pads_init(&sd->entity, DEMOD_NUM_PADS, core->pads);
+ if (res < 0)
+ return res;
+
+ sd->entity.ops = &tvp5150_sd_media_ops;
+#endif
+ return 0;
+}
+
+
/* ----------------------------------------------------------------------- */
static const struct v4l2_ctrl_ops tvp5150_ctrl_ops = {
@@ -1246,6 +1268,9 @@ static const struct v4l2_subdev_vbi_ops tvp5150_vbi_ops = {
};
static const struct v4l2_subdev_pad_ops tvp5150_pad_ops = {
+#ifdef CONFIG_MEDIA_CONTROLLER
+ .pad_init = tvp5150_pad_init,
+#endif
.enum_mbus_code = tvp5150_enum_mbus_code,
.enum_frame_size = tvp5150_enum_frame_size,
.set_fmt = tvp5150_fill_fmt,
@@ -1475,20 +1500,6 @@ static int tvp5150_probe(struct i2c_client *c,
v4l2_i2c_subdev_init(sd, c, &tvp5150_ops);
sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
-#if defined(CONFIG_MEDIA_CONTROLLER)
- core->pads[DEMOD_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK;
- core->pads[DEMOD_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE;
- core->pads[DEMOD_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE;
-
- sd->entity.function = MEDIA_ENT_F_ATV_DECODER;
-
- res = media_entity_pads_init(&sd->entity, DEMOD_NUM_PADS, core->pads);
- if (res < 0)
- return res;
-
- sd->entity.ops = &tvp5150_sd_media_ops;
-#endif
-
res = tvp5150_detect_version(core);
if (res < 0)
return res;
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index 6ba6e8f982fc..fc3c199e5500 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -587,14 +587,15 @@ int __must_check media_device_register_entity(struct media_device *mdev,
media_gobj_create(mdev, MEDIA_GRAPH_PAD,
&entity->pads[i].graph_obj);
+ spin_unlock(&mdev->lock);
+
/* invoke entity_notify callbacks */
list_for_each_entry_safe(notify, next, &mdev->entity_notify, list) {
(notify)->notify(entity, notify->notify_data);
}
- spin_unlock(&mdev->lock);
-
mutex_lock(&mdev->graph_mutex);
+
if (mdev->entity_internal_idx_max
>= mdev->pm_count_walk.ent_enum.idx_max) {
struct media_entity_graph new = { .top = 0 };
diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
index 5b808500e7e7..6bcdf557e027 100644
--- a/drivers/media/v4l2-core/v4l2-common.c
+++ b/drivers/media/v4l2-core/v4l2-common.c
@@ -112,6 +112,14 @@ EXPORT_SYMBOL(v4l2_ctrl_query_fill);
void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client,
const struct v4l2_subdev_ops *ops)
{
+ /*
+ * Initialize the MC pads - for now, this will be called
+ * unconditionally, since the current implementation will defer
+ * the pads initialization until the media_dev is created.
+ */
+ if (v4l2_subdev_has_op(sd, pad, pad_init))
+ sd->ops->pad->pad_init(sd);
+
v4l2_subdev_init(sd, ops);
sd->flags |= V4L2_SUBDEV_FL_IS_I2C;
/* the owner is the same as the i2c_client's driver owner */
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index 11e2dfec0198..c9bb221029e4 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -572,6 +572,9 @@ struct v4l2_subdev_pad_config {
/**
* struct v4l2_subdev_pad_ops - v4l2-subdev pad level operations
*
+ * @pad_init: callback that initializes the media-controller specific part
+ * of the subdev driver, creating its pads
+ *
* @enum_mbus_code: callback for VIDIOC_SUBDEV_ENUM_MBUS_CODE ioctl handler
* code.
* @enum_frame_size: callback for VIDIOC_SUBDEV_ENUM_FRAME_SIZE ioctl handler
@@ -607,6 +610,7 @@ struct v4l2_subdev_pad_config {
* may be adjusted by the subdev driver to device capabilities.
*/
struct v4l2_subdev_pad_ops {
+ int (*pad_init)(struct v4l2_subdev *sd);
int (*enum_mbus_code)(struct v4l2_subdev *sd,
struct v4l2_subdev_pad_config *cfg,
struct v4l2_subdev_mbus_code_enum *code);
--
2.5.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH v2] [media] media-device: Don't call notify callbacks holding a spinlock
2016-03-14 19:16 [PATCH] [media] media-device: Don't call notify callbacks holding a spinlock Mauro Carvalho Chehab
@ 2016-03-14 19:19 ` Mauro Carvalho Chehab
2016-03-15 0:53 ` Shuah Khan
2016-03-14 19:31 ` [PATCH] " kbuild test robot
2016-03-17 11:38 ` Laurent Pinchart
2 siblings, 1 reply; 6+ messages in thread
From: Mauro Carvalho Chehab @ 2016-03-14 19:19 UTC (permalink / raw)
To: Linux Media Mailing List
Cc: Mauro Carvalho Chehab, Mauro Carvalho Chehab, Shuah Khan
The notify routines may sleep. So, they can't be called in spinlock
context. Also, they may want to call other media routines that might
be spinning the spinlock, like creating a link.
This fixes the following bug:
[ 1839.510587] BUG: sleeping function called from invalid context at mm/slub.c:1289
[ 1839.510881] in_atomic(): 1, irqs_disabled(): 0, pid: 3479, name: modprobe
[ 1839.511157] 4 locks held by modprobe/3479:
[ 1839.511415] #0: (&dev->mutex){......}, at: [<ffffffff81ce8933>] __driver_attach+0xa3/0x160
[ 1839.512381] #1: (&dev->mutex){......}, at: [<ffffffff81ce8941>] __driver_attach+0xb1/0x160
[ 1839.512388] #2: (register_mutex#5){+.+.+.}, at: [<ffffffffa10596c7>] usb_audio_probe+0x257/0x1c90 [snd_usb_audio]
[ 1839.512401] #3: (&(&mdev->lock)->rlock){+.+.+.}, at: [<ffffffffa0e6051b>] media_device_register_entity+0x1cb/0x700 [media]
[ 1839.512412] CPU: 2 PID: 3479 Comm: modprobe Not tainted 4.5.0-rc3+ #49
[ 1839.512415] Hardware name: /NUC5i7RYB, BIOS RYBDWi35.86A.0350.2015.0812.1722 08/12/2015
[ 1839.512417] 0000000000000000 ffff8803b3f6f288 ffffffff81933901 ffff8803c4bae000
[ 1839.512422] ffff8803c4bae5c8 ffff8803b3f6f2b0 ffffffff811c6af5 ffff8803c4bae000
[ 1839.512427] ffffffff8285d7f6 0000000000000509 ffff8803b3f6f2f0 ffffffff811c6ce5
[ 1839.512432] Call Trace:
[ 1839.512436] [<ffffffff81933901>] dump_stack+0x85/0xc4
[ 1839.512440] [<ffffffff811c6af5>] ___might_sleep+0x245/0x3a0
[ 1839.512443] [<ffffffff811c6ce5>] __might_sleep+0x95/0x1a0
[ 1839.512446] [<ffffffff8155aade>] kmem_cache_alloc_trace+0x20e/0x300
[ 1839.512451] [<ffffffffa0e66e3d>] ? media_add_link+0x4d/0x140 [media]
[ 1839.512455] [<ffffffffa0e66e3d>] media_add_link+0x4d/0x140 [media]
[ 1839.512459] [<ffffffffa0e69931>] media_create_pad_link+0xa1/0x600 [media]
[ 1839.512463] [<ffffffffa0fe11b3>] au0828_media_graph_notify+0x173/0x360 [au0828]
[ 1839.512467] [<ffffffffa0e68a6a>] ? media_gobj_create+0x1ba/0x480 [media]
[ 1839.512471] [<ffffffffa0e606fb>] media_device_register_entity+0x3ab/0x700 [media]
Tested with an HVR-950Q, under the following testcases:
1) load au0828 driver first, and then snd-usb-audio;
2) load snd-usb-audio driver first, and then au0828;
3) loading both drivers, and then connecting the device.
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
---
Please disconsider verison 1. It got amended with an experimental patch.
drivers/media/media-device.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
index 6ba6e8f982fc..fc3c199e5500 100644
--- a/drivers/media/media-device.c
+++ b/drivers/media/media-device.c
@@ -587,14 +587,15 @@ int __must_check media_device_register_entity(struct media_device *mdev,
media_gobj_create(mdev, MEDIA_GRAPH_PAD,
&entity->pads[i].graph_obj);
+ spin_unlock(&mdev->lock);
+
/* invoke entity_notify callbacks */
list_for_each_entry_safe(notify, next, &mdev->entity_notify, list) {
(notify)->notify(entity, notify->notify_data);
}
- spin_unlock(&mdev->lock);
-
mutex_lock(&mdev->graph_mutex);
+
if (mdev->entity_internal_idx_max
>= mdev->pm_count_walk.ent_enum.idx_max) {
struct media_entity_graph new = { .top = 0 };
--
2.5.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH v2] [media] media-device: Don't call notify callbacks holding a spinlock
2016-03-14 19:19 ` [PATCH v2] " Mauro Carvalho Chehab
@ 2016-03-15 0:53 ` Shuah Khan
0 siblings, 0 replies; 6+ messages in thread
From: Shuah Khan @ 2016-03-15 0:53 UTC (permalink / raw)
To: Mauro Carvalho Chehab, Linux Media Mailing List
Cc: Mauro Carvalho Chehab, Shuah Khan
On 03/14/2016 01:19 PM, Mauro Carvalho Chehab wrote:
> The notify routines may sleep. So, they can't be called in spinlock
> context. Also, they may want to call other media routines that might
> be spinning the spinlock, like creating a link.
>
> This fixes the following bug:
>
> [ 1839.510587] BUG: sleeping function called from invalid context at mm/slub.c:1289
> [ 1839.510881] in_atomic(): 1, irqs_disabled(): 0, pid: 3479, name: modprobe
> [ 1839.511157] 4 locks held by modprobe/3479:
> [ 1839.511415] #0: (&dev->mutex){......}, at: [<ffffffff81ce8933>] __driver_attach+0xa3/0x160
> [ 1839.512381] #1: (&dev->mutex){......}, at: [<ffffffff81ce8941>] __driver_attach+0xb1/0x160
> [ 1839.512388] #2: (register_mutex#5){+.+.+.}, at: [<ffffffffa10596c7>] usb_audio_probe+0x257/0x1c90 [snd_usb_audio]
> [ 1839.512401] #3: (&(&mdev->lock)->rlock){+.+.+.}, at: [<ffffffffa0e6051b>] media_device_register_entity+0x1cb/0x700 [media]
> [ 1839.512412] CPU: 2 PID: 3479 Comm: modprobe Not tainted 4.5.0-rc3+ #49
> [ 1839.512415] Hardware name: /NUC5i7RYB, BIOS RYBDWi35.86A.0350.2015.0812.1722 08/12/2015
> [ 1839.512417] 0000000000000000 ffff8803b3f6f288 ffffffff81933901 ffff8803c4bae000
> [ 1839.512422] ffff8803c4bae5c8 ffff8803b3f6f2b0 ffffffff811c6af5 ffff8803c4bae000
> [ 1839.512427] ffffffff8285d7f6 0000000000000509 ffff8803b3f6f2f0 ffffffff811c6ce5
> [ 1839.512432] Call Trace:
> [ 1839.512436] [<ffffffff81933901>] dump_stack+0x85/0xc4
> [ 1839.512440] [<ffffffff811c6af5>] ___might_sleep+0x245/0x3a0
> [ 1839.512443] [<ffffffff811c6ce5>] __might_sleep+0x95/0x1a0
> [ 1839.512446] [<ffffffff8155aade>] kmem_cache_alloc_trace+0x20e/0x300
> [ 1839.512451] [<ffffffffa0e66e3d>] ? media_add_link+0x4d/0x140 [media]
> [ 1839.512455] [<ffffffffa0e66e3d>] media_add_link+0x4d/0x140 [media]
> [ 1839.512459] [<ffffffffa0e69931>] media_create_pad_link+0xa1/0x600 [media]
> [ 1839.512463] [<ffffffffa0fe11b3>] au0828_media_graph_notify+0x173/0x360 [au0828]
> [ 1839.512467] [<ffffffffa0e68a6a>] ? media_gobj_create+0x1ba/0x480 [media]
> [ 1839.512471] [<ffffffffa0e606fb>] media_device_register_entity+0x3ab/0x700 [media]
>
> Tested with an HVR-950Q, under the following testcases:
>
> 1) load au0828 driver first, and then snd-usb-audio;
> 2) load snd-usb-audio driver first, and then au0828;
> 3) loading both drivers, and then connecting the device.
>
> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Looks good. Tested. Inserting device with au0828 blacklisted. Just the audio graph
gets created and then modprobed au0828. The complete graph looks good. Also tested
without blacklisting, so both drivers are probed together. Graph looks good.
Tested-by: Shuah Khan <shuahkh@osg.samsung.com>
thanks,
-- Shuah
> ---
>
> Please disconsider verison 1. It got amended with an experimental patch.
>
> drivers/media/media-device.c | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
> index 6ba6e8f982fc..fc3c199e5500 100644
> --- a/drivers/media/media-device.c
> +++ b/drivers/media/media-device.c
> @@ -587,14 +587,15 @@ int __must_check media_device_register_entity(struct media_device *mdev,
> media_gobj_create(mdev, MEDIA_GRAPH_PAD,
> &entity->pads[i].graph_obj);
>
> + spin_unlock(&mdev->lock);
> +
> /* invoke entity_notify callbacks */
> list_for_each_entry_safe(notify, next, &mdev->entity_notify, list) {
> (notify)->notify(entity, notify->notify_data);
> }
>
> - spin_unlock(&mdev->lock);
> -
> mutex_lock(&mdev->graph_mutex);
> +
> if (mdev->entity_internal_idx_max
> >= mdev->pm_count_walk.ent_enum.idx_max) {
> struct media_entity_graph new = { .top = 0 };
>
--
Shuah Khan
Sr. Linux Kernel Developer
Open Source Innovation Group
Samsung Research America (Silicon Valley)
shuahkh@osg.samsung.com | (970) 217-8978
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] [media] media-device: Don't call notify callbacks holding a spinlock
2016-03-14 19:16 [PATCH] [media] media-device: Don't call notify callbacks holding a spinlock Mauro Carvalho Chehab
2016-03-14 19:19 ` [PATCH v2] " Mauro Carvalho Chehab
@ 2016-03-14 19:31 ` kbuild test robot
2016-03-17 11:38 ` Laurent Pinchart
2 siblings, 0 replies; 6+ messages in thread
From: kbuild test robot @ 2016-03-14 19:31 UTC (permalink / raw)
To: Mauro Carvalho Chehab
Cc: kbuild-all, Linux Media Mailing List, Mauro Carvalho Chehab,
Mauro Carvalho Chehab, Shuah Khan, Javier Martinez Canillas,
Laurent Pinchart, Hans Verkuil, Prabhakar Lad
[-- Attachment #1: Type: text/plain, Size: 1467 bytes --]
Hi Mauro,
[auto build test WARNING on sailus-media/master]
[also build test WARNING on next-20160314]
[cannot apply to v4.5]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]
url: https://github.com/0day-ci/linux/commits/Mauro-Carvalho-Chehab/media-device-Don-t-call-notify-callbacks-holding-a-spinlock/20160315-031954
base: git://linuxtv.org/media_tree.git master
config: i386-randconfig-x001-201611 (attached as .config)
reproduce:
# save the attached .config to linux build tree
make ARCH=i386
All warnings (new ones prefixed by >>):
drivers/media/i2c/tvp5150.c: In function 'tvp5150_pad_init':
>> drivers/media/i2c/tvp5150.c:1214:6: warning: unused variable 'res' [-Wunused-variable]
int res;
^
>> drivers/media/i2c/tvp5150.c:1213:18: warning: unused variable 'core' [-Wunused-variable]
struct tvp5150 *core = to_tvp5150(sd);
^
vim +/res +1214 drivers/media/i2c/tvp5150.c
1207
1208 return 0;
1209 }
1210
1211 static int __maybe_unused tvp5150_pad_init(struct v4l2_subdev *sd)
1212 {
> 1213 struct tvp5150 *core = to_tvp5150(sd);
> 1214 int res;
1215
1216 #if defined(CONFIG_MEDIA_CONTROLLER)
1217 core->pads[DEMOD_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK;
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 23879 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH] [media] media-device: Don't call notify callbacks holding a spinlock
2016-03-14 19:16 [PATCH] [media] media-device: Don't call notify callbacks holding a spinlock Mauro Carvalho Chehab
2016-03-14 19:19 ` [PATCH v2] " Mauro Carvalho Chehab
2016-03-14 19:31 ` [PATCH] " kbuild test robot
@ 2016-03-17 11:38 ` Laurent Pinchart
2016-03-17 17:43 ` Mauro Carvalho Chehab
2 siblings, 1 reply; 6+ messages in thread
From: Laurent Pinchart @ 2016-03-17 11:38 UTC (permalink / raw)
To: Mauro Carvalho Chehab
Cc: Linux Media Mailing List, Mauro Carvalho Chehab, Shuah Khan,
Javier Martinez Canillas, Hans Verkuil, Prabhakar Lad
Hi Mauro,
On Monday 14 March 2016 16:16:29 Mauro Carvalho Chehab wrote:
> The notify routines may sleep. So, they can't be called in spinlock
> context. Also, they may want to call other media routines that might
> be spinning the spinlock, like creating a link.
>
> This fixes the following bug:
>
> [ 1839.510587] BUG: sleeping function called from invalid context at
> mm/slub.c:1289 [ 1839.510881] in_atomic(): 1, irqs_disabled(): 0, pid:
> 3479, name: modprobe [ 1839.511157] 4 locks held by modprobe/3479:
> [ 1839.511415] #0: (&dev->mutex){......}, at: [<ffffffff81ce8933>]
> __driver_attach+0xa3/0x160 [ 1839.512381] #1: (&dev->mutex){......}, at:
> [<ffffffff81ce8941>] __driver_attach+0xb1/0x160 [ 1839.512388] #2:
> (register_mutex#5){+.+.+.}, at: [<ffffffffa10596c7>]
> usb_audio_probe+0x257/0x1c90 [snd_usb_audio] [ 1839.512401] #3:
> (&(&mdev->lock)->rlock){+.+.+.}, at: [<ffffffffa0e6051b>]
> media_device_register_entity+0x1cb/0x700 [media] [ 1839.512412] CPU: 2 PID:
> 3479 Comm: modprobe Not tainted 4.5.0-rc3+ #49 [ 1839.512415] Hardware
> name: /NUC5i7RYB, BIOS RYBDWi35.86A.0350.2015.0812.1722
> 08/12/2015 [ 1839.512417] 0000000000000000 ffff8803b3f6f288
> ffffffff81933901 ffff8803c4bae000 [ 1839.512422] ffff8803c4bae5c8
> ffff8803b3f6f2b0 ffffffff811c6af5 ffff8803c4bae000 [ 1839.512427]
> ffffffff8285d7f6 0000000000000509 ffff8803b3f6f2f0 ffffffff811c6ce5 [
> 1839.512432] Call Trace:
> [ 1839.512436] [<ffffffff81933901>] dump_stack+0x85/0xc4
> [ 1839.512440] [<ffffffff811c6af5>] ___might_sleep+0x245/0x3a0
> [ 1839.512443] [<ffffffff811c6ce5>] __might_sleep+0x95/0x1a0
> [ 1839.512446] [<ffffffff8155aade>] kmem_cache_alloc_trace+0x20e/0x300
> [ 1839.512451] [<ffffffffa0e66e3d>] ? media_add_link+0x4d/0x140 [media]
> [ 1839.512455] [<ffffffffa0e66e3d>] media_add_link+0x4d/0x140 [media]
> [ 1839.512459] [<ffffffffa0e69931>] media_create_pad_link+0xa1/0x600
> [media] [ 1839.512463] [<ffffffffa0fe11b3>]
> au0828_media_graph_notify+0x173/0x360 [au0828] [ 1839.512467]
> [<ffffffffa0e68a6a>] ? media_gobj_create+0x1ba/0x480 [media] [ 1839.512471]
> [<ffffffffa0e606fb>] media_device_register_entity+0x3ab/0x700 [media]
>
> Tested with an HVR-950Q, under the following testcases:
>
> 1) load au0828 driver first, and then snd-usb-audio;
> 2) load snd-usb-audio driver first, and then au0828;
> 3) loading both drivers, and then connecting the device.
>
> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
> ---
> drivers/media/i2c/tvp5150.c | 39 ++++++++++++++++++++------------
> drivers/media/media-device.c | 5 +++--
> drivers/media/v4l2-core/v4l2-common.c | 8 +++++++
> include/media/v4l2-subdev.h | 4 ++++
> 4 files changed, 40 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c
> index ff18444e19e4..14004fd7d0fb 100644
> --- a/drivers/media/i2c/tvp5150.c
> +++ b/drivers/media/i2c/tvp5150.c
> @@ -1208,6 +1208,28 @@ static int tvp5150_registered_async(struct
> v4l2_subdev *sd) return 0;
> }
>
> +static int __maybe_unused tvp5150_pad_init(struct v4l2_subdev *sd)
> +{
> + struct tvp5150 *core = to_tvp5150(sd);
> + int res;
> +
> +#if defined(CONFIG_MEDIA_CONTROLLER)
> + core->pads[DEMOD_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK;
> + core->pads[DEMOD_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE;
> + core->pads[DEMOD_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE;
> +
> + sd->entity.function = MEDIA_ENT_F_ATV_DECODER;
> +
> + res = media_entity_pads_init(&sd->entity, DEMOD_NUM_PADS, core->pads);
> + if (res < 0)
> + return res;
> +
> + sd->entity.ops = &tvp5150_sd_media_ops;
> +#endif
> + return 0;
> +}
> +
> +
> /* -----------------------------------------------------------------------
> */
>
> static const struct v4l2_ctrl_ops tvp5150_ctrl_ops = {
> @@ -1246,6 +1268,9 @@ static const struct v4l2_subdev_vbi_ops
> tvp5150_vbi_ops = { };
>
> static const struct v4l2_subdev_pad_ops tvp5150_pad_ops = {
> +#ifdef CONFIG_MEDIA_CONTROLLER
> + .pad_init = tvp5150_pad_init,
> +#endif
> .enum_mbus_code = tvp5150_enum_mbus_code,
> .enum_frame_size = tvp5150_enum_frame_size,
> .set_fmt = tvp5150_fill_fmt,
> @@ -1475,20 +1500,6 @@ static int tvp5150_probe(struct i2c_client *c,
> v4l2_i2c_subdev_init(sd, c, &tvp5150_ops);
> sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
>
> -#if defined(CONFIG_MEDIA_CONTROLLER)
> - core->pads[DEMOD_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK;
> - core->pads[DEMOD_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE;
> - core->pads[DEMOD_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE;
> -
> - sd->entity.function = MEDIA_ENT_F_ATV_DECODER;
> -
> - res = media_entity_pads_init(&sd->entity, DEMOD_NUM_PADS, core->pads);
> - if (res < 0)
> - return res;
> -
> - sd->entity.ops = &tvp5150_sd_media_ops;
> -#endif
> -
> res = tvp5150_detect_version(core);
> if (res < 0)
> return res;
> diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
> index 6ba6e8f982fc..fc3c199e5500 100644
> --- a/drivers/media/media-device.c
> +++ b/drivers/media/media-device.c
> @@ -587,14 +587,15 @@ int __must_check media_device_register_entity(struct
> media_device *mdev, media_gobj_create(mdev, MEDIA_GRAPH_PAD,
> &entity->pads[i].graph_obj);
>
> + spin_unlock(&mdev->lock);
> +
> /* invoke entity_notify callbacks */
> list_for_each_entry_safe(notify, next, &mdev->entity_notify, list) {
> (notify)->notify(entity, notify->notify_data);
> }
I don't think this is the right approach. There's no lock protecting the
entity_notify list, and nothing that prevents the notifiers from touching the
entity_notify list. The list_for_each_entry_safe() function doesn't help you
there, it only protects against deletion of the current list entry.
Locking needs to be audited and fixed, let's not push a bug fix that
introduces another bug.
Furthermore, I wonder if we really need notifiers. They add complexity and are
difficult to get right, isn't there another possible approach ?
> - spin_unlock(&mdev->lock);
> -
> mutex_lock(&mdev->graph_mutex);
> +
> if (mdev->entity_internal_idx_max
>
> >= mdev->pm_count_walk.ent_enum.idx_max) {
>
> struct media_entity_graph new = { .top = 0 };
> diff --git a/drivers/media/v4l2-core/v4l2-common.c
> b/drivers/media/v4l2-core/v4l2-common.c index 5b808500e7e7..6bcdf557e027
> 100644
> --- a/drivers/media/v4l2-core/v4l2-common.c
> +++ b/drivers/media/v4l2-core/v4l2-common.c
> @@ -112,6 +112,14 @@ EXPORT_SYMBOL(v4l2_ctrl_query_fill);
> void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client
> *client, const struct v4l2_subdev_ops *ops)
> {
> + /*
> + * Initialize the MC pads - for now, this will be called
> + * unconditionally, since the current implementation will defer
> + * the pads initialization until the media_dev is created.
> + */
> + if (v4l2_subdev_has_op(sd, pad, pad_init))
> + sd->ops->pad->pad_init(sd);
> +
> v4l2_subdev_init(sd, ops);
> sd->flags |= V4L2_SUBDEV_FL_IS_I2C;
> /* the owner is the same as the i2c_client's driver owner */
> diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
> index 11e2dfec0198..c9bb221029e4 100644
> --- a/include/media/v4l2-subdev.h
> +++ b/include/media/v4l2-subdev.h
> @@ -572,6 +572,9 @@ struct v4l2_subdev_pad_config {
> /**
> * struct v4l2_subdev_pad_ops - v4l2-subdev pad level operations
> *
> + * @pad_init: callback that initializes the media-controller specific part
> + * of the subdev driver, creating its pads
> + *
> * @enum_mbus_code: callback for VIDIOC_SUBDEV_ENUM_MBUS_CODE ioctl handler
> * code.
> * @enum_frame_size: callback for VIDIOC_SUBDEV_ENUM_FRAME_SIZE ioctl
> handler @@ -607,6 +610,7 @@ struct v4l2_subdev_pad_config {
> * may be adjusted by the subdev driver to device
> capabilities. */
> struct v4l2_subdev_pad_ops {
> + int (*pad_init)(struct v4l2_subdev *sd);
> int (*enum_mbus_code)(struct v4l2_subdev *sd,
> struct v4l2_subdev_pad_config *cfg,
> struct v4l2_subdev_mbus_code_enum *code);
--
Regards,
Laurent Pinchart
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH] [media] media-device: Don't call notify callbacks holding a spinlock
2016-03-17 11:38 ` Laurent Pinchart
@ 2016-03-17 17:43 ` Mauro Carvalho Chehab
0 siblings, 0 replies; 6+ messages in thread
From: Mauro Carvalho Chehab @ 2016-03-17 17:43 UTC (permalink / raw)
To: Laurent Pinchart
Cc: Linux Media Mailing List, Mauro Carvalho Chehab, Shuah Khan,
Javier Martinez Canillas, Hans Verkuil, Prabhakar Lad
Em Thu, 17 Mar 2016 13:38:56 +0200
Laurent Pinchart <laurent.pinchart@ideasonboard.com> escreveu:
> Hi Mauro,
>
> On Monday 14 March 2016 16:16:29 Mauro Carvalho Chehab wrote:
> > The notify routines may sleep. So, they can't be called in spinlock
> > context. Also, they may want to call other media routines that might
> > be spinning the spinlock, like creating a link.
> >
> > This fixes the following bug:
> >
> > [ 1839.510587] BUG: sleeping function called from invalid context at
> > mm/slub.c:1289 [ 1839.510881] in_atomic(): 1, irqs_disabled(): 0, pid:
> > 3479, name: modprobe [ 1839.511157] 4 locks held by modprobe/3479:
> > [ 1839.511415] #0: (&dev->mutex){......}, at: [<ffffffff81ce8933>]
> > __driver_attach+0xa3/0x160 [ 1839.512381] #1: (&dev->mutex){......}, at:
> > [<ffffffff81ce8941>] __driver_attach+0xb1/0x160 [ 1839.512388] #2:
> > (register_mutex#5){+.+.+.}, at: [<ffffffffa10596c7>]
> > usb_audio_probe+0x257/0x1c90 [snd_usb_audio] [ 1839.512401] #3:
> > (&(&mdev->lock)->rlock){+.+.+.}, at: [<ffffffffa0e6051b>]
> > media_device_register_entity+0x1cb/0x700 [media] [ 1839.512412] CPU: 2 PID:
> > 3479 Comm: modprobe Not tainted 4.5.0-rc3+ #49 [ 1839.512415] Hardware
> > name: /NUC5i7RYB, BIOS RYBDWi35.86A.0350.2015.0812.1722
> > 08/12/2015 [ 1839.512417] 0000000000000000 ffff8803b3f6f288
> > ffffffff81933901 ffff8803c4bae000 [ 1839.512422] ffff8803c4bae5c8
> > ffff8803b3f6f2b0 ffffffff811c6af5 ffff8803c4bae000 [ 1839.512427]
> > ffffffff8285d7f6 0000000000000509 ffff8803b3f6f2f0 ffffffff811c6ce5 [
> > 1839.512432] Call Trace:
> > [ 1839.512436] [<ffffffff81933901>] dump_stack+0x85/0xc4
> > [ 1839.512440] [<ffffffff811c6af5>] ___might_sleep+0x245/0x3a0
> > [ 1839.512443] [<ffffffff811c6ce5>] __might_sleep+0x95/0x1a0
> > [ 1839.512446] [<ffffffff8155aade>] kmem_cache_alloc_trace+0x20e/0x300
> > [ 1839.512451] [<ffffffffa0e66e3d>] ? media_add_link+0x4d/0x140 [media]
> > [ 1839.512455] [<ffffffffa0e66e3d>] media_add_link+0x4d/0x140 [media]
> > [ 1839.512459] [<ffffffffa0e69931>] media_create_pad_link+0xa1/0x600
> > [media] [ 1839.512463] [<ffffffffa0fe11b3>]
> > au0828_media_graph_notify+0x173/0x360 [au0828] [ 1839.512467]
> > [<ffffffffa0e68a6a>] ? media_gobj_create+0x1ba/0x480 [media] [ 1839.512471]
> > [<ffffffffa0e606fb>] media_device_register_entity+0x3ab/0x700 [media]
> >
> > Tested with an HVR-950Q, under the following testcases:
> >
> > 1) load au0828 driver first, and then snd-usb-audio;
> > 2) load snd-usb-audio driver first, and then au0828;
> > 3) loading both drivers, and then connecting the device.
> >
> > Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
> > ---
> > drivers/media/i2c/tvp5150.c | 39 ++++++++++++++++++++------------
> > drivers/media/media-device.c | 5 +++--
> > drivers/media/v4l2-core/v4l2-common.c | 8 +++++++
> > include/media/v4l2-subdev.h | 4 ++++
> > 4 files changed, 40 insertions(+), 16 deletions(-)
> >
> > diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c
> > index ff18444e19e4..14004fd7d0fb 100644
> > --- a/drivers/media/i2c/tvp5150.c
> > +++ b/drivers/media/i2c/tvp5150.c
> > @@ -1208,6 +1208,28 @@ static int tvp5150_registered_async(struct
> > v4l2_subdev *sd) return 0;
> > }
> >
> > +static int __maybe_unused tvp5150_pad_init(struct v4l2_subdev *sd)
> > +{
> > + struct tvp5150 *core = to_tvp5150(sd);
> > + int res;
> > +
> > +#if defined(CONFIG_MEDIA_CONTROLLER)
> > + core->pads[DEMOD_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK;
> > + core->pads[DEMOD_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE;
> > + core->pads[DEMOD_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE;
> > +
> > + sd->entity.function = MEDIA_ENT_F_ATV_DECODER;
> > +
> > + res = media_entity_pads_init(&sd->entity, DEMOD_NUM_PADS, core->pads);
> > + if (res < 0)
> > + return res;
> > +
> > + sd->entity.ops = &tvp5150_sd_media_ops;
> > +#endif
> > + return 0;
> > +}
> > +
> > +
> > /* -----------------------------------------------------------------------
> > */
> >
> > static const struct v4l2_ctrl_ops tvp5150_ctrl_ops = {
> > @@ -1246,6 +1268,9 @@ static const struct v4l2_subdev_vbi_ops
> > tvp5150_vbi_ops = { };
> >
> > static const struct v4l2_subdev_pad_ops tvp5150_pad_ops = {
> > +#ifdef CONFIG_MEDIA_CONTROLLER
> > + .pad_init = tvp5150_pad_init,
> > +#endif
> > .enum_mbus_code = tvp5150_enum_mbus_code,
> > .enum_frame_size = tvp5150_enum_frame_size,
> > .set_fmt = tvp5150_fill_fmt,
> > @@ -1475,20 +1500,6 @@ static int tvp5150_probe(struct i2c_client *c,
> > v4l2_i2c_subdev_init(sd, c, &tvp5150_ops);
> > sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
> >
> > -#if defined(CONFIG_MEDIA_CONTROLLER)
> > - core->pads[DEMOD_PAD_IF_INPUT].flags = MEDIA_PAD_FL_SINK;
> > - core->pads[DEMOD_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE;
> > - core->pads[DEMOD_PAD_VBI_OUT].flags = MEDIA_PAD_FL_SOURCE;
> > -
> > - sd->entity.function = MEDIA_ENT_F_ATV_DECODER;
> > -
> > - res = media_entity_pads_init(&sd->entity, DEMOD_NUM_PADS, core->pads);
> > - if (res < 0)
> > - return res;
> > -
> > - sd->entity.ops = &tvp5150_sd_media_ops;
> > -#endif
> > -
> > res = tvp5150_detect_version(core);
> > if (res < 0)
> > return res;
> > diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
> > index 6ba6e8f982fc..fc3c199e5500 100644
> > --- a/drivers/media/media-device.c
> > +++ b/drivers/media/media-device.c
> > @@ -587,14 +587,15 @@ int __must_check media_device_register_entity(struct
> > media_device *mdev, media_gobj_create(mdev, MEDIA_GRAPH_PAD,
> > &entity->pads[i].graph_obj);
> >
> > + spin_unlock(&mdev->lock);
> > +
> > /* invoke entity_notify callbacks */
> > list_for_each_entry_safe(notify, next, &mdev->entity_notify, list) {
> > (notify)->notify(entity, notify->notify_data);
> > }
>
> I don't think this is the right approach. There's no lock protecting the
> entity_notify list, and nothing that prevents the notifiers from touching the
> entity_notify list. The list_for_each_entry_safe() function doesn't help you
> there, it only protects against deletion of the current list entry.
>
> Locking needs to be audited and fixed, let's not push a bug fix that
> introduces another bug.
Sakari proposed a different approach. I ran a loop 1000 times doing
unbinding/rebinding au0828, keeping snd-usb-audio bind, and running 3
other processes calling G_TOPOLOGY. It worked 100%. Not a single
trouble.
Such patch is at:
https://patchwork.linuxtv.org/patch/33490/
> Furthermore, I wonder if we really need notifiers. They add complexity and are
> difficult to get right, isn't there another possible approach ?
Sorry, but I can't see any other approach to create links between the
entities created by different and independent drivers that would be
better than notifiers.
In this specific case, the USB Audio Class driver (snd-usb-audio)
doesn't know anything about the V4L2 driver. Only the V4L2 driver
knows what links should be created to connect the audio I2S inputs.
The probing order is also random, meaning that either the V4L2
driver or the ALSA driver will be probed first.
Thanks,
Mauro
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2016-03-17 17:43 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-03-14 19:16 [PATCH] [media] media-device: Don't call notify callbacks holding a spinlock Mauro Carvalho Chehab
2016-03-14 19:19 ` [PATCH v2] " Mauro Carvalho Chehab
2016-03-15 0:53 ` Shuah Khan
2016-03-14 19:31 ` [PATCH] " kbuild test robot
2016-03-17 11:38 ` Laurent Pinchart
2016-03-17 17:43 ` Mauro Carvalho Chehab
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox