[PATCH] Fix for "bpf -m|-M" options to appropriately display MEMLOCK and UID
by Lianbo Jiang
Kernel commit <80ee81e0403c> ("bpf: Eliminate rlimit-based memory
accounting infra for bpf maps") removed the struct bpf_map_memory
member from struct bpf_map. Without the patch, "bpf -m|-M" options
will print the following errors:
crash> bpf -m 1
ID BPF_MAP BPF_MAP_TYPE MAP_FLAGS
1 ffff96ba41804400 ARRAY 00000000
KEY_SIZE: 4 VALUE_SIZE: 8 MAX_ENTRIES: 64 MEMLOCK: (unknown)
^^^^^^^
NAME: "dist" UID: (unknown)
^^^^^^^
Signed-off-by: Lianbo Jiang <lijiang(a)redhat.com>
---
bpf.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 64 insertions(+), 3 deletions(-)
diff --git a/bpf.c b/bpf.c
index cb6b0ed385f9..d45e9ab9311b 100644
--- a/bpf.c
+++ b/bpf.c
@@ -15,6 +15,7 @@
*/
#include "defs.h"
+#include <stdbool.h>
struct bpf_info {
ulong status;
@@ -63,6 +64,66 @@ static int do_old_idr(int, ulong, struct list_pair *);
#define PROG_VERBOSE (0x40)
#define MAP_VERBOSE (0x80)
+static bool map_is_per_cpu(ulong type)
+{
+ /*
+ * See the definition of bpf_map_type:
+ * include/uapi/linux/bpf.h
+ */
+ #define BPF_MAP_TYPE_PERCPU_HASH (5UL)
+ #define BPF_MAP_TYPE_PERCPU_ARRAY (6UL)
+ #define BPF_MAP_TYPE_LRU_PERCPU_HASH (10UL)
+ #define BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE (21UL)
+
+ return type == BPF_MAP_TYPE_PERCPU_HASH ||
+ type == BPF_MAP_TYPE_PERCPU_ARRAY ||
+ type == BPF_MAP_TYPE_LRU_PERCPU_HASH ||
+ type == BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE;
+}
+
+static bool map_is_fd_map(ulong type)
+{
+ /*
+ * See the definition of bpf_map_type:
+ * include/uapi/linux/bpf.h
+ */
+ #define BPF_MAP_TYPE_PROG_ARRAY (3UL)
+ #define BPF_MAP_TYPE_PERF_EVENT_ARRAY (4UL)
+ #define BPF_MAP_TYPE_CGROUP_ARRAY (8UL)
+ #define BPF_MAP_TYPE_ARRAY_OF_MAPS (12UL)
+ #define BPF_MAP_TYPE_HASH_OF_MAPS (13UL)
+
+ return type == BPF_MAP_TYPE_PROG_ARRAY ||
+ type == BPF_MAP_TYPE_PERF_EVENT_ARRAY ||
+ type == BPF_MAP_TYPE_CGROUP_ARRAY ||
+ type == BPF_MAP_TYPE_ARRAY_OF_MAPS ||
+ type == BPF_MAP_TYPE_HASH_OF_MAPS;
+
+}
+
+static ulong bpf_map_memory_size(ulong map_type, ulong vsize, ulong ksize, ulong esize)
+{
+ ulong memsize,valsize;
+ int cpus = 0;
+
+ valsize = vsize;
+
+ if (map_is_fd_map(map_type))
+ valsize = sizeof(ulong);
+
+ if (map_is_per_cpu(map_type)) {
+ cpus = get_cpus_possible();
+ if (!cpus)
+ error(WARNING, "cpu_possible_map does not exist, pissible cpus: %d\n", cpus);
+
+ valsize = roundup(vsize, 8) * cpus;
+ }
+
+ memsize = roundup((ksize + valsize), 8);
+
+ return roundup((esize * memsize), PAGESIZE());
+}
+
void
cmd_bpf(void)
{
@@ -332,7 +393,7 @@ do_bpf(ulong flags, ulong prog_id, ulong map_id, int radix)
{
struct bpf_info *bpf;
int i, c, found, entries, type;
- uint uid, map_pages, key_size, value_size, max_entries;
+ uint uid, map_pages, key_size = 0, value_size = 0, max_entries = 0;
ulong bpf_prog_aux, bpf_func, end_func, addr, insnsi, user;
ulong do_progs, do_maps;
ulonglong load_time;
@@ -603,7 +664,7 @@ do_map_only:
map_pages = UINT(bpf->bpf_map_buf + OFFSET(bpf_map_pages));
fprintf(fp, "%d\n", map_pages * PAGESIZE());
} else
- fprintf(fp, "(unknown)\n");
+ fprintf(fp, "%ld\n", bpf_map_memory_size(type, value_size, key_size, max_entries));
fprintf(fp, " NAME: ");
if (VALID_MEMBER(bpf_map_name)) {
@@ -632,7 +693,7 @@ do_map_only:
else
fprintf(fp, "(unknown)\n");
} else
- fprintf(fp, "(unknown)\n");
+ fprintf(fp, "(unused)\n");
}
if (flags & DUMP_STRUCT) {
--
2.20.1
2 years, 9 months
[PATCH v3 0/7] log: output logs of printk safe buffers
by shogo.matsumoto@fujitsu.com
This patch set introduces -s option for log builtin command to display
printk safe buffers (safe_print_seq/nmi_print_seq) as follows:
===
crash> log -s
PRINTK_SAFE_SEQ_BUF: nmi_print_seq
CPU: 0 ADDR: ffff969d7bc19ce0 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 printk safe buffers are also displayed at the bottom of
'log' output so as not to overlook them.
===
crash> log
...
[nmi_print_seq] Uhhuh. NMI received for unknown reason 20 on CPU 0.
[nmi_print_seq] Do you have a strange power saving mode enabled?
[nmi_print_seq] Dazed and confused, but trying to continue
===
-m and -t options are also supported.
Note that the safe buffer (struct printk_safe_seq_buf) was introduced
in kernel-4.11 (Merge commit 7d91de74436a69c2b78a7a72f1e7f97f8b4396fa)
and removed in kernel-5.15 (93d102f094be9beab28e5afb656c188b16a3793b).
Changes since v2:
- Add support new options -s, -t, -m (Kazu)
- Add help text (Kazu)
[v1]: https://listman.redhat.com/archives/crash-utility/2021-December/msg00031....
[v2]: https://listman.redhat.com/archives/crash-utility/2022-January/msg00004.html
Test program is attached in the above v2 patch e-mail.
Shogo Matsumoto (7):
log: introduce -s option
log: adjust indent and line breaks for log -s
log: append printk safe buffer output to 'log'
log: add support -t option for output of printk safe buffers
log: add support -m for output of printk safe buffers
symbols: add support 'help -o' for printk safe buffers
log: add help text for printk safe buffers
defs.h | 5 ++
help.c | 25 ++++++++-
kernel.c | 159 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
symbols.c | 5 ++
4 files changed, 192 insertions(+), 2 deletions(-)
--
2.29.2
2 years, 9 months
[PATCH] arm64: Use CONFIG_ARM64_VA_BITS to initialize VA_BITS_ACTUAL
by Huang Shijie
For DISKDUMP case, we can get VA_BITS_ACTUAL from CONFIG_ARM64_VA_BITS.
Without this patch, we may have to use "--machdep vabits_actual=48" to
set the VA_BITS_ACTUAL.
Signed-off-by: Huang Shijie <shijie(a)os.amperecomputing.com>
---
arm64.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arm64.c b/arm64.c
index 4f2c2b5..2b3ec02 100644
--- a/arm64.c
+++ b/arm64.c
@@ -4170,6 +4170,12 @@ arm64_calc_VA_BITS(void)
} else if (machdep->machspec->VA_BITS_ACTUAL) {
machdep->machspec->VA_BITS = machdep->machspec->VA_BITS_ACTUAL;
machdep->machspec->VA_START = _VA_START(machdep->machspec->VA_BITS_ACTUAL);
+ } else if (pc->flags & DISKDUMP) {
+ if (machdep->machspec->CONFIG_ARM64_VA_BITS) {
+ machdep->machspec->VA_BITS_ACTUAL = machdep->machspec->CONFIG_ARM64_VA_BITS;
+ machdep->machspec->VA_BITS = machdep->machspec->CONFIG_ARM64_VA_BITS;
+ machdep->machspec->VA_START = _VA_START(machdep->machspec->VA_BITS_ACTUAL);
+ }
} else
error(FATAL, "cannot determine VA_BITS_ACTUAL\n");
}
--
2.30.2
2 years, 9 months
Re: [Crash-utility] [PATCH] Fix for "kmem -s|-S" and "bt -F[F]" on Linux 5.17-rc1
by lijiang
Hi, Kazu
Thank you for the fix. This looks good to me, Applied.
On Thu, Feb 3, 2022 at 1:00 AM <crash-utility-request(a)redhat.com> wrote:
> Date: Wed, 2 Feb 2022 02:14:56 +0000
> From: HAGIO KAZUHITO(?????) <k-hagio-ab(a)nec.com>
> To: "Discussion list for crash utility usage, maintenance and
> development" <crash-utility(a)redhat.com>
> Cc: lijiang <lijiang(a)redhat.com>
> Subject: [Crash-utility] [PATCH] Fix for "kmem -s|-S" and "bt -F[F]"
> on Linux 5.17-rc1
> Message-ID:
> <
> TYYPR01MB6777C8112AA17B711A30B082DD279(a)TYYPR01MB6777.jpnprd01.prod.outlook.com
> >
>
> Content-Type: text/plain; charset="iso-2022-jp"
>
> Since the following kernel commits split slab info from struct page
> into struct slab, crash cannot get several slab related offsets from
> struct page.
>
> d122019bf061 ("mm: Split slab into its own type")
> 07f910f9b729 ("mm: Remove slab from struct page")
>
> Without the patch, "kmem -s|-S" and "bt -F[F]" options cannot work
> correctly with the following errors:
>
> crash> kmem -s kmem_cache
> CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME
> kmem: page_to_nid: invalid page: ffff9454afc35020
> kmem: kmem_cache: cannot gather relevant slab data
> ffff945140042000 216 ? ? ? 8k kmem_cache
>
> crash> bt -F
> ...
> bt: invalid structure member offset: page_slab
> FILE: memory.c LINE: 9477 FUNCTION: vaddr_to_kmem_cache()
>
> Signed-by: Kazuhito Hagio <k-hagio-ab(a)nec.com>
> ---
> memory.c | 13 +++++++++++++
> 1 file changed, 13 insertions(+)
>
> diff --git a/memory.c b/memory.c
> index e80c59ea4534..8448ddc3a16c 100644
> --- a/memory.c
> +++ b/memory.c
> @@ -421,6 +421,8 @@ vm_init(void)
> MEMBER_OFFSET_INIT(page_prev, "page", "prev");
> if (INVALID_MEMBER(page_next))
> ANON_MEMBER_OFFSET_INIT(page_next, "page", "next");
> + if (INVALID_MEMBER(page_next))
> + MEMBER_OFFSET_INIT(page_next, "slab", "next");
>
> MEMBER_OFFSET_INIT(page_list, "page", "list");
> if (VALID_MEMBER(page_list)) {
> @@ -747,11 +749,15 @@ vm_init(void)
> MEMBER_OFFSET_INIT(kmem_cache_random, "kmem_cache",
> "random");
> MEMBER_OFFSET_INIT(kmem_cache_cpu_freelist,
> "kmem_cache_cpu", "freelist");
> MEMBER_OFFSET_INIT(kmem_cache_cpu_page, "kmem_cache_cpu",
> "page");
> + if (INVALID_MEMBER(kmem_cache_cpu_page))
> + MEMBER_OFFSET_INIT(kmem_cache_cpu_page,
> "kmem_cache_cpu", "slab");
> MEMBER_OFFSET_INIT(kmem_cache_cpu_node, "kmem_cache_cpu",
> "node");
> MEMBER_OFFSET_INIT(kmem_cache_cpu_partial,
> "kmem_cache_cpu", "partial");
> MEMBER_OFFSET_INIT(page_inuse, "page", "inuse");
> if (INVALID_MEMBER(page_inuse))
> ANON_MEMBER_OFFSET_INIT(page_inuse, "page",
> "inuse");
> + if (INVALID_MEMBER(page_inuse))
> + MEMBER_OFFSET_INIT(page_inuse, "slab", "inuse");
> MEMBER_OFFSET_INIT(page_offset, "page", "offset");
> if (INVALID_MEMBER(page_offset))
> ANON_MEMBER_OFFSET_INIT(page_offset, "page",
> "offset");
> @@ -763,6 +769,9 @@ vm_init(void)
> if (INVALID_MEMBER(page_slab))
> ANON_MEMBER_OFFSET_INIT(page_slab, "page",
> "slab_cache");
> }
> + if (INVALID_MEMBER(page_slab))
> + MEMBER_OFFSET_INIT(page_slab, "slab",
> "slab_cache");
> +
> MEMBER_OFFSET_INIT(page_slab_page, "page", "slab_page");
> if (INVALID_MEMBER(page_slab_page))
> ANON_MEMBER_OFFSET_INIT(page_slab_page, "page",
> "slab_page");
> @@ -772,10 +781,14 @@ vm_init(void)
> MEMBER_OFFSET_INIT(page_freelist, "page", "freelist");
> if (INVALID_MEMBER(page_freelist))
> ANON_MEMBER_OFFSET_INIT(page_freelist, "page",
> "freelist");
> + if (INVALID_MEMBER(page_freelist))
> + MEMBER_OFFSET_INIT(page_freelist, "slab",
> "freelist");
> if (INVALID_MEMBER(kmem_cache_objects)) {
> MEMBER_OFFSET_INIT(kmem_cache_oo, "kmem_cache",
> "oo");
> /* NOTE: returns offset of containing bitfield */
> ANON_MEMBER_OFFSET_INIT(page_objects, "page",
> "objects");
> + if (INVALID_MEMBER(page_objects))
> + ANON_MEMBER_OFFSET_INIT(page_objects,
> "slab", "objects");
> }
> if (VALID_MEMBER(kmem_cache_node)) {
> ARRAY_LENGTH_INIT(len, NULL, "kmem_cache.node",
> NULL, 0);
> --
> 2.27.0
>
>
>
>
> ------------------------------
>
> --
> Crash-utility mailing list
> Crash-utility(a)redhat.com
> https://listman.redhat.com/mailman/listinfo/crash-utility
>
> End of Crash-utility Digest, Vol 197, Issue 1
> *********************************************
>
>
2 years, 9 months
how to see local variables in frame
by Vimal Agrawal
Hi,
I don't see any option to see local variables in vmcore using crash
utility. Tried gdb as well. Gdb is not able to dump stack.
(gdb) bt
#0 sysrq_handle_crash (key=99) at drivers/tty/sysrq.c:147
Backtrace stopped: Cannot access memory at address 0xffffb8c6c132fe40
(gdb) x 0xffffb8c6c132fe40
0xffffb8c6c132fe40: Cannot access memory at address 0xffffb8c6c132fe40
(gdb) info reg rsp
rsp 0xffffb8c6c132fe38 0xffffb8c6c132fe38
(gdb)
I have loaded symbols on specific .text, .data and .bss load addresses
using following commands:
> gdb -c kcrash_vmcore
gdb> add-symbol-file ~/crash3/vmlinux 0xffffffff97000000 -s .data
0xffffffff97c00000 -s .bss 0xffffffff97fa5000
I could decode .text and global .data symbols but not stack addresses
and local variables. I have tried enabling CONFIG_FRAME_POINTER and also
tried the latest version of gdb and crash as well but no help.
Can someone please suggest and comment if this is indeed possible with
gdb/crash to decode local variables from vmcore?
Vimal Agrawal
2 years, 9 months
[PATCH] Fix for "kmem -s|-S" and "bt -F[F]" on Linux 5.17-rc1
by HAGIO KAZUHITO(萩尾 一仁)
Since the following kernel commits split slab info from struct page
into struct slab, crash cannot get several slab related offsets from
struct page.
d122019bf061 ("mm: Split slab into its own type")
07f910f9b729 ("mm: Remove slab from struct page")
Without the patch, "kmem -s|-S" and "bt -F[F]" options cannot work
correctly with the following errors:
crash> kmem -s kmem_cache
CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME
kmem: page_to_nid: invalid page: ffff9454afc35020
kmem: kmem_cache: cannot gather relevant slab data
ffff945140042000 216 ? ? ? 8k kmem_cache
crash> bt -F
...
bt: invalid structure member offset: page_slab
FILE: memory.c LINE: 9477 FUNCTION: vaddr_to_kmem_cache()
Signed-by: Kazuhito Hagio <k-hagio-ab(a)nec.com>
---
memory.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/memory.c b/memory.c
index e80c59ea4534..8448ddc3a16c 100644
--- a/memory.c
+++ b/memory.c
@@ -421,6 +421,8 @@ vm_init(void)
MEMBER_OFFSET_INIT(page_prev, "page", "prev");
if (INVALID_MEMBER(page_next))
ANON_MEMBER_OFFSET_INIT(page_next, "page", "next");
+ if (INVALID_MEMBER(page_next))
+ MEMBER_OFFSET_INIT(page_next, "slab", "next");
MEMBER_OFFSET_INIT(page_list, "page", "list");
if (VALID_MEMBER(page_list)) {
@@ -747,11 +749,15 @@ vm_init(void)
MEMBER_OFFSET_INIT(kmem_cache_random, "kmem_cache", "random");
MEMBER_OFFSET_INIT(kmem_cache_cpu_freelist, "kmem_cache_cpu", "freelist");
MEMBER_OFFSET_INIT(kmem_cache_cpu_page, "kmem_cache_cpu", "page");
+ if (INVALID_MEMBER(kmem_cache_cpu_page))
+ MEMBER_OFFSET_INIT(kmem_cache_cpu_page, "kmem_cache_cpu", "slab");
MEMBER_OFFSET_INIT(kmem_cache_cpu_node, "kmem_cache_cpu", "node");
MEMBER_OFFSET_INIT(kmem_cache_cpu_partial, "kmem_cache_cpu", "partial");
MEMBER_OFFSET_INIT(page_inuse, "page", "inuse");
if (INVALID_MEMBER(page_inuse))
ANON_MEMBER_OFFSET_INIT(page_inuse, "page", "inuse");
+ if (INVALID_MEMBER(page_inuse))
+ MEMBER_OFFSET_INIT(page_inuse, "slab", "inuse");
MEMBER_OFFSET_INIT(page_offset, "page", "offset");
if (INVALID_MEMBER(page_offset))
ANON_MEMBER_OFFSET_INIT(page_offset, "page", "offset");
@@ -763,6 +769,9 @@ vm_init(void)
if (INVALID_MEMBER(page_slab))
ANON_MEMBER_OFFSET_INIT(page_slab, "page", "slab_cache");
}
+ if (INVALID_MEMBER(page_slab))
+ MEMBER_OFFSET_INIT(page_slab, "slab", "slab_cache");
+
MEMBER_OFFSET_INIT(page_slab_page, "page", "slab_page");
if (INVALID_MEMBER(page_slab_page))
ANON_MEMBER_OFFSET_INIT(page_slab_page, "page", "slab_page");
@@ -772,10 +781,14 @@ vm_init(void)
MEMBER_OFFSET_INIT(page_freelist, "page", "freelist");
if (INVALID_MEMBER(page_freelist))
ANON_MEMBER_OFFSET_INIT(page_freelist, "page", "freelist");
+ if (INVALID_MEMBER(page_freelist))
+ MEMBER_OFFSET_INIT(page_freelist, "slab", "freelist");
if (INVALID_MEMBER(kmem_cache_objects)) {
MEMBER_OFFSET_INIT(kmem_cache_oo, "kmem_cache", "oo");
/* NOTE: returns offset of containing bitfield */
ANON_MEMBER_OFFSET_INIT(page_objects, "page", "objects");
+ if (INVALID_MEMBER(page_objects))
+ ANON_MEMBER_OFFSET_INIT(page_objects, "slab", "objects");
}
if (VALID_MEMBER(kmem_cache_node)) {
ARRAY_LENGTH_INIT(len, NULL, "kmem_cache.node", NULL, 0);
--
2.27.0
2 years, 9 months