From cb54d3904fbfe329c8a022fffe05fe53185d3612 Mon Sep 17 00:00:00 2001 From: Wedson Almeida Filho Date: Tue, 29 Mar 2022 22:05:23 +0000 Subject: [PATCH] gpio: pl061: use raw spinlock Lockdep finds the issue below when we use a regular spinlock. The issue is that the ack callback is called with a raw spinlock held, so we cannot try to acquire a regular one. [ 6.209959] ============================= [ 6.210193] [ BUG: Invalid wait context ] [ 6.210490] 5.17.0-rc8-126314-g126438203c44-dirty #482 Not tainted [ 6.210968] ----------------------------- [ 6.211200] swapper/0/1 is trying to lock: [ 6.211457] ffff0000039e4c88 (PL061Data::inner){....}-{3:3}, at: rust_helper_spin_lock+0x10/0x1c [ 6.212324] other info that might help us debug this: [ 6.212714] context-{5:5} [ 6.213157] 3 locks held by swapper/0/1: [ 6.213559] #0: ffff000003353188 (&dev->mutex){....}-{4:4}, at: __driver_attach+0xe0/0x190 [ 6.214080] #1: ffff800009ed6bf0 (irq_domain_mutex){+.+.}-{4:4}, at: irq_domain_associate+0x58/0x1bc [ 6.214598] #2: ffff0000050c04f8 (lock_class){....}-{2:2}, at: __irq_get_desc_lock+0x6c/0x94 [ 6.215105] stack backtrace: [ 6.215507] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 5.17.0-rc8-126314-g126438203c44-dirty #482 [ 6.216109] Hardware name: linux,dummy-virt (DT) [ 6.216688] Call trace: [ 6.217075] dump_backtrace+0xec/0x10c [ 6.217370] show_stack+0x18/0x24 [ 6.217560] dump_stack_lvl+0x7c/0xa0 [ 6.217772] dump_stack+0x18/0x44 [ 6.217962] __lock_acquire+0x9e0/0xbf8 [ 6.218176] lock_acquire+0xf4/0x1c0 [ 6.218386] _raw_spin_lock+0x6c/0x84 [ 6.218577] rust_helper_spin_lock+0x10/0x1c [ 6.218810] _RINvNtCsbgmUaSdIQ4l_6kernel3irq16irq_ack_callbackINtNtNtB4_4gpio7irqchip14IrqChipAdapterNtCs7lwOkdKm4ly_15gpio_pl061_rust11PL061DeviceEEB1q_+0x50/0xac [ 6.219566] irq_set_chip_and_handler_name+0x138/0x1a4 [ 6.219848] gpiochip_irq_map+0x5c/0x108 [ 6.220083] irq_domain_associate+0x7c/0x1bc [ 6.220343] irq_create_mapping_affinity+0x120/0x190 [ 6.220754] gpiochip_to_irq+0x48/0xd4 [ 6.221147] gpiod_to_irq+0x54/0x8c [ 6.221469] gpio_keys_probe+0x2ec/0x8b8 [ 6.221703] platform_probe+0xa8/0xd0 [ 6.221917] really_probe+0x12c/0x2f8 [ 6.222107] __driver_probe_device+0xb4/0xe0 [ 6.222352] driver_probe_device+0x40/0x134 [ 6.222602] __driver_attach+0xec/0x190 [ 6.222810] bus_for_each_dev+0x80/0xcc [ 6.223033] driver_attach+0x24/0x30 [ 6.223243] bus_add_driver+0x100/0x1e0 [ 6.223439] driver_register+0x78/0x110 [ 6.223619] __platform_driver_register+0x24/0x30 [ 6.223855] gpio_keys_init+0x1c/0x28 [ 6.224051] do_one_initcall+0xb8/0x19c [ 6.224255] do_initcall_level+0xa0/0xc0 [ 6.224461] do_initcalls+0x54/0x94 [ 6.224927] do_basic_setup+0x50/0x60 [ 6.225145] kernel_init_freeable+0x88/0xe0 [ 6.225422] kernel_init+0x20/0x1a0 [ 6.225628] ret_from_fork+0x10/0x20 Signed-off-by: Wedson Almeida Filho --- drivers/gpio/gpio_pl061_rust.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpio/gpio_pl061_rust.rs b/drivers/gpio/gpio_pl061_rust.rs index e0a12d3b65c749..13c8c3eb3e4fdb 100644 --- a/drivers/gpio/gpio_pl061_rust.rs +++ b/drivers/gpio/gpio_pl061_rust.rs @@ -10,7 +10,7 @@ use kernel::{ irq::{self, ExtraResult, IrqData, LockedIrqData}, power, prelude::*, - sync::{Ref, RefBorrow, SpinLock}, + sync::{RawSpinLock, Ref, RefBorrow}, }; const GPIODIR: usize = 0x400; @@ -41,7 +41,7 @@ struct PL061DataInner { struct PL061Data { dev: device::Device, - inner: SpinLock, + inner: RawSpinLock, } struct PL061Resources { @@ -283,15 +283,15 @@ impl amba::Driver for PL061Device { }, PL061Data { dev: device::Device::from_dev(dev), - // SAFETY: We call `spinlock_init` below. - inner: unsafe { SpinLock::new(PL061DataInner::default()) }, + // SAFETY: We call `rawspinlock_init` below. + inner: unsafe { RawSpinLock::new(PL061DataInner::default()) }, }, "PL061::Registrations" )?; // SAFETY: General part of the data is pinned when `data` is. let gen_inner = unsafe { data.as_mut().map_unchecked_mut(|d| &mut (**d).inner) }; - kernel::spinlock_init!(gen_inner, "PL061Data::inner"); + kernel::rawspinlock_init!(gen_inner, "PL061Data::inner"); let data = Ref::::from(data);