Skip to content

Commit a3f6a89

Browse files
Marc Zyngierakpm00
authored andcommitted
scripts: fix gfp-translate after ___GFP_*_BITS conversion to an enum
Richard reports that since 772dd03 ("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/[email protected] Fixes: 772dd03 ("mm: enumerate all gfp flags") Signed-off-by: Marc Zyngier <[email protected]> Reported-by: Richard Weinberger <[email protected]> Cc: Petr Tesařík <[email protected]> Cc: Suren Baghdasaryan <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent bfe0857 commit a3f6a89

File tree

1 file changed

+49
-17
lines changed

1 file changed

+49
-17
lines changed

scripts/gfp-translate

Lines changed: 49 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -62,25 +62,57 @@ if [ "$GFPMASK" = "none" ]; then
6262
fi
6363

6464
# 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
7266

73-
# Parse the flags
74-
IFS="
75-
"
7667
echo Source: $SOURCE
7768
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
8469

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+
86118
exit 0

0 commit comments

Comments
 (0)