lkml.org 
[lkml]   [2020]   [Apr]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.6 055/254] irqchip/gic-v4: Provide irq_retrigger to avoid circular locking dependency
    Date
    From: Marc Zyngier <maz@kernel.org>

    [ Upstream commit 7809f7011c3bce650e502a98afeb05961470d865 ]

    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: Marc Zyngier <maz@kernel.org>
    Link: https://lore.kernel.org/r/20200310184921.23552-5-maz@kernel.org
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/irqchip/irq-gic-v3-its.c | 6 ++++++
    1 file changed, 6 insertions(+)

    diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
    index da883a6910284..7c8f65c9c32de 100644
    --- a/drivers/irqchip/irq-gic-v3-its.c
    +++ b/drivers/irqchip/irq-gic-v3-its.c
    @@ -3679,12 +3679,18 @@ static int its_vpe_set_irqchip_state(struct irq_data *d,
    return 0;
    }

    +static int its_vpe_retrigger(struct irq_data *d)
    +{
    + return !its_vpe_set_irqchip_state(d, IRQCHIP_STATE_PENDING, true);
    +}
    +
    static struct irq_chip its_vpe_irq_chip = {
    .name = "GICv4-vpe",
    .irq_mask = its_vpe_mask_irq,
    .irq_unmask = its_vpe_unmask_irq,
    .irq_eoi = irq_chip_eoi_parent,
    .irq_set_affinity = its_vpe_set_affinity,
    + .irq_retrigger = its_vpe_retrigger,
    .irq_set_irqchip_state = its_vpe_set_irqchip_state,
    .irq_set_vcpu_affinity = its_vpe_set_vcpu_affinity,
    };
    --
    2.20.1


    \
     
     \ /
      Last update: 2020-04-16 16:59    [W:6.324 / U:0.040 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site