[PATCH v2 2/6] regmap: Use flexible sleep

Marek Szyprowski m.szyprowski at samsung.com
Wed Sep 2 08:47:31 EDT 2020


Hi Dmitry,

On 30.08.2020 20:53, Dmitry Osipenko wrote:
> The multi-reg write function uses udelay(), which is a busy-loop based
> delaying function that is not suitable for a long delays. Hence let's
> replace the udelay() with fsleep(), which is flexible sleep function that
> selects best delay function based on the delay-time.
>
> Signed-off-by: Dmitry Osipenko <digetx at gmail.com>

This patch landed in today's linux-next (20200902) as commit 
2b32d2f7ce0a. Sadly it breaks booting of ARM 64bit Amlogic S922X based 
Odroid N2 board. Here is the log:

BUG: scheduling while atomic: kworker/4:1/46/0x00000003
5 locks held by kworker/4:1/46:
  #0: ffff0000dfc06738 ((wq_completion)events){+.+.}-{0:0}, at: 
process_one_work+0x200/0x718
  #1: ffff80001320bdd0 (deferred_probe_work){+.+.}-{0:0}, at: 
process_one_work+0x200/0x718
  #2: ffff0000df4b6188 (&dev->mutex){....}-{3:3}, at: 
__device_attach+0x3c/0x150
  #3: ffff800012306e70 (enable_lock){+.+.}-{2:2}, at: 
clk_enable_lock+0x48/0x128
  #4: ffff0000de01c418 (syscon:110:(&syscon_config)->lock){+.+.}-{2:2}, 
at: regmap_lock_spinlock+0x14/0x28
Modules linked in:
CPU: 4 PID: 46 Comm: kworker/4:1 Not tainted 5.9.0-rc2+ #1570
Hardware name: Hardkernel ODROID-N2 (DT)
Workqueue: events deferred_probe_work_func
Call trace:
  dump_backtrace+0x0/0x1d0
  show_stack+0x14/0x20
  dump_stack+0xec/0x16c
  __schedule_bug+0x64/0x98
  __schedule+0x7e0/0x8a0
  schedule+0x78/0x118
  schedule_hrtimeout_range_clock+0x84/0x108
  schedule_hrtimeout_range+0x10/0x18
  usleep_range+0x88/0xb8
  _regmap_multi_reg_write+0x188/0x4e0
  regmap_multi_reg_write+0x38/0x58
  meson_clk_pll_init+0x80/0xd8
  meson_clk_pcie_pll_enable+0x48/0xd8
  clk_core_enable+0xc8/0x2b0
  clk_core_enable+0xa8/0x2b0
  clk_core_enable+0xa8/0x2b0
  clk_core_enable+0xa8/0x2b0
  clk_core_enable_lock+0x20/0x40
  clk_enable+0x14/0x28
  phy_g12a_usb3_pcie_probe+0x130/0x210
  platform_drv_probe+0x50/0xa8
  really_probe+0x110/0x400
  driver_probe_device+0x54/0xb8
  __device_attach_driver+0x90/0xc0
  bus_for_each_drv+0x70/0xc8
  __device_attach+0xec/0x150
  device_initial_probe+0x10/0x18
  bus_probe_device+0x94/0xa0
  deferred_probe_work_func+0x70/0xa8
  process_one_work+0x2a8/0x718
  worker_thread+0x48/0x460
  kthread+0x134/0x160
  ret_from_fork+0x10/0x1c
BUG: sleeping function called from invalid context at mm/slab.h:498
in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 46, name: kworker/4:1
3 locks held by kworker/4:1/46:
  #0: ffff0000dfc06738 ((wq_completion)events){+.+.}-{0:0}, at: 
process_one_work+0x200/0x718
  #1: ffff80001320bdd0 (deferred_probe_work){+.+.}-{0:0}, at: 
process_one_work+0x200/0x718
  #2: ffff0000df4b6188 (&dev->mutex){....}-{3:3}, at: 
__device_attach+0x3c/0x150
CPU: 4 PID: 46 Comm: kworker/4:1 Tainted: G        W 5.9.0-rc2+ #1570
Hardware name: Hardkernel ODROID-N2 (DT)
Workqueue: events deferred_probe_work_func
Call trace:
  dump_backtrace+0x0/0x1d0
  show_stack+0x14/0x20
  dump_stack+0xec/0x16c
  ___might_sleep+0x1d4/0x1f8
  __might_sleep+0x4c/0x88
  slab_pre_alloc_hook.constprop.96+0xf4/0x138
  __kmalloc_node_track_caller+0x6c/0x288
  devres_alloc_node+0x54/0xc0
  devm_reset_control_array_get+0x34/0xc0
  phy_g12a_usb3_pcie_probe+0x148/0x210
  platform_drv_probe+0x50/0xa8
  really_probe+0x110/0x400
  driver_probe_device+0x54/0xb8
  __device_attach_driver+0x90/0xc0
  bus_for_each_drv+0x70/0xc8
  __device_attach+0xec/0x150
  device_initial_probe+0x10/0x18
  bus_probe_device+0x94/0xa0
  deferred_probe_work_func+0x70/0xa8
  process_one_work+0x2a8/0x718
  worker_thread+0x48/0x460
  kthread+0x134/0x160
  ret_from_fork+0x10/0x1c
------------[ cut here ]------------
kernel BUG at mm/vmalloc.c:2066!
Internal error: Oops - BUG: 0 [#1] PREEMPT SMP
Modules linked in:
CPU: 4 PID: 46 Comm: kworker/4:1 Tainted: G        W 5.9.0-rc2+ #1570
Hardware name: Hardkernel ODROID-N2 (DT)
Workqueue: events deferred_probe_work_func
pstate: 00000005 (nzcv daif -PAN -UAO BTYPE=--)
pc : __get_vm_area_node+0x190/0x198
lr : get_vm_area_caller+0x34/0x40
sp : ffff80001320b9f0
x29: ffff80001320b9f0 x28: ffff8000124bf68d
x27: ffff0000e47ce005 x26: ffff0000e484a6a8
x25: 0000000000000009 x24: ffff80001220f000
x23: 0068000000000707 x22: ffff800010531544
x21: 0000000000000000 x20: 00000000ffe09000
x19: 0000000000001000 x18: ffffffffffffffff
x17: 0000000089f66c61 x16: 00000000b502d7d1
x15: ffff80001220fa48 x14: ffff0000de6df18a
x13: ffff0000de6df189 x12: 0000000000000030
x11: 0000000000000003 x10: ffff8000124f8c58
x9 : 0000000000000000 x8 : 00000000fffffffe
x7 : ffff800010531544 x6 : 0000000000000cc0
x5 : 00000000ffffffff x4 : fffffdffbfff0000
x3 : ffff800010000000 x2 : 0000000000000001
x1 : 0000000000000001 x0 : 0000000000001000
Call trace:
  __get_vm_area_node+0x190/0x198
  __ioremap_caller+0x68/0xe0
  __ioremap+0x38/0x40
  __devm_ioremap+0x7c/0xf8
  __devm_ioremap_resource+0xa8/0x160
  devm_ioremap_resource+0x10/0x18
  devm_platform_get_and_ioremap_resource+0x70/0x78
  devm_platform_ioremap_resource+0x10/0x18
  dwc3_meson_g12a_probe+0x60/0x518
  platform_drv_probe+0x50/0xa8
  really_probe+0x110/0x400
  driver_probe_device+0x54/0xb8
  __device_attach_driver+0x90/0xc0
  bus_for_each_drv+0x70/0xc8
  __device_attach+0xec/0x150
  device_initial_probe+0x10/0x18
  bus_probe_device+0x94/0xa0
  deferred_probe_work_func+0x70/0xa8
  process_one_work+0x2a8/0x718
  worker_thread+0x48/0x460
  kthread+0x134/0x160
  ret_from_fork+0x10/0x1c
Code: cb010000 11000400 17ffffe8 d503201f (d4210000)
---[ end trace b621320ae7bce6b7 ]---
Kernel panic - not syncing: Aiee, killing interrupt handler!
SMP: stopping secondary CPUs
Kernel Offset: disabled
CPU features: 0x0240002,20082004
Memory Limit: none
---[ end Kernel panic - not syncing: Aiee, killing interrupt handler! ]---

Reverting this commit on top of current linux-next fixes board booting.

> ---
>   drivers/base/regmap/regmap.c | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
> index e93700af7e6e..a417cb1a11dc 100644
> --- a/drivers/base/regmap/regmap.c
> +++ b/drivers/base/regmap/regmap.c
> @@ -2231,7 +2231,7 @@ static int _regmap_range_multi_paged_reg_write(struct regmap *map,
>   					return ret;
>   
>   				if (regs[i].delay_us)
> -					udelay(regs[i].delay_us);
> +					fsleep(regs[i].delay_us);
>   
>   				base += n;
>   				n = 0;
> @@ -2268,7 +2268,7 @@ static int _regmap_multi_reg_write(struct regmap *map,
>   				return ret;
>   
>   			if (regs[i].delay_us)
> -				udelay(regs[i].delay_us);
> +				fsleep(regs[i].delay_us);
>   		}
>   		return 0;
>   	}

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland




More information about the linux-amlogic mailing list