Hi,
There seem to have been some churn regarding Perf problems with per-cpu memory
allocation which uses vmalloc. Long story short: faulting NMIs reactivate NMIs
faster than supposed, because x86 re-enables NMIs at the first iret encountered,
which leads to nested NMIs.
x86_32 cannot use vmalloc_sync_all() to sychronize the TLBs from every
processes because the vmalloc area is mapped in a different address space for
each process on this architecture. A second alternative is to duplicate the
per-cpu allocation API to have a variant using kmalloc only. This would lead to
code and API duplication and should probably be kept as last resort. A third
solution to this problem is to make the page fault handler aware of NMIs and
ensure it can be called from this context. This third solution is proposed by
this patchset.
So I'm respinning this patchset which has been sitting for a while, used for
about 1-2 years in the LTTng tree without problems, already tested in a -tip
sub-branch in the past. It uses a ret/popf instruction pair instead of iret when
it detects that a trap handler is nested over an NMI. A second patch takes care
of making the page fault handler nmi-safe by using the cr3 register rather than
accessing ->current, which could be in the middle of being changed by a context
switch.
Thanks,
Mathieu
--
Mathieu Desnoyers
Operating System Efficiency R&D Consultant
EfficiOS Inc.
http://www.efficios.com
> x86_32 cannot use vmalloc_sync_all() to sychronize the TLBs from every
> processes because the vmalloc area is mapped in a different address space for
That doesn't make sense. vmalloc_all_sync() should work on 32bit too.
It just needs to walk all processes and fix up every page table.
-Andi
* Andi Kleen ([email protected]) wrote:
> > x86_32 cannot use vmalloc_sync_all() to sychronize the TLBs from every
> > processes because the vmalloc area is mapped in a different address space for
>
> That doesn't make sense. vmalloc_all_sync() should work on 32bit too.
> It just needs to walk all processes and fix up every page table.
Yeah, I've been taken aback when Tejun told me that a few moments ago. I
initially thought that vmalloc_sync_all() synchronized all page mappings of all
processes on x86_32. But apparently that does not seem to be the case. I'm
adding him in CC.
Thanks,
Mathieu
--
Mathieu Desnoyers
Operating System Efficiency R&D Consultant
EfficiOS Inc.
http://www.efficios.com
On Wed, Jul 14, 2010 at 01:08:05PM -0400, Mathieu Desnoyers wrote:
> * Andi Kleen ([email protected]) wrote:
> > > x86_32 cannot use vmalloc_sync_all() to sychronize the TLBs from every
> > > processes because the vmalloc area is mapped in a different address space for
> >
> > That doesn't make sense. vmalloc_all_sync() should work on 32bit too.
> > It just needs to walk all processes and fix up every page table.
>
> Yeah, I've been taken aback when Tejun told me that a few moments ago. I
> initially thought that vmalloc_sync_all() synchronized all page mappings of all
> processes on x86_32. But apparently that does not seem to be the case. I'm
> adding him in CC.
Well it worked when it was originally written. That was for the case
of a NMI handler in a module. If it doesn't work fix it. I don't
think the NMI-safe fault is really needed with it.
-Andi
Hello,
On 07/14/2010 08:56 PM, Andi Kleen wrote:
> On Wed, Jul 14, 2010 at 01:08:05PM -0400, Mathieu Desnoyers wrote:
>> * Andi Kleen ([email protected]) wrote:
>>>> x86_32 cannot use vmalloc_sync_all() to sychronize the TLBs from
>>>> every processes because the vmalloc area is mapped in a different
>>>> address space for
>>> That doesn't make sense. vmalloc_all_sync() should work on 32bit
>>> too. It just needs to walk all processes and fix up every page
>>> table.
Yeah, vmalloc_sync_all() synchronizes everything by walking every page
table, so it should work. I was saying that just flushing TLB
wouldn't cut it because multiple top level page table entries can be
used to map vmalloc areas. It seems that both 32 and 64bit does that
tho.
Thanks.
--
tejun