From: Andy Fleming <afleming@freescale.com>
To: Andrew Morton <akpm@osdl.org>
Cc: "Maciej W. Rozycki" <macro@linux-mips.org>,
Ben Collins <ben.collins@ubuntu.com>,
linux-kernel@vger.kernel.org, Linus Torvalds <torvalds@osdl.org>,
Jeff Garzik <jeff@garzik.org>
Subject: Re: [PATCH] Export current_is_keventd() for libphy
Date: Tue, 5 Dec 2006 14:59:31 -0600 [thread overview]
Message-ID: <6FD5FD7A-4CC2-481A-BC87-B869F045B347@freescale.com> (raw)
In-Reply-To: <20061205123958.497a7bd6.akpm@osdl.org>
On Dec 5, 2006, at 14:39, Andrew Morton wrote:
> On Tue, 5 Dec 2006 17:48:05 +0000 (GMT)
> "Maciej W. Rozycki" <macro@linux-mips.org> wrote:
>
>> Essentially there is a race when disconnecting from a PHY, because
>> interrupt delivery uses the event queue for processing. The
>> function to
>> handle interrupts that is called from the event queue is phy_change
>> ().
>> It takes a pointer to a structure that is associated with the
>> PHY. At the
>> time phy_stop_interrupts() is called there may be one or more
>> calls to
>> phy_change() still pending on the event queue. They may not be
>> able to be
>> processed until the structure passed to phy_change() have been
>> freed, at
>> which point calling the function is wrong.
>>
>> One way of avoiding it is calling flush_scheduled_work() from
>> phy_stop_interrupts(). This is fine as long as a caller of
>> phy_stop_interrupts() (not necessarily the immediate one calling into
>> libphy) does not hold the netlink lock.
>
> So let me try to rephrase...
>
> - phy_change() is the workqueue callback function. It is executed by
> keventd.
>
> - Something under phy_change() takes rtnl_lock() (but what??)
I don't think it's phy_change(). It's something else that may be
scheduled.
>
> - phy_stop_interrupts() does flush_scheduled_work(). This has to
> following logic:
>
> - if I am kevetnd, run phy_change() directly.
>
> - If I am not keventd, wait for keventd() to run phy_change()
>
> - So if the caller of phy_stop_interrupt() already holds rtnl_lock(),
> and if that caller is keventd then it will recur onto rntl_lock()
> and
> will deadlock.
>
> Problem is, if the caller of phy_stop_interrupt() is *not* keventd,
> that
> caller will still deadlock, because that caller is waiting for
> keventd to
> run phy_change(), and keventd cannot do that, because the not-keventd
> process already holds rtnl_lock.
>
>
> Now, afaict, there are only two callers of phy_stop_interrupts(): the
> close() handlers of gianfar.c and fs_enet-main.c (confusingly held in
> netdevice.stop (confusingly called by dev_close())). Via
> phy_disconnect.
> Did I miss anything?
Right now, that's probably about right.
>
> And the dev_close() caller holds rtnl_lock.
>
Ok, I think this is the summary:
- phy_change() is the work queue callback function (scheduled when a
PHY interrupt occurs)
- dev_close() invokes the controller's stop/close/whatever function,
and it calls phy_disconnect()
- phy_disconnect() calls phy_stop_interrupts(). To prevent any
pending phy_change() calls from getting confused, phy_stop_interrupts
() needs to flush the queue. Otherwise, subsequent memory freeings
will leave phy_change() hanging.
- If phy_stop_interrupts() calls flush_scheduled_work(), keventd will
execute its queues while rtnl_lock is held, providing opportunity for
other callbacks to deadlock.
- innocent puppies are slaughtered, and the world mourns.
Maciej's solution is to schedule phy_disconnect() to be called from a
work queue. That solution should work, but it sounds like it doesn't
require the check for if keventd is running.
Of course, my objection to it is that it now requires the ethernet
controller to be excessively aware of the details of how the PHY Lib
is handling the PHY interrupts (by scheduling them on a work queue).
Andy
next prev parent reply other threads:[~2006-12-05 20:59 UTC|newest]
Thread overview: 54+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-12-03 5:50 Ben Collins
2006-12-03 9:16 ` Andrew Morton
2006-12-04 19:17 ` Steve Fox
2006-12-05 18:05 ` Maciej W. Rozycki
2006-12-05 17:48 ` Maciej W. Rozycki
2006-12-05 18:07 ` Linus Torvalds
2006-12-05 19:31 ` Andrew Morton
2006-12-05 18:57 ` Andy Fleming
2006-12-06 12:31 ` Maciej W. Rozycki
2006-12-05 20:39 ` Andrew Morton
2006-12-05 20:59 ` Andy Fleming [this message]
2006-12-05 21:26 ` Andrew Morton
2006-12-05 21:37 ` Roland Dreier
2006-12-05 21:57 ` Andrew Morton
2006-12-05 23:49 ` Roland Dreier
2006-12-05 23:52 ` Roland Dreier
2006-12-06 15:25 ` Maciej W. Rozycki
2006-12-06 15:57 ` Andrew Morton
2006-12-06 17:17 ` Linus Torvalds
2006-12-07 1:21 ` Linus Torvalds
2006-12-07 6:42 ` Andrew Morton
2006-12-07 7:49 ` Andrew Morton
2006-12-07 10:29 ` David Howells
2006-12-07 10:42 ` Andrew Morton
2006-12-07 17:05 ` Jeff Garzik
2006-12-07 17:57 ` Andrew Morton
2006-12-07 18:17 ` Andrew Morton
2006-12-08 16:52 ` [PATCH] group xtime, xtime_lock, wall_to_monotonic, avenrun, calc_load_count fields together in ktimed Eric Dumazet
2006-12-09 5:46 ` Andrew Morton
2006-12-09 6:07 ` Randy Dunlap
2006-12-11 20:44 ` Eric Dumazet
2006-12-11 22:00 ` Andrew Morton
2006-12-13 21:26 ` [PATCH] Introduce time_data, a new structure to hold jiffies, xtime, xtime_lock, wall_to_monotonic, calc_load_count and avenrun Eric Dumazet
2006-12-15 5:24 ` Andrew Morton
2006-12-15 11:21 ` Eric Dumazet
2006-12-15 16:21 ` Eric Dumazet
2006-12-07 18:08 ` [PATCH] Export current_is_keventd() for libphy Maciej W. Rozycki
2006-12-07 18:59 ` Andy Fleming
2006-12-07 16:49 ` Linus Torvalds
2006-12-07 17:52 ` Andrew Morton
2006-12-07 18:01 ` Linus Torvalds
2006-12-07 18:16 ` Andrew Morton
2006-12-07 18:27 ` Linus Torvalds
2006-12-07 15:28 ` Maciej W. Rozycki
2006-12-06 17:43 ` David Howells
2006-12-06 17:50 ` Jeff Garzik
2006-12-06 18:07 ` Linus Torvalds
2006-12-06 17:53 ` Linus Torvalds
2006-12-06 17:58 ` Linus Torvalds
2006-12-06 18:33 ` Linus Torvalds
2006-12-06 18:37 ` Linus Torvalds
2006-12-06 18:43 ` David Howells
2006-12-06 19:02 ` Linus Torvalds
2006-12-06 18:02 ` David Howells
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=6FD5FD7A-4CC2-481A-BC87-B869F045B347@freescale.com \
--to=afleming@freescale.com \
--cc=akpm@osdl.org \
--cc=ben.collins@ubuntu.com \
--cc=jeff@garzik.org \
--cc=linux-kernel@vger.kernel.org \
--cc=macro@linux-mips.org \
--cc=torvalds@osdl.org \
/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
all inboxes | Powered by JetHome®