[PATCH v3 2/7] log: adjust indent and line breaks for log -s
by shogo.matsumoto@fujitsu.com
Signed-off-by: Shogo Matsumoto <shogo.matsumoto(a)fujitsu.com>
---
kernel.c | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/kernel.c b/kernel.c
index 461a5f2..57fe355 100644
--- a/kernel.c
+++ b/kernel.c
@@ -11553,6 +11553,8 @@ dump_audit(void)
error(INFO, "kernel audit log is empty\n");
}
+#define PRINTK_SAFE_SEQ_BUF_INDENT 2
+
static void
__dump_printk_safe_seq_buf(char *buf_name, int msg_flags)
{
@@ -11591,27 +11593,44 @@ __dump_printk_safe_seq_buf(char *buf_name, int msg_flags)
if (len > 0) {
int i, n;
char *p;
+ bool start_of_line;
readmem(buffer_addr + per_cpu_offset, KVADDR,
buffer, buffer_size,
"printk_safe_seq_buf buffer", FAULT_ON_ERROR);
+ start_of_line = true;
n = (len <= buffer_size) ? len : buffer_size;
for (i = 0, p = buffer; i < n; i++, p++) {
+ bool sol = start_of_line;
+ start_of_line = false;
if (*p == 0x1) { //SOH
i++; p++;
+
+ if (!sol)
+ fprintf(fp, "\n");
+
+ fprintf(fp, space(PRINTK_SAFE_SEQ_BUF_INDENT));
+
continue;
} else {
+ if (sol)
+ fprintf(fp, "%s", space(PRINTK_SAFE_SEQ_BUF_INDENT));
+
if (isprint(*p) || isspace(*p)) {
fputc(*p, fp);
+ if (*p == '\n')
+ start_of_line = true;
} else {
fputc('.', fp);
}
}
}
+ if (!start_of_line)
+ fputc('\n', fp);
fputc('\n', fp);
} else {
- fprintf(fp, "(empty)\n\n");
+ fprintf(fp, "%s(empty)\n\n", space(PRINTK_SAFE_SEQ_BUF_INDENT));
}
}
FREEBUF(buffer);
--
2.29.2
2 years, 10 months
[PATCH v3 1/7] log: introduce -s option
by shogo.matsumoto@fujitsu.com
Introduce a new option -s for log command which outputs
unflushed logs of the printk safe buffers
(safe_print_seq/nmi_print_seq) as follows:
PRINTK_SAFE_SEQ_BUF: nmi_print_seq
CPU: 0 ADDR: ffff8ca4fbc19ce0 LEN: 150 MESSAGE_LOST: 0
Uhhuh. NMI received for unknown reason 20 on CPU 0.
Do you have a strange power saving mode enabled?
Dazed and confused, but trying to continue
The buffers are displayed for each CPU. For an empty
buffer, '(empty)' will be printed.
Signed-off-by: Shogo Matsumoto <shogo.matsumoto(a)fujitsu.com>
---
defs.h | 5 +++
kernel.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 111 insertions(+), 1 deletion(-)
diff --git a/defs.h b/defs.h
index b63741c..c26e604 100644
--- a/defs.h
+++ b/defs.h
@@ -2146,6 +2146,9 @@ struct offset_table { /* stash of commonly-used offsets */
long wait_queue_entry_private;
long wait_queue_head_head;
long wait_queue_entry_entry;
+ long printk_safe_seq_buf_len;
+ long printk_safe_seq_buf_message_lost;
+ long printk_safe_seq_buf_buffer;
};
struct size_table { /* stash of commonly-used sizes */
@@ -2310,6 +2313,7 @@ struct size_table { /* stash of commonly-used sizes */
long prb_desc;
long wait_queue_entry;
long task_struct_state;
+ long printk_safe_seq_buf_buffer;
};
struct array_table {
@@ -5699,6 +5703,7 @@ void dump_log(int);
#define SHOW_LOG_TEXT (0x4)
#define SHOW_LOG_AUDIT (0x8)
#define SHOW_LOG_CTIME (0x10)
+#define SHOW_LOG_SAFE (0x20)
void set_cpu(int);
void clear_machdep_cache(void);
struct stack_hook *gather_text_list(struct bt_info *);
diff --git a/kernel.c b/kernel.c
index 37b7af7..461a5f2 100644
--- a/kernel.c
+++ b/kernel.c
@@ -93,6 +93,7 @@ static void source_tree_init(void);
static ulong dump_audit_skb_queue(ulong);
static ulong __dump_audit(char *);
static void dump_audit(void);
+static void dump_printk_safe_seq_buf(int);
static char *vmcoreinfo_read_string(const char *);
static void check_vmcoreinfo(void);
static int is_pvops_xen(void);
@@ -4998,7 +4999,7 @@ cmd_log(void)
msg_flags = 0;
- while ((c = getopt(argcnt, args, "Ttdma")) != EOF) {
+ while ((c = getopt(argcnt, args, "Ttdmas")) != EOF) {
switch(c)
{
case 'T':
@@ -5016,6 +5017,9 @@ cmd_log(void)
case 'a':
msg_flags |= SHOW_LOG_AUDIT;
break;
+ case 's':
+ msg_flags |= SHOW_LOG_SAFE;
+ break;
default:
argerrs++;
break;
@@ -5047,6 +5051,11 @@ cmd_log(void)
return;
}
+ if (msg_flags & SHOW_LOG_SAFE) {
+ dump_printk_safe_seq_buf(msg_flags);
+ return;
+ }
+
dump_log(msg_flags);
}
@@ -11544,6 +11553,102 @@ dump_audit(void)
error(INFO, "kernel audit log is empty\n");
}
+static void
+__dump_printk_safe_seq_buf(char *buf_name, int msg_flags)
+{
+ int cpu, buffer_size;
+ char *buffer;
+ ulong base_addr, len_addr, message_lost_addr, buffer_addr;
+
+ if (!symbol_exists(buf_name)) {
+ return;
+ }
+
+ base_addr = symbol_value(buf_name);
+ len_addr = base_addr + OFFSET(printk_safe_seq_buf_len)
+ + OFFSET(atomic_t_counter);
+ message_lost_addr = base_addr
+ + OFFSET(printk_safe_seq_buf_message_lost)
+ + OFFSET(atomic_t_counter);
+ buffer_addr = base_addr + OFFSET(printk_safe_seq_buf_buffer);
+ buffer_size = SIZE(printk_safe_seq_buf_buffer);
+ buffer = GETBUF(buffer_size);
+
+ fprintf(fp, "PRINTK_SAFE_SEQ_BUF: %s\n", buf_name);
+ for (cpu = 0; cpu < kt->cpus; cpu++) {
+ int len, message_lost;
+ ulong per_cpu_offset;
+ per_cpu_offset = kt->__per_cpu_offset[cpu];
+
+ readmem(len_addr + per_cpu_offset, KVADDR, &len, sizeof(int),
+ "printk_safe_seq_buf len", FAULT_ON_ERROR);
+ readmem(message_lost_addr + per_cpu_offset, KVADDR,
+ &message_lost, sizeof(int),
+ "printk_safe_seq_buf message_lost", FAULT_ON_ERROR);
+ fprintf(fp, "CPU: %d ADDR: %lx LEN: %d MESSAGE_LOST: %d\n",
+ cpu, base_addr + per_cpu_offset, len, message_lost);
+
+ if (len > 0) {
+ int i, n;
+ char *p;
+
+ readmem(buffer_addr + per_cpu_offset, KVADDR,
+ buffer, buffer_size,
+ "printk_safe_seq_buf buffer", FAULT_ON_ERROR);
+
+ n = (len <= buffer_size) ? len : buffer_size;
+ for (i = 0, p = buffer; i < n; i++, p++) {
+ if (*p == 0x1) { //SOH
+ i++; p++;
+ continue;
+ } else {
+ if (isprint(*p) || isspace(*p)) {
+ fputc(*p, fp);
+ } else {
+ fputc('.', fp);
+ }
+ }
+ }
+ fputc('\n', fp);
+ } else {
+ fprintf(fp, "(empty)\n\n");
+ }
+ }
+ FREEBUF(buffer);
+}
+
+static void
+dump_printk_safe_seq_buf(int msg_flags)
+{
+ if (!STRUCT_EXISTS("printk_safe_seq_buf"))
+ return;
+
+ if (INVALID_SIZE(printk_safe_seq_buf_buffer)) {
+ MEMBER_OFFSET_INIT(printk_safe_seq_buf_len,
+ "printk_safe_seq_buf", "len");
+ MEMBER_OFFSET_INIT(printk_safe_seq_buf_message_lost,
+ "printk_safe_seq_buf", "message_lost");
+ MEMBER_OFFSET_INIT(printk_safe_seq_buf_buffer,
+ "printk_safe_seq_buf", "buffer");
+
+ if (!INVALID_MEMBER(printk_safe_seq_buf_buffer)) {
+ MEMBER_SIZE_INIT(printk_safe_seq_buf_buffer,
+ "printk_safe_seq_buf", "buffer");
+ }
+ }
+
+ if (INVALID_MEMBER(printk_safe_seq_buf_len) ||
+ INVALID_MEMBER(printk_safe_seq_buf_message_lost) ||
+ INVALID_MEMBER(printk_safe_seq_buf_buffer) ||
+ INVALID_SIZE(printk_safe_seq_buf_buffer)) {
+ error(INFO, "-s not supported with this kernel version\n");
+ return;
+ }
+
+ __dump_printk_safe_seq_buf("nmi_print_seq", msg_flags);
+ __dump_printk_safe_seq_buf("safe_print_seq", msg_flags);
+}
+
/*
* Reads a string value from the VMCOREINFO data stored in (live) memory.
*
--
2.29.2
2 years, 10 months
[PATCH v2] GDB: fix completion related libstdc++ assert
by Lianbo Jiang
Currently crash built with some specific flags (-D_GLIBCXX_ASSERTIONS
and etc.) may abort and print the following error when running the gdb
list command or tab-completion of symbols. For example:
crash> l panic
/usr/include/c++/11/string_view:234: ...
Aborted (core dumped)
crash> p "TAB completion"
crash> p /usr/include/c++/11/string_view:234: ...
Aborted (core dumped)
When the name string is null(the length of name is zero), there are
multiple places where array access is out of bounds in the gdb/ada-lang.c
(see ada_fold_name() and ada_lookup_name_info()).
The patch backports these gdb patches:
6a780b676637 ("Fix completion related libstdc++ assert when using -D_GLIBCXX_DEBUG")
2ccee230f830 ("Fix off-by-one error in ada_fold_name")
Signed-off-by: Lianbo Jiang <lijiang(a)redhat.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab(a)nec.com>
---
gdb-10.2.patch | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/gdb-10.2.patch b/gdb-10.2.patch
index 1332b6638028..f5e4c06e6f97 100644
--- a/gdb-10.2.patch
+++ b/gdb-10.2.patch
@@ -1591,3 +1591,34 @@
max += 2;
limit = cols / max;
if (limit != 1 && (limit * max == cols))
+--- gdb-10.2/gdb/ada-lang.c.orig
++++ gdb-10.2/gdb/ada-lang.c
+@@ -997,7 +997,7 @@ ada_fold_name (gdb::string_view name)
+ int len = name.size ();
+ GROW_VECT (fold_buffer, fold_buffer_size, len + 1);
+
+- if (name[0] == '\'')
++ if (!name.empty () && name[0] == '\'')
+ {
+ strncpy (fold_buffer, name.data () + 1, len - 2);
+ fold_buffer[len - 2] = '\000';
+@@ -1006,8 +1006,9 @@ ada_fold_name (gdb::string_view name)
+ {
+ int i;
+
+- for (i = 0; i <= len; i += 1)
++ for (i = 0; i < len; i += 1)
+ fold_buffer[i] = tolower (name[i]);
++ fold_buffer[i] = '\0';
+ }
+
+ return fold_buffer;
+@@ -13596,7 +13597,7 @@ ada_lookup_name_info::ada_lookup_name_info (const lookup_name_info &lookup_name)
+ {
+ gdb::string_view user_name = lookup_name.name ();
+
+- if (user_name[0] == '<')
++ if (!user_name.empty () && user_name[0] == '<')
+ {
+ if (user_name.back () == '>')
+ m_encoded_name
--
2.20.1
2 years, 10 months
[PATCH] Improve the ps performance for vmcores with large number of threads
by Tao Liu
Previously, the ps command will iterate over all threads which
have the same tgid, to accumulate their rss value, in order to
get a thread/process's final rss value as part of the final output.
For non-live systems, the rss accumulation values are identical for
threads which have the same tgid, so there is no need to do the
iteration and accumulation repeatly, thus a lot of readmem calls are
skipped. Otherwise it will be the performance bottleneck if the
vmcores have a large number of threads.
In this patch, the rss accumulation value will be stored in a cache,
next time a thread with the same tgid will take it directly without
the iteration.
For example, we can monitor the performance issue when a vmcore has
~65k processes, most of which are threads for several specific
processes. Without the patch, it will take ~7h for ps command
to finish. With the patch, ps command will finish in 1min.
Signed-off-by: Tao Liu <ltao(a)redhat.com>
---
defs.h | 1 +
memory.c | 67 ++++++++++++++++++++++++++++++--------------------------
task.c | 1 +
3 files changed, 38 insertions(+), 31 deletions(-)
diff --git a/defs.h b/defs.h
index b63741c..55600d5 100644
--- a/defs.h
+++ b/defs.h
@@ -829,6 +829,7 @@ struct task_context { /* context stored for each task */
struct tgid_context { /* tgid and task stored for each task */
ulong tgid;
ulong task;
+ long rss_cache;
};
struct task_table { /* kernel/local task table data */
diff --git a/memory.c b/memory.c
index 5af45fd..b930933 100644
--- a/memory.c
+++ b/memory.c
@@ -4665,7 +4665,7 @@ void
get_task_mem_usage(ulong task, struct task_mem_usage *tm)
{
struct task_context *tc;
- long rss = 0;
+ long rss = 0, rss_cache = 0;
BZERO(tm, sizeof(struct task_mem_usage));
@@ -4730,38 +4730,43 @@ get_task_mem_usage(ulong task, struct task_mem_usage *tm)
(last->tgid == (last + 1)->tgid))
last++;
- while (first <= last)
- {
- /* count 0 -> filepages */
- if (!readmem(first->task +
- OFFSET(task_struct_rss_stat) +
- OFFSET(task_rss_stat_count), KVADDR,
- &sync_rss,
- sizeof(int),
- "task_struct rss_stat MM_FILEPAGES",
- RETURN_ON_ERROR))
- continue;
-
- rss += sync_rss;
-
- /* count 1 -> anonpages */
- if (!readmem(first->task +
- OFFSET(task_struct_rss_stat) +
- OFFSET(task_rss_stat_count) +
- sizeof(int),
- KVADDR, &sync_rss,
- sizeof(int),
- "task_struct rss_stat MM_ANONPAGES",
- RETURN_ON_ERROR))
- continue;
-
- rss += sync_rss;
-
- if (first == last)
- break;
- first++;
+ /* We will use rss_cache only for dumpfile */
+ if (ACTIVE() || last->rss_cache == UNINITIALIZED) {
+ while (first <= last)
+ {
+ /* count 0 -> filepages */
+ if (!readmem(first->task +
+ OFFSET(task_struct_rss_stat) +
+ OFFSET(task_rss_stat_count), KVADDR,
+ &sync_rss,
+ sizeof(int),
+ "task_struct rss_stat MM_FILEPAGES",
+ RETURN_ON_ERROR))
+ continue;
+
+ rss_cache += sync_rss;
+
+ /* count 1 -> anonpages */
+ if (!readmem(first->task +
+ OFFSET(task_struct_rss_stat) +
+ OFFSET(task_rss_stat_count) +
+ sizeof(int),
+ KVADDR, &sync_rss,
+ sizeof(int),
+ "task_struct rss_stat MM_ANONPAGES",
+ RETURN_ON_ERROR))
+ continue;
+
+ rss_cache += sync_rss;
+
+ if (first == last)
+ break;
+ first++;
+ }
+ last->rss_cache = rss_cache;
}
+ rss += last->rss_cache;
tt->last_tgid = last;
}
}
diff --git a/task.c b/task.c
index 263a834..9868a6e 100644
--- a/task.c
+++ b/task.c
@@ -2947,6 +2947,7 @@ add_context(ulong task, char *tp)
tg = tt->tgid_array + tt->running_tasks;
tg->tgid = *tgid_addr;
tg->task = task;
+ tg->rss_cache = UNINITIALIZED;
if (do_verify && !verify_task(tc, do_verify)) {
error(INFO, "invalid task address: %lx\n", tc->task);
--
2.33.1
2 years, 10 months
[PATCH] GDB: fix completion related libstdc++ assert
by Lianbo Jiang
Currently, crash may generate core dump and print the following
error when running the commands "l panic" or "p" TAB completion.
crash> l panic
/usr/include/c++/11/string_view:234: ...
Aborted (core dumped)
crash> p "TAB completion"
crash> p /usr/include/c++/11/string_view:234: ...
Aborted (core dumped)
When the name string is null(the length of name is zero), there
are multiple places where array access is out of bounds in the
gdb/ada-lang.c(see ada_fold_name() and ada_lookup_name_info()).
Signed-off-by: Lianbo Jiang <lijiang(a)redhat.com>
Signed-off-by: Kazuhito Hagio <k-hagio-ab(a)nec.com>
---
gdb-10.2.patch | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/gdb-10.2.patch b/gdb-10.2.patch
index 1332b6638028..16165839b360 100644
--- a/gdb-10.2.patch
+++ b/gdb-10.2.patch
@@ -1591,3 +1591,32 @@
max += 2;
limit = cols / max;
if (limit != 1 && (limit * max == cols))
+--- gdb-10.2/gdb/ada-lang.c.orig
++++ gdb-10.2/gdb/ada-lang.c
+@@ -997,7 +997,7 @@ ada_fold_name (gdb::string_view name)
+ int len = name.size ();
+ GROW_VECT (fold_buffer, fold_buffer_size, len + 1);
+
+- if (name[0] == '\'')
++ if (name.size () > 0 && name[0] == '\'')
+ {
+ strncpy (fold_buffer, name.data () + 1, len - 2);
+ fold_buffer[len - 2] = '\000';
+@@ -1006,7 +1006,7 @@ ada_fold_name (gdb::string_view name)
+ {
+ int i;
+
+- for (i = 0; i <= len; i += 1)
++ for (i = 0; i < len; i++)
+ fold_buffer[i] = tolower (name[i]);
+ }
+
+@@ -13596,7 +13596,7 @@ ada_lookup_name_info::ada_lookup_name_info (const lookup_name_info &lookup_name)
+ {
+ gdb::string_view user_name = lookup_name.name ();
+
+- if (user_name[0] == '<')
++ if (user_name.size () > 0 && user_name[0] == '<')
+ {
+ if (user_name.back () == '>')
+ m_encoded_name
--
2.20.1
2 years, 10 months
[PATCH] Remove ptype command from "ps -t" option to reduce memory and time
by HAGIO KAZUHITO(萩尾 一仁)
With some vmlinux e.g. RHEL9 ones, the first execution of the gdb ptype
command heavily consumes memory and time. The "ps -t" option uses it
in start_time_timespec() and it can be replaced with crash macros.
This can reduce about 1.4 GB memory and 6 seconds time comsumption in
the following test:
$ echo "ps -t" | time crash vmlinux vmcore
Without the patch:
11.60user 0.43system 0:11.94elapsed 100%CPU (0avgtext+0avgdata 1837964maxresident)k
0inputs+400outputs (0major+413636minor)pagefaults 0swaps
With the patch:
5.40user 0.16system 0:05.46elapsed 101%CPU (0avgtext+0avgdata 417896maxresident)k
0inputs+384outputs (0major+41528minor)pagefaults 0swaps
Although the ptype command and similar ones cannot be fully removed,
but removing some of them will make the use of crash safer, especially
for an automatic crash analyzer.
Signed-off-by: Kazuhito Hagio <k-hagio-ab(a)nec.com>
---
task.c | 25 +++++--------------------
1 file changed, 5 insertions(+), 20 deletions(-)
diff --git a/task.c b/task.c
index 263a8344dd94..a79ed0d96fb5 100644
--- a/task.c
+++ b/task.c
@@ -4662,8 +4662,6 @@ show_task_times(struct task_context *tcp, ulong flags)
static int
start_time_timespec(void)
{
- char buf[BUFSIZE];
-
switch(tt->flags & (TIMESPEC | NO_TIMESPEC | START_TIME_NSECS))
{
case TIMESPEC:
@@ -4677,24 +4675,11 @@ start_time_timespec(void)
tt->flags |= NO_TIMESPEC;
- open_tmpfile();
- sprintf(buf, "ptype struct task_struct");
- if (!gdb_pass_through(buf, NULL, GNU_RETURN_ON_ERROR)) {
- close_tmpfile();
- return FALSE;
- }
-
- rewind(pc->tmpfile);
- while (fgets(buf, BUFSIZE, pc->tmpfile)) {
- if (strstr(buf, "start_time;")) {
- if (strstr(buf, "struct timespec")) {
- tt->flags &= ~NO_TIMESPEC;
- tt->flags |= TIMESPEC;
- }
- }
- }
-
- close_tmpfile();
+ if (VALID_MEMBER(task_struct_start_time) &&
+ STREQ(MEMBER_TYPE_NAME("task_struct", "start_time"), "timespec")) {
+ tt->flags &= ~NO_TIMESPEC;
+ tt->flags |= TIMESPEC;
+ }
if ((tt->flags & NO_TIMESPEC) && (SIZE(task_struct_start_time) == 8)) {
tt->flags &= ~NO_TIMESPEC;
--
2.27.0
2 years, 10 months
Ptdump extension module incompatibility with Linux version >=5.5
by Linu Cherian
Hi,
While experimenting ptdump extension module with Kernel version 5.8.x , came across few incompatibility issues.
struct ring_buffer got renamed to struct perf_buffer starting from kernel version 5.5 and seems the latest ptdump extension
available here is https://github.com/crash-utility/crash-extensions/raw/master/ptdump-1.0.7... not updated and still
uses the "struct ring_buffer".
Hence,
"/* array of struct pages for pt buffer */
if(!get_member(struct_ring_buffer, "ring_buffer", "aux_pages",
&aux_pages))
return FALSE;"
was failing in ptdump.c
Few questions.
1. Do we have a extension module maintained somewhere else that supports the later kernels >=5.5
2. How do we usually manage such incompatibility issues (dependency on Kernel structures)?
Was trying to explore the arm64 solution in line with ptdump.
Thanks.
2 years, 10 months
[PATCH] Move the initialization of "boot_date" to task_init()
by Lianbo Jiang
The "boot_date" is initialized conditionally in the cmd_log(), which may
display incorrect "boot_date" value with the following command before
running the "log -T" command:
crash> help -k | grep date
date: Wed Dec 22 13:39:29 IST 2021
boot_date: Thu Jan 1 05:30:00 IST 1970
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The calculation of "boot_date" depends on the HZ value, and the HZ will
be calculated in task_init() at the latest, so let's move it here.
Fixes: c86250bce29f ("Introduction of the "log -T" option...")
Signed-off-by: Lianbo Jiang <lijiang(a)redhat.com>
---
kernel.c | 18 +++---------------
task.c | 10 ++++++++++
2 files changed, 13 insertions(+), 15 deletions(-)
diff --git a/kernel.c b/kernel.c
index 36c57ed501ad..094fe9b2efad 100644
--- a/kernel.c
+++ b/kernel.c
@@ -5025,21 +5025,9 @@ cmd_log(void)
if (argerrs)
cmd_usage(pc->curcmd, SYNOPSIS);
- if (msg_flags & SHOW_LOG_CTIME) {
- if (pc->flags & MINIMAL_MODE) {
- error(WARNING, "the option '-T' is not available in minimal mode\n");
- return;
- }
-
- if (kt->boot_date.tv_sec == 0) {
- ulonglong uptime_jiffies;
- ulong uptime_sec;
-
- get_uptime(NULL, &uptime_jiffies);
- uptime_sec = (uptime_jiffies)/(ulonglong)machdep->hz;
- kt->boot_date.tv_sec = kt->date.tv_sec - uptime_sec;
- kt->boot_date.tv_nsec = 0;
- }
+ if (msg_flags & SHOW_LOG_CTIME && pc->flags & MINIMAL_MODE) {
+ error(WARNING, "the option '-T' is not available in minimal mode\n");
+ return;
}
if (msg_flags & SHOW_LOG_AUDIT) {
diff --git a/task.c b/task.c
index 76e184ae70b1..263a8344dd94 100644
--- a/task.c
+++ b/task.c
@@ -692,6 +692,16 @@ task_init(void)
stack_overflow_check_init();
+ if (machdep->hz) {
+ ulonglong uptime_jiffies;
+ ulong uptime_sec;
+
+ get_uptime(NULL, &uptime_jiffies);
+ uptime_sec = (uptime_jiffies)/(ulonglong)machdep->hz;
+ kt->boot_date.tv_sec = kt->date.tv_sec - uptime_sec;
+ kt->boot_date.tv_nsec = 0;
+ }
+
tt->flags |= TASK_INIT_DONE;
}
--
2.20.1
2 years, 10 months
[PATCH 1/1] memory: Handle struct slab changes in linux-next
by Alexander Egorenkov
Since linux-next commit fe1e19081321 ("mm: Split slab into its own type"),
the struct slab is used for both SLAB and SLUB. Therefore, don't depend
on the non-presence of the struct slab to decide whether SLAB implementation
should be chosen and use the member variable "cpu_slab" of the struct
kmem_cache instead, it should be present only in SLUB.
Signed-off-by: Alexander Egorenkov <egorenar(a)linux.ibm.com>
---
memory.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/memory.c b/memory.c
index 86c02c132890..5af45fd7d834 100644
--- a/memory.c
+++ b/memory.c
@@ -576,7 +576,8 @@ vm_init(void)
STRUCT_SIZE_INIT(cpucache_s, "cpucache_s");
} else if (!VALID_STRUCT(kmem_slab_s) &&
- !VALID_STRUCT(slab_s) &&
+ !VALID_STRUCT(slab_s) &&
+ !MEMBER_EXISTS("kmem_cache", "cpu_slab") &&
(VALID_STRUCT(slab) || (vt->flags & SLAB_OVERLOAD_PAGE))) {
vt->flags |= PERCPU_KMALLOC_V2;
--
2.31.1
2 years, 10 months
[PATCH] Fix for "help -m" option to display correct hz value
by Lianbo Jiang
Kernel commit 3e9a99eba058 ("block/mq-deadline: Rename dd_init_queue()
and dd_exit_queue()") renamed dd_init_queue to dd_init_sched. Without
the patch, the 'help -m' may print incorrect hz value as follows:
crash> help -m | grep hz
hz: 1000 <---The correct hz value on ppc64le machine is 100.
^^^^
Fixes: b93027ce5c75 ("Add alternate HZ calculation using write_expire")
Signed-off-by: Lianbo Jiang <lijiang(a)redhat.com>
---
task.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/task.c b/task.c
index bb6a5da8ad33..e24f06396a6c 100644
--- a/task.c
+++ b/task.c
@@ -440,6 +440,8 @@ task_init(void)
}
} else if ((symbol_exists("dd_init_queue") &&
gdb_set_crash_scope(symbol_value("dd_init_queue"), "dd_init_queue")) ||
+ (symbol_exists("dd_init_sched") &&
+ gdb_set_crash_scope(symbol_value("dd_init_sched"), "dd_init_sched")) ||
(symbol_exists("deadline_init_queue") &&
gdb_set_crash_scope(symbol_value("deadline_init_queue"), "deadline_init_queue"))) {
char buf[BUFSIZE];
--
2.20.1
2 years, 10 months