Kernel analysis utility for live systems, netdump, diskdump, kdump, LKCD or mcore dumpfiles
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

894 lines
34 KiB

commit a10917ba3203aa8b20e2aa1b84dc12c1e17445e1
Author: Dave Anderson <anderson@redhat.com>
Date: Thu Jul 19 13:43:07 2018 -0400
Update for "ps" and "foreach" commands to display and recognize two
new process states, "ID" for the TASK_IDLE macro introduced in
Linux 4.2, and "NE" for the TASK_NEW bit introduced in Linux 4.8.
(k-hagio@ab.jp.nec.com)
diff --git a/help.c b/help.c
index 54bf9b4..83cda7c 100644
--- a/help.c
+++ b/help.c
@@ -837,7 +837,7 @@ char *help_foreach[] = {
" kernel perform the command(s) on all kernel threads.",
" active perform the command(s) on the active thread on each CPU.",
" state perform the command(s) on all tasks in the specified state, which",
-" may be one of: RU, IN, UN, ST, ZO, TR, SW, DE, WA or PA.\n",
+" may be one of: RU, IN, UN, ST, ZO, TR, SW, DE, WA, PA, ID or NE.\n",
" If none of the task-identifying arguments above are entered, the command",
" will be performed on all tasks.\n",
" command select one or more of the following commands to be run on the tasks",
@@ -1292,7 +1292,7 @@ char *help_ps[] = {
" 3. the CPU number that the task ran on last.",
" 4. the task_struct address or the kernel stack pointer of the process.",
" (see -s option below)",
-" 5. the task state (RU, IN, UN, ZO, ST, TR, DE, SW, WA, PA).",
+" 5. the task state (RU, IN, UN, ZO, ST, TR, DE, SW, WA, PA, ID, NE).",
" 6. the percentage of physical memory being used by this task.",
" 7. the virtual address size of this task in kilobytes.",
" 8. the resident set size of this task in kilobytes.",
diff --git a/task.c b/task.c
index 1b32629..39fb0de 100644
--- a/task.c
+++ b/task.c
@@ -5172,6 +5172,7 @@ static long _WAKING_ = TASK_STATE_UNINITIALIZED;
static long _NONINTERACTIVE_ = TASK_STATE_UNINITIALIZED;
static long _PARKED_ = TASK_STATE_UNINITIALIZED;
static long _NOLOAD_ = TASK_STATE_UNINITIALIZED;
+static long _NEW_ = TASK_STATE_UNINITIALIZED;
#define valid_task_state(X) ((X) != TASK_STATE_UNINITIALIZED)
@@ -5249,6 +5250,10 @@ dump_task_states(void)
if (valid_task_state(_NOLOAD_))
fprintf(fp, " NOLOAD: %3ld (0x%lx)\n",
_NOLOAD_, _NOLOAD_);
+
+ if (valid_task_state(_NEW_))
+ fprintf(fp, " NEW: %3ld (0x%lx)\n",
+ _NEW_, _NEW_);
}
@@ -5282,6 +5287,7 @@ old_defaults:
/*
* If the later version of stat_nam[] array exists that contains
* WAKING, WAKEKILL and PARKED, use it instead of task_state_array[].
+ * Available since kernel version 2.6.33 to 4.13.
*/
if (((len = get_array_length("stat_nam", NULL, 0)) > 0) &&
read_string(symbol_value("stat_nam"), buf, BUFSIZE-1) &&
@@ -5331,6 +5337,9 @@ old_defaults:
case 'N':
_NOLOAD_ = (1 << (i-1));
break;
+ case 'n':
+ _NEW_ = (1 << (i-1));
+ break;
}
}
@@ -5393,7 +5402,16 @@ old_defaults:
_NONINTERACTIVE_ = 64;
}
- if (THIS_KERNEL_VERSION >= LINUX(2,6,32)) {
+ if (THIS_KERNEL_VERSION >= LINUX(4,14,0)) {
+ if (valid_task_state(_PARKED_)) {
+ bitpos = _PARKED_;
+ _DEAD_ |= (bitpos << 1); /* TASK_DEAD */
+ _WAKEKILL_ = (bitpos << 2); /* TASK_WAKEKILL */
+ _WAKING_ = (bitpos << 3); /* TASK_WAKING */
+ _NOLOAD_ = (bitpos << 4); /* TASK_NOLOAD */
+ _NEW_ = (bitpos << 5); /* TASK_NEW */
+ }
+ } else if (THIS_KERNEL_VERSION >= LINUX(2,6,32)) {
/*
* Account for states not listed in task_state_array[]
*/
@@ -5481,6 +5499,10 @@ task_state_string_verbose(ulong task, char *buf)
sprintf(&buf[strlen(buf)], "%sTASK_NOLOAD",
count++ ? "|" : "");
+ if (valid_task_state(_NEW_) && (state & _NEW_))
+ sprintf(&buf[strlen(buf)], "%sTASK_NEW",
+ count++ ? "|" : "");
+
if (valid_task_state(_NONINTERACTIVE_) &&
(state & _NONINTERACTIVE_))
sprintf(&buf[strlen(buf)], "%sTASK_NONINTERACTIVE",
@@ -5530,7 +5552,11 @@ task_state_string(ulong task, char *buf, int verbose)
}
if (state & _UNINTERRUPTIBLE_) {
- sprintf(buf, "UN");
+ if (valid_task_state(_NOLOAD_) &&
+ (state & _NOLOAD_))
+ sprintf(buf, "ID");
+ else
+ sprintf(buf, "UN");
valid++;
set++;
}
@@ -5576,6 +5602,11 @@ task_state_string(ulong task, char *buf, int verbose)
valid++;
}
+ if (state == _NEW_) {
+ sprintf(buf, "NE");
+ valid++;
+ }
+
if (valid && exclusive)
strcat(buf, "EX");
@@ -6273,6 +6304,8 @@ cmd_foreach(void)
STREQ(args[optind], "DE") ||
STREQ(args[optind], "PA") ||
STREQ(args[optind], "WA") ||
+ STREQ(args[optind], "ID") ||
+ STREQ(args[optind], "NE") ||
STREQ(args[optind], "SW")) {
if (fd->flags & FOREACH_STATE)
@@ -6298,6 +6331,10 @@ cmd_foreach(void)
fd->state = _PARKED_;
else if (STREQ(args[optind], "WA"))
fd->state = _WAKING_;
+ else if (STREQ(args[optind], "ID"))
+ fd->state = _UNINTERRUPTIBLE_|_NOLOAD_;
+ else if (STREQ(args[optind], "NE"))
+ fd->state = _NEW_;
if (fd->state == TASK_STATE_UNINITIALIZED)
error(FATAL,
@@ -6678,6 +6715,19 @@ foreach(struct foreach_data *fd)
if (fd->state == _RUNNING_) {
if (task_state(tc->task) != _RUNNING_)
continue;
+ } else if (fd->state & _UNINTERRUPTIBLE_) {
+ if (!(task_state(tc->task) & _UNINTERRUPTIBLE_))
+ continue;
+
+ if (valid_task_state(_NOLOAD_)) {
+ if (fd->state & _NOLOAD_) {
+ if (!(task_state(tc->task) & _NOLOAD_))
+ continue;
+ } else {
+ if ((task_state(tc->task) & _NOLOAD_))
+ continue;
+ }
+ }
} else if (!(task_state(tc->task) & fd->state))
continue;
}
commit 6c39a3d39b799e1f3f26e8017bcfa458d38d3820
Author: Dave Anderson <anderson@redhat.com>
Date: Wed Aug 8 11:31:17 2018 -0400
Fix for running live on ARM64 kernels against /proc/kcore on kernels
configured with CONFIG_RANDOMIZE_BASE. Without the patch, depending
upon the hardware platform, the session may fail with the error message
"crash: vmlinux and /proc/kcore do not match!".
(anderson@redhat.com)
diff --git a/arm64.c b/arm64.c
index 150e7d7..4ee53ce 100644
--- a/arm64.c
+++ b/arm64.c
@@ -125,7 +125,8 @@ arm64_init(int when)
free(string);
}
- if (ms->kimage_voffset) {
+ if (ms->kimage_voffset ||
+ (ACTIVE() && (symbol_value_from_proc_kallsyms("kimage_voffset") != BADVAL))) {
machdep->flags |= NEW_VMEMMAP;
/*
@@ -771,6 +772,17 @@ arm64_calc_kimage_voffset(void)
char *p1;
int errflag;
FILE *iomem;
+ ulong kimage_voffset, vaddr;
+
+ if (pc->flags & PROC_KCORE) {
+ kimage_voffset = symbol_value_from_proc_kallsyms("kimage_voffset");
+ if ((kimage_voffset != BADVAL) &&
+ (READMEM(pc->mfd, &vaddr, sizeof(ulong),
+ kimage_voffset, KCORE_USE_VADDR) > 0)) {
+ ms->kimage_voffset = vaddr;
+ return;
+ }
+ }
if ((iomem = fopen("/proc/iomem", "r")) == NULL)
return;
@@ -838,16 +850,22 @@ arm64_calc_phys_offset(void)
int errflag;
FILE *iomem;
physaddr_t paddr;
+ ulong vaddr;
struct syment *sp;
if ((machdep->flags & NEW_VMEMMAP) &&
ms->kimage_voffset && (sp = kernel_symbol_search("memstart_addr"))) {
- if (pc->flags & PROC_KCORE)
+ if (pc->flags & PROC_KCORE) {
+ vaddr = symbol_value_from_proc_kallsyms("memstart_addr");
+ if (vaddr == BADVAL)
+ vaddr = sp->value;
paddr = KCORE_USE_VADDR;
- else
+ } else {
+ vaddr = sp->value;
paddr = sp->value - machdep->machspec->kimage_voffset;
+ }
if (READMEM(pc->mfd, &phys_offset, sizeof(phys_offset),
- sp->value, paddr) > 0) {
+ vaddr, paddr) > 0) {
ms->phys_offset = phys_offset;
return;
}
diff --git a/defs.h b/defs.h
index 5af82be..da2ae04 100644
--- a/defs.h
+++ b/defs.h
@@ -5067,6 +5067,7 @@ struct syment *per_cpu_symbol_search(char *);
int symbol_exists(char *s);
int kernel_symbol_exists(char *s);
struct syment *kernel_symbol_search(char *);
+ulong symbol_value_from_proc_kallsyms(char *);
int get_syment_array(char *, struct syment **, int);
void set_temporary_radix(unsigned int, unsigned int *);
void restore_current_radix(unsigned int);
diff --git a/symbols.c b/symbols.c
index 8ff1430..df84ee2 100644
--- a/symbols.c
+++ b/symbols.c
@@ -28,7 +28,6 @@ static void store_sysmap_symbols(void);
static ulong relocate(ulong, char *, int);
static int relocate_force(ulong, char *);
static void kaslr_init(void);
-static ulong symbol_value_from_proc_kallsyms(char *);
static void strip_module_symbol_end(char *s);
static int compare_syms(const void *, const void *);
static int compare_mods(const void *, const void *);
@@ -997,7 +996,7 @@ relocate_force(ulong symval, char *symname)
/*
* Get a symbol value from /proc/kallsyms.
*/
-static ulong
+ulong
symbol_value_from_proc_kallsyms(char *symname)
{
FILE *kp;
commit 455da1ae5c7f22ba870aa57e071dad340749bdcd
Author: Dave Anderson <anderson@redhat.com>
Date: Wed Aug 8 14:20:21 2018 -0400
Modify the output of the "kmem -[sS]" header and contents such that
the slab cache name string is moved from the second column to the
the last column. Since the slab cache name strings have become
increasingly longer over time, without the patch, the numerical
column contents may be skewed so far to the right that the output
becomes difficult to read.
(k-hagio@ab.jp.nec.com)
diff --git a/help.c b/help.c
index 83cda7c..a189038 100644
--- a/help.c
+++ b/help.c
@@ -6692,8 +6692,8 @@ char *help_kmem[] = {
" Find all of the combined slab/page structures that are used by",
" the kmalloc-8192 slab cache:\n",
" %s> kmem -s kmalloc-8192",
-" CACHE NAME OBJSIZE ALLOCATED TOTAL SLABS SSIZE",
-" ffff880215802e00 kmalloc-8192 8192 65 80 20 32k",
+" CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME",
+" ffff880215802e00 8192 65 80 20 32k kmalloc-8192",
" %s> kmem -m slab_cache | grep ffff880215802e00",
" ffffea0004117800 ffff880215802e00 ",
" ffffea00041ca600 ffff880215802e00 ",
@@ -6889,72 +6889,72 @@ char *help_kmem[] = {
" ",
" Display kmalloc() slab data:\n",
" %s> kmem -s",
-" CACHE NAME OBJSIZE ALLOCATED TOTAL SLABS SSIZE",
-" c02eadc0 kmem_cache 232 58 68 4 4k",
-" f79c2888 ip_vs_conn 128 0 0 0 4k",
-" f79c2970 tcp_tw_bucket 96 0 0 0 4k",
-" f79c2a58 tcp_bind_bucket 32 12 565 5 4k",
-" f79c2b40 tcp_open_request 64 0 59 1 4k",
-" f79c2c28 inet_peer_cache 64 1 59 1 4k",
-" f79c2d10 ip_fib_hash 32 11 339 3 4k",
-" f79c2df8 ip_dst_cache 160 8 120 5 4k",
-" f79c2ee0 arp_cache 128 1 30 1 4k",
-" c8402970 blkdev_requests 96 30208 37800 945 4k",
-" c8402a58 nfs_read_data 384 0 0 0 4k",
-" c8402b40 nfs_write_data 384 0 0 0 4k",
-" c8402c28 nfs_page 96 0 0 0 4k",
-" c8402d10 dnotify cache 20 0 0 0 4k",
-" c8402df8 file lock cache 92 3 336 8 4k",
-" c8402ee0 fasync cache 16 0 0 0 4k",
-" c84027a0 uid_cache 32 3 339 3 4k",
-" c84026b8 skbuff_head_cache 160 320 624 26 4k",
-" c84025d0 sock 832 32 180 20 8k",
-" c84024e8 sigqueue 132 0 203 7 4k",
-" c8402400 cdev_cache 64 19 472 8 4k",
-" c8402318 bdev_cache 64 8 236 4 4k",
-" c8402230 mnt_cache 96 11 120 3 4k",
-" c8402148 inode_cache 480 817 848 106 4k",
-" c8402060 dentry_cache 128 1352 1470 49 4k",
-" c8403ee0 filp 96 244 440 11 4k",
-" c8403df8 names_cache 4096 0 12 12 4k",
-" c8403d10 buffer_head 96 14936 16000 400 4k",
-" c8403c28 mm_struct 128 25 240 8 4k",
-" c8403b40 vm_area_struct 64 393 1298 22 4k",
-" c8403a58 fs_cache 64 30 472 8 4k",
-" c8403970 files_cache 416 30 135 15 4k",
-" c8403888 signal_act 1312 32 99 33 4k",
-" c84037a0 size-131072(DMA) 131072 0 0 0 128k",
-" c84036b8 size-131072 131072 1 1 1 128k",
-" c84035d0 size-65536(DMA) 65536 0 0 0 64k",
-" c84034e8 size-65536 65536 0 0 0 64k",
-" c8403400 size-32768(DMA) 32768 0 0 0 32k",
-" c8403318 size-32768 32768 0 1 1 32k",
-" c8403230 size-16384(DMA) 16384 0 0 0 16k",
-" c8403148 size-16384 16384 0 0 0 16k",
-" c8403060 size-8192(DMA) 8192 0 0 0 8k",
-" c8401ee0 size-8192 8192 1 2 2 8k",
-" c8401df8 size-4096(DMA) 4096 0 0 0 4k",
-" c8401d10 size-4096 4096 30 30 30 4k",
-" c8401c28 size-2048(DMA) 2048 0 0 0 4k",
-" c8401b40 size-2048 2048 37 132 66 4k",
-" c8401a58 size-1024(DMA) 1024 0 0 0 4k",
-" c8401970 size-1024 1024 301 328 82 4k",
-" c8401888 size-512(DMA) 512 0 0 0 4k",
-" c84017a0 size-512 512 141 168 21 4k",
-" c84016b8 size-256(DMA) 256 0 0 0 4k",
-" c84015d0 size-256 256 80 435 29 4k",
-" c84014e8 size-128(DMA) 128 0 0 0 4k",
-" c8401400 size-128 128 508 840 28 4k",
-" c8401318 size-64(DMA) 64 0 0 0 4k",
-" c8401230 size-64 64 978 1357 23 4k",
-" c8401148 size-32(DMA) 32 0 0 0 4k",
-" c8401060 size-32 32 1244 1808 16 4k",
+" CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME",
+" c02eadc0 232 58 68 4 4k kmem_cache",
+" f79c2888 128 0 0 0 4k ip_vs_conn",
+" f79c2970 96 0 0 0 4k tcp_tw_bucket",
+" f79c2a58 32 12 565 5 4k tcp_bind_bucket",
+" f79c2b40 64 0 59 1 4k tcp_open_request",
+" f79c2c28 64 1 59 1 4k inet_peer_cache",
+" f79c2d10 32 11 339 3 4k ip_fib_hash",
+" f79c2df8 160 8 120 5 4k ip_dst_cache",
+" f79c2ee0 128 1 30 1 4k arp_cache",
+" c8402970 96 30208 37800 945 4k blkdev_requests",
+" c8402a58 384 0 0 0 4k nfs_read_data",
+" c8402b40 384 0 0 0 4k nfs_write_data",
+" c8402c28 96 0 0 0 4k nfs_page",
+" c8402d10 20 0 0 0 4k dnotify cache",
+" c8402df8 92 3 336 8 4k file lock cache",
+" c8402ee0 16 0 0 0 4k fasync cache",
+" c84027a0 32 3 339 3 4k uid_cache",
+" c84026b8 160 320 624 26 4k skbuff_head_cache",
+" c84025d0 832 32 180 20 8k sock",
+" c84024e8 132 0 203 7 4k sigqueue",
+" c8402400 64 19 472 8 4k cdev_cache",
+" c8402318 64 8 236 4 4k bdev_cache",
+" c8402230 96 11 120 3 4k mnt_cache",
+" c8402148 480 817 848 106 4k inode_cache",
+" c8402060 128 1352 1470 49 4k dentry_cache",
+" c8403ee0 96 244 440 11 4k filp",
+" c8403df8 4096 0 12 12 4k names_cache",
+" c8403d10 96 14936 16000 400 4k buffer_head",
+" c8403c28 128 25 240 8 4k mm_struct",
+" c8403b40 64 393 1298 22 4k vm_area_struct",
+" c8403a58 64 30 472 8 4k fs_cache",
+" c8403970 416 30 135 15 4k files_cache",
+" c8403888 1312 32 99 33 4k signal_act",
+" c84037a0 131072 0 0 0 128k size-131072(DMA)",
+" c84036b8 131072 1 1 1 128k size-131072",
+" c84035d0 65536 0 0 0 64k size-65536(DMA)",
+" c84034e8 65536 0 0 0 64k size-65536",
+" c8403400 32768 0 0 0 32k size-32768(DMA)",
+" c8403318 32768 0 1 1 32k size-32768",
+" c8403230 16384 0 0 0 16k size-16384(DMA)",
+" c8403148 16384 0 0 0 16k size-16384",
+" c8403060 8192 0 0 0 8k size-8192(DMA)",
+" c8401ee0 8192 1 2 2 8k size-8192",
+" c8401df8 4096 0 0 0 4k size-4096(DMA)",
+" c8401d10 4096 30 30 30 4k size-4096",
+" c8401c28 2048 0 0 0 4k size-2048(DMA)",
+" c8401b40 2048 37 132 66 4k size-2048",
+" c8401a58 1024 0 0 0 4k size-1024(DMA)",
+" c8401970 1024 301 328 82 4k size-1024",
+" c8401888 512 0 0 0 4k size-512(DMA)",
+" c84017a0 512 141 168 21 4k size-512",
+" c84016b8 256 0 0 0 4k size-256(DMA)",
+" c84015d0 256 80 435 29 4k size-256",
+" c84014e8 128 0 0 0 4k size-128(DMA)",
+" c8401400 128 508 840 28 4k size-128",
+" c8401318 64 0 0 0 4k size-64(DMA)",
+" c8401230 64 978 1357 23 4k size-64",
+" c8401148 32 0 0 0 4k size-32(DMA)",
+" c8401060 32 1244 1808 16 4k size-32",
" ",
" Display all slab data in the \"arp_cache\" cache:\n",
" %s> kmem -S arp_cache",
-" CACHE NAME OBJSIZE ALLOCATED TOTAL SLABS SSIZE",
-" f79c2ee0 arp_cache 128 1 30 1 4k",
+" CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME",
+" f79c2ee0 128 1 30 1 4k arp_cache",
" SLAB MEMORY TOTAL ALLOCATED FREE",
" f729d000 f729d0a0 30 1 29",
" FREE / [ALLOCATED]",
@@ -6991,8 +6991,8 @@ char *help_kmem[] = {
" ",
" Search the kmalloc() slab subsystem for address c3fbdb60:\n",
" %s> kmem -s c3fbdb60",
-" CACHE NAME OBJSIZE ALLOCATED TOTAL SLABS SSIZE",
-" c8402970 blkdev_requests 96 30208 37800 945 4k",
+" CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME",
+" c8402970 96 30208 37800 945 4k blkdev_requests",
" SLAB MEMORY TOTAL ALLOCATED FREE",
" c3fbd020 c3fbd0e0 40 40 0",
" FREE / [ALLOCATED]",
@@ -7000,8 +7000,8 @@ char *help_kmem[] = {
" ",
" Make a generic search (no flags) for the same address c3fbdb60:\n",
" %s> kmem c3fbdb60 ",
-" CACHE NAME OBJSIZE ALLOCATED TOTAL SLABS SSIZE",
-" c8402970 blkdev_requests 96 30208 37800 945 4k",
+" CACHE OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME",
+" c8402970 96 30208 37800 945 4k blkdev_requests",
" SLAB MEMORY TOTAL ALLOCATED FREE",
" c3fbd020 c3fbd0e0 40 40 0 ",
" FREE / [ALLOCATED]",
diff --git a/memory.c b/memory.c
index 81ed689..5bcf09e 100644
--- a/memory.c
+++ b/memory.c
@@ -172,7 +172,6 @@ static void dump_kmem_cache(struct meminfo *);
static void dump_kmem_cache_percpu_v1(struct meminfo *);
static void dump_kmem_cache_percpu_v2(struct meminfo *);
static void dump_kmem_cache_slub(struct meminfo *);
-static void dump_kmem_cache_info_v2(struct meminfo *);
static void kmem_cache_list_common(void);
static ulong get_cpu_slab_ptr(struct meminfo *, int, ulong *);
static unsigned int oo_order(ulong);
@@ -9379,7 +9378,7 @@ kmem_cache_init(void)
if (!strlen(kmem_cache_hdr))
sprintf(kmem_cache_hdr,
- "CACHE%sNAME OBJSIZE ALLOCATED TOTAL SLABS SSIZE\n",
+ "CACHE%s OBJSIZE ALLOCATED TOTAL SLABS SSIZE NAME\n",
space(VADDR_PRLEN > 8 ? 12 : 4));
if (!strlen(free_inuse_hdr))
@@ -9964,55 +9963,36 @@ ignore_cache(struct meminfo *si, char *name)
#define KMEM_SLAB_OVERLOAD_PAGE (8)
#define KMEM_SLAB_FREELIST (9)
-#define DUMP_KMEM_CACHE_INFO_V1() \
- { \
- char b1[BUFSIZE]; \
- fprintf(fp, "%s %-18s %8ld ", \
- mkstring(b1, VADDR_PRLEN, LJUST|LONG_HEX, MKSTR(si->cache)), \
- buf, si->size); \
- fprintf(fp, "%9ld %8ld %5ld %3ldk\n", \
- vt->flags & PERCPU_KMALLOC_V1 ? \
- si->inuse - si->cpucached_cache : \
- si->inuse, si->num_slabs * si->c_num, \
- si->num_slabs, si->slabsize/1024); \
- }
-
-#define DUMP_KMEM_CACHE_INFO_V2() dump_kmem_cache_info_v2(si)
+#define DUMP_KMEM_CACHE_INFO() dump_kmem_cache_info(si)
static void
-dump_kmem_cache_info_v2(struct meminfo *si)
+dump_kmem_cache_info(struct meminfo *si)
{
char b1[BUFSIZE];
- char b2[BUFSIZE];
- int namelen, sizelen, spacelen;
-
- fprintf(fp, "%s ",
- mkstring(b1, VADDR_PRLEN, LJUST|LONG_HEX, MKSTR(si->cache)));
-
- namelen = strlen(si->curname);
- sprintf(b2, "%ld", si->size);
- sizelen = strlen(b2);
- spacelen = 0;
-
- if (namelen++ > 18) {
- spacelen = 29 - namelen - sizelen;
- fprintf(fp, "%s%s%ld ", si->curname,
- space(spacelen <= 0 ? 1 : spacelen), si->size);
- if (spacelen > 0)
- spacelen = 1;
- sprintf(b1, "%c%dld ", '%', 9 + spacelen - 1);
+ ulong objsize, allocated, total;
+
+ if (si->flags & SLAB_GATHER_FAILURE)
+ error(INFO, "%s: cannot gather relevant slab data\n", si->curname);
+
+ objsize = (vt->flags & KMALLOC_SLUB) ? si->objsize : si->size;
+
+ fprintf(fp, "%s %8ld ",
+ mkstring(b1, VADDR_PRLEN, LJUST|LONG_HEX, MKSTR(si->cache)),
+ objsize);
+
+ if (si->flags & SLAB_GATHER_FAILURE) {
+ fprintf(fp, "%9s %8s %5s ", "?", "?", "?");
} else {
- fprintf(fp, "%-18s %8ld ", si->curname, si->size);
- sprintf(b1, "%c%dld ", '%', 9);
- }
+ allocated = (vt->flags & (PERCPU_KMALLOC_V1|PERCPU_KMALLOC_V2)) ?
+ si->inuse - si->cpucached_cache : si->inuse;
+ total = (vt->flags & KMALLOC_SLUB) ?
+ si->inuse + si->free : si->num_slabs * si->c_num;
- fprintf(fp, b1, vt->flags & (PERCPU_KMALLOC_V2) ?
- si->inuse - si->cpucached_cache : si->inuse);
+ fprintf(fp, "%9ld %8ld %5ld ",
+ allocated, total, si->num_slabs);
+ }
- fprintf(fp, "%8ld %s%5ld %s%3ldk\n",
- si->num_slabs * si->c_num,
- si->num_slabs < 100000 ? " " : "", si->num_slabs,
- (si->slabsize/1024) < 1000 ? " " : "", si->slabsize/1024);
+ fprintf(fp, "%4ldk %s\n", si->slabsize/1024, si->curname);
}
#define DUMP_SLAB_INFO() \
@@ -10152,7 +10132,7 @@ dump_kmem_cache(struct meminfo *si)
do_slab_chain(SLAB_GET_COUNTS, si);
if (!(si->flags & (ADDRESS_SPECIFIED|GET_SLAB_PAGES)))
- DUMP_KMEM_CACHE_INFO_V1();
+ DUMP_KMEM_CACHE_INFO();
if (si->flags == GET_SLAB_PAGES)
si->retval += (si->num_slabs *
@@ -10166,7 +10146,7 @@ dump_kmem_cache(struct meminfo *si)
if (si->found) {
fprintf(fp, "%s", kmem_cache_hdr);
- DUMP_KMEM_CACHE_INFO_V1();
+ DUMP_KMEM_CACHE_INFO();
fprintf(fp, "%s", slab_hdr);
DUMP_SLAB_INFO();
@@ -10362,7 +10342,7 @@ dump_kmem_cache_percpu_v1(struct meminfo *si)
do_slab_chain_percpu_v1(SLAB_GET_COUNTS, si);
if (!(si->flags & (ADDRESS_SPECIFIED|GET_SLAB_PAGES))) {
- DUMP_KMEM_CACHE_INFO_V1();
+ DUMP_KMEM_CACHE_INFO();
if (CRASHDEBUG(3))
dump_struct("kmem_cache_s", si->cache, 0);
}
@@ -10382,7 +10362,7 @@ dump_kmem_cache_percpu_v1(struct meminfo *si)
if (si->found) {
fprintf(fp, "%s", kmem_cache_hdr);
- DUMP_KMEM_CACHE_INFO_V1();
+ DUMP_KMEM_CACHE_INFO();
fprintf(fp, "%s", slab_hdr);
gather_slab_cached_count(si);
DUMP_SLAB_INFO();
@@ -10617,7 +10597,7 @@ dump_kmem_cache_percpu_v2(struct meminfo *si)
do_slab_chain_percpu_v2(SLAB_GET_COUNTS, si);
if (!(si->flags & (ADDRESS_SPECIFIED|GET_SLAB_PAGES))) {
- DUMP_KMEM_CACHE_INFO_V2();
+ DUMP_KMEM_CACHE_INFO();
if (CRASHDEBUG(3))
dump_struct("kmem_cache_s", si->cache, 0);
}
@@ -10644,7 +10624,7 @@ dump_kmem_cache_percpu_v2(struct meminfo *si)
if (si->found) {
fprintf(fp, "%s", kmem_cache_hdr);
- DUMP_KMEM_CACHE_INFO_V2();
+ DUMP_KMEM_CACHE_INFO();
fprintf(fp, "%s", slab_hdr);
gather_slab_cached_count(si);
DUMP_SLAB_INFO();
@@ -18064,56 +18044,6 @@ kmem_cache_list_common(void)
FREEBUF(cache_list);
}
-#define DUMP_KMEM_CACHE_INFO_SLUB() dump_kmem_cache_info_slub(si)
-
-static void
-dump_kmem_cache_info_slub(struct meminfo *si)
-{
- char b1[BUFSIZE];
- char b2[BUFSIZE];
- int namelen, sizelen, spacelen;
-
- if (si->flags & SLAB_GATHER_FAILURE)
- error(INFO, "%s: cannot gather relevant slab data\n", si->curname);
-
- fprintf(fp, "%s ",
- mkstring(b1, VADDR_PRLEN, LJUST|LONG_HEX, MKSTR(si->cache)));
-
- namelen = strlen(si->curname);
- sprintf(b2, "%ld", si->objsize);
- sizelen = strlen(b2);
- spacelen = 0;
-
- if (namelen++ > 18) {
- spacelen = 29 - namelen - sizelen;
- fprintf(fp, "%s%s%ld ", si->curname,
- space(spacelen <= 0 ? 1 : spacelen), si->objsize);
- if (spacelen > 0)
- spacelen = 1;
- if (si->flags & SLAB_GATHER_FAILURE)
- sprintf(b1, "%c%ds ", '%', 9 + spacelen - 1);
- else
- sprintf(b1, "%c%dld ", '%', 9 + spacelen - 1);
- } else {
- fprintf(fp, "%-18s %8ld ", si->curname, si->objsize);
- if (si->flags & SLAB_GATHER_FAILURE)
- sprintf(b1, "%c%ds ", '%', 9);
- else
- sprintf(b1, "%c%dld ", '%', 9);
- }
-
- if (si->flags & SLAB_GATHER_FAILURE) {
- fprintf(fp, b1, "?");
- fprintf(fp, "%8s %5s %4ldk\n",
- "?", "?", si->slabsize/1024);
- } else {
- fprintf(fp, b1, si->inuse);
- fprintf(fp, "%8ld %5ld %4ldk\n",
- si->inuse + si->free,
- si->num_slabs, si->slabsize/1024);
- }
-}
-
static void
dump_kmem_cache_slub(struct meminfo *si)
{
@@ -18214,7 +18144,7 @@ dump_kmem_cache_slub(struct meminfo *si)
!get_kmem_cache_slub_data(GET_SLUB_OBJECTS, si))
si->flags |= SLAB_GATHER_FAILURE;
- DUMP_KMEM_CACHE_INFO_SLUB();
+ DUMP_KMEM_CACHE_INFO();
if (si->flags & SLAB_GATHER_FAILURE) {
si->flags &= ~SLAB_GATHER_FAILURE;
commit ba03b66cec24fc0033d4378be08f5f9a96cd4a91
Author: Dave Anderson <anderson@redhat.com>
Date: Thu Aug 9 10:54:46 2018 -0400
Fix for the "files" and "net -s" commands when a task has an open
files count that exceeds 1024 (FD_SETSIZE) file descriptors. Without
the patch, the commands may omit the display of open file descriptors.
(tan.hu@zte.com.cn)
diff --git a/filesys.c b/filesys.c
index 0ace8f4..47f5a24 100644
--- a/filesys.c
+++ b/filesys.c
@@ -2380,7 +2380,8 @@ open_files_dump(ulong task, int flags, struct reference *ref)
int max_fdset = 0;
int max_fds = 0;
ulong open_fds_addr;
- fd_set open_fds;
+ int open_fds_size;
+ ulong *open_fds;
ulong fd;
ulong file;
ulong value;
@@ -2583,16 +2584,25 @@ open_files_dump(ulong task, int flags, struct reference *ref)
open_fds_addr = ULONG(files_struct_buf +
OFFSET(files_struct_open_fds));
+ open_fds_size = MAX(max_fdset, max_fds) / BITS_PER_BYTE;
+ open_fds = (ulong *)GETBUF(open_fds_size);
+ if (!open_fds) {
+ if (fdtable_buf)
+ FREEBUF(fdtable_buf);
+ FREEBUF(files_struct_buf);
+ return;
+ }
+
if (open_fds_addr) {
if (VALID_MEMBER(files_struct_open_fds_init) &&
(open_fds_addr == (files_struct_addr +
OFFSET(files_struct_open_fds_init))))
BCOPY(files_struct_buf +
OFFSET(files_struct_open_fds_init),
- &open_fds, sizeof(fd_set));
+ open_fds, open_fds_size);
else
- readmem(open_fds_addr, KVADDR, &open_fds,
- sizeof(fd_set), "fdtable open_fds",
+ readmem(open_fds_addr, KVADDR, open_fds,
+ open_fds_size, "fdtable open_fds",
FAULT_ON_ERROR);
}
@@ -2607,6 +2617,7 @@ open_files_dump(ulong task, int flags, struct reference *ref)
if (fdtable_buf)
FREEBUF(fdtable_buf);
FREEBUF(files_struct_buf);
+ FREEBUF(open_fds);
return;
}
@@ -2617,11 +2628,11 @@ open_files_dump(ulong task, int flags, struct reference *ref)
j = 0;
for (;;) {
unsigned long set;
- i = j * __NFDBITS;
+ i = j * BITS_PER_LONG;
if (((max_fdset >= 0) && (i >= max_fdset)) ||
(i >= max_fds))
break;
- set = open_fds.__fds_bits[j++];
+ set = open_fds[j++];
while (set) {
if (set & 1) {
readmem(fd + i*sizeof(struct file *), KVADDR,
@@ -2665,6 +2676,7 @@ open_files_dump(ulong task, int flags, struct reference *ref)
if (fdtable_buf)
FREEBUF(fdtable_buf);
FREEBUF(files_struct_buf);
+ FREEBUF(open_fds);
}
/*
diff --git a/net.c b/net.c
index 4199091..f08f22a 100644
--- a/net.c
+++ b/net.c
@@ -1373,7 +1373,8 @@ dump_sockets_workhorse(ulong task, ulong flag, struct reference *ref)
int max_fdset = 0;
int max_fds = 0;
ulong open_fds_addr = 0;
- fd_set open_fds;
+ ulong *open_fds;
+ int open_fds_size;
ulong fd;
ulong file;
int i, j;
@@ -1446,12 +1447,18 @@ dump_sockets_workhorse(ulong task, ulong flag, struct reference *ref)
sizeof(void *), "files_struct fd addr", FAULT_ON_ERROR);
}
+ open_fds_size = MAX(max_fdset, max_fds) / BITS_PER_BYTE;
+ open_fds = (ulong *)GETBUF(open_fds_size);
+ if (!open_fds)
+ return;
+
if (open_fds_addr)
- readmem(open_fds_addr, KVADDR, &open_fds, sizeof(fd_set),
+ readmem(open_fds_addr, KVADDR, open_fds, open_fds_size,
"files_struct open_fds", FAULT_ON_ERROR);
if (!open_fds_addr || !fd) {
if (!NET_REFERENCE_CHECK(ref))
fprintf(fp, "No open sockets.\n");
+ FREEBUF(open_fds);
return;
}
@@ -1479,10 +1486,10 @@ dump_sockets_workhorse(ulong task, ulong flag, struct reference *ref)
j = 0;
for (;;) {
unsigned long set;
- i = j * __NFDBITS;
+ i = j * BITS_PER_LONG;
if (((max_fdset >= 0) && (i >= max_fdset)) || (i >= max_fds))
break;
- set = open_fds.__fds_bits[j++];
+ set = open_fds[j++];
while (set) {
if (set & 1) {
readmem(fd + i*sizeof(struct file *), KVADDR,
@@ -1505,6 +1512,8 @@ dump_sockets_workhorse(ulong task, ulong flag, struct reference *ref)
if (NET_REFERENCE_FOUND(ref))
fprintf(fp, "\n");
+
+ FREEBUF(open_fds);
}
commit e9532aea6818b347bc0740f39efd4ec844cfb9b0
Author: Dave Anderson <anderson@redhat.com>
Date: Thu Aug 9 11:20:26 2018 -0400
As an addendum to the new "kmem -[sS]" output format, align the slab
cache name string so that it is beneath the "NAME" header column when
the "kmem -I &lt;slab-cache>" option is used to ignore a slab cache,
or if the scan of the metadata of a slab cache enounters corruption.
Also remove a superfluous line from the "help kmem" description of
the "kmem -I" option.
(k-hagio@ab.jp.nec.com, anderson@redhat.com)
diff --git a/help.c b/help.c
index a189038..aeeb056 100644
--- a/help.c
+++ b/help.c
@@ -6495,7 +6495,6 @@ char *help_kmem[] = {
" all slab cache names and addresses are listed.",
" -I slab when used with -s or -S, one or more slab cache names in a",
" comma-separated list may be specified as slab caches to ignore.",
-" their hugepage size, total and free counts, and name.",
" -g displays the enumerator value of all bits in the page structure's",
" \"flags\" field.",
" flags when used with -g, translates all bits in this hexadecimal page",
diff --git a/memory.c b/memory.c
index 5bcf09e..4790cf6 100644
--- a/memory.c
+++ b/memory.c
@@ -9963,6 +9963,9 @@ ignore_cache(struct meminfo *si, char *name)
#define KMEM_SLAB_OVERLOAD_PAGE (8)
#define KMEM_SLAB_FREELIST (9)
+#define DUMP_KMEM_CACHE_TAG(addr, name, tag) \
+ fprintf(fp, "%lx %-43s %s\n", addr, tag, name)
+
#define DUMP_KMEM_CACHE_INFO() dump_kmem_cache_info(si)
static void
@@ -10094,7 +10097,7 @@ dump_kmem_cache(struct meminfo *si)
goto next_cache;
if (ignore_cache(si, buf)) {
- fprintf(fp, "%lx %-18s [IGNORED]\n", si->cache, buf);
+ DUMP_KMEM_CACHE_TAG(si->cache, buf, "[IGNORED]");
goto next_cache;
}
@@ -10303,7 +10306,7 @@ dump_kmem_cache_percpu_v1(struct meminfo *si)
goto next_cache;
if (ignore_cache(si, buf)) {
- fprintf(fp, "%lx %-18s [IGNORED]\n", si->cache, buf);
+ DUMP_KMEM_CACHE_TAG(si->cache, buf, "[IGNORED]");
goto next_cache;
}
@@ -10547,12 +10550,12 @@ dump_kmem_cache_percpu_v2(struct meminfo *si)
goto next_cache;
if (ignore_cache(si, buf)) {
- fprintf(fp, "%lx %-18s [IGNORED]\n", si->cache, buf);
+ DUMP_KMEM_CACHE_TAG(si->cache, buf, "[IGNORED]");
goto next_cache;
}
if (bad_slab_cache(si->cache)) {
- fprintf(fp, "%lx %-18s [INVALID/CORRUPTED]\n", si->cache, buf);
+ DUMP_KMEM_CACHE_TAG(si->cache, buf, "[INVALID/CORRUPTED]");
goto next_cache;
}
@@ -18109,8 +18112,7 @@ dump_kmem_cache_slub(struct meminfo *si)
fprintf(fp, "%s", kmem_cache_hdr);
}
if (ignore_cache(si, buf)) {
- fprintf(fp, "%lx %-18s [IGNORED]\n",
- si->cache_list[i], buf);
+ DUMP_KMEM_CACHE_TAG(si->cache_list[i], buf, "[IGNORED]");
goto next_cache;
}