On 09/12/24 15:42, Petr Tesarik wrote:
On Mon, 9 Dec 2024 13:12:49 +0100 Peter Zijlstra peterz@infradead.org wrote:
On Mon, Dec 09, 2024 at 01:04:43PM +0100, Valentin Schneider wrote:
But I wonder what exactly was the original scenario encountered by Valentin. I mean, if TLB entry invalidations were necessary to sync changes to kernel text after flipping a static branch, then it might be less overhead to make a list of affected pages and call INVLPG on them.
No; TLB is not involved with text patching (on x86).
Valentin, do you happen to know?
So from my experimentation (hackbench + kernel compilation on housekeeping CPUs, dummy while(1) userspace loop on isolated CPUs), the TLB flushes only occurred from vunmap() - mainly from all the hackbench threads coming and going.
Right, we have virtually mapped stacks.
Wait... Are you talking about the kernel stac? But that's only 4 pages (or 8 pages with KASAN), so that should be easily handled with INVLPG. No CR4 dances are needed for that.
What am I missing?
So the gist of the IPI deferral thing is to coalesce IPI callbacks into a single flag value that is read & acted on upon kernel entry. Freeing a task's kernel stack is not the only thing that can issue a vunmap(), so instead of tracking all the pages affected by the unmap (which is potentially an ever-growing memory leak as long as no kernel entry happens on the isolated CPUs), we just flush everything.
Quick tracing with my dummy benchmark mostly shows
vfree_atomic() -> drain_vmap_work()
but pretty much any vfree() / kvfree_rcu() from the housekeeping CPUs can get us that IPI.