Skip to content

Commit b366022

Browse files
torvaldsgregkh
authored andcommitted
mm: avoid gcc complaint about pointer casting
commit e77d587a2c04e82c6a0dffa4a32c874a4029385d upstream. 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: 64c8902ed441 ("migrate_pages: split unmap_and_move() to _unmap() and _move()") Cc: Huang, Ying <[email protected]> Cc: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 23c4cb8 commit b366022

File tree

1 file changed

+8
-2
lines changed

1 file changed

+8
-2
lines changed

mm/migrate.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,19 +1017,25 @@ static int move_to_new_folio(struct folio *dst, struct folio *src,
10171017
* destination folio. This is safe because nobody is using them
10181018
* except us.
10191019
*/
1020+
union migration_ptr {
1021+
struct anon_vma *anon_vma;
1022+
struct address_space *mapping;
1023+
};
10201024
static void __migrate_folio_record(struct folio *dst,
10211025
unsigned long page_was_mapped,
10221026
struct anon_vma *anon_vma)
10231027
{
1024-
dst->mapping = (void *)anon_vma;
1028+
union migration_ptr ptr = { .anon_vma = anon_vma };
1029+
dst->mapping = ptr.mapping;
10251030
dst->private = (void *)page_was_mapped;
10261031
}
10271032

10281033
static void __migrate_folio_extract(struct folio *dst,
10291034
int *page_was_mappedp,
10301035
struct anon_vma **anon_vmap)
10311036
{
1032-
*anon_vmap = (void *)dst->mapping;
1037+
union migration_ptr ptr = { .mapping = dst->mapping };
1038+
*anon_vmap = ptr.anon_vma;
10331039
*page_was_mappedp = (unsigned long)dst->private;
10341040
dst->mapping = NULL;
10351041
dst->private = NULL;

0 commit comments

Comments
 (0)