[PATCH] ARM: tlb: Prevent flushing insane large ranges one by one

Thomas Gleixner tglx at linutronix.de
Wed May 24 08:51:55 PDT 2023


On Wed, May 24 2023 at 11:23, Russell King wrote:
> On Wed, May 24, 2023 at 11:18:12AM +0100, Robin Murphy wrote:
>> > +static inline unsigned int __attribute_const__ read_cpuid_tlbsize(void)
>> > +{
>> > +	return 64 << ((read_cpuid(CPUID_TLBTYPE) >> 1) & 0x03);
>> > +}
>> 
>> This appears to be specific to Cortex-A9 - these bits are
>> implementation-defined, and it looks like on on most other Arm Ltd. CPUs
>> they have no meaning at all, e.g.[1][2][3], but they could still hold some
>> wildly unrelated value on other implementations.

Bah.

> That sucks. I guess we'll need to decode the main CPU ID register and
> have a table, except for Cortex-A9 where we can read the TLB size.
>
> If that's not going to work either, then the MM layer needs to get
> fixed not to be so utterly stupid to request a TLB flush over an
> insanely large range - or people will just have to put up with
> latency sucking on 32-bit ARM platforms.

The problem is that there are legitimate cases for large ranges. Even if
we can provide a list or an array of ranges then due to the batching in
the vmap layer it can end up with a large number of pages to flush.

There is an obviously CPU specific crossover point where

      N * t(single) > t(all) + t(refill)

That needs some perf analysis, but I'd be truly surprised if $N would be
large. On x86 the crossover point is around 32 pages.

Lets just assume 32 pages for that A9 too. That's 128k, which is not an
unreasonable size for large buffers. Though its way under the batching
threshold of the vmalloc code, which scales logarithmicaly with the
number of online cpus:

        fls(num_online_cpus()) * (32UL * 1024 * 1024);

That's 64M, i.e. 16k pages, for 2 CPUs... The reasoning there is that a
single flush all is in sum way cheaper than 16k individual flushes right
at the point of each *free() operation.

Where the vmalloc layer can be less silly, is for the immediate flush
case which only flushes 3 pages, but that wont show up yesterday.

For now (and eventual backporting) the occasional flush all is
definitely a better choice than the current situation.

Thanks,

        tglx



More information about the linux-arm-kernel mailing list