Skip to content

vc_sm_cma: BUG: sleeping function called from invalid context #6815

Open
@pobrn

Description

@pobrn

Describe the bug

vc_sm.c:get_kernel_id() calls idr_alloc() with GFP_KERNEL under a spinlock.

(Also, does lookup_kernel_id() need to take the lock as well?)

Steps to reproduce the behaviour

Start capturing from a camera with e.g. cam (from libcamera).

Device (s)

Raspberry Pi 4 Mod. B

System

Linux <hostname> 6.15.0-rc3-v8+ #2 SMP PREEMPT Thu Apr 24 18:47:39 CEST 2025 aarch64 GNU/Linux

Logs

# cam -c1 -C32
[0:00:34.572735259] [311]  INFO Camera camera_manager.cpp:326 libcamera v0.5.0+155-94e7d330-dirty (2025-04-25)
[0:00:34.780727131] [312]  WARN CameraSensorProperties camera_sensor_properties.cpp:463 No static properties available for 'imx708_wide'
[0:00:34.780877790] [312]  WARN CameraSensorProperties camera_sensor_properties.cpp:465 Please consider updating the camera sensor properties database
[0:00:35.064659868] [312]  WARN RPiSdn sdn.cpp:40 Using legacy SDN tuning - please consider moving SDN inside rpi.denoise
[0:00:35.067119191] [312]  WARN CameraSensor camera_sensor_legacy.cpp:501 'imx708_wide': No sensor delays found in static properties. Assuming unverified defaults.
[0:00:35.070015603] [312]  INFO RPI vc4.cpp:407 Registered camera /base/soc/i2c0mux/i2c@1/imx708@1a to Unicam device /dev/media4 and ISP device /dev/media0
Using camera /base/soc/i2c0mux/i2c@1/imx708@1a as cam0
[0:00:35.071686595] [311]  INFO Camera camera.cpp:1258 configuring streams: (0) 800x600-XRGB8888
[0:00:35.074298429] [312]  INFO RPI vc4.cpp:576 Sensor: /base/soc/i2c0mux/i2c@1/imx708@1a - Selected sensor format: 1536x864-SBGGR10_1X10 - Selected unicam format: 1536x864-pBAA
[   35.406296] BUG: sleeping function called from invalid context at ./include/linux/sched/mm.h:321
[   35.406348] in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 312, name: cam
[   35.406388] preempt_count: 1, expected: 0
[   35.406409] RCU nest depth: 0, expected: 0
cam0: Capture 32 frames
[   35.406614] 2 locks held by cam/312:
[   35.406625]  #0: ffff0cdc08021858 (&node->queue_lock){+.+.}-{4:4}, at: __video_do_ioctl+0xf8/0x4a0 [videodev]
[   35.406788]  #1: ffff0cdc0654b8f8 (&sm_state->kernelid_map_lock){+.+.}-{3:3}, at: vc_sm_cma_import_dmabuf_internal+0x248/0x448 [vc_sm_cma]
[   35.406850] CPU: 0 UID: 0 PID: 312 Comm: cam Tainted: G         C          6.15.0-rc3-v8+ #2 PREEMPT 
[   35.406867] Tainted: [C]=CRAP
[   35.406872] Hardware name: Raspberry Pi 4 Model B Rev 1.5 (DT)
[   35.406879] Call trace:
[   35.406884]  show_stack+0x20/0x40 (C)
[   35.406907]  dump_stack_lvl+0x70/0x98
[   35.406923]  dump_stack+0x18/0x24
[   35.406935]  __might_resched+0x164/0x240
[   35.406950]  __might_sleep+0x50/0x90
[   35.406963]  kmem_cache_alloc_noprof+0x21c/0x450
[   35.406979]  radix_tree_node_alloc.constprop.0+0x54/0xf0
[   35.406997]  idr_get_free+0x224/0x2e0
[   35.407012]  idr_alloc_u32+0x78/0x108
[   35.407029]  idr_alloc+0x44/0x90
[   35.407043]  vc_sm_cma_import_dmabuf_internal+0x264/0x448 [vc_sm_cma]
[   35.407063]  vc_sm_cma_import_dmabuf+0x60/0xf8 [vc_sm_cma]
[   35.407081]  vchiq_mmal_submit_buffer+0xc4/0x190 [bcm2835_mmal_vchiq]
[   35.407105]  bcm2835_isp_node_buffer_queue+0xa4/0x130 [bcm2835_isp]
[   35.407123]  __enqueue_in_driver+0x78/0x160 [videobuf2_common]
[   35.407160]  vb2_start_streaming+0x3c/0x190 [videobuf2_common]
[   35.407191]  vb2_core_streamon+0xe0/0x1d0 [videobuf2_common]
[   35.407221]  vb2_ioctl_streamon+0x60/0xb0 [videobuf2_v4l2]
[   35.407249]  v4l_streamon+0x2c/0x40 [videodev]
[   35.407340]  __video_do_ioctl+0x410/0x4a0 [videodev]
[   35.407426]  video_usercopy+0x2f4/0x890 [videodev]
[   35.407511]  video_ioctl2+0x20/0x50 [videodev]
[   35.407596]  v4l2_ioctl+0x48/0x78 [videodev]
[   35.407680]  __arm64_sys_ioctl+0xbc/0x100
[   35.407695]  invoke_syscall+0x50/0x120
[   35.407707]  el0_svc_common.constprop.0+0xc8/0xf0
[   35.407719]  do_el0_svc+0x24/0x38
[   35.407729]  el0_svc+0x48/0x110
[   35.407743]  el0t_64_sync_handler+0x10c/0x140
[   35.407757]  el0t_64_sync+0x198/0x1a0

Additional context

The following seems to work so far:

diff --git a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c
index 4ebe909d7d97..8609d6ec7657 100644
--- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c
+++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c
@@ -91,7 +91,7 @@ struct sm_state_t {
 
        struct sm_instance *sm_handle;  /* Handle for videocore service. */
 
-       spinlock_t kernelid_map_lock;   /* Spinlock protecting kernelid_map */
+       struct mutex kernelid_map_lock; /* protecting kernelid_map */
        struct idr kernelid_map;
 
        struct mutex map_lock;          /* Global map lock. */
@@ -127,25 +127,20 @@ static int sm_inited;
 
 static int get_kernel_id(struct vc_sm_buffer *buffer)
 {
-       int handle;
-
-       spin_lock(&sm_state->kernelid_map_lock);
-       handle = idr_alloc(&sm_state->kernelid_map, buffer, 0, 0, GFP_KERNEL);
-       spin_unlock(&sm_state->kernelid_map_lock);
-
-       return handle;
+       guard(mutex)(&sm_state->kernelid_map_lock);
+       return idr_alloc(&sm_state->kernelid_map, buffer, 0, 0, GFP_KERNEL);
 }
 
 static struct vc_sm_buffer *lookup_kernel_id(int handle)
 {
+       guard(mutex)(&sm_state->kernelid_map_lock);
        return idr_find(&sm_state->kernelid_map, handle);
 }
 
 static void free_kernel_id(int handle)
 {
-       spin_lock(&sm_state->kernelid_map_lock);
+       guard(mutex)(&sm_state->kernelid_map_lock);
        idr_remove(&sm_state->kernelid_map, handle);
-       spin_unlock(&sm_state->kernelid_map_lock);
 }
 
 static int vc_sm_cma_seq_file_show(struct seq_file *s, void *v)
@@ -1494,7 +1489,7 @@ static int bcm2835_vc_sm_cma_probe(struct vchiq_device *device)
        sm_state->device = device;
        mutex_init(&sm_state->map_lock);
 
-       spin_lock_init(&sm_state->kernelid_map_lock);
+       mutex_init(&sm_state->kernelid_map_lock);
        idr_init_base(&sm_state->kernelid_map, 1);
 
        device->dev.dma_parms = devm_kzalloc(&device->dev,

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions