Re: x86/mce: machine check warning during poweroff
From: Greg KH
Date: Mon Jan 16 2012 - 13:11:51 EST
On Sat, Jan 14, 2012 at 06:49:38AM -0800, Greg KH wrote:
> On Fri, Jan 13, 2012 at 06:53:04PM -0800, Linus Torvalds wrote:
> > On Fri, Jan 13, 2012 at 6:41 PM, Srivatsa S. Bhat
> > <srivatsa.bhat@xxxxxxxxxxxxxxxxxx> wrote:
> > >
> > > YES!! Finally I have a fix for this whole MCE thing! :-)
> >
> > Goodie.
> >
> > > The patch below works perfectly for me - I tested multiple CPU hotplug
> > > operations as well as multiple pm_test runs at core level. Please let me
> > > know if this solves the suspend issue as well..
> >
> > Ok, I'll try, and I bet it does.
> >
> > HOWEVER.
> >
> > I'd be a whole lot happier knowing exactly which field in "struct
> > device" that needed to be NULL before it gets registered.
> >
> > I don't like how
> >
> > device_register() + device_create_file(dev)..
> >
> > is not sufficiently undone by
> >
> > .. device_remove_file(dev) + device_unregister()
> >
> > so that it can't be repeated. Exactly *what* state is stale and
> > re-used incorrectly if you do that device_register() a second time.
> >
> > It smells like a misfeature of the device core handling.
>
> It has to do with the fact that this is a "static" device that is being
> reused. Normally it would be cleaned up properly in the release
> function, but as there isn't one, some fields are being left in a bad
> state.
Kay, I looked at this this morning, and it comes down to the line:
DEFINE_PER_CPU(struct device, mce_device);
Where we are creating static struct device variables. I'm guessing this
is just done for "convenience" as we really don't care about where in
memory these structures are, we just want to make sure we have enough of
them around (this is the way all the other mce per-cpu structures are
handled.)
I couldn't figure out a "simple" way to create a variable per cpu here,
dynamically. I tried doing something like:
struct device *mce_device[CONFIG_NR_CPUS];
and dynamically create and clean them up when they go away, setting the
array value to NULL when they are unregistered, and let them clean up in
the release function, but does that race with creating the device again?
It seems that this would work, but I'm probably missing something
obvious here, any ideas?
The "correct" way to fix this up would be to have a per-cpu structure
for all of the different mce things that are created in this driver
(struct device, struct mce, exception counts, work queues, polling
banks, etc.), but that seems pretty messy, and I imagine some of these
want to stay as-is for some performance issues. As I don't know this
code at all, I'm a bit leary to make that kind of change.
thanks,
greg k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/