From: Josh Triplett <josh@joshtriplett.org>
To: David Decotigny <decot@googlers.com>
Cc: "linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
Ben Hutchings <bhutchings@solarflare.com>,
"David S. Miller" <davem@davemloft.net>,
Or Gerlitz <ogerlitz@mellanox.com>,
Amir Vadai <amirv@mellanox.com>,
"Paul E. McKenney" <paul.mckenney@linaro.org>,
Thomas Gleixner <tglx@linutronix.de>,
Andrew Morton <akpm@linux-foundation.org>,
David Howells <dhowells@redhat.com>,
Paul Gortmaker <paul.gortmaker@windriver.com>
Subject: Re: [PATCH v1] lib: cpu_rmap: avoid flushing all workqueues
Date: Fri, 28 Dec 2012 16:16:33 -0800 [thread overview]
Message-ID: <20121229001633.GA17342@leaf> (raw)
In-Reply-To: <CAG88wWadShHHK_7DwyDmYYZkCHXmrF0NKtJDY0aSYcEjisP95A@mail.gmail.com>
On Fri, Dec 28, 2012 at 10:18:11AM -0800, David Decotigny wrote:
> Thank you, Josh,
>
> A few comments below, and the revised version shortly.
Responses below.
> On Thu, Dec 27, 2012 at 8:04 PM, Josh Triplett <josh@joshtriplett.org> wrote:
> > On Thu, Dec 27, 2012 at 11:24:34AM -0800, David Decotigny wrote:
> >> In some cases, free_irq_cpu_rmap() is called while holding a lock
> >> (eg. rtnl). This can lead to deadlocks, because it invokes
> >> flush_scheduled_work() which ends up waiting for whole system
> >> workqueue to flush, but some pending works might try to acquire the
> >> lock we are already holding.
> >>
> >> This commit uses reference-counting to replace
> >> irq_run_affinity_notifiers(). It also removes
> >> irq_run_affinity_notifiers() altogether.
> >>
> >> Signed-off-by: David Decotigny <decot@googlers.com>
> >
> > A couple of comments below; with those addressed,
> > Reviewed-by: Josh Triplett <josh@joshtriplett.org>
> >
> >> --- a/lib/cpu_rmap.c
> >> +++ b/lib/cpu_rmap.c
> >> @@ -230,16 +256,23 @@ irq_cpu_rmap_notify(struct irq_affinity_notify *notify, const cpumask_t *mask)
> >> pr_warning("irq_cpu_rmap_notify: update failed: %d\n", rc);
> >> }
> >>
> >> +/**
> >> + * irq_cpu_rmap_release - reclaiming callback for IRQ subsystem
> >> + * @ref: kref to struct irq_affinity_notify passed by irq/manage.c
> >> + */
> >> static void irq_cpu_rmap_release(struct kref *ref)
> >> {
> >> struct irq_glue *glue =
> >> container_of(ref, struct irq_glue, notify.kref);
> >> + struct cpu_rmap *rmap = glue->rmap;
> >> +
> >> kfree(glue);
> >> + kref_put(&rmap->refcount, reclaim_cpu_rmap);
> >
> > Likewise, but also, why not call free_cpu_rmap(glue->rmap) before
> > kfree(glue) so you don't need the local copy?
>
> I prefer to keep this kref_put here. I believe that calling something
> named "free_cpu_rmap" here might be misleading. It's code sharing vs.
> what we actually need to do, even though both are equivalent... for
> now.
If calling something named free_cpu_rmap feels wrong here, perhaps you
should call it cpu_rmap_put or cpu_rmap_unref or similar instead, since
it doesn't actually free unless the refcount goes to zero. Then you
could have irq_cpu_rmap_release calling cpu_rmap_put, which feels more
natural. But in any case, I think you should avoid having multiple
instances of the full call to kref_put on a cpu_rmap.
> For the order, it was deliberate, to have some kind of symmetry with
> kfree/kref_put in the error path we have in next function
> (irq_cpu_rmap_add). I reversed the order in that next function to
> avoid this unneeded local variable here. New ordering makes more sense
> anyways.
Ah, I see; makes sense to me.
> >> }
> >>
> >> /**
> >> * irq_cpu_rmap_add - add an IRQ to a CPU affinity reverse-map
> >> - * @rmap: The reverse-map
> >> + * @rmap: The per-IRQ reverse-map
> >> * @irq: The IRQ number
> >> *
> >> * This adds an IRQ affinity notifier that will update the reverse-map
> >> @@ -259,9 +292,12 @@ int irq_cpu_rmap_add(struct cpu_rmap *rmap, int irq)
> >> glue->notify.release = irq_cpu_rmap_release;
> >> glue->rmap = rmap;
> >> glue->index = cpu_rmap_add(rmap, glue);
> >> + kref_get(&rmap->refcount);
> >> rc = irq_set_affinity_notifier(irq, &glue->notify);
> >> - if (rc)
> >> + if (rc) {
> >> kfree(glue);
> >> + kref_put(&rmap->refcount, reclaim_cpu_rmap);
> >
> > Likewise.
>
> I prefer to leave the explicit kref_put here too.
In this case, for symmetry with kref_get?
Would it help to add a cpu_rmap_get, along with cpu_rmap_put?
static inline struct cpu_rmap *cpu_rmap_get(struct cpu_rmap *rmap)
{
kref_get(&rmap->refcount);
return rmap;
}
...
glue->rmap = cpu_rmap_get(rmap);
...
> Next version soon, after some re-testing.
Thanks.
- Josh Triplett
prev parent reply other threads:[~2012-12-29 0:16 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <cover.1356635879.git.decot@googlers.com>
2012-12-27 19:24 ` [PATCH v1] lib: cpu_rmap: avoid flushing all workqueues David Decotigny
2012-12-28 4:04 ` Josh Triplett
2012-12-28 18:18 ` David Decotigny
2012-12-29 0:16 ` Josh Triplett [this message]
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=20121229001633.GA17342@leaf \
--to=josh@joshtriplett.org \
--cc=akpm@linux-foundation.org \
--cc=amirv@mellanox.com \
--cc=bhutchings@solarflare.com \
--cc=davem@davemloft.net \
--cc=decot@googlers.com \
--cc=dhowells@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=ogerlitz@mellanox.com \
--cc=paul.gortmaker@windriver.com \
--cc=paul.mckenney@linaro.org \
--cc=tglx@linutronix.de \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.