[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v2 0/7] Nesting support for lazy MMU mode
On 09/09/2025 11:21, David Hildenbrand wrote: > On 09.09.25 04:16, Andrew Morton wrote: >> On Mon, 8 Sep 2025 08:39:24 +0100 Kevin Brodsky >> <kevin.brodsky@xxxxxxx> wrote: >> >>> The main change enabling nesting is patch 2, following the approach >>> suggested by Catalin Marinas [4]: have enter() return some state and >>> the matching leave() take that state. >> >> This is so totally the correct way. Thanks. > > Staring at this, I wonder if we could alternatively handle it like > pagefault_disable()/pagefault_enable(), having something like > current->lazy_mmu_enabled. > > We wouldn't have to worry about preemption in that case I guess > (unless the arch has special requirements). > > Not sure if that was already discussed, just a thought. Based on the outcome of the discussion with David on patch 2 [1p], there is indeed an alternative approach that we should seriously consider. In summary: * Keep the API stateless, handle nesting with a counter in task_struct * Introduce new functions to temporarily disable lazy_mmu without impacting nesting, track that with a bool in task_struct (addresses the situation in mm/kasan/shadow.c and possibly some x86 cases too) * Move as much handling from arch_* to generic functions What the new generic infrastructure would look like: struct task_struct { ... #ifdef CONFIG_ARCH_LAZY_MMU struct { uint8_t count; bool enabled; /* or paused, see below */ } lazy_mmu_state; #endif } * lazy_mmu_mode_enable(): if (!lazy_mmu_state.count) { arch_enter_lazy_mmu_mode(); lazy_mmu_state.enabled = true; } lazy_mmu_state.count++; * lazy_mmu_mode_disable(): lazy_mmu_count--; if (!lazy_mmu_state.count) { lazy_mmu_state.enabled = false; arch_leave_lazy_mmu_mode(); } else { arch_flush_lazy_mmu_mode(); } * lazy_mmu_mode_pause(): lazy_mmu_state.enabled = false; arch_leave_lazy_mmu_mode(); * lazy_mmu_mode_resume(); arch_enter_lazy_mmu_mode(); lazy_mmu_state.enabled = true; The generic enable()/disable() helpers are able to handle most of the logic, leaving only truly arch-specific code to the arch callbacks: * Updating lazy_mmu_state * Sanity checks on lazy_mmu_state (e.g. count underflow/overflow, pause()/resume() only called when count > 0, etc.) * Bailing out if in_interrupt() (not done consistently across arch's at the moment) A further improvement is to make arch code check lazy_mmu_state.enabled to determine whether lazy_mmu is enabled at any given point. At the moment every arch uses a different mechanism, and this is an occasion to make them converge. The arch callback interface remains unchanged, and we are resurrecting arch_flush_lazy_mmu_mode() to handle the nested disable() case (flushing must happen when exiting a section regardless of nesting): enable() -> arch_enter() enable() -> [nothing] disable() -> arch_flush() disable() -> arch_leave() Note: lazy_mmu_state.enabled (set whenever lazy_mmu is actually enabled) could be replaced with lazy_mmu_state.paused (set inside a pause()/resume() section). I believe this is equivalent but the former is slightly more convenient for arch code - to be confirmed in practice. Any thoughts on this? Unless there are concerns, I will move towards that approach in v3. - Kevin [1p] https://lore.kernel.org/all/4aa28016-5678-4c66-8104-8dcc3fa2f5ce@xxxxxxxxxx/t/#u
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |