lkml.org 
[lkml]   [2015]   [Jul]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH 1/1] regmap: regcache-rbtree: Use GFP_ATOMIC when using spinlocks
Date
When regmap locking is done using spinlocks (e.g. using
devm_regmap_init_mmio_clk) access is protected using spin_lock_irqsave.
So when calling regmap_write the first time and a node is about to be
inserted kzalloc must not be called with GFP_KERNEL. At this point
interrupts are disabled. This fixes the following warning:
[ 8.605433] WARNING: CPU: 0 PID: 130 at kernel/lockdep.c:2740 lockdep_trace_alloc+0x124/0x128()
[ 8.614096] DEBUG_LOCKS_WARN_ON(irqs_disabled_flags(flags))
[ 8.619469] Modules linked in: ads7846 gpio_mcp23s08 spidev lm75 ads1015 snd_soc_vf610_sgtl5000 snd_soc_sgtl5000 snd_soc_core snd_compress regmap_i2c snd_pcm_dmaengine snd_pcm snd_page_alloc regmap_spi snd_timer snd ahci_platform(+) soundcore libahci libata dwc3(+) fsl_dcu_fb(+) usb_common cfbfillrect cfbimgblt cfbcopyarea spi_fsl_dspi i2c_imx gpio_keys_polled input_polldev gpio_keys
[ 8.653912] CPU: 0 PID: 130 Comm: udevd Not tainted 3.12.37-rt51+ #859
[ 8.660413] Backtrace:
[ 8.662890] [<800127a4>] (dump_backtrace+0x0/0x110) from [<800129bc>] (show_stack+0x18/0x1c)
[ 8.671299] r6:00000000 r5:bf1de028 r4:80536834 r3:00000000
[ 8.677020] [<800129a4>] (show_stack+0x0/0x1c) from [<803a63bc>] (dump_stack+0xa0/0xdc)
[ 8.685011] [<803a631c>] (dump_stack+0x0/0xdc) from [<80022890>] (warn_slowpath_common+0x74/0x90)
[ 8.693842] r6:00000ab4 r5:00000009 r4:bf1dfa80 r3:bf0adac0
[ 8.699535] [<8002281c>] (warn_slowpath_common+0x0/0x90) from [<800228e4>] (warn_slowpath_fmt+0x38/0x40)
[ 8.708970] r8:000080d0 r7:600f0093 r6:000080d0 r5:bf1de020 r4:80536918
[ 8.715703] [<800228ac>] (warn_slowpath_fmt+0x0/0x40) from [<80074444>] (lockdep_trace_alloc+0x124/0x128)
[ 8.725221] r3:80483004 r2:8047dad0
[ 8.728809] [<80074320>] (lockdep_trace_alloc+0x0/0x128) from [<800c68b0>] (kmem_cache_alloc+0x34/0x17c)
[ 8.738242] r7:00000200 r6:00000200 r5:000080d0 r4:bf801f00
[ 8.743929] [<800c687c>] (kmem_cache_alloc+0x0/0x17c) from [<80256ca0>] (regcache_rbtree_node_alloc+0x28/0x14c)
[ 8.753975] [<80256c78>] (regcache_rbtree_node_alloc+0x0/0x14c) from [<802570e8>] (regcache_rbtree_write+0xe0/0x2c4)
[ 8.764447] r8:0000021c r7:00000200 r6:00000200 r5:bf1bce00 r4:00000000
[ 8.764447] r3:00000000
[ 8.772310] [<80257008>] (regcache_rbtree_write+0x0/0x2c4) from [<80255ed0>] (regcache_write+0x5c/0x64)
[ 8.781666] [<80255e74>] (regcache_write+0x0/0x64) from [<802550d8>] (_regmap_raw_write+0x144/0x5e8)
[ 8.790756] r6:bf3cbb88 r5:00000004 r4:bf1bce00 r3:00000000
[ 8.796432] [<80254f94>] (_regmap_raw_write+0x0/0x5e8) from [<802555fc>] (_regmap_bus_raw_write+0x80/0xa0)
[ 8.806047] [<8025557c>] (_regmap_bus_raw_write+0x0/0xa0) from [<802548b8>] (_regmap_write+0x60/0x9c)
[ 8.815224] r6:00000000 r5:00000200 r4:bf1bce00
[ 8.819854] [<80254858>] (_regmap_write+0x0/0x9c) from [<80255a34>] (regmap_write+0x48/0x68)
[ 8.828254] r7:c0ec0000 r6:00000000 r5:00000200 r4:bf1bce00
[ 8.833949] [<802559ec>] (regmap_write+0x0/0x68) from [<7f035a68>] (fsl_dcu_probe+0x268/0x7d4 [fsl_dcu_fb])
[ 8.843642] r6:8128573c r5:bf3cb910 r4:00000200 r3:00000000
[ 8.849324] [<7f035800>] (fsl_dcu_probe+0x0/0x7d4 [fsl_dcu_fb]) from [<8024dfe8>] (platform_drv_probe+0x20/0x24)
[ 8.859461] [<8024dfc8>] (platform_drv_probe+0x0/0x24) from [<8024cb9c>] (driver_probe_device+0xa0/0x384)
[ 8.868990] [<8024cafc>] (driver_probe_device+0x0/0x384) from [<8024cf68>] (__driver_attach+0x9c/0xa0)
[ 8.878263] [<8024cecc>] (__driver_attach+0x0/0xa0) from [<8024ac34>] (bus_for_each_dev+0x68/0x9c)
[ 8.887178] r6:8024cecc r5:7f036c9c r4:00000000 r3:bf923f5c
[ 8.892855] [<8024abcc>] (bus_for_each_dev+0x0/0x9c) from [<8024c604>] (driver_attach+0x24/0x28)
[ 8.901599] r6:bf36b700 r5:80540918 r4:7f036c9c
[ 8.906236] [<8024c5e0>] (driver_attach+0x0/0x28) from [<8024c1b8>] (bus_add_driver+0x1f8/0x2b4)
[ 8.914989] [<8024bfc0>] (bus_add_driver+0x0/0x2b4) from [<8024d384>] (driver_register+0x80/0x100)
[ 8.923907] r7:00000001 r6:7f036f28 r5:7f036f34 r4:7f036c9c
[ 8.929584] [<8024d304>] (driver_register+0x0/0x100) from [<8024e5f0>] (__platform_driver_register+0x5c/0x64)
[ 8.939451] r5:7f036f34 r4:bf1dff48
[ 8.943040] [<8024e594>] (__platform_driver_register+0x0/0x64) from [<7f03901c>] (fsl_dcu_driver_init+0x1c/0x24 [fsl_dcu_fb])
[ 8.954297] [<7f039000>] (fsl_dcu_driver_init+0x0/0x24 [fsl_dcu_fb]) from [<800087fc>] (do_one_initcall+0xdc/0x188)
[ 8.964690] [<80008720>] (do_one_initcall+0x0/0x188) from [<80081800>] (load_module+0x1794/0x1cb4)
[ 8.973613] [<8008006c>] (load_module+0x0/0x1cb4) from [<80081ec0>] (SyS_finit_module+0x88/0xb8)
[ 8.982365] [<80081e38>] (SyS_finit_module+0x0/0xb8) from [<8000f2c0>] (ret_fast_syscall+0x0/0x48)
[ 8.991282] r6:00000000 r5:00000000 r4:00000000

Signed-off-by: Alexander Stein <alexander.stein@systec-electronic.com>
---
Despite the fact that the backtrace is from a non-mainline, somewhat older
kernel, the code has not changed meanwhile and is still applicable.

drivers/base/regmap/regcache-rbtree.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c
index 81751a4..1480f96 100644
--- a/drivers/base/regmap/regcache-rbtree.c
+++ b/drivers/base/regmap/regcache-rbtree.c
@@ -285,19 +285,21 @@ static int regcache_rbtree_insert_to_block(struct regmap *map,
unsigned int pos, offset;
unsigned long *present;
u8 *blk;
+ gfp_t flags;

blklen = (top_reg - base_reg) / map->reg_stride + 1;
pos = (reg - base_reg) / map->reg_stride;
offset = (rbnode->base_reg - base_reg) / map->reg_stride;
+ flags = map->bus->fast_io ? GFP_ATOMIC : GFP_KERNEL;

blk = krealloc(rbnode->block,
blklen * map->cache_word_size,
- GFP_KERNEL);
+ flags);
if (!blk)
return -ENOMEM;

present = krealloc(rbnode->cache_present,
- BITS_TO_LONGS(blklen) * sizeof(*present), GFP_KERNEL);
+ BITS_TO_LONGS(blklen) * sizeof(*present), flags);
if (!present) {
kfree(blk);
return -ENOMEM;
@@ -326,8 +328,9 @@ regcache_rbtree_node_alloc(struct regmap *map, unsigned int reg)
struct regcache_rbtree_node *rbnode;
const struct regmap_range *range;
int i;
+ gfp_t flags = map->bus->fast_io ? GFP_ATOMIC : GFP_KERNEL;

- rbnode = kzalloc(sizeof(*rbnode), GFP_KERNEL);
+ rbnode = kzalloc(sizeof(*rbnode), flags);
if (!rbnode)
return NULL;

@@ -353,12 +356,12 @@ regcache_rbtree_node_alloc(struct regmap *map, unsigned int reg)
}

rbnode->block = kmalloc(rbnode->blklen * map->cache_word_size,
- GFP_KERNEL);
+ flags);
if (!rbnode->block)
goto err_free;

rbnode->cache_present = kzalloc(BITS_TO_LONGS(rbnode->blklen) *
- sizeof(*rbnode->cache_present), GFP_KERNEL);
+ sizeof(*rbnode->cache_present), flags);
if (!rbnode->cache_present)
goto err_free_block;

--
2.3.6


\
 
 \ /
  Last update: 2015-07-16 18:01    [W:0.097 / U:0.816 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site