From: Tvrtko Ursulin <tursulin@ursulin.net>
To: linux-kernel@vger.kernel.org
Cc: Thomas Gleixner <tglx@linutronix.de>,
Ingo Molnar <mingo@kernel.org>,
Peter Zijlstra <peterz@infradead.org>,
Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>,
Boris Ostrovsky <boris.ostrovsky@oracle.com>
Subject: Possible bug in CPU hotplug handling (4.14.0-rc5)
Date: Fri, 20 Oct 2017 18:37:46 +0100 [thread overview]
Message-ID: <64e7e66f-a90b-eaa8-de70-51a8d907b5b4@ursulin.net> (raw)
Hi all,
I think I've found in bug in the CPU hotplug handling when multi-instance
states are used. That is in the 4.14.0-rc5 kernel.
I have not attempted to get to the bottom of the issue to propose an actual
fix, since the logic there looks somewhat complex, but thought to first
seek opinion of the people in the know regarding this area.
What I think is happening is that when a multi-instance state is registered
last, the per-cpu st->node field remains "sticky" ie. remains set to the
address of the node belonging to the client which registered last.
The following hotplug event will then call all the callbacks passing that
same st->node to all the clients. Obviously bad things happen then, ranging
from oopses to silent memory corruption.
I have added some custom log messages to catch this and if you can try to
follow through them this is what happens. First a multi-instance state
client registers:
cpuhp store callbacks state=176 name=perf/x86/intel/i915:online multi=1
i915 cpuhp slot 176
cpuhp_issue_call state=176 node=ffff88021db38390
cpuhp_thread_fun cpu=0 state=176 bringup=1 node=ffff88021db38390
cpuhp_invoke_callback multi-single cpu=0 state=176 node=ffff88021db38390
cpuhp_thread_fun result=0
cpuhp_issue_call state=176 node=ffff88021db38390
cpuhp_thread_fun cpu=1 state=176 bringup=1 node=ffff88021db38390
cpuhp_invoke_callback multi-single cpu=1 state=176 node=ffff88021db38390
cpuhp_thread_fun result=0
cpuhp_issue_call state=176 node=ffff88021db38390
cpuhp_thread_fun cpu=2 state=176 bringup=1 node=ffff88021db38390
cpuhp_invoke_callback multi-single cpu=2 state=176 node=ffff88021db38390
cpuhp_thread_fun result=0
cpuhp_issue_call state=176 node=ffff88021db38390
cpuhp_thread_fun cpu=3 state=176 bringup=1 node=ffff88021db38390
cpuhp_invoke_callback multi-single cpu=3 state=176 node=ffff88021db38390
cpuhp_thread_fun result=0
cpuhp_issue_call state=176 node=ffff88021db38390
cpuhp_thread_fun cpu=4 state=176 bringup=1 node=ffff88021db38390
cpuhp_invoke_callback multi-single cpu=4 state=176 node=ffff88021db38390
cpuhp_thread_fun result=0
cpuhp_issue_call state=176 node=ffff88021db38390
cpuhp_thread_fun cpu=5 state=176 bringup=1 node=ffff88021db38390
cpuhp_invoke_callback multi-single cpu=5 state=176 node=ffff88021db38390
cpuhp_thread_fun result=0
cpuhp_issue_call state=176 node=ffff88021db38390
cpuhp_thread_fun cpu=6 state=176 bringup=1 node=ffff88021db38390
cpuhp_invoke_callback multi-single cpu=6 state=176 node=ffff88021db38390
cpuhp_thread_fun result=0
cpuhp_issue_call state=176 node=ffff88021db38390
cpuhp_thread_fun cpu=7 state=176 bringup=1 node=ffff88021db38390
cpuhp_invoke_callback multi-single cpu=7 state=176 node=ffff88021db38390
cpuhp_thread_fun result=0
cpuhp added state=176 node=ffff88021db38390
Then a hotplug event happens:
cpuhp store callbacks state=176 name=perf/x86/intel/i915:online multi=1
i915 cpuhp slot 176
cpuhp_issue_call state=176 node=ffff88021db38390
cpuhp_thread_fun cpu=0 state=176 bringup=1 node=ffff88021db38390
cpuhp_invoke_callback multi-single cpu=0 state=176 node=ffff88021db38390
cpuhp_thread_fun result=0
cpuhp_issue_call state=176 node=ffff88021db38390
cpuhp_thread_fun cpu=1 state=176 bringup=1 node=ffff88021db38390
cpuhp_invoke_callback multi-single cpu=1 state=176 node=ffff88021db38390
cpuhp_thread_fun result=0
cpuhp_issue_call state=176 node=ffff88021db38390
cpuhp_thread_fun cpu=2 state=176 bringup=1 node=ffff88021db38390
cpuhp_invoke_callback multi-single cpu=2 state=176 node=ffff88021db38390
cpuhp_thread_fun result=0
cpuhp_issue_call state=176 node=ffff88021db38390
cpuhp_thread_fun cpu=3 state=176 bringup=1 node=ffff88021db38390
cpuhp_invoke_callback multi-single cpu=3 state=176 node=ffff88021db38390
cpuhp_thread_fun result=0
cpuhp_issue_call state=176 node=ffff88021db38390
cpuhp_thread_fun cpu=4 state=176 bringup=1 node=ffff88021db38390
cpuhp_invoke_callback multi-single cpu=4 state=176 node=ffff88021db38390
cpuhp_thread_fun result=0
cpuhp_issue_call state=176 node=ffff88021db38390
cpuhp_thread_fun cpu=5 state=176 bringup=1 node=ffff88021db38390
cpuhp_invoke_callback multi-single cpu=5 state=176 node=ffff88021db38390
cpuhp_thread_fun result=0
cpuhp_issue_call state=176 node=ffff88021db38390
cpuhp_thread_fun cpu=6 state=176 bringup=1 node=ffff88021db38390
cpuhp_invoke_callback multi-single cpu=6 state=176 node=ffff88021db38390
cpuhp_thread_fun result=0
cpuhp_issue_call state=176 node=ffff88021db38390
cpuhp_thread_fun cpu=7 state=176 bringup=1 node=ffff88021db38390
cpuhp_invoke_callback multi-single cpu=7 state=176 node=ffff88021db38390
cpuhp_thread_fun result=0
cpuhp added state=176 node=ffff88021db38390
... etc ..
As you can see the node belonging to the i915 client is passed to all other
registered callbacks. (Due how cpuhp_thread_fun calls cpuhp_invoke_callback
with a set st->node, which then takes a different path in the latter.)
When another multi-instance client, like for example padata (via pcrypt),
is present, it will use the wrong pointer to dereference it's internal data
structure.
In this particular case I have ensured our client is the last to register
by re-loading it after boot. But I guess the same could happen depending on
the order of registrations during boot.
I can workaround around this in i915 by registering, and immediately
unregistering a dummy state, after the real one has been registered. This
action ensures the st->node field gets cleared.
If desired I could try to cook up a simple reproducer module? Or perhaps
it is immediately obvious to people experienced in this area what is
happening?
Kind regards,
Tvrtko
next reply other threads:[~2017-10-20 17:37 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-10-20 17:37 Tvrtko Ursulin [this message]
2017-10-20 18:14 ` Possible bug in CPU hotplug handling (4.14.0-rc5) Thomas Gleixner
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=64e7e66f-a90b-eaa8-de70-51a8d907b5b4@ursulin.net \
--to=tursulin@ursulin.net \
--cc=bigeasy@linutronix.de \
--cc=boris.ostrovsky@oracle.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=paulmck@linux.vnet.ibm.com \
--cc=peterz@infradead.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox