Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752875AbbGPPtG (ORCPT ); Thu, 16 Jul 2015 11:49:06 -0400 Received: from webbox1416.server-home.net ([77.236.96.61]:37245 "EHLO webbox1416.server-home.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750769AbbGPPtE (ORCPT ); Thu, 16 Jul 2015 11:49:04 -0400 From: Alexander Stein To: Mark Brown , Greg Kroah-Hartman Cc: Alexander Stein , linux-kernel@vger.kernel.org Subject: [PATCH 1/1] regmap: regcache-rbtree: Use GFP_ATOMIC when using spinlocks Date: Thu, 16 Jul 2015 17:48:52 +0200 Message-Id: <1437061732-21018-1-git-send-email-alexander.stein@systec-electronic.com> X-Mailer: git-send-email 2.3.6 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 7124 Lines: 124 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 --- 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 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/