• Matthew Wilcox (Oracle)'s avatar
    minmax: add in_range() macro · f9bff0e3
    Matthew Wilcox (Oracle) authored
    Patch series "New page table range API", v6.
    
    This patchset changes the API used by the MM to set up page table entries.
    The four APIs are:
    
        set_ptes(mm, addr, ptep, pte, nr)
        update_mmu_cache_range(vma, addr, ptep, nr)
        flush_dcache_folio(folio) 
        flush_icache_pages(vma, page, nr)
    
    flush_dcache_folio() isn't technically new, but no architecture
    implemented it, so I've done that for them.  The old APIs remain around
    but are mostly implemented by calling the new interfaces.
    
    The new APIs are based around setting up N page table entries at once. 
    The N entries belong to the same PMD, the same folio and the same VMA, so
    ptep++ is a legitimate operation, and locking is taken care of for you. 
    Some architectures can do a better job of it than just a loop, but I have
    hesitated to make too deep a change to architectures I don't understand
    well.
    
    One thing I have changed in every architecture is that PG_arch_1 is now a
    per-folio bit instead of a per-page bit when used for dcache clean/dirty
    tracking.  This was something that would have to happen eventually, and it
    makes sense to do it now rather than iterate over every page involved in a
    cache flush and figure out if it needs to happen.
    
    The point of all this is better performance, and Fengwei Yin has measured
    improvement on x86.  I suspect you'll see improvement on your architecture
    too.  Try the new will-it-scale test mentioned here:
    https://lore.kernel.org/linux-mm/20230206140639.538867-5-fengwei.yin@intel.com/
    You'll need to run it on an XFS filesystem and have
    CONFIG_TRANSPARENT_HUGEPAGE set.
    
    This patchset is the basis for much of the anonymous large folio work
    being done by Ryan, so it's received quite a lot of testing over the last
    few months.
    
    
    This patch (of 38):
    
    Determine if a value lies within a range more efficiently (subtraction +
    comparison vs two comparisons and an AND).  It also has useful (under some
    circumstances) behaviour if the range exceeds the maximum value of the
    type.  Convert all the conflicting definitions of in_range() within the
    kernel; some can use the generic definition while others need their own
    definition.
    
    Link: https://lkml.kernel.org/r/20230802151406.3735276-1-willy@infradead.org
    Link: https://lkml.kernel.org/r/20230802151406.3735276-2-willy@infradead.orgSigned-off-by: default avatarMatthew Wilcox (Oracle) <willy@infradead.org>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    f9bff0e3
core.h 5.85 KB