Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

scripts: fix gfp-translate after ___GFP_*_BITS conversion to an enum

Richard reports that since 772dd0342727c ("mm: enumerate all gfp flags"),
gfp-translate is broken, as the bit numbers are implicit, leaving the
shell script unable to extract them. Even more, some bits are now at a
variable location, making it double extra hard to parse using a simple
shell script.

Use a brute-force approach to the problem by generating a small C stub
that will use the enum to dump the interesting bits.

As an added bonus, we are now able to identify invalid bits for a given
configuration. As an added drawback, we cannot parse include files that
predate this change anymore. Tough luck.

Link: https://lkml.kernel.org/r/20240823163850.3791201-1-maz@kernel.org
Fixes: 772dd0342727 ("mm: enumerate all gfp flags")
Signed-off-by: Marc Zyngier <maz@kernel.org>
Reported-by: Richard Weinberger <richard@nod.at>
Cc: Petr Tesařík <petr@tesarici.cz>
Cc: Suren Baghdasaryan <surenb@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Marc Zyngier and committed by
Andrew Morton
a3f6a89c bfe0857c

+49 -17
+49 -17
scripts/gfp-translate
··· 62 62 fi 63 63 64 64 # Extract GFP flags from the kernel source 65 - TMPFILE=`mktemp -t gfptranslate-XXXXXX` || exit 1 66 - grep -q ___GFP $SOURCE/include/linux/gfp_types.h 67 - if [ $? -eq 0 ]; then 68 - grep "^#define ___GFP" $SOURCE/include/linux/gfp_types.h | sed -e 's/u$//' | grep -v GFP_BITS > $TMPFILE 69 - else 70 - grep "^#define __GFP" $SOURCE/include/linux/gfp_types.h | sed -e 's/(__force gfp_t)//' | sed -e 's/u)/)/' | grep -v GFP_BITS | sed -e 's/)\//) \//' > $TMPFILE 71 - fi 65 + TMPFILE=`mktemp -t gfptranslate-XXXXXX.c` || exit 1 72 66 73 - # Parse the flags 74 - IFS=" 75 - " 76 67 echo Source: $SOURCE 77 68 echo Parsing: $GFPMASK 78 - for LINE in `cat $TMPFILE`; do 79 - MASK=`echo $LINE | awk '{print $3}'` 80 - if [ $(($GFPMASK&$MASK)) -ne 0 ]; then 81 - echo $LINE 82 - fi 83 - done 84 69 85 - rm -f $TMPFILE 70 + ( 71 + cat <<EOF 72 + #include <stdint.h> 73 + #include <stdio.h> 74 + 75 + // Try to fool compiler.h into not including extra stuff 76 + #define __ASSEMBLY__ 1 77 + 78 + #include <generated/autoconf.h> 79 + #include <linux/gfp_types.h> 80 + 81 + static const char *masks[] = { 82 + EOF 83 + 84 + sed -nEe 's/^[[:space:]]+(___GFP_.*)_BIT,.*$/\1/p' $SOURCE/include/linux/gfp_types.h | 85 + while read b; do 86 + cat <<EOF 87 + #if defined($b) && ($b > 0) 88 + [${b}_BIT] = "$b", 89 + #endif 90 + EOF 91 + done 92 + 93 + cat <<EOF 94 + }; 95 + 96 + int main(int argc, char *argv[]) 97 + { 98 + unsigned long long mask = $GFPMASK; 99 + 100 + for (int i = 0; i < sizeof(mask) * 8; i++) { 101 + unsigned long long bit = 1ULL << i; 102 + if (mask & bit) 103 + printf("\t%-25s0x%llx\n", 104 + (i < ___GFP_LAST_BIT && masks[i]) ? 105 + masks[i] : "*** INVALID ***", 106 + bit); 107 + } 108 + 109 + return 0; 110 + } 111 + EOF 112 + ) > $TMPFILE 113 + 114 + ${CC:-gcc} -Wall -o ${TMPFILE}.bin -I $SOURCE/include $TMPFILE && ${TMPFILE}.bin 115 + 116 + rm -f $TMPFILE ${TMPFILE}.bin 117 + 86 118 exit 0