public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Borislav Petkov <bp@alien8.de>
To: Oleg Nesterov <oleg@redhat.com>
Cc: riel@redhat.com, dave.hansen@linux.intel.com, sbsiddha@gmail.com,
	luto@amacapital.net, tglx@linutronix.de, mingo@kernel.org,
	hpa@zytor.com, fenghua.yu@intel.com, x86@kernel.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH 2/8] x86, fpu: unlazy_fpu: don't do __thread_fpu_end() if use_eager_fpu()
Date: Tue, 17 Feb 2015 13:09:17 +0100	[thread overview]
Message-ID: <20150217120917.GA26165@pd.tnic> (raw)
In-Reply-To: <20150217104730.GA22233@redhat.com>

On Tue, Feb 17, 2015 at 11:47:30AM +0100, Oleg Nesterov wrote:
> On 02/16, Borislav Petkov wrote:
> >
> > On Fri, Feb 06, 2015 at 03:01:59PM -0500, riel@redhat.com wrote:
> > > From: Oleg Nesterov <oleg@redhat.com>
> > >
> > > unlazy_fpu()->__thread_fpu_end() doesn't look right if use_eager_fpu().
> > > Unconditional __thread_fpu_end() is only correct if we know that this
> > > thread can't return to user-mode and use FPU.
> > >
> > > Fortunately it has only 2 callers. fpu_copy() checks use_eager_fpu(),
> > > and init_fpu(current) can be only called by the coredumping thread via
> > > regset->get(). But it is exported to modules, and imo this should be
> > > fixed anyway.
> > >
> > > And if we check use_eager_fpu() we can use __save_fpu() like fpu_copy()
> > > and save_init_fpu() do.
> > >
> > > - It seems that even !use_eager_fpu() case doesn't need the unconditional
> > >   __thread_fpu_end(), we only need it if __save_init_fpu() returns 0.
> >
> > I can follow so far.
> >
> > > - It is still not clear to me if __save_init_fpu() can safely nest with
> > >   another save + restore from __kernel_fpu_begin(). If not, we can use
> > >   kernel_fpu_disable() to fix the race.
> >
> > Well, my primitive understanding would say no, not safely, for the
> > simple reason that we have only one XSAVE state area per thread.
> > However, __kernel_fpu_begin() is called with preemption disabled so ...
> > I guess I'm still not seeing the race.
> 
> This is not about preemption. But let me first say that I do not know
> how the FPU hardware actually works, and I do not understand the FPU
> asm code at all.

Same here :-P

> Let's look at this code
> 
> 	if (__thread_has_fpu(tsk)) {
> 		__save_init_fpu(tsk);	// interrupt -> kernel_fpu_begin()
> 		__thread_fpu_end(tsk);
> 	}
> 
> Suppose that kernel_fpu_begin() from interrupt races with __save_init_fpu()
> in progress. Is this safe? I do not know.

I guess this was the reason for

	WARN_ON_ONCE(!irq_fpu_usable());

in kernel_fpu_begin(). And even that solution is not sufficient. Check
out this thread:

https://lkml.kernel.org/r/tip-baa916f39b50ad91661534652110df40396acda0@git.kernel.org

for similar issues with the current handling of FPU state.

> My concern is that (I think) __save_init_fpu() can save the FPU state _and_
> modify it (say, it can reset some register to default value). This means that
> the nested __save_init_fpu() from __kernel_fpu_begin() can save the modified
> register again to current->thread.fpu.

Oh ok, I see what you mean.

> If my understanding is wrong, then why switch_fpu_prepare() clears .last_cpu
> if __save_init_fpu() returns 0 (which iiuc means that CPU's state does not
> match the saved state) ?

Right, this should be the reason why fpu_save_init() signals intact FPU
state with its retval.

Although I don't know what that XSTATE_FP bit checking is supposed to
mean as manuals say XCR0[0] is always 1. And nothing says that XSAVE
would ever clear it...

But the FNSAVE case, for example and IMHO, says that after FWAIT which
would raise unmasked FPU exceptions and thus clear FPU control register
bits...

Long story short, yeah, we better prevent concurrent __save_init_fpu()
from happening...

> Plus I have other (more vague) concerns...

Same here. :-\

Our FPU code is nuts and misses a lot of comments.

> > Btw, what is kernel_fpu_disable()? Can't find it here.
> 
> It's already in Linus's tree, see
> 
> 14e153ef75eecae8fd0738ffb42120f4962a00cd x86, fpu: Introduce per-cpu in_kernel_fpu state
> 33a3ebdc077fd85f1bf4d4586eea579b297461ae x86, fpu: Don't abuse has_fpu in __kernel_fpu_begin/end()
> 7575637ab293861a799f3bbafe0d8c597389f4e9 x86, fpu: Fix math_state_restore() race with kernel_fpu_begin()

Ah, and I was working on a plain 3.19, that's why I didn't see it. I'll rebase
your patches then.

> And, Borislav, thanks for looking at this!

Sure. Thanks for the patience and explaining stuff to me! :)

-- 
Regards/Gruss,
    Boris.

ECO tip #101: Trim your mails when you reply.
--

  reply	other threads:[~2015-02-17 12:10 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-02-06 20:01 [PATCH 0/8] x86,fpu: various small FPU cleanups and optimizations riel
2015-02-06 20:01 ` [PATCH 1/8] x86, fpu: unlazy_fpu: don't reset thread.fpu_counter riel
2015-02-16 17:04   ` Borislav Petkov
2015-02-16 17:58     ` Rik van Riel
2015-02-16 18:14       ` Oleg Nesterov
2015-02-16 18:16         ` Borislav Petkov
2015-02-19 11:32   ` [tip:x86/fpu] x86/fpu: Don't " tip-bot for Oleg Nesterov
2015-02-06 20:01 ` [PATCH 2/8] x86, fpu: unlazy_fpu: don't do __thread_fpu_end() if use_eager_fpu() riel
2015-02-16 20:25   ` Borislav Petkov
2015-02-17 10:47     ` Oleg Nesterov
2015-02-17 12:09       ` Borislav Petkov [this message]
2015-02-19 11:32   ` [tip:x86/fpu] x86/fpu: Don't " tip-bot for Oleg Nesterov
2015-02-06 20:02 ` [PATCH 3/8] x86, fpu: kill save_init_fpu(), change math_error() to use unlazy_fpu() riel
2015-02-16 21:09   ` Borislav Petkov
2015-02-16 21:30     ` Rik van Riel
2015-02-17 10:58       ` Oleg Nesterov
2015-02-19 11:32   ` [tip:x86/fpu] x86/fpu: Change math_error() to use unlazy_fpu(), kill (now) unused save_init_fpu() tip-bot for Oleg Nesterov
2015-02-06 20:02 ` [PATCH 4/8] x86,fpu: move lazy restore functions up a few lines riel
2015-02-19 11:33   ` [tip:x86/fpu] x86/fpu: Move " tip-bot for Rik van Riel
2015-02-06 20:02 ` [PATCH 5/8] x86,fpu: introduce task_disable_lazy_fpu_restore helper riel
2015-02-19 11:33   ` [tip:x86/fpu] x86/fpu: Introduce task_disable_lazy_fpu_restore() helper tip-bot for Rik van Riel
2015-02-06 20:02 ` [PATCH 6/8] x86,fpu: use an explicit if/else in switch_fpu_prepare riel
2015-02-17  8:44   ` Borislav Petkov
2015-02-19 11:33   ` [tip:x86/fpu] x86/fpu: Use an explicit if/ else in switch_fpu_prepare() tip-bot for Rik van Riel
2015-02-06 20:02 ` [PATCH 7/8] x86,fpu: use disable_task_lazy_fpu_restore helper riel
2015-02-17  9:00   ` Borislav Petkov
2015-02-17 11:04     ` Oleg Nesterov
2015-02-17 12:11       ` Borislav Petkov
2015-02-19 11:34   ` [tip:x86/fpu] x86/fpu: Use task_disable_lazy_fpu_restore() helper tip-bot for Rik van Riel
2015-02-06 20:02 ` [PATCH 8/8] x86,fpu: also check fpu_lazy_restore when use_eager_fpu riel
2015-02-19 11:34   ` [tip:x86/fpu] x86/fpu: Also check fpu_lazy_restore() when use_eager_fpu() tip-bot for Rik van Riel
2015-02-16 15:26 ` [PATCH 0/8] x86,fpu: various small FPU cleanups and optimizations Rik van Riel
2015-02-16 16:00   ` Borislav Petkov

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=20150217120917.GA26165@pd.tnic \
    --to=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=fenghua.yu@intel.com \
    --cc=hpa@zytor.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@amacapital.net \
    --cc=mingo@kernel.org \
    --cc=oleg@redhat.com \
    --cc=riel@redhat.com \
    --cc=sbsiddha@gmail.com \
    --cc=tglx@linutronix.de \
    --cc=x86@kernel.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