mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2024-12-29 09:12:07 +00:00
scripts: fix gfp-translate after ___GFP_*_BITS conversion to an enum
Richard reports that since772dd03427
("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:772dd03427
("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>
This commit is contained in:
parent
bfe0857c20
commit
a3f6a89c83
@ -62,25 +62,57 @@ if [ "$GFPMASK" = "none" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Extract GFP flags from the kernel source
|
# Extract GFP flags from the kernel source
|
||||||
TMPFILE=`mktemp -t gfptranslate-XXXXXX` || exit 1
|
TMPFILE=`mktemp -t gfptranslate-XXXXXX.c` || exit 1
|
||||||
grep -q ___GFP $SOURCE/include/linux/gfp_types.h
|
|
||||||
if [ $? -eq 0 ]; then
|
|
||||||
grep "^#define ___GFP" $SOURCE/include/linux/gfp_types.h | sed -e 's/u$//' | grep -v GFP_BITS > $TMPFILE
|
|
||||||
else
|
|
||||||
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
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Parse the flags
|
|
||||||
IFS="
|
|
||||||
"
|
|
||||||
echo Source: $SOURCE
|
echo Source: $SOURCE
|
||||||
echo Parsing: $GFPMASK
|
echo Parsing: $GFPMASK
|
||||||
for LINE in `cat $TMPFILE`; do
|
|
||||||
MASK=`echo $LINE | awk '{print $3}'`
|
|
||||||
if [ $(($GFPMASK&$MASK)) -ne 0 ]; then
|
|
||||||
echo $LINE
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
rm -f $TMPFILE
|
(
|
||||||
|
cat <<EOF
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
// Try to fool compiler.h into not including extra stuff
|
||||||
|
#define __ASSEMBLY__ 1
|
||||||
|
|
||||||
|
#include <generated/autoconf.h>
|
||||||
|
#include <linux/gfp_types.h>
|
||||||
|
|
||||||
|
static const char *masks[] = {
|
||||||
|
EOF
|
||||||
|
|
||||||
|
sed -nEe 's/^[[:space:]]+(___GFP_.*)_BIT,.*$/\1/p' $SOURCE/include/linux/gfp_types.h |
|
||||||
|
while read b; do
|
||||||
|
cat <<EOF
|
||||||
|
#if defined($b) && ($b > 0)
|
||||||
|
[${b}_BIT] = "$b",
|
||||||
|
#endif
|
||||||
|
EOF
|
||||||
|
done
|
||||||
|
|
||||||
|
cat <<EOF
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
unsigned long long mask = $GFPMASK;
|
||||||
|
|
||||||
|
for (int i = 0; i < sizeof(mask) * 8; i++) {
|
||||||
|
unsigned long long bit = 1ULL << i;
|
||||||
|
if (mask & bit)
|
||||||
|
printf("\t%-25s0x%llx\n",
|
||||||
|
(i < ___GFP_LAST_BIT && masks[i]) ?
|
||||||
|
masks[i] : "*** INVALID ***",
|
||||||
|
bit);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
) > $TMPFILE
|
||||||
|
|
||||||
|
${CC:-gcc} -Wall -o ${TMPFILE}.bin -I $SOURCE/include $TMPFILE && ${TMPFILE}.bin
|
||||||
|
|
||||||
|
rm -f $TMPFILE ${TMPFILE}.bin
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
Loading…
Reference in New Issue
Block a user