• Robin Murphy's avatar
    iommu/io-pgtable-arm: Improve split_blk_unmap · fb3a9579
    Robin Murphy authored
    The current split_blk_unmap implementation suffers from some inscrutable
    pointer trickery for creating the tables to replace the block entry, but
    more than that it also suffers from hideous inefficiency. For example,
    the most pathological case of unmapping a level 3 page from a level 1
    block will allocate 513 lower-level tables to remap the entire block at
    page granularity, when only 2 are actually needed (the rest can be
    covered by level 2 block entries).
    
    Also, we would like to be able to relax the spinlock requirement in
    future, for which the roll-back-and-try-again logic for race resolution
    would be pretty hideous under the current paradigm.
    
    Both issues can be resolved most neatly by turning things sideways:
    instead of repeatedly recursing into __arm_lpae_map() map to build up an
    entire new sub-table depth-first, we can directly replace the block
    entry with a next-level table of block/page entries, then repeat by
    unmapping at the next level if necessary. With a little refactoring of
    some helper functions, the code ends up not much bigger than before, but
    considerably easier to follow and to adapt in future.
    Signed-off-by: default avatarRobin Murphy <robin.murphy@arm.com>
    Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
    fb3a9579
io-pgtable-arm.c 28.4 KB