• Linus Torvalds's avatar
    mm: avoid gcc complaint about pointer casting · e77d587a
    Linus Torvalds authored
    The migration code ends up temporarily stashing information of the wrong
    type in unused fields of the newly allocated destination folio.  That
    all works fine, but gcc does complain about the pointer type mis-use:
    
        mm/migrate.c: In function ‘__migrate_folio_extract’:
        mm/migrate.c:1050:20: note: randstruct: casting between randomized structure pointer types (ssa): ‘struct anon_vma’ and ‘struct address_space’
    
         1050 |         *anon_vmap = (void *)dst->mapping;
              |         ~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
    
    and gcc is actually right to complain since it really doesn't understand
    that this is a very temporary special case where this is ok.
    
    This could be fixed in different ways by just obfuscating the assignment
    sufficiently that gcc doesn't see what is going on, but the truly
    "proper C" way to do this is by explicitly using a union.
    
    Using unions for type conversions like this is normally hugely ugly and
    syntactically nasty, but this really is one of the few cases where we
    want to make it clear that we're not doing type conversion, we're really
    re-using the value bit-for-bit just using another type.
    
    IOW, this should not become a common pattern, but in this one case using
    that odd union is probably the best way to document to the compiler what
    is conceptually going on here.
    
    [ Side note: there are valid cases where we convert pointers to other
      pointer types, notably the whole "folio vs page" situation, where the
      types actually have fundamental commonalities.
    
      The fact that the gcc note is limited to just randomized structures
      means that we don't see equivalent warnings for those cases, but it
      migth also mean that we miss other cases where we do play these kinds
      of dodgy games, and this kind of explicit conversion might be a good
      idea. ]
    
    I verified that at least for an allmodconfig build on x86-64, this
    generates the exact same code, apart from line numbers and assembler
    comment changes.
    
    Fixes: 64c8902e ("migrate_pages: split unmap_and_move() to _unmap() and _move()")
    Cc: Huang, Ying <ying.huang@intel.com>
    Cc: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    e77d587a
migrate.c 69.1 KB