From: Will Deacon <will@kernel.org>
To: Waiman Long <longman@redhat.com>
Cc: Mark Rutland <mark.rutland@arm.com>,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, Robin Murphy <robin.murphy@arm.com>
Subject: Re: [PATCH v3] perf/arm-dmc620: Fix dmc620_pmu_irqs_lock/cpu_hotplug_lock circular lock dependency
Date: Fri, 4 Aug 2023 17:28:13 +0100 [thread overview]
Message-ID: <20230804162812.GC30679@willie-the-truck> (raw)
In-Reply-To: <62d4b353-0237-9ec6-a63e-8a7a6764aba5@redhat.com>
On Wed, Aug 02, 2023 at 09:37:31PM -0400, Waiman Long wrote:
>
> On 7/28/23 11:06, Will Deacon wrote:
> > On Fri, Jul 21, 2023 at 11:17:28PM -0400, Waiman Long wrote:
> > > The following circular locking dependency was reported when running
> > > cpus online/offline test on an arm64 system.
> > >
> > > [ 84.195923] Chain exists of:
> > > dmc620_pmu_irqs_lock --> cpu_hotplug_lock --> cpuhp_state-down
> > >
> > > [ 84.207305] Possible unsafe locking scenario:
> > >
> > > [ 84.213212] CPU0 CPU1
> > > [ 84.217729] ---- ----
> > > [ 84.222247] lock(cpuhp_state-down);
> > > [ 84.225899] lock(cpu_hotplug_lock);
> > > [ 84.232068] lock(cpuhp_state-down);
> > > [ 84.238237] lock(dmc620_pmu_irqs_lock);
> > > [ 84.242236]
> > > *** DEADLOCK ***
> > >
> > > The problematic locking order seems to be
> > >
> > > lock(dmc620_pmu_irqs_lock) --> lock(cpu_hotplug_lock)
> > >
> > > This locking order happens when dmc620_pmu_get_irq() is called from
> > > dmc620_pmu_device_probe(). Since dmc620_pmu_irqs_lock is used for
> > > protecting the dmc620_pmu_irqs structure only, we don't actually need
> > > to hold the lock when adding a new instance to the CPU hotplug subsystem.
> > >
> > > Fix this possible deadlock scenario by releasing the lock before
> > > calling cpuhp_state_add_instance_nocalls() and reacquiring it afterward.
> > > To avoid the possibility of 2 racing dmc620_pmu_get_irq() calls inserting
> > > duplicated dmc620_pmu_irq structures with the same irq number, a dummy
> > > entry is inserted before releasing the lock which will block a competing
> > > thread from inserting another irq structure of the same irq number.
> > >
> > > Suggested-by: Robin Murphy <robin.murphy@arm.com>
> > > Signed-off-by: Waiman Long <longman@redhat.com>
> > > ---
> > > drivers/perf/arm_dmc620_pmu.c | 28 ++++++++++++++++++++++------
> > > 1 file changed, 22 insertions(+), 6 deletions(-)
> > >
> > > diff --git a/drivers/perf/arm_dmc620_pmu.c b/drivers/perf/arm_dmc620_pmu.c
> > > index 9d0f01c4455a..7cafd4dd4522 100644
> > > --- a/drivers/perf/arm_dmc620_pmu.c
> > > +++ b/drivers/perf/arm_dmc620_pmu.c
> > > @@ -76,6 +76,7 @@ struct dmc620_pmu_irq {
> > > refcount_t refcount;
> > > unsigned int irq_num;
> > > unsigned int cpu;
> > > + unsigned int valid;
> > > };
> > > struct dmc620_pmu {
> > > @@ -423,9 +424,14 @@ static struct dmc620_pmu_irq *__dmc620_pmu_get_irq(int irq_num)
> > > struct dmc620_pmu_irq *irq;
> > > int ret;
> > > - list_for_each_entry(irq, &dmc620_pmu_irqs, irqs_node)
> > > - if (irq->irq_num == irq_num && refcount_inc_not_zero(&irq->refcount))
> > > + list_for_each_entry(irq, &dmc620_pmu_irqs, irqs_node) {
> > > + if (irq->irq_num != irq_num)
> > > + continue;
> > > + if (!irq->valid)
> > > + return ERR_PTR(-EAGAIN); /* Try again later */
> > It looks like this can bubble up to the probe() routine. Does the driver
> > core handle -EAGAIN coming back from a probe routine?
> Right, I should add code to handle this error condition. I think it can be
> handled in dmc620_pmu_get_irq(). The important thing is to release the
> mutex, wait a few ms and try again. What do you think?
I don't really follow, but waiting a few ms and trying again sounds like
a really nasty hack for something which doesn't appear to be constrained
by broken hardware. In other words, we got ourselves into this mess, so
we should be able to resolve it properly.
Will
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2023-08-04 16:28 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-07-22 3:17 [PATCH v3] perf/arm-dmc620: Fix dmc620_pmu_irqs_lock/cpu_hotplug_lock circular lock dependency Waiman Long
2023-07-28 15:06 ` Will Deacon
2023-08-03 1:37 ` Waiman Long
2023-08-03 1:44 ` Waiman Long
2023-08-04 16:29 ` Will Deacon
2023-08-04 16:41 ` Waiman Long
2023-08-04 16:28 ` Will Deacon [this message]
2023-08-04 16:51 ` Waiman Long
2023-08-04 16:59 ` Will Deacon
2023-08-04 17:03 ` Waiman Long
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230804162812.GC30679@willie-the-truck \
--to=will@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=longman@redhat.com \
--cc=mark.rutland@arm.com \
--cc=robin.murphy@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox