public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/2] Add decoder for GFP masks to tools.
@ 2013-01-08 23:24 Cody P Schafer
  2013-01-08 23:24 ` [PATCH 1/2] gfp: split out defines for gfp flags into seperate header Cody P Schafer
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Cody P Schafer @ 2013-01-08 23:24 UTC (permalink / raw)
  To: LKML; +Cc: Mel Gorman, Andrew Morton

I needed to decode some gfp_masks to debug an oom-killer invocation, and wrote
this tool to avoid doing the decoding manually.

Bad things about this: slightly hacky use of code intended for use with ftrace,
splitting linux/gfp.h into 2 parts.

Good things: No additional places need modification to keep the decoder up to
date, no mistakes from manual gfp_mask decoding.

 include/linux/gfp-flags.h     | 143 +++++++++++++++++++++++++++++++++++++++++
 include/linux/gfp.h           | 144 +-----------------------------------------
 tools/gfp-decode/.gitignore   |   1 +
 tools/gfp-decode/Makefile     |  11 ++++
 tools/gfp-decode/gfp-decode.c |  89 ++++++++++++++++++++++++++
 5 files changed, 245 insertions(+), 143 deletions(-)

---

On the topic of writing Makefiles for tools/*, it would be extremely
convienient if a system was setup which allowed simple specification of final
executable(s) and the objects to compose them rather than having each tool
write a custom Makefile.

For example (potentially):

	TARGETS = gfp-decode
	obj-gfp-decode = gfp-decode.o
	include ../scripts/Makefile.magic


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/2] gfp: split out defines for gfp flags into seperate header
  2013-01-08 23:24 [PATCH 0/2] Add decoder for GFP masks to tools Cody P Schafer
@ 2013-01-08 23:24 ` Cody P Schafer
  2013-01-08 23:24 ` [PATCH 2/2] tools: add gfp mask decoder Cody P Schafer
  2013-01-10 11:36 ` [PATCH 0/2] Add decoder for GFP masks to tools Mel Gorman
  2 siblings, 0 replies; 5+ messages in thread
From: Cody P Schafer @ 2013-01-08 23:24 UTC (permalink / raw)
  To: LKML; +Cc: Mel Gorman, Andrew Morton, Cody P Schafer

Split the current linux/gfp.h into gfp.h and gfp-flags.h
All the defines for flags are placed into gfp-flags.h which is included
from gfp.h

This split allows the use of the defines by userspace tools, such as a
gfp decoder.

Signed-off-by: Cody P Schafer <cody@linux.vnet.ibm.com>
---
 include/linux/gfp-flags.h | 143 +++++++++++++++++++++++++++++++++++++++++++++
 include/linux/gfp.h       | 144 +---------------------------------------------
 2 files changed, 144 insertions(+), 143 deletions(-)
 create mode 100644 include/linux/gfp-flags.h

diff --git a/include/linux/gfp-flags.h b/include/linux/gfp-flags.h
new file mode 100644
index 0000000..572e4c0
--- /dev/null
+++ b/include/linux/gfp-flags.h
@@ -0,0 +1,143 @@
+/* Plain integer GFP bitmasks. Do not use this directly. */
+#define ___GFP_DMA		0x01u
+#define ___GFP_HIGHMEM		0x02u
+#define ___GFP_DMA32		0x04u
+#define ___GFP_MOVABLE		0x08u
+#define ___GFP_WAIT		0x10u
+#define ___GFP_HIGH		0x20u
+#define ___GFP_IO		0x40u
+#define ___GFP_FS		0x80u
+#define ___GFP_COLD		0x100u
+#define ___GFP_NOWARN		0x200u
+#define ___GFP_REPEAT		0x400u
+#define ___GFP_NOFAIL		0x800u
+#define ___GFP_NORETRY		0x1000u
+#define ___GFP_MEMALLOC		0x2000u
+#define ___GFP_COMP		0x4000u
+#define ___GFP_ZERO		0x8000u
+#define ___GFP_NOMEMALLOC	0x10000u
+#define ___GFP_HARDWALL		0x20000u
+#define ___GFP_THISNODE		0x40000u
+#define ___GFP_RECLAIMABLE	0x80000u
+#define ___GFP_KMEMCG		0x100000u
+#define ___GFP_NOTRACK		0x200000u
+#define ___GFP_NO_KSWAPD	0x400000u
+#define ___GFP_OTHER_NODE	0x800000u
+#define ___GFP_WRITE		0x1000000u
+/* If the above are modified, __GFP_BITS_SHIFT may need updating */
+
+/*
+ * GFP bitmasks..
+ *
+ * Zone modifiers (see linux/mmzone.h - low three bits)
+ *
+ * Do not put any conditional on these. If necessary modify the definitions
+ * without the underscores and use them consistently. The definitions here may
+ * be used in bit comparisons.
+ */
+#define __GFP_DMA	((__force gfp_t)___GFP_DMA)
+#define __GFP_HIGHMEM	((__force gfp_t)___GFP_HIGHMEM)
+#define __GFP_DMA32	((__force gfp_t)___GFP_DMA32)
+#define __GFP_MOVABLE	((__force gfp_t)___GFP_MOVABLE)  /* Page is movable */
+#define GFP_ZONEMASK	(__GFP_DMA|__GFP_HIGHMEM|__GFP_DMA32|__GFP_MOVABLE)
+/*
+ * Action modifiers - doesn't change the zoning
+ *
+ * __GFP_REPEAT: Try hard to allocate the memory, but the allocation attempt
+ * _might_ fail.  This depends upon the particular VM implementation.
+ *
+ * __GFP_NOFAIL: The VM implementation _must_ retry infinitely: the caller
+ * cannot handle allocation failures.  This modifier is deprecated and no new
+ * users should be added.
+ *
+ * __GFP_NORETRY: The VM implementation must not retry indefinitely.
+ *
+ * __GFP_MOVABLE: Flag that this page will be movable by the page migration
+ * mechanism or reclaimed
+ */
+#define __GFP_WAIT	((__force gfp_t)___GFP_WAIT)	/* Can wait and reschedule? */
+#define __GFP_HIGH	((__force gfp_t)___GFP_HIGH)	/* Should access emergency pools? */
+#define __GFP_IO	((__force gfp_t)___GFP_IO)	/* Can start physical IO? */
+#define __GFP_FS	((__force gfp_t)___GFP_FS)	/* Can call down to low-level FS? */
+#define __GFP_COLD	((__force gfp_t)___GFP_COLD)	/* Cache-cold page required */
+#define __GFP_NOWARN	((__force gfp_t)___GFP_NOWARN)	/* Suppress page allocation failure warning */
+#define __GFP_REPEAT	((__force gfp_t)___GFP_REPEAT)	/* See above */
+#define __GFP_NOFAIL	((__force gfp_t)___GFP_NOFAIL)	/* See above */
+#define __GFP_NORETRY	((__force gfp_t)___GFP_NORETRY) /* See above */
+#define __GFP_MEMALLOC	((__force gfp_t)___GFP_MEMALLOC)/* Allow access to emergency reserves */
+#define __GFP_COMP	((__force gfp_t)___GFP_COMP)	/* Add compound page metadata */
+#define __GFP_ZERO	((__force gfp_t)___GFP_ZERO)	/* Return zeroed page on success */
+#define __GFP_NOMEMALLOC ((__force gfp_t)___GFP_NOMEMALLOC) /* Don't use emergency reserves.
+							 * This takes precedence over the
+							 * __GFP_MEMALLOC flag if both are
+							 * set
+							 */
+#define __GFP_HARDWALL   ((__force gfp_t)___GFP_HARDWALL) /* Enforce hardwall cpuset memory allocs */
+#define __GFP_THISNODE	((__force gfp_t)___GFP_THISNODE)/* No fallback, no policies */
+#define __GFP_RECLAIMABLE ((__force gfp_t)___GFP_RECLAIMABLE) /* Page is reclaimable */
+#define __GFP_NOTRACK	((__force gfp_t)___GFP_NOTRACK)  /* Don't track with kmemcheck */
+
+#define __GFP_NO_KSWAPD	((__force gfp_t)___GFP_NO_KSWAPD)
+#define __GFP_OTHER_NODE ((__force gfp_t)___GFP_OTHER_NODE) /* On behalf of other node */
+#define __GFP_KMEMCG	((__force gfp_t)___GFP_KMEMCG) /* Allocation comes from a memcg-accounted resource */
+#define __GFP_WRITE	((__force gfp_t)___GFP_WRITE)	/* Allocator intends to dirty page */
+
+/*
+ * This may seem redundant, but it's a way of annotating false positives vs.
+ * allocations that simply cannot be supported (e.g. page tables).
+ */
+#define __GFP_NOTRACK_FALSE_POSITIVE (__GFP_NOTRACK)
+
+#define __GFP_BITS_SHIFT 25	/* Room for N __GFP_FOO bits */
+#define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1))
+
+/* This equals 0, but use constants in case they ever change */
+#define GFP_NOWAIT	(GFP_ATOMIC & ~__GFP_HIGH)
+/* GFP_ATOMIC means both !wait (__GFP_WAIT not set) and use emergency pool */
+#define GFP_ATOMIC	(__GFP_HIGH)
+#define GFP_NOIO	(__GFP_WAIT)
+#define GFP_NOFS	(__GFP_WAIT | __GFP_IO)
+#define GFP_KERNEL	(__GFP_WAIT | __GFP_IO | __GFP_FS)
+#define GFP_TEMPORARY	(__GFP_WAIT | __GFP_IO | __GFP_FS | \
+			 __GFP_RECLAIMABLE)
+#define GFP_USER	(__GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HARDWALL)
+#define GFP_HIGHUSER	(__GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HARDWALL | \
+			 __GFP_HIGHMEM)
+#define GFP_HIGHUSER_MOVABLE	(__GFP_WAIT | __GFP_IO | __GFP_FS | \
+				 __GFP_HARDWALL | __GFP_HIGHMEM | \
+				 __GFP_MOVABLE)
+#define GFP_IOFS	(__GFP_IO | __GFP_FS)
+#define GFP_TRANSHUGE	(GFP_HIGHUSER_MOVABLE | __GFP_COMP | \
+			 __GFP_NOMEMALLOC | __GFP_NORETRY | __GFP_NOWARN | \
+			 __GFP_NO_KSWAPD)
+
+#ifdef CONFIG_NUMA
+#define GFP_THISNODE	(__GFP_THISNODE | __GFP_NOWARN | __GFP_NORETRY)
+#else
+#define GFP_THISNODE	((__force gfp_t)0)
+#endif
+
+/* This mask makes up all the page movable related flags */
+#define GFP_MOVABLE_MASK (__GFP_RECLAIMABLE|__GFP_MOVABLE)
+
+/* Control page allocator reclaim behavior */
+#define GFP_RECLAIM_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_FS|\
+			__GFP_NOWARN|__GFP_REPEAT|__GFP_NOFAIL|\
+			__GFP_NORETRY|__GFP_MEMALLOC|__GFP_NOMEMALLOC)
+
+/* Control slab gfp mask during early boot */
+#define GFP_BOOT_MASK (__GFP_BITS_MASK & ~(__GFP_WAIT|__GFP_IO|__GFP_FS))
+
+/* Control allocation constraints */
+#define GFP_CONSTRAINT_MASK (__GFP_HARDWALL|__GFP_THISNODE)
+
+/* Do not use these with a slab allocator */
+#define GFP_SLAB_BUG_MASK (__GFP_DMA32|__GFP_HIGHMEM|~__GFP_BITS_MASK)
+
+/* Flag - indicates that the buffer will be suitable for DMA.  Ignored on some
+   platforms, used as appropriate on others */
+
+#define GFP_DMA		__GFP_DMA
+
+/* 4GB DMA on some platforms */
+#define GFP_DMA32	__GFP_DMA32
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index 0f615eb..33d79f3 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -9,149 +9,7 @@
 
 struct vm_area_struct;
 
-/* Plain integer GFP bitmasks. Do not use this directly. */
-#define ___GFP_DMA		0x01u
-#define ___GFP_HIGHMEM		0x02u
-#define ___GFP_DMA32		0x04u
-#define ___GFP_MOVABLE		0x08u
-#define ___GFP_WAIT		0x10u
-#define ___GFP_HIGH		0x20u
-#define ___GFP_IO		0x40u
-#define ___GFP_FS		0x80u
-#define ___GFP_COLD		0x100u
-#define ___GFP_NOWARN		0x200u
-#define ___GFP_REPEAT		0x400u
-#define ___GFP_NOFAIL		0x800u
-#define ___GFP_NORETRY		0x1000u
-#define ___GFP_MEMALLOC		0x2000u
-#define ___GFP_COMP		0x4000u
-#define ___GFP_ZERO		0x8000u
-#define ___GFP_NOMEMALLOC	0x10000u
-#define ___GFP_HARDWALL		0x20000u
-#define ___GFP_THISNODE		0x40000u
-#define ___GFP_RECLAIMABLE	0x80000u
-#define ___GFP_KMEMCG		0x100000u
-#define ___GFP_NOTRACK		0x200000u
-#define ___GFP_NO_KSWAPD	0x400000u
-#define ___GFP_OTHER_NODE	0x800000u
-#define ___GFP_WRITE		0x1000000u
-/* If the above are modified, __GFP_BITS_SHIFT may need updating */
-
-/*
- * GFP bitmasks..
- *
- * Zone modifiers (see linux/mmzone.h - low three bits)
- *
- * Do not put any conditional on these. If necessary modify the definitions
- * without the underscores and use them consistently. The definitions here may
- * be used in bit comparisons.
- */
-#define __GFP_DMA	((__force gfp_t)___GFP_DMA)
-#define __GFP_HIGHMEM	((__force gfp_t)___GFP_HIGHMEM)
-#define __GFP_DMA32	((__force gfp_t)___GFP_DMA32)
-#define __GFP_MOVABLE	((__force gfp_t)___GFP_MOVABLE)  /* Page is movable */
-#define GFP_ZONEMASK	(__GFP_DMA|__GFP_HIGHMEM|__GFP_DMA32|__GFP_MOVABLE)
-/*
- * Action modifiers - doesn't change the zoning
- *
- * __GFP_REPEAT: Try hard to allocate the memory, but the allocation attempt
- * _might_ fail.  This depends upon the particular VM implementation.
- *
- * __GFP_NOFAIL: The VM implementation _must_ retry infinitely: the caller
- * cannot handle allocation failures.  This modifier is deprecated and no new
- * users should be added.
- *
- * __GFP_NORETRY: The VM implementation must not retry indefinitely.
- *
- * __GFP_MOVABLE: Flag that this page will be movable by the page migration
- * mechanism or reclaimed
- */
-#define __GFP_WAIT	((__force gfp_t)___GFP_WAIT)	/* Can wait and reschedule? */
-#define __GFP_HIGH	((__force gfp_t)___GFP_HIGH)	/* Should access emergency pools? */
-#define __GFP_IO	((__force gfp_t)___GFP_IO)	/* Can start physical IO? */
-#define __GFP_FS	((__force gfp_t)___GFP_FS)	/* Can call down to low-level FS? */
-#define __GFP_COLD	((__force gfp_t)___GFP_COLD)	/* Cache-cold page required */
-#define __GFP_NOWARN	((__force gfp_t)___GFP_NOWARN)	/* Suppress page allocation failure warning */
-#define __GFP_REPEAT	((__force gfp_t)___GFP_REPEAT)	/* See above */
-#define __GFP_NOFAIL	((__force gfp_t)___GFP_NOFAIL)	/* See above */
-#define __GFP_NORETRY	((__force gfp_t)___GFP_NORETRY) /* See above */
-#define __GFP_MEMALLOC	((__force gfp_t)___GFP_MEMALLOC)/* Allow access to emergency reserves */
-#define __GFP_COMP	((__force gfp_t)___GFP_COMP)	/* Add compound page metadata */
-#define __GFP_ZERO	((__force gfp_t)___GFP_ZERO)	/* Return zeroed page on success */
-#define __GFP_NOMEMALLOC ((__force gfp_t)___GFP_NOMEMALLOC) /* Don't use emergency reserves.
-							 * This takes precedence over the
-							 * __GFP_MEMALLOC flag if both are
-							 * set
-							 */
-#define __GFP_HARDWALL   ((__force gfp_t)___GFP_HARDWALL) /* Enforce hardwall cpuset memory allocs */
-#define __GFP_THISNODE	((__force gfp_t)___GFP_THISNODE)/* No fallback, no policies */
-#define __GFP_RECLAIMABLE ((__force gfp_t)___GFP_RECLAIMABLE) /* Page is reclaimable */
-#define __GFP_NOTRACK	((__force gfp_t)___GFP_NOTRACK)  /* Don't track with kmemcheck */
-
-#define __GFP_NO_KSWAPD	((__force gfp_t)___GFP_NO_KSWAPD)
-#define __GFP_OTHER_NODE ((__force gfp_t)___GFP_OTHER_NODE) /* On behalf of other node */
-#define __GFP_KMEMCG	((__force gfp_t)___GFP_KMEMCG) /* Allocation comes from a memcg-accounted resource */
-#define __GFP_WRITE	((__force gfp_t)___GFP_WRITE)	/* Allocator intends to dirty page */
-
-/*
- * This may seem redundant, but it's a way of annotating false positives vs.
- * allocations that simply cannot be supported (e.g. page tables).
- */
-#define __GFP_NOTRACK_FALSE_POSITIVE (__GFP_NOTRACK)
-
-#define __GFP_BITS_SHIFT 25	/* Room for N __GFP_FOO bits */
-#define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1))
-
-/* This equals 0, but use constants in case they ever change */
-#define GFP_NOWAIT	(GFP_ATOMIC & ~__GFP_HIGH)
-/* GFP_ATOMIC means both !wait (__GFP_WAIT not set) and use emergency pool */
-#define GFP_ATOMIC	(__GFP_HIGH)
-#define GFP_NOIO	(__GFP_WAIT)
-#define GFP_NOFS	(__GFP_WAIT | __GFP_IO)
-#define GFP_KERNEL	(__GFP_WAIT | __GFP_IO | __GFP_FS)
-#define GFP_TEMPORARY	(__GFP_WAIT | __GFP_IO | __GFP_FS | \
-			 __GFP_RECLAIMABLE)
-#define GFP_USER	(__GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HARDWALL)
-#define GFP_HIGHUSER	(__GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HARDWALL | \
-			 __GFP_HIGHMEM)
-#define GFP_HIGHUSER_MOVABLE	(__GFP_WAIT | __GFP_IO | __GFP_FS | \
-				 __GFP_HARDWALL | __GFP_HIGHMEM | \
-				 __GFP_MOVABLE)
-#define GFP_IOFS	(__GFP_IO | __GFP_FS)
-#define GFP_TRANSHUGE	(GFP_HIGHUSER_MOVABLE | __GFP_COMP | \
-			 __GFP_NOMEMALLOC | __GFP_NORETRY | __GFP_NOWARN | \
-			 __GFP_NO_KSWAPD)
-
-#ifdef CONFIG_NUMA
-#define GFP_THISNODE	(__GFP_THISNODE | __GFP_NOWARN | __GFP_NORETRY)
-#else
-#define GFP_THISNODE	((__force gfp_t)0)
-#endif
-
-/* This mask makes up all the page movable related flags */
-#define GFP_MOVABLE_MASK (__GFP_RECLAIMABLE|__GFP_MOVABLE)
-
-/* Control page allocator reclaim behavior */
-#define GFP_RECLAIM_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_FS|\
-			__GFP_NOWARN|__GFP_REPEAT|__GFP_NOFAIL|\
-			__GFP_NORETRY|__GFP_MEMALLOC|__GFP_NOMEMALLOC)
-
-/* Control slab gfp mask during early boot */
-#define GFP_BOOT_MASK (__GFP_BITS_MASK & ~(__GFP_WAIT|__GFP_IO|__GFP_FS))
-
-/* Control allocation constraints */
-#define GFP_CONSTRAINT_MASK (__GFP_HARDWALL|__GFP_THISNODE)
-
-/* Do not use these with a slab allocator */
-#define GFP_SLAB_BUG_MASK (__GFP_DMA32|__GFP_HIGHMEM|~__GFP_BITS_MASK)
-
-/* Flag - indicates that the buffer will be suitable for DMA.  Ignored on some
-   platforms, used as appropriate on others */
-
-#define GFP_DMA		__GFP_DMA
-
-/* 4GB DMA on some platforms */
-#define GFP_DMA32	__GFP_DMA32
+#include <linux/gfp-flags.h>
 
 /* Convert GFP flags to their corresponding migrate type */
 static inline int allocflags_to_migratetype(gfp_t gfp_flags)
-- 
1.8.0.3


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 2/2] tools: add gfp mask decoder
  2013-01-08 23:24 [PATCH 0/2] Add decoder for GFP masks to tools Cody P Schafer
  2013-01-08 23:24 ` [PATCH 1/2] gfp: split out defines for gfp flags into seperate header Cody P Schafer
@ 2013-01-08 23:24 ` Cody P Schafer
  2013-01-10 11:36 ` [PATCH 0/2] Add decoder for GFP masks to tools Mel Gorman
  2 siblings, 0 replies; 5+ messages in thread
From: Cody P Schafer @ 2013-01-08 23:24 UTC (permalink / raw)
  To: LKML; +Cc: Mel Gorman, Andrew Morton, Cody P Schafer, Cody P Schafer

From: Cody P Schafer <jmesmon@gmail.com>

Allows decoding of gfp_masks printed, for example, when the oom-killer
is invoked.

Example usage:

	[    6.464753] kthreadd invoked oom-killer: gfp_mask=0x1000d0, order=1, oom_score_adj=0

	$ ./gfp-decode 0x1000d0
	GFP_KERNEL|GFP_KMEMCG

Internally, it reuses some of the ftrace structure for decoding the
gfp_mask.

Signed-off-by: Cody P Schafer <cody@linux.vnet.ibm.com>
---
 tools/gfp-decode/.gitignore   |  1 +
 tools/gfp-decode/Makefile     | 11 ++++++
 tools/gfp-decode/gfp-decode.c | 89 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 101 insertions(+)
 create mode 100644 tools/gfp-decode/.gitignore
 create mode 100644 tools/gfp-decode/Makefile
 create mode 100644 tools/gfp-decode/gfp-decode.c

diff --git a/tools/gfp-decode/.gitignore b/tools/gfp-decode/.gitignore
new file mode 100644
index 0000000..eca2466
--- /dev/null
+++ b/tools/gfp-decode/.gitignore
@@ -0,0 +1 @@
+/gfp-decode
diff --git a/tools/gfp-decode/Makefile b/tools/gfp-decode/Makefile
new file mode 100644
index 0000000..51f375a
--- /dev/null
+++ b/tools/gfp-decode/Makefile
@@ -0,0 +1,11 @@
+include ../scripts/Makefile.include
+
+all: $(OUTPUT)gfp-decode
+
+CC = $(CROSS_COMPILE)gcc
+ALL_CFLAGS = $(CFLAGS) $(EXTRA_WARNINGS) -Wall -Wextra -I../../include
+
+$(OUTPUT)gfp-decode: gfp-decode.c
+	$(QUIET_CC)$(CC) -o $@ $(ALL_CFLAGS) $(LDFLAGS) $<
+clean:
+	$(RM) $(OUTPUT)gfp-decode
diff --git a/tools/gfp-decode/gfp-decode.c b/tools/gfp-decode/gfp-decode.c
new file mode 100644
index 0000000..4997f22
--- /dev/null
+++ b/tools/gfp-decode/gfp-decode.c
@@ -0,0 +1,89 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "../../include/trace/events/gfpflags.h"
+
+typedef unsigned gfp_t; /* from linux/types.h */
+#define __force
+#include "../../include/linux/gfp-flags.h"
+
+/* taken from linux/ftrace_event.h */
+struct trace_print_flags {
+	unsigned long		mask;
+	const char		*name;
+};
+
+/*
+ * taken from include/trace/ftrace.h
+ * modified to not pass 'p' to ftrace_print_flags_seq().
+ */
+#define __print_flags(flag, delim, flag_array...)			\
+	({								\
+		static const struct trace_print_flags __flags[] =	\
+			{ flag_array, { -1, NULL } };			\
+		ftrace_print_flags_seq(delim, flag, __flags);	\
+	})
+
+/*
+ * taken from kernel/trace/trace_output.c
+ * modified to use standard puts,putc, and printf and remove use of the buffer.
+ */
+static void
+ftrace_print_flags_seq(const char *delim,
+		       unsigned long flags,
+		       const struct trace_print_flags *flag_array)
+{
+	unsigned long mask;
+	const char *str;
+	int i, first = 1;
+
+	for (i = 0;  flag_array[i].name && flags; i++) {
+
+		mask = flag_array[i].mask;
+		if ((flags & mask) != mask)
+			continue;
+
+		str = flag_array[i].name;
+		flags &= ~mask;
+		if (!first && delim)
+			fputs(delim, stdout);
+		else
+			first = 0;
+		fputs(str, stdout);
+	}
+
+	/* check for left over flags */
+	if (flags) {
+		if (!first && delim)
+			fputs(delim, stdout);
+		printf("0x%lx", flags);
+	}
+	putchar('\n');
+}
+
+int main(int argc, char **argv)
+{
+	int i;
+
+	if (argc < 2) {
+		printf("usage: %s <gfp hex mask>..\n", argv[0]);
+		return 1;
+	}
+
+	for (i = 1; i < argc; i++) {
+		char *cur = argv[i];
+		char *r;
+		unsigned long flags;
+		if (cur[0] == '0' && cur[1] == 'x')
+			cur = &cur[2];
+		flags = strtoul(cur, &r, 16);
+		if (*r != '\0') {
+			fprintf(stderr, "skipping arg %d\n", i-1);
+			continue;
+		}
+
+		show_gfp_flags(flags);
+	}
+
+	return 0;
+}
-- 
1.8.0.3


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 0/2] Add decoder for GFP masks to tools.
  2013-01-08 23:24 [PATCH 0/2] Add decoder for GFP masks to tools Cody P Schafer
  2013-01-08 23:24 ` [PATCH 1/2] gfp: split out defines for gfp flags into seperate header Cody P Schafer
  2013-01-08 23:24 ` [PATCH 2/2] tools: add gfp mask decoder Cody P Schafer
@ 2013-01-10 11:36 ` Mel Gorman
  2013-01-10 17:37   ` Cody P Schafer
  2 siblings, 1 reply; 5+ messages in thread
From: Mel Gorman @ 2013-01-10 11:36 UTC (permalink / raw)
  To: Cody P Schafer; +Cc: LKML, Andrew Morton

On Tue, Jan 08, 2013 at 03:24:13PM -0800, Cody P Schafer wrote:
> I needed to decode some gfp_masks to debug an oom-killer invocation, and wrote
> this tool to avoid doing the decoding manually.
> 
> Bad things about this: slightly hacky use of code intended for use with ftrace,
> splitting linux/gfp.h into 2 parts.
> 
> Good things: No additional places need modification to keep the decoder up to
> date, no mistakes from manual gfp_mask decoding.
> 

Any particular reason you did not use scripts/gfp-translate?

$ bash ./scripts/gfp-translate 0x1000d0
Source: /home/mel/git-public/linux-2.6
Parsing: 0x1000d0
#define ___GFP_WAIT		0x10
#define ___GFP_IO		0x40
#define ___GFP_FS		0x80
#define ___GFP_KMEMCG		0x100000

Script is dumb as rocks, requires access to the source code and does not
translate flag combinations into something like GFP_KERNEL but it's usually
sufficient. I'm not pushed either way but if you want to push your tool
then the patch should also delete scripts/gfp-translate.

-- 
Mel Gorman
SUSE Labs

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 0/2] Add decoder for GFP masks to tools.
  2013-01-10 11:36 ` [PATCH 0/2] Add decoder for GFP masks to tools Mel Gorman
@ 2013-01-10 17:37   ` Cody P Schafer
  0 siblings, 0 replies; 5+ messages in thread
From: Cody P Schafer @ 2013-01-10 17:37 UTC (permalink / raw)
  To: Mel Gorman; +Cc: LKML, Andrew Morton

(Sorry Mel, you're getting this twice because I forgot CC's last time)
On 01/10/2013 03:36 AM, Mel Gorman wrote:
> Any particular reason you did not use scripts/gfp-translate?

Because I didn't look hard enough & didn't see it :(

> Script is dumb as rocks, requires access to the source code and does not
> translate flag combinations into something like GFP_KERNEL but it's usually
> sufficient. I'm not pushed either way but if you want to push your tool
> then the patch should also delete scripts/gfp-translate.

No preference. Since we have gfp-translate already in tree, it makes 
sense just to keep using it.



^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2013-01-10 17:39 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-01-08 23:24 [PATCH 0/2] Add decoder for GFP masks to tools Cody P Schafer
2013-01-08 23:24 ` [PATCH 1/2] gfp: split out defines for gfp flags into seperate header Cody P Schafer
2013-01-08 23:24 ` [PATCH 2/2] tools: add gfp mask decoder Cody P Schafer
2013-01-10 11:36 ` [PATCH 0/2] Add decoder for GFP masks to tools Mel Gorman
2013-01-10 17:37   ` Cody P Schafer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox