File 0005-Fix-waitq-command-for-Linux-4.13-and-later-kernels.patch of Package crash
From eaf14f852ae79f7745934e213661f1c6abac711e Mon Sep 17 00:00:00 2001
From: Greg Edwards <gedwards@ddn.com>
Date: Wed, 23 Jun 2021 13:50:47 -0600
Subject: [PATCH] Fix 'waitq' command for Linux 4.13 and later kernels
The wait queue structs and members were renamed in 4.13 in commits:
ac6424b981bc ("sched/wait: Rename wait_queue_t => wait_queue_entry_t")
9d9d676f595b ("sched/wait: Standardize internal naming of wait-queue heads")
2055da97389a ("sched/wait: Disambiguate wq_entry->task_list and wq_head->task_list naming")
Add support to the 'waitq' command for these more recent kernels.
[ kh: suppressed compilation warnings ]
Signed-off-by: Greg Edwards <gedwards@ddn.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
---
defs.h | 4 ++++
kernel.c | 27 +++++++++++++++++++++++----
symbols.c | 10 +++++++++-
3 files changed, 36 insertions(+), 5 deletions(-)
diff --git a/defs.h b/defs.h
index 42c8074..6bb00e2 100644
--- a/defs.h
+++ b/defs.h
@@ -2138,6 +2138,9 @@ struct offset_table { /* stash of commonly-used offsets */
long atomic_long_t_counter;
long block_device_bd_device;
long block_device_bd_stats;
+ long wait_queue_entry_private;
+ long wait_queue_head_head;
+ long wait_queue_entry_entry;
};
struct size_table { /* stash of commonly-used sizes */
@@ -2300,6 +2303,7 @@ struct size_table { /* stash of commonly-used sizes */
long printk_info;
long printk_ringbuffer;
long prb_desc;
+ long wait_queue_entry;
};
struct array_table {
diff --git a/kernel.c b/kernel.c
index 528f6ee..e123f76 100644
--- a/kernel.c
+++ b/kernel.c
@@ -615,7 +615,15 @@ kernel_init()
kt->flags |= TVEC_BASES_V1;
STRUCT_SIZE_INIT(__wait_queue, "__wait_queue");
- if (VALID_STRUCT(__wait_queue)) {
+ STRUCT_SIZE_INIT(wait_queue_entry, "wait_queue_entry");
+ if (VALID_STRUCT(wait_queue_entry)) {
+ MEMBER_OFFSET_INIT(wait_queue_entry_private,
+ "wait_queue_entry", "private");
+ MEMBER_OFFSET_INIT(wait_queue_head_head,
+ "wait_queue_head", "head");
+ MEMBER_OFFSET_INIT(wait_queue_entry_entry,
+ "wait_queue_entry", "entry");
+ } else if (VALID_STRUCT(__wait_queue)) {
if (MEMBER_EXISTS("__wait_queue", "task"))
MEMBER_OFFSET_INIT(__wait_queue_task,
"__wait_queue", "task");
@@ -9367,9 +9375,9 @@ dump_waitq(ulong wq, char *wq_name)
struct list_data list_data, *ld;
ulong *wq_list; /* addr of wait queue element */
ulong next_offset; /* next pointer of wq element */
- ulong task_offset; /* offset of task in wq element */
+ ulong task_offset = 0; /* offset of task in wq element */
int cnt; /* # elems on Queue */
- int start_index; /* where to start in wq array */
+ int start_index = -1; /* where to start in wq array */
int i;
ld = &list_data;
@@ -9397,9 +9405,20 @@ dump_waitq(ulong wq, char *wq_name)
ld->list_head_offset = OFFSET(__wait_queue_task_list);
ld->member_offset = next_offset;
+ start_index = 1;
+ } else if (VALID_STRUCT(wait_queue_entry)) {
+ ulong head_offset;
+
+ next_offset = OFFSET(list_head_next);
+ task_offset = OFFSET(wait_queue_entry_private);
+ head_offset = OFFSET(wait_queue_head_head);
+ ld->end = ld->start = wq + head_offset + next_offset;
+ ld->list_head_offset = OFFSET(wait_queue_entry_entry);
+ ld->member_offset = next_offset;
+
start_index = 1;
} else {
- return;
+ error(FATAL, "cannot determine wait queue structures\n");
}
hq_open();
diff --git a/symbols.c b/symbols.c
index 370d4c3..67c135f 100644
--- a/symbols.c
+++ b/symbols.c
@@ -9817,7 +9817,13 @@ dump_offset_table(char *spec, ulong makestruct)
OFFSET(__wait_queue_head_task_list));
fprintf(fp, " __wait_queue_task_list: %ld\n",
OFFSET(__wait_queue_task_list));
-
+ fprintf(fp, " wait_queue_entry_private: %ld\n",
+ OFFSET(wait_queue_entry_private));
+ fprintf(fp, " wait_queue_head_head: %ld\n",
+ OFFSET(wait_queue_head_head));
+ fprintf(fp, " wait_queue_entry_entry: %ld\n",
+ OFFSET(wait_queue_entry_entry));
+
fprintf(fp, " pglist_data_node_zones: %ld\n",
OFFSET(pglist_data_node_zones));
fprintf(fp, " pglist_data_node_mem_map: %ld\n",
@@ -10717,6 +10723,8 @@ dump_offset_table(char *spec, ulong makestruct)
fprintf(fp, " wait_queue: %ld\n", SIZE(wait_queue));
fprintf(fp, " __wait_queue: %ld\n",
SIZE(__wait_queue));
+ fprintf(fp, " wait_queue_entry: %ld\n",
+ SIZE(wait_queue_entry));
fprintf(fp, " device: %ld\n", SIZE(device));
fprintf(fp, " net_device: %ld\n", SIZE(net_device));
--
2.33.1