• Fabio M. De Francesco's avatar
    firmware_loader: Replace kmap() with kmap_local_page() · f2d57765
    Fabio M. De Francesco authored
    The use of kmap() is being deprecated in favor of kmap_local_page().
    
    Two main problems with kmap(): (1) It comes with an overhead as mapping
    space is restricted and protected by a global lock for synchronization and
    (2) kmap() also requires global TLB invalidation when the kmap’s pool
    wraps and it might block when the mapping space is fully utilized until a
    slot becomes available.
    
    kmap_local_page() is preferred over kmap() and kmap_atomic(). Where it
    cannot mechanically replace the latters, code refactor should be considered
    (special care must be taken if kernel virtual addresses are aliases in
    different contexts).
    
    With kmap_local_page() the mappings are per thread, CPU local, can take
    page faults, and can be called from any context (including interrupts).
    
    Call kmap_local_page() in firmware_loader wherever kmap() is currently
    used. In firmware_rw() use the helpers copy_{from,to}_page() instead of
    open coding the local mappings + memcpy().
    
    Successfully tested with "firmware" selftests on a QEMU/KVM 32-bits VM
    with 4GB RAM, booting a kernel with HIGHMEM64GB enabled.
    
    Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    Cc: Luis Chamberlain <mcgrof@kernel.org>
    Suggested-by: default avatarIra Weiny <ira.weiny@intel.com>
    Reviewed-by: default avatarTakashi Iwai <tiwai@suse.de>
    Signed-off-by: default avatarFabio M. De Francesco <fmdefrancesco@gmail.com>
    Link: https://lore.kernel.org/r/20220714235030.12732-1-fmdefrancesco@gmail.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    f2d57765
main.c 39.1 KB