@@ -577,24 +577,98 @@ netdev_features(void)
577577{
578578}
579579
580+ struct page_flags_test {
581+ int width ;
582+ int shift ;
583+ int mask ;
584+ unsigned long value ;
585+ const char * fmt ;
586+ const char * name ;
587+ };
588+
589+ static struct page_flags_test pft [] = {
590+ {SECTIONS_WIDTH , SECTIONS_PGSHIFT , SECTIONS_MASK ,
591+ 0 , "%d" , "section" },
592+ {NODES_WIDTH , NODES_PGSHIFT , NODES_MASK ,
593+ 0 , "%d" , "node" },
594+ {ZONES_WIDTH , ZONES_PGSHIFT , ZONES_MASK ,
595+ 0 , "%d" , "zone" },
596+ {LAST_CPUPID_WIDTH , LAST_CPUPID_PGSHIFT , LAST_CPUPID_MASK ,
597+ 0 , "%#x" , "lastcpupid" },
598+ {KASAN_TAG_WIDTH , KASAN_TAG_PGSHIFT , KASAN_TAG_MASK ,
599+ 0 , "%#x" , "kasantag" },
600+ };
601+
602+ static void __init
603+ page_flags_test (int section , int node , int zone , int last_cpupid ,
604+ int kasan_tag , int flags , const char * name , char * cmp_buf )
605+ {
606+ unsigned long values [] = {section , node , zone , last_cpupid , kasan_tag };
607+ unsigned long page_flags = 0 ;
608+ unsigned long size = 0 ;
609+ bool append = false;
610+ int i ;
611+
612+ flags &= BIT (NR_PAGEFLAGS ) - 1 ;
613+ if (flags ) {
614+ page_flags |= flags ;
615+ snprintf (cmp_buf + size , BUF_SIZE - size , "%s" , name );
616+ size = strlen (cmp_buf );
617+ #if SECTIONS_WIDTH || NODES_WIDTH || ZONES_WIDTH || \
618+ LAST_CPUPID_WIDTH || KASAN_TAG_WIDTH
619+ /* Other information also included in page flags */
620+ snprintf (cmp_buf + size , BUF_SIZE - size , "|" );
621+ size = strlen (cmp_buf );
622+ #endif
623+ }
624+
625+ /* Set the test value */
626+ for (i = 0 ; i < ARRAY_SIZE (pft ); i ++ )
627+ pft [i ].value = values [i ];
628+
629+ for (i = 0 ; i < ARRAY_SIZE (pft ); i ++ ) {
630+ if (!pft [i ].width )
631+ continue ;
632+
633+ if (append ) {
634+ snprintf (cmp_buf + size , BUF_SIZE - size , "|" );
635+ size = strlen (cmp_buf );
636+ }
637+
638+ page_flags |= (pft [i ].value & pft [i ].mask ) << pft [i ].shift ;
639+ snprintf (cmp_buf + size , BUF_SIZE - size , "%s=" , pft [i ].name );
640+ size = strlen (cmp_buf );
641+ snprintf (cmp_buf + size , BUF_SIZE - size , pft [i ].fmt ,
642+ pft [i ].value & pft [i ].mask );
643+ size = strlen (cmp_buf );
644+ append = true;
645+ }
646+
647+ test (cmp_buf , "%pGp" , & page_flags );
648+ }
649+
580650static void __init
581651flags (void )
582652{
583653 unsigned long flags ;
584- gfp_t gfp ;
585654 char * cmp_buffer ;
655+ gfp_t gfp ;
656+
657+ cmp_buffer = kmalloc (BUF_SIZE , GFP_KERNEL );
658+ if (!cmp_buffer )
659+ return ;
586660
587661 flags = 0 ;
588- test ( "" , "%pGp " , & flags );
662+ page_flags_test ( 0 , 0 , 0 , 0 , 0 , flags , " " , cmp_buffer );
589663
590- /* Page flags should filter the zone id */
591664 flags = 1UL << NR_PAGEFLAGS ;
592- test ( "" , "%pGp " , & flags );
665+ page_flags_test ( 0 , 0 , 0 , 0 , 0 , flags , " " , cmp_buffer );
593666
594667 flags |= 1UL << PG_uptodate | 1UL << PG_dirty | 1UL << PG_lru
595668 | 1UL << PG_active | 1UL << PG_swapbacked ;
596- test ("uptodate|dirty|lru|active|swapbacked" , "%pGp" , & flags );
597-
669+ page_flags_test (1 , 1 , 1 , 0x1fffff , 1 , flags ,
670+ "uptodate|dirty|lru|active|swapbacked" ,
671+ cmp_buffer );
598672
599673 flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC
600674 | VM_DENYWRITE ;
@@ -609,10 +683,6 @@ flags(void)
609683 gfp = __GFP_ATOMIC ;
610684 test ("__GFP_ATOMIC" , "%pGg" , & gfp );
611685
612- cmp_buffer = kmalloc (BUF_SIZE , GFP_KERNEL );
613- if (!cmp_buffer )
614- return ;
615-
616686 /* Any flags not translated by the table should remain numeric */
617687 gfp = ~__GFP_BITS_MASK ;
618688 snprintf (cmp_buffer , BUF_SIZE , "%#lx" , (unsigned long ) gfp );
0 commit comments