powerpc/64s/radix: Optimize flush_tlb_range
authorNicholas Piggin <npiggin@gmail.com>
Tue, 7 Nov 2017 07:53:07 +0000 (18:53 +1100)
committerMichael Ellerman <mpe@ellerman.id.au>
Fri, 10 Nov 2017 10:33:33 +0000 (21:33 +1100)
commitcbf09c837720f72f5e63ab7a2d331ec6cc9a3417
tree7af2917fe54977c8068dcc75d3cfa65fd4638a48
parentd665767e39fa4a9e725f92d77ba2060c5ce273dc
powerpc/64s/radix: Optimize flush_tlb_range

Currently for radix, flush_tlb_range flushes the entire PID, because
the Linux mm code does not tell us about page size here for THP vs
regular pages. This is quite sub-optimal for small mremap / mprotect
/ change_protection.

So implement va range flushes with two flush passes, one for each
page size (regular and THP). The second flush has an order of matnitude
fewer tlbie instructions than the first, so it is a relatively small
additional cost.

There is still room for improvement here with some changes to generic
APIs, particularly if there are mostly THP pages to be invalidated,
the small page flushes could be reduced.

Time to mprotect 1 page of memory (after mmap, touch):
vanilla 2.9us   1.8us
patched 1.2us   1.6us

Time to mprotect 30 pages of memory (after mmap, touch):
vanilla 8.2us   7.2us
patched 6.9us   17.9us

Time to mprotect 34 pages of memory (after mmap, touch):
vanilla 9.1us   8.0us
patched 9.0us   8.0us

34 pages is the point at which the invalidation switches from va
to entire PID, which tlbie can do in a single instruction. This is
why in the case of 30 pages, the new code runs slower for this test.
This is a deliberate tradeoff already present in the unmap and THP
promotion code, the idea is that the benefit from avoiding flushing
entire TLB for this PID on all threads in the system.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
arch/powerpc/mm/tlb-radix.c