Commit e3469a6c authored by Kari Suvanto's avatar Kari Suvanto Committed by popcornmix
Browse files

usb: dwc: fix inconsistent lock state



Lockdep gives this splat during boot:
[    4.136748] =================================
[    4.145487] [ INFO: inconsistent lock state ]
[    4.154157] 3.16.1+ #12 Not tainted
[    4.161852] ---------------------------------
[    4.170459] inconsistent {IN-HARDIRQ-W} -> {HARDIRQ-ON-W} usage.
[    4.180776] khubd/18 [HC0[0]:SC0[0]:HE1:SE1] takes:
[    4.189971]  (&((spinlock_t *)hcd->lock)->rlock){?.-...}, at: [<c0351490>] dwc_otg_hcd_qh_free+0x18/0xcc
[    4.204074] {IN-HARDIRQ-W} state was registered at:
[    4.213359]   [<c04a8680>] _raw_spin_lock+0x40/0x50
[    4.222743]   [<c033f010>] dwc_otg_handle_common_intr+0x44/0xd90
[    4.233133]   [<c03333c8>] dwc_otg_common_irq+0xc/0x18
[    4.242739]   [<c00634d4>] handle_irq_event_percpu+0x34/0x150
[    4.252955]   [<c006362c>] handle_irq_event+0x3c/0x5c
[    4.262395]   [<c0065984>] handle_level_irq+0x8c/0x130
[    4.271972]   [<c0062e40>] generic_handle_irq+0x28/0x40
[    4.281489]   [<c000e96c>] handle_IRQ+0x30/0x84
[    4.290442]   [<c04a9698>] __irq_svc+0x38/0xd0
[    4.299164]   [<c0357194>] DWC_MODIFY_REG32+0x64/0x84
[    4.308613]   [<c0333af4>] dwc_otg_driver_probe+0x720/0x7a8
[    4.318523]   [<c02daab0>] platform_drv_probe+0x18/0x48
[    4.328141]   [<c02d926c>] really_probe+0x68/0x200
[    4.337334]   [<c02d94f8>] __driver_attach+0xa0/0xa4
[    4.346592]   [<c02d7998>] bus_for_each_dev+0x60/0x94
[    4.355998]   [<c02d8b70>] bus_add_driver+0x140/0x1ec
[    4.365262]   [<c02d9b18>] driver_register+0x78/0xf8
[    4.374561]   [<c065e0f4>] dwc_otg_driver_init+0x58/0x114
[    4.384271]   [<c00086a4>] do_one_initcall+0x80/0x1cc
[    4.393661]   [<c0646c94>] kernel_init_freeable+0xf0/0x1b0
[    4.403501]   [<c049d83c>] kernel_init+0x8/0xec
[    4.412308]   [<c000e128>] ret_from_fork+0x14/0x2c
[    4.421444] irq event stamp: 2351
[    4.428928] hardirqs last  enabled at (2351): [<c04a89b8>] _raw_spin_unlock_irqrestore+0x7c/0x94
[    4.442100] hardirqs last disabled at (2350): [<c04a87a0>] _raw_spin_lock_irqsave+0x1c/0x64
[    4.454802] softirqs last  enabled at (2320): [<c0023b94>] __do_softirq+0x1ac/0x26c
[    4.466739] softirqs last disabled at (2297): [<c0023f80>] irq_exit+0xac/0x100
[    4.478260]
[    4.478260] other info that might help us debug this:
[    4.493215]  Possible unsafe locking scenario:
[    4.493215]
[    4.507451]        CPU0
[    4.513932]        ----
[    4.520505]   lock(&((spinlock_t *)hcd->lock)->rlock);
[    4.529767]   <Interrupt>
[    4.536515]     lock(&((spinlock_t *)hcd->lock)->rlock);
[    4.545951]
[    4.545951]  *** DEADLOCK ***
[    4.545951]
[    4.564132] 3 locks held by khubd/18:
[    4.571884]  #0:  (&dev->mutex){......}, at: [<c0321da8>] hub_thread+0x98/0x1000
[    4.583536]  #1:  (&port_dev->status_lock){+.+.+.}, at: [<c032234c>] hub_thread+0x63c/0x1000
[    4.596241]  #2:  (&bus->usb_address0_mutex){+.+.+.}, at: [<c031f164>] hub_port_init+0x5c/0xb24
[    4.609307]
[    4.609307] stack backtrace:
[    4.621705] CPU: 0 PID: 18 Comm: khubd Not tainted 3.16.1+ #12
[    4.631643] [<c00137e4>] (unwind_backtrace) from [<c0011530>] (show_stack+0x10/0x14)
[    4.643580] [<c0011530>] (show_stack) from [<c049f650>] (print_usage_bug+0x240/0x2b0)
[    4.655608] [<c049f650>] (print_usage_bug) from [<c0057a24>] (mark_lock+0x1d0/0x67c)
[    4.667527] [<c0057a24>] (mark_lock) from [<c0058a10>] (__lock_acquire+0x5d4/0x1ae0)
[    4.679551] [<c0058a10>] (__lock_acquire) from [<c005a6c8>] (lock_acquire+0x6c/0x8c)
[    4.691610] [<c005a6c8>] (lock_acquire) from [<c04a8680>] (_raw_spin_lock+0x40/0x50)
[    4.703584] [<c04a8680>] (_raw_spin_lock) from [<c0351490>] (dwc_otg_hcd_qh_free+0x18/0xcc)
[    4.716305] [<c0351490>] (dwc_otg_hcd_qh_free) from [<c034a60c>] (dwc_otg_hcd_endpoint_disable+0x9c/0xb0)
[    4.730246] [<c034a60c>] (dwc_otg_hcd_endpoint_disable) from [<c034d650>] (endpoint_disable+0x18/0x24)
[    4.743919] [<c034d650>] (endpoint_disable) from [<c031e0d0>] (usb_ep0_reinit+0x14/0x38)
[    4.756379] [<c031e0d0>] (usb_ep0_reinit) from [<c031f3ac>] (hub_port_init+0x2a4/0xb24)
[    4.768652] [<c031f3ac>] (hub_port_init) from [<c0322360>] (hub_thread+0x650/0x1000)
[    4.780824] [<c0322360>] (hub_thread) from [<c003ec3c>] (kthread+0xc8/0xe4)
[    4.792231] [<c003ec3c>] (kthread) from [<c000e128>] (ret_from_fork+0x14/0x2c)

This splat shows that the hcd spinlock is used from hard irq context and also from
process context with irqs on.

To fix this, use spinlock_irqsave instead of spinlock in dwc_otg_hcd_qh_free.

Signed-off-by: default avatarKari Suvanto <karis79@gmail.com>
parent babaed9d
Loading
Loading
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment