merged.

Bruce

In message: [linux-yocto][linux-yocto v6.6/standard/nxp-sdk-6.6/nxp-soc & 
v6.6/standard/preempt-rt/nxp-sdk-6.6/nxp-soc][PATCH 1/2] dmaengine: imx-sdma: 
Make runtime PM irq safe
on 12/12/2024 Xiaolei Wang wrote:

> Make runtime PM irq safe to avoid the following
> trace during the resume process, irq safe has told
> the runtime PM core to run with interrupts disabled.
> The dma_free_coherent() can't be invoked in interrupt
> context, otherwise it will also cause warnings. Therefore,
> in order to avoid these warnings, remove the allocation
> of bd0_phys in resume().
> 
> BUG: sleeping function called from invalid context at 
> drivers/base/power/runtime.c:1163
> in_atomic(): 1, irqs_disabled(): 128, non_block: 0, pid: 540, name: aplay
> preempt_count: 1, expected: 0
> RCU nest depth: 0, expected: 0
> 1 held lock by aplay/540:
>   #0: ffffff80d5c96910 (&group->lock){....}-{2:2}, at: 
> snd_pcm_stream_lock_irq+0x40/0x50
> irq event stamp: 10036
> hardirqs last enabled at (10035): [<ffffffc009174dc0>] 
> _raw_spin_unlock_irq+0x40/0x80
> hardirqs last disabled at (10036): [<ffffffc009175354>] 
> _raw_spin_lock_irq+0xf0/0xfc
> softirqs last enabled at (9620): [<ffffffc008018614>] 
> fpsimd_restore_current_state+0x44/0xc0
> softirqs last disabled at (9618): [<ffffffc008017288>] 
> get_cpu_fpsimd_context+0x8/0x70
> Preemption disabled at:
> [<ffffffc008dc6560>] snd_pcm_stream_lock_irq+0x40/0x50
> CPU: 2 PID: 540 Comm: aplay Tainted: G C 6.1.68-yocto-standard #1
> Hardware name: NXP i.MX8MPlus EVK board (DT)
> Call trace:
>   dump_backtrace.part.0+0xcc/0xe0
>   show_stack+0x20/0x30
>   dump_stack_lvl+0x9c/0xd0
>   dump_stack+0x18/0x34
>   __might_resched+0x188/0x290
>   __might_sleep+0x50/0xa0
>   __pm_runtime_resume+0xa8/0xb0
>   sdma_prep_dma_cyclic+0x60/0x2a0 [imx_sdma]
>   snd_dmaengine_pcm_trigger+0xf8/0x190
>   dmaengine_pcm_trigger+0x20/0x2c
>   snd_soc_pcm_component_trigger+0x14c/0x224
>   soc_pcm_trigger+0xc0/0x200
>   snd_pcm_do_start+0x3c/0x4c
>   snd_pcm_action_single+0x50/0xb0
>   snd_pcm_action+0x84/0xa0
>   snd_pcm_start+0x2c/0x40
>   __snd_pcm_lib_xfer+0x594/0x7c0
>   snd_pcm_common_ioctl+0x1370/0x1a3c
>   snd_pcm_ioctl+0x38/0x50
>   __arm64_sys_ioctl+0xb4/0x100
>   invoke_syscall+0x5c/0x130
>   el0_svc_common.constprop.0+0x68/0x124
>   do_el0_svc+0x34/0xc0
>   el0_svc+0x48/0xc0
>   el0t_64_sync_handler+0xf4/0x120
>   el0t_64_sync+0x18c/0x190
> 
> Signed-off-by: Xiaolei Wang <[email protected]>
> Signed-off-by: Bruce Ashfield <[email protected]>
> ---
>  drivers/dma/imx-sdma.c | 63 +++++++++++++++++++++---------------------
>  1 file changed, 32 insertions(+), 31 deletions(-)
> 
> diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
> index 647a3bc81ac1..16d54d97efbc 100644
> --- a/drivers/dma/imx-sdma.c
> +++ b/drivers/dma/imx-sdma.c
> @@ -894,11 +894,16 @@ static int sdma_load_script(struct sdma_engine *sdma)
>       ram_code = (void *)header + header->ram_code_start;
>       sdma->ram_code_start = header->ram_code_start;
>  
> -     buf_virt = dma_alloc_coherent(sdma->dev, header->ram_code_size,
> -                                   &buf_phys, GFP_KERNEL);
> +     buf_virt = kzalloc(header->ram_code_size, GFP_NOWAIT);
>       if (!buf_virt)
>               return -ENOMEM;
>  
> +     buf_phys = dma_map_single(sdma->dev, buf_virt,
> +                                     header->ram_code_size,
> +                                     DMA_TO_DEVICE);
> +     if (dma_mapping_error(sdma->dev, buf_phys))
> +             return -ENOMEM;
> +
>       spin_lock_irqsave(&sdma->channel_0_lock, flags);
>  
>       bd0->mode.command = C0_SETPM;
> @@ -913,7 +918,9 @@ static int sdma_load_script(struct sdma_engine *sdma)
>  
>       spin_unlock_irqrestore(&sdma->channel_0_lock, flags);
>  
> -     dma_free_coherent(sdma->dev, header->ram_code_size, buf_virt, buf_phys);
> +     dma_unmap_single(sdma->dev, buf_phys,
> +                             header->ram_code_size, DMA_TO_DEVICE);
> +     kfree(buf_virt);
>  
>       sdma_add_scripts(sdma, addr);
>  
> @@ -1570,14 +1577,6 @@ static int sdma_request_channel0(struct sdma_engine 
> *sdma)
>  {
>       int ret = -EBUSY;
>  
> -     if (sdma->iram_pool)
> -             sdma->bd0 = gen_pool_dma_alloc(sdma->iram_pool,
> -                                     sizeof(struct sdma_buffer_descriptor),
> -                                     &sdma->bd0_phys);
> -     else
> -             sdma->bd0 = dma_alloc_coherent(sdma->dev,
> -                                     sizeof(struct sdma_buffer_descriptor),
> -                                     &sdma->bd0_phys, GFP_NOWAIT);
>       if (!sdma->bd0) {
>               ret = -ENOMEM;
>               goto out;
> @@ -1649,15 +1648,6 @@ static int sdma_runtime_suspend(struct device *dev)
>       clk_disable(sdma->clk_ipg);
>       clk_disable(sdma->clk_ahb);
>  
> -     /* free channel0 bd */
> -     if (sdma->iram_pool)
> -             gen_pool_free(sdma->iram_pool, (unsigned long)sdma->bd0,
> -                           sizeof(struct sdma_buffer_descriptor));
> -     else
> -             dma_free_coherent(sdma->dev,
> -                               sizeof(struct sdma_buffer_descriptor),
> -                               sdma->bd0, sdma->bd0_phys);
> -
>       return 0;
>  }
>  
> @@ -1678,17 +1668,6 @@ static int sdma_runtime_resume(struct device *dev)
>        * not off indeed.
>        */
>       if (readl_relaxed(sdma->regs + SDMA_H_C0PTR)) {
> -             if (sdma->iram_pool)
> -                     sdma->bd0 = gen_pool_dma_alloc(sdma->iram_pool,
> -                                     sizeof(struct sdma_buffer_descriptor),
> -                                     &sdma->bd0_phys);
> -             else
> -                     sdma->bd0 = dma_alloc_coherent(sdma->dev,
> -                                     sizeof(struct sdma_buffer_descriptor),
> -                                     &sdma->bd0_phys, GFP_NOWAIT);
> -             if (!sdma->bd0)
> -                     ret = -ENOMEM;
> -
>               sdma->channel_control[0].base_bd_ptr = sdma->bd0_phys;
>               sdma->channel_control[0].current_bd_ptr = sdma->bd0_phys;
>  
> @@ -2423,6 +2402,18 @@ static int sdma_init_sw(struct sdma_engine *sdma)
>               return ret;
>       }
>  
> +     if (sdma->iram_pool)
> +             sdma->bd0 = gen_pool_dma_alloc(sdma->iram_pool,
> +                                     sizeof(struct sdma_buffer_descriptor),
> +                                     &sdma->bd0_phys);
> +     else
> +             sdma->bd0 = dma_alloc_coherent(sdma->dev,
> +                                     sizeof(struct sdma_buffer_descriptor),
> +                                     &sdma->bd0_phys, GFP_NOWAIT);
> +     if (!sdma->bd0)
> +             ret = -ENOMEM;
> +
> +
>       sdma->context = (void *)sdma->channel_control +
>               MAX_DMA_CHANNELS * sizeof(struct sdma_channel_control);
>       sdma->context_phys = sdma->ccb_phys +
> @@ -2663,6 +2654,7 @@ static int sdma_probe(struct platform_device *pdev)
>               /* For the largest period size 64KB, the dma transfer time
>                * is about 8 sec.
>                */
> +             pm_runtime_irq_safe(&pdev->dev);
>               pm_runtime_set_autosuspend_delay(&pdev->dev, 8000);
>               pm_runtime_use_autosuspend(&pdev->dev);
>               pm_runtime_mark_last_busy(&pdev->dev);
> @@ -2709,6 +2701,15 @@ static int sdma_remove(struct platform_device *pdev)
>               sdma_runtime_suspend(&pdev->dev);
>       }
>  
> +     /* free channel0 bd */
> +     if (sdma->iram_pool)
> +             gen_pool_free(sdma->iram_pool, (unsigned long)sdma->bd0,
> +                             sizeof(struct sdma_buffer_descriptor));
> +     else
> +             dma_free_coherent(sdma->dev,
> +                             sizeof(struct sdma_buffer_descriptor),
> +                             sdma->bd0, sdma->bd0_phys);
> +
>       platform_set_drvdata(pdev, NULL);
>       return 0;
>  }
> -- 
> 2.25.1
> 
-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#14670): 
https://lists.yoctoproject.org/g/linux-yocto/message/14670
Mute This Topic: https://lists.yoctoproject.org/mt/110076849/21656
Group Owner: [email protected]
Unsubscribe: https://lists.yoctoproject.org/g/linux-yocto/unsub 
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to