diff mbox series

[162/178] mm: page_alloc: dump migrate-failed pages

Message ID 20210430060130.NUadzonOe%akpm@linux-foundation.org (mailing list archive)
State New, archived
Headers show
Series [001/178] arch/ia64/kernel/head.S: remove duplicate include | expand

Commit Message

Andrew Morton April 30, 2021, 6:01 a.m. UTC
From: Minchan Kim <minchan@kernel.org>
Subject: mm: page_alloc: dump migrate-failed pages

Currently, debugging CMA allocation failures is quite limited.  The most
common source of these failures seems to be page migration which doesn't
provide any useful information on the reason of the failure by itself. 
alloc_contig_range can report those failures as it holds a list of
migrate-failed pages.

The information logged by dump_page() has already proven helpful for
debugging allocation issues, like identifying long-term pinnings on
ZONE_MOVABLE or MIGRATE_CMA.

Let's use the dynamic debugging infrastructure, such that we avoid
flooding the logs and creating a lot of noise on frequent
alloc_contig_range() calls.  This information is helpful for debugging
only.

There are two ifdefery conditions to support common dyndbg options:

- CONFIG_DYNAMIC_DEBUG_CORE && DYNAMIC_DEBUG_MODULE
  It aims for supporting the feature with only specific file with
  adding ccflags.

- CONFIG_DYNAMIC_DEBUG
  It aims for supporting the feature with system wide globally.

A simple example to enable the feature:

Admin could enable the dump like this(by default, disabled)

	echo "func alloc_contig_dump_pages +p" > control

Admin could disable it.

	echo "func alloc_contig_dump_pages =_" > control

Detail goes Documentation/admin-guide/dynamic-debug-howto.rst

A concern is utility functions in dump_page use inconsistent
loglevels. In the future, we might want to make the loglevels
used inside dump_page() consistent and eventually rework the way
we log the information here. See [1].

[1] https://lore.kernel.org/linux-mm/YEh4doXvyuRl5BDB@google.com/

Link: https://lkml.kernel.org/r/20210311194042.825152-1-minchan@kernel.org
Signed-off-by: Minchan Kim <minchan@kernel.org>
Reviewed-by: David Hildenbrand <david@redhat.com>
Cc: John Dias <joaodias@google.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: Jason Baron <jbaron@akamai.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 mm/page_alloc.c |   22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

Comments

Jim Cromie May 2, 2021, 3:10 a.m. UTC | #1
On Fri, Apr 30, 2021 at 12:01 AM Andrew Morton
<akpm@linux-foundation.org> wrote:
>
> From: Minchan Kim <minchan@kernel.org>
> Subject: mm: page_alloc: dump migrate-failed pages
>
> Currently, debugging CMA allocation failures is quite limited.  The most
> common source of these failures seems to be page migration which doesn't
> provide any useful information on the reason of the failure by itself.
> alloc_contig_range can report those failures as it holds a list of
> migrate-failed pages.
>
> The information logged by dump_page() has already proven helpful for
> debugging allocation issues, like identifying long-term pinnings on
> ZONE_MOVABLE or MIGRATE_CMA.
>
> Let's use the dynamic debugging infrastructure, such that we avoid
> flooding the logs and creating a lot of noise on frequent
> alloc_contig_range() calls.  This information is helpful for debugging
> only.
>
> There are two ifdefery conditions to support common dyndbg options:
>
> - CONFIG_DYNAMIC_DEBUG_CORE && DYNAMIC_DEBUG_MODULE
>   It aims for supporting the feature with only specific file with
>   adding ccflags.
>
> - CONFIG_DYNAMIC_DEBUG
>   It aims for supporting the feature with system wide globally.
>
> A simple example to enable the feature:
>
> Admin could enable the dump like this(by default, disabled)
>
>         echo "func alloc_contig_dump_pages +p" > control
>
> Admin could disable it.
>
>         echo "func alloc_contig_dump_pages =_" > control
>
> Detail goes Documentation/admin-guide/dynamic-debug-howto.rst
>
> A concern is utility functions in dump_page use inconsistent
> loglevels. In the future, we might want to make the loglevels
> used inside dump_page() consistent and eventually rework the way
> we log the information here. See [1].
>

FWIW, the  "format ^$prefix" specifier allows selection of "classes"
of pr_debugs
examples:
"^drm:kms:" etc
"^drm:" too, for example to set +fmlt across entire subsystem
"gvt:"
"^Lo", "^MID", "^HI"
"^1:", "^2:", "^3:"

all hierarchy / set-creation is applied by authors
diff mbox series

Patch

--- a/mm/page_alloc.c~mm-page_alloc-dump-migrate-failed-pages
+++ a/mm/page_alloc.c
@@ -8497,6 +8497,27 @@  static unsigned long pfn_max_align_up(un
 				pageblock_nr_pages));
 }
 
+#if defined(CONFIG_DYNAMIC_DEBUG) || \
+	(defined(CONFIG_DYNAMIC_DEBUG_CORE) && defined(DYNAMIC_DEBUG_MODULE))
+/* Usage: See admin-guide/dynamic-debug-howto.rst */
+static void alloc_contig_dump_pages(struct list_head *page_list)
+{
+	DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, "migrate failure");
+
+	if (DYNAMIC_DEBUG_BRANCH(descriptor)) {
+		struct page *page;
+
+		dump_stack();
+		list_for_each_entry(page, page_list, lru)
+			dump_page(page, "migration failure");
+	}
+}
+#else
+static inline void alloc_contig_dump_pages(struct list_head *page_list)
+{
+}
+#endif
+
 /* [start, end) must belong to a single zone. */
 static int __alloc_contig_migrate_range(struct compact_control *cc,
 					unsigned long start, unsigned long end)
@@ -8540,6 +8561,7 @@  static int __alloc_contig_migrate_range(
 				NULL, (unsigned long)&mtc, cc->mode, MR_CONTIG_RANGE);
 	}
 	if (ret < 0) {
+		alloc_contig_dump_pages(&cc->migratepages);
 		putback_movable_pages(&cc->migratepages);
 		return ret;
 	}