From 2d27b3694bf0996767b6e5282b9d39784d1524c1 Mon Sep 17 00:00:00 2001
From: Tao Liu <ltao@redhat.com>
Date: Mon, 11 Jul 2022 15:28:25 +0800
Subject: [PATCH 1/2] Skip memcg info in __process_stacktrace for page_owner
backend
Kernel patch set [1] extended page_owner to show memcg information:
Page allocated via order 0, mask 0x0(), pid 1, tgid 1 (swapper/0), ts 158908732 ns, free_ts 0 ns
PFN 4540 type Unmovable Block 8 type Unmovable Flags 0xfffffc0010200(slab|head|node=0|zone=1|lastcpupid=0x1fffff)
register_early_stack+0x28/0x57
init_page_owner+0x1d/0x2f
kernel_init_freeable+0x138/0x1a2
kernel_init+0x16/0x120
Slab cache page
Page allocated via order 0, mask 0x400dc0(GFP_KERNEL_ACCOUNT|__GFP_ZERO), pid 737, tgid 737 (NetworkManager), ts 3964670439 ns, free_ts 3961489285 ns
PFN 11172 type Unmovable Block 21 type Unmovable Flags 0xfffffc0000000(node=0|zone=1|lastcpupid=0x1fffff)
get_page_from_freelist+0x3f0/0x500
__alloc_pages+0xe6/0x230
pte_alloc_one+0x15/0x50
...
asm_exc_page_fault+0x1e/0x30
Charged (via objcg) to memcg NetworkManager.service
"^Slab|^Charged" lines are unexpected for __process_stacktrace.
As a result, error messages as "Page owner stacktrace malformed"
will be output and fail.
This patch fix the issue by skip the memcg info lines when iterating
stacktrace.
[1]: https://lore.kernel.org/all/20220202203036.744010-3-longman@redhat.com/T/#mcd67a65c84092f71efb766d0d509f0e8255d4dc2
Signed-off-by: Tao Liu <ltao@redhat.com>
---
src/backend/page_owner.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/src/backend/page_owner.c b/src/backend/page_owner.c
index f66d77d..156f688 100644
--- a/src/backend/page_owner.c
+++ b/src/backend/page_owner.c
@@ -37,6 +37,23 @@
static char *page_owner_file;
+static char *memcg_info[] = {
+ "Slab cache page",
+ "Charged ",
+};
+
+static int is_memcg_info(char *str)
+{
+ for (int i = 0;
+ i < sizeof(memcg_info) / sizeof(__typeof__(memcg_info[0]));
+ i++) {
+ if (!strncmp(str, memcg_info[i], strlen(memcg_info[i]))) {
+ return true;
+ }
+ }
+ return false;
+}
+
static struct Tracenode* __process_stacktrace(
struct Tracenode *tn, struct PageEvent *pe, char *line, FILE *file)
{
@@ -45,6 +62,7 @@ static struct Tracenode* __process_stacktrace(
int callsite_len;
unsigned long len;
+retry:
if (!fgets(line, MAX_LINE, file)) {
log_error("Page owner file ended unexpectly before stacktrace.\n");
return NULL;
@@ -56,6 +74,9 @@ static struct Tracenode* __process_stacktrace(
return NULL;
}
+ if (is_memcg_info(line))
+ goto retry;
+
/* Empty line, end of a stacktrace */
if (line[0] == '\n' || line[0] == '\r')
return tn;
--
2.33.1