• Marc Zyngier's avatar
    irqchip/gic-v4: Provide irq_retrigger to avoid circular locking dependency · 7809f701
    Marc Zyngier authored
    On a very heavily loaded D05 with GICv4, I managed to trigger the
    following lockdep splat:
    
    [ 6022.598864] ======================================================
    [ 6022.605031] WARNING: possible circular locking dependency detected
    [ 6022.611200] 5.6.0-rc4-00026-geee7c7b0f498 #680 Tainted: G            E
    [ 6022.618061] ------------------------------------------------------
    [ 6022.624227] qemu-system-aar/7569 is trying to acquire lock:
    [ 6022.629789] ffff042f97606808 (&p->pi_lock){-.-.}, at: try_to_wake_up+0x54/0x7a0
    [ 6022.637102]
    [ 6022.637102] but task is already holding lock:
    [ 6022.642921] ffff002fae424cf0 (&irq_desc_lock_class){-.-.}, at: __irq_get_desc_lock+0x5c/0x98
    [ 6022.651350]
    [ 6022.651350] which lock already depends on the new lock.
    [ 6022.651350]
    [ 6022.659512]
    [ 6022.659512] the existing dependency chain (in reverse order) is:
    [ 6022.666980]
    [ 6022.666980] -> #2 (&irq_desc_lock_class){-.-.}:
    [ 6022.672983]        _raw_spin_lock_irqsave+0x50/0x78
    [ 6022.677848]        __irq_get_desc_lock+0x5c/0x98
    [ 6022.682453]        irq_set_vcpu_affinity+0x40/0xc0
    [ 6022.687236]        its_make_vpe_non_resident+0x6c/0xb8
    [ 6022.692364]        vgic_v4_put+0x54/0x70
    [ 6022.696273]        vgic_v3_put+0x20/0xd8
    [ 6022.700183]        kvm_vgic_put+0x30/0x48
    [ 6022.704182]        kvm_arch_vcpu_put+0x34/0x50
    [ 6022.708614]        kvm_sched_out+0x34/0x50
    [ 6022.712700]        __schedule+0x4bc/0x7f8
    [ 6022.716697]        schedule+0x50/0xd8
    [ 6022.720347]        kvm_arch_vcpu_ioctl_run+0x5f0/0x978
    [ 6022.725473]        kvm_vcpu_ioctl+0x3d4/0x8f8
    [ 6022.729820]        ksys_ioctl+0x90/0xd0
    [ 6022.733642]        __arm64_sys_ioctl+0x24/0x30
    [ 6022.738074]        el0_svc_common.constprop.3+0xa8/0x1e8
    [ 6022.743373]        do_el0_svc+0x28/0x88
    [ 6022.747198]        el0_svc+0x14/0x40
    [ 6022.750761]        el0_sync_handler+0x124/0x2b8
    [ 6022.755278]        el0_sync+0x140/0x180
    [ 6022.759100]
    [ 6022.759100] -> #1 (&rq->lock){-.-.}:
    [ 6022.764143]        _raw_spin_lock+0x38/0x50
    [ 6022.768314]        task_fork_fair+0x40/0x128
    [ 6022.772572]        sched_fork+0xe0/0x210
    [ 6022.776484]        copy_process+0x8c4/0x18d8
    [ 6022.780742]        _do_fork+0x88/0x6d8
    [ 6022.784478]        kernel_thread+0x64/0x88
    [ 6022.788563]        rest_init+0x30/0x270
    [ 6022.792390]        arch_call_rest_init+0x14/0x1c
    [ 6022.796995]        start_kernel+0x498/0x4c4
    [ 6022.801164]
    [ 6022.801164] -> #0 (&p->pi_lock){-.-.}:
    [ 6022.806382]        __lock_acquire+0xdd8/0x15c8
    [ 6022.810813]        lock_acquire+0xd0/0x218
    [ 6022.814896]        _raw_spin_lock_irqsave+0x50/0x78
    [ 6022.819761]        try_to_wake_up+0x54/0x7a0
    [ 6022.824018]        wake_up_process+0x1c/0x28
    [ 6022.828276]        wakeup_softirqd+0x38/0x40
    [ 6022.832533]        __tasklet_schedule_common+0xc4/0xf0
    [ 6022.837658]        __tasklet_schedule+0x24/0x30
    [ 6022.842176]        check_irq_resend+0xc8/0x158
    [ 6022.846609]        irq_startup+0x74/0x128
    [ 6022.850606]        __enable_irq+0x6c/0x78
    [ 6022.854602]        enable_irq+0x54/0xa0
    [ 6022.858431]        its_make_vpe_non_resident+0xa4/0xb8
    [ 6022.863557]        vgic_v4_put+0x54/0x70
    [ 6022.867469]        kvm_arch_vcpu_blocking+0x28/0x38
    [ 6022.872336]        kvm_vcpu_block+0x48/0x490
    [ 6022.876594]        kvm_handle_wfx+0x18c/0x310
    [ 6022.880938]        handle_exit+0x138/0x198
    [ 6022.885022]        kvm_arch_vcpu_ioctl_run+0x4d4/0x978
    [ 6022.890148]        kvm_vcpu_ioctl+0x3d4/0x8f8
    [ 6022.894494]        ksys_ioctl+0x90/0xd0
    [ 6022.898317]        __arm64_sys_ioctl+0x24/0x30
    [ 6022.902748]        el0_svc_common.constprop.3+0xa8/0x1e8
    [ 6022.908046]        do_el0_svc+0x28/0x88
    [ 6022.911871]        el0_svc+0x14/0x40
    [ 6022.915434]        el0_sync_handler+0x124/0x2b8
    [ 6022.919951]        el0_sync+0x140/0x180
    [ 6022.923773]
    [ 6022.923773] other info that might help us debug this:
    [ 6022.923773]
    [ 6022.931762] Chain exists of:
    [ 6022.931762]   &p->pi_lock --> &rq->lock --> &irq_desc_lock_class
    [ 6022.931762]
    [ 6022.942101]  Possible unsafe locking scenario:
    [ 6022.942101]
    [ 6022.948007]        CPU0                    CPU1
    [ 6022.952523]        ----                    ----
    [ 6022.957039]   lock(&irq_desc_lock_class);
    [ 6022.961036]                                lock(&rq->lock);
    [ 6022.966595]                                lock(&irq_desc_lock_class);
    [ 6022.973109]   lock(&p->pi_lock);
    [ 6022.976324]
    [ 6022.976324]  *** DEADLOCK ***
    
    This is happening because we have a pending doorbell that requires
    retrigger. As SW retriggering is done in a tasklet, we trigger the
    circular dependency above.
    
    The easy cop-out is to provide a retrigger callback that doesn't
    require acquiring any extra lock.
    Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
    Link: https://lore.kernel.org/r/20200310184921.23552-5-maz@kernel.org
    7809f701
irq-gic-v3-its.c 120 KB