Expand dump-functions for excluding user/unused memory (This is rebase commit for merging to development)
This commit is contained in:
committed by
Ken Sato
parent
325082a571
commit
a05b6e1ba8
@ -198,6 +198,7 @@ nmi:
|
||||
movw %gs,%ax
|
||||
movl %eax,%gs:PANIC_REGS+0xA0
|
||||
movq $1,%gs:PANICED
|
||||
call ihk_mc_query_mem_areas
|
||||
1:
|
||||
hlt
|
||||
jmp 1b
|
||||
|
||||
@ -1094,6 +1094,276 @@ int visit_pte_range(page_table_t pt, void *start0, void *end0, int pgshift,
|
||||
return walk_pte_l4(pt, 0, start, end, &visit_pte_l4, &args);
|
||||
}
|
||||
|
||||
static int walk_pte_l1_safe(struct page_table *pt, uint64_t base, uint64_t start,
|
||||
uint64_t end, walk_pte_fn_t *funcp, void *args)
|
||||
{
|
||||
int six;
|
||||
int eix;
|
||||
int ret;
|
||||
int i;
|
||||
int error;
|
||||
uint64_t off;
|
||||
unsigned long phys;
|
||||
|
||||
if (!pt)
|
||||
return 0;
|
||||
|
||||
six = (start <= base)? 0: ((start - base) >> PTL1_SHIFT);
|
||||
eix = ((end == 0) || ((base + PTL2_SIZE) <= end))? PT_ENTRIES
|
||||
: (((end - base) + (PTL1_SIZE - 1)) >> PTL1_SHIFT);
|
||||
|
||||
ret = -ENOENT;
|
||||
for (i = six; i < eix; ++i) {
|
||||
|
||||
phys = pte_get_phys(&pt->entry[i]);
|
||||
if (-1 == ihk_mc_chk_page_address(phys))
|
||||
continue;
|
||||
|
||||
off = i * PTL1_SIZE;
|
||||
error = (*funcp)(args, &pt->entry[i], base+off, start, end);
|
||||
if (!error) {
|
||||
ret = 0;
|
||||
}
|
||||
else if (error != -ENOENT) {
|
||||
ret = error;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int walk_pte_l2_safe(struct page_table *pt, uint64_t base, uint64_t start,
|
||||
uint64_t end, walk_pte_fn_t *funcp, void *args)
|
||||
{
|
||||
int six;
|
||||
int eix;
|
||||
int ret;
|
||||
int i;
|
||||
int error;
|
||||
uint64_t off;
|
||||
unsigned long phys;
|
||||
|
||||
if (!pt)
|
||||
return 0;
|
||||
|
||||
six = (start <= base)? 0: ((start - base) >> PTL2_SHIFT);
|
||||
eix = ((end == 0) || ((base + PTL3_SIZE) <= end))? PT_ENTRIES
|
||||
: (((end - base) + (PTL2_SIZE - 1)) >> PTL2_SHIFT);
|
||||
|
||||
ret = -ENOENT;
|
||||
for (i = six; i < eix; ++i) {
|
||||
|
||||
phys = pte_get_phys(&pt->entry[i]);
|
||||
if (-1 == ihk_mc_chk_page_address(phys))
|
||||
continue;
|
||||
|
||||
off = i * PTL2_SIZE;
|
||||
error = (*funcp)(args, &pt->entry[i], base+off, start, end);
|
||||
if (!error) {
|
||||
ret = 0;
|
||||
}
|
||||
else if (error != -ENOENT) {
|
||||
ret = error;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int walk_pte_l3_safe(struct page_table *pt, uint64_t base, uint64_t start,
|
||||
uint64_t end, walk_pte_fn_t *funcp, void *args)
|
||||
{
|
||||
int six;
|
||||
int eix;
|
||||
int ret;
|
||||
int i;
|
||||
int error;
|
||||
uint64_t off;
|
||||
unsigned long phys;
|
||||
|
||||
if (!pt)
|
||||
return 0;
|
||||
|
||||
six = (start <= base)? 0: ((start - base) >> PTL3_SHIFT);
|
||||
eix = ((end == 0) || ((base + PTL4_SIZE) <= end))? PT_ENTRIES
|
||||
: (((end - base) + (PTL3_SIZE - 1)) >> PTL3_SHIFT);
|
||||
|
||||
ret = -ENOENT;
|
||||
for (i = six; i < eix; ++i) {
|
||||
|
||||
phys = pte_get_phys(&pt->entry[i]);
|
||||
if (-1 == ihk_mc_chk_page_address(phys))
|
||||
continue;
|
||||
|
||||
off = i * PTL3_SIZE;
|
||||
error = (*funcp)(args, &pt->entry[i], base+off, start, end);
|
||||
if (!error) {
|
||||
ret = 0;
|
||||
}
|
||||
else if (error != -ENOENT) {
|
||||
ret = error;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int walk_pte_l4_safe(struct page_table *pt, uint64_t base, uint64_t start,
|
||||
uint64_t end, walk_pte_fn_t *funcp, void *args)
|
||||
{
|
||||
int six;
|
||||
int eix;
|
||||
int ret;
|
||||
int i;
|
||||
int error;
|
||||
uint64_t off;
|
||||
unsigned long phys;
|
||||
|
||||
if (!pt)
|
||||
return 0;
|
||||
|
||||
six = (start <= base)? 0: ((start - base) >> PTL4_SHIFT);
|
||||
eix = (end == 0)? PT_ENTRIES
|
||||
:(((end - base) + (PTL4_SIZE - 1)) >> PTL4_SHIFT);
|
||||
|
||||
ret = -ENOENT;
|
||||
for (i = six; i < eix; ++i) {
|
||||
|
||||
phys = pte_get_phys(&pt->entry[i]);
|
||||
if (-1 == ihk_mc_chk_page_address(phys))
|
||||
continue;
|
||||
|
||||
off = i * PTL4_SIZE;
|
||||
error = (*funcp)(args, &pt->entry[i], base+off, start, end);
|
||||
if (!error) {
|
||||
ret = 0;
|
||||
}
|
||||
else if (error != -ENOENT) {
|
||||
ret = error;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int visit_pte_l1_safe(void *arg0, pte_t *ptep, uintptr_t base,
|
||||
uintptr_t start, uintptr_t end)
|
||||
{
|
||||
struct visit_pte_args *args = arg0;
|
||||
|
||||
if (*ptep == PTE_NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (*args->funcp)(args->arg, args->pt, ptep, (void *)base,
|
||||
PTL1_SHIFT);
|
||||
}
|
||||
|
||||
static int visit_pte_l2_safe(void *arg0, pte_t *ptep, uintptr_t base,
|
||||
uintptr_t start, uintptr_t end)
|
||||
{
|
||||
int error;
|
||||
struct visit_pte_args *args = arg0;
|
||||
struct page_table *pt;
|
||||
|
||||
if (*ptep == PTE_NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((*ptep & PFL2_SIZE)
|
||||
&& (start <= base)
|
||||
&& (((base + PTL2_SIZE) <= end)
|
||||
|| (end == 0))
|
||||
&& (!args->pgshift || (args->pgshift == PTL2_SHIFT))) {
|
||||
error = (*args->funcp)(args->arg, args->pt, ptep,
|
||||
(void *)base, PTL2_SHIFT);
|
||||
if (error != -E2BIG) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
if (*ptep & PFL2_SIZE) {
|
||||
ekprintf("visit_pte_l2:split large page\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
pt = phys_to_virt(*ptep & PT_PHYSMASK);
|
||||
|
||||
error = walk_pte_l1_safe(pt, base, start, end, &visit_pte_l1_safe, arg0);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int visit_pte_l3_safe(void *arg0, pte_t *ptep, uintptr_t base,
|
||||
uintptr_t start, uintptr_t end)
|
||||
{
|
||||
int error;
|
||||
struct visit_pte_args *args = arg0;
|
||||
struct page_table *pt;
|
||||
|
||||
if (*ptep == PTE_NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((*ptep & PFL3_SIZE)
|
||||
&& (start <= base)
|
||||
&& (((base + PTL3_SIZE) <= end)
|
||||
|| (end == 0))
|
||||
&& (!args->pgshift || (args->pgshift == PTL3_SHIFT))
|
||||
&& use_1gb_page) {
|
||||
error = (*args->funcp)(args->arg, args->pt, ptep,
|
||||
(void *)base, PTL3_SHIFT);
|
||||
if (error != -E2BIG) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
if (*ptep & PFL3_SIZE) {
|
||||
ekprintf("visit_pte_l3:split large page\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
pt = phys_to_virt(*ptep & PT_PHYSMASK);
|
||||
|
||||
error = walk_pte_l2_safe(pt, base, start, end, &visit_pte_l2_safe, arg0);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int visit_pte_l4_safe(void *arg0, pte_t *ptep, uintptr_t base,
|
||||
uintptr_t start, uintptr_t end)
|
||||
{
|
||||
int error;
|
||||
struct page_table *pt;
|
||||
|
||||
if (*ptep == PTE_NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
pt = phys_to_virt(*ptep & PT_PHYSMASK);
|
||||
|
||||
error = walk_pte_l3_safe(pt, base, start, end, &visit_pte_l3_safe, arg0);
|
||||
return error;
|
||||
}
|
||||
|
||||
int visit_pte_range_safe(page_table_t pt, void *start0, void *end0, int pgshift,
|
||||
enum visit_pte_flag flags, pte_visitor_t *funcp, void *arg)
|
||||
{
|
||||
const uintptr_t start = (uintptr_t)start0;
|
||||
const uintptr_t end = (uintptr_t)end0;
|
||||
struct visit_pte_args args;
|
||||
|
||||
args.pt = pt;
|
||||
args.flags = flags;
|
||||
args.funcp = funcp;
|
||||
args.arg = arg;
|
||||
args.pgshift = pgshift;
|
||||
|
||||
return walk_pte_l4_safe(pt, 0, start, end, &visit_pte_l4_safe, &args);
|
||||
}
|
||||
|
||||
struct clear_range_args {
|
||||
int free_physical;
|
||||
struct memobj *memobj;
|
||||
|
||||
@ -31,6 +31,7 @@ fi
|
||||
|
||||
INTERVAL=1
|
||||
LOGMODE=0
|
||||
DUMP_LEVEL=24
|
||||
facility="LOG_LOCAL6"
|
||||
chown_option=`logname 2> /dev/null`
|
||||
|
||||
@ -43,7 +44,7 @@ fi
|
||||
turbo=""
|
||||
ihk_irq=""
|
||||
|
||||
while getopts :ti:k:c:m:o:f:r:q: OPT
|
||||
while getopts :ti:k:c:m:o:f:r:q:d: OPT
|
||||
do
|
||||
case ${OPT} in
|
||||
f) facility=${OPTARG}
|
||||
@ -86,6 +87,8 @@ do
|
||||
;;
|
||||
t) turbo="turbo"
|
||||
;;
|
||||
d) DUMP_LEVEL=${OPTARG}
|
||||
;;
|
||||
*) echo "invalid option -${OPT}" >&2
|
||||
exit 1
|
||||
esac
|
||||
@ -214,6 +217,9 @@ if [ "${ENABLE_MCOVERLAYFS}" == "yes" ]; then
|
||||
if [ ${linux_version_code} -eq 199168 -a ${rhel_release} -ge 327 ]; then
|
||||
enable_mcoverlay="yes"
|
||||
fi
|
||||
if [ ${linux_version_code} -ge 262144 -a ${linux_version_code} -lt 262400 ]; then
|
||||
enable_mcoverlay="yes"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
@ -395,7 +401,7 @@ if ! ${SBINDIR}/ihkosctl 0 load ${KERNDIR}/mckernel.img; then
|
||||
fi
|
||||
|
||||
# Set kernel arguments
|
||||
if ! ${SBINDIR}/ihkosctl 0 kargs "hidos ksyslogd=${LOGMODE} $turbo"; then
|
||||
if ! ${SBINDIR}/ihkosctl 0 kargs "hidos ksyslogd=${LOGMODE} $turbo dump_level=${DUMP_LEVEL}"; then
|
||||
echo "error: setting kernel arguments" >&2
|
||||
error_exit "os_created"
|
||||
fi
|
||||
|
||||
@ -518,6 +518,8 @@ AC_CONFIG_FILES([
|
||||
Makefile
|
||||
executer/user/Makefile
|
||||
executer/user/arch/$ARCH/Makefile
|
||||
executer/user/arch/x86_64/Makefile
|
||||
executer/user/vmcore2mckdump
|
||||
executer/kernel/mcctrl/Makefile
|
||||
executer/kernel/mcctrl/arch/$ARCH/Makefile
|
||||
executer/kernel/mcoverlayfs/Makefile
|
||||
|
||||
6671
executer/include/defs.h
Executable file
6671
executer/include/defs.h
Executable file
File diff suppressed because it is too large
Load Diff
@ -21,7 +21,10 @@ endif
|
||||
endif
|
||||
ifeq ($(BUILD_MODULE_TMP),rhel)
|
||||
ifeq ($(BUILD_MODULE),none)
|
||||
BUILD_MODULE=$(shell if [ ${LINUX_VERSION_CODE} -eq 199168 -a ${RHEL_RELEASE} -ge 327 -a ${RHEL_RELEASE} -le 514 ]; then echo "linux-3.10.0-327.36.1.el7"; else echo "none"; fi)
|
||||
BUILD_MODULE=$(shell if [ ${LINUX_VERSION_CODE} -eq 199168 -a ${RHEL_RELEASE} -ge 327 -a ${RHEL_RELEASE} -le 693 ]; then echo "linux-3.10.0-327.36.1.el7"; else echo "none"; fi)
|
||||
endif
|
||||
ifeq ($(BUILD_MODULE),none)
|
||||
BUILD_MODULE=$(shell if [ ${LINUX_VERSION_CODE} -ge 262144 -a ${LINUX_VERSION_CODE} -lt 262400 ]; then echo "linux-4.0.9"; else echo "none"; fi)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
@ -13,7 +13,7 @@ CFLAGS=-Wall -O -I. -I$(VPATH)/arch/${ARCH}
|
||||
LDFLAGS=@LDFLAGS@
|
||||
RPATH=$(shell echo $(LDFLAGS)|awk '{for(i=1;i<=NF;i++){if($$i~/^-L/){w=$$i;sub(/^-L/,"-Wl,-rpath,",w);print w}}}')
|
||||
VPATH=@abs_srcdir@
|
||||
TARGET=mcexec libsched_yield
|
||||
TARGET=mcexec libsched_yield ldump2mcdump.so
|
||||
@uncomment_if_ENABLE_MEMDUMP@TARGET+=eclair
|
||||
LIBS=@LIBS@
|
||||
ARCH=@ARCH@
|
||||
@ -45,6 +45,9 @@ eclair: eclair.c
|
||||
$(CC) $(CFLAGS) -I${IHKDIR} -o $@ $^ $(LIBS)
|
||||
endif
|
||||
|
||||
ldump2mcdump.so: ldump2mcdump.c
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -shared -fPIC -o $@ $<
|
||||
|
||||
libsched_yield: libsched_yield.c
|
||||
$(CC) -shared -fPIC -Wl,-soname,sched_yield.so.1 -o libsched_yield.so.1.0.0 $^ -lc -ldl
|
||||
|
||||
@ -83,6 +86,7 @@ install::
|
||||
mkdir -p -m 755 $(BINDIR)
|
||||
install -m 755 mcexec $(BINDIR)
|
||||
mkdir -p -m 755 $(MCKERNEL_LIBDIR)
|
||||
install -m 755 ldump2mcdump.so $(MCKERNEL_LIBDIR)
|
||||
install -m 755 libsched_yield.so.1.0.0 $(MCKERNEL_LIBDIR)
|
||||
ifeq ($(ENABLE_QLMPI),yes)
|
||||
install -m 644 ../include/qlmpilib.h $(MCKERNEL_INCDIR)
|
||||
@ -94,3 +98,5 @@ ifeq ($(ENABLE_QLMPI),yes)
|
||||
install -m 755 ql_talker $(SBINDIR)
|
||||
endif
|
||||
@uncomment_if_ENABLE_MEMDUMP@install -m 755 eclair $(BINDIR)
|
||||
@uncomment_if_ENABLE_MEMDUMP@install -m 755 vmcore2mckdump $(BINDIR)
|
||||
|
||||
|
||||
@ -29,6 +29,8 @@
|
||||
|
||||
#define CPU_TID_BASE 1000000
|
||||
|
||||
#define PHYSMEM_NAME_SIZE 32
|
||||
|
||||
struct options {
|
||||
uint8_t cpu;
|
||||
uint8_t help;
|
||||
@ -123,6 +125,8 @@ static int read_physmem(uintptr_t pa, void *buf, size_t size) {
|
||||
bfd_boolean ok;
|
||||
int i;
|
||||
|
||||
char physmem_name[PHYSMEM_NAME_SIZE];
|
||||
|
||||
off = 0;
|
||||
/* Check if pa is valid in any chunks and figure
|
||||
* out the global offset in dump section */
|
||||
@ -135,8 +139,6 @@ static int read_physmem(uintptr_t pa, void *buf, size_t size) {
|
||||
off += (pa - mem_chunks->chunks[i].addr);
|
||||
break;
|
||||
}
|
||||
|
||||
off += mem_chunks->chunks[i].size;
|
||||
}
|
||||
|
||||
if (i == mem_chunks->nr_chunks) {
|
||||
@ -144,6 +146,15 @@ static int read_physmem(uintptr_t pa, void *buf, size_t size) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
memset(physmem_name,0,sizeof(physmem_name));
|
||||
sprintf(physmem_name, "physmem%d",i);
|
||||
|
||||
dumpscn = bfd_get_section_by_name(dumpbfd, physmem_name);
|
||||
if (!dumpscn) {
|
||||
bfd_perror("read_physmem:bfd_get_section_by_name(physmem)");
|
||||
return 1;
|
||||
}
|
||||
|
||||
ok = bfd_get_section_contents(dumpbfd, dumpscn, buf, off, size);
|
||||
if (!ok) {
|
||||
bfd_perror("read_physmem:bfd_get_section_contents");
|
||||
@ -596,6 +607,11 @@ static int setup_symbols(char *fname) {
|
||||
|
||||
static int setup_dump(char *fname) {
|
||||
bfd_boolean ok;
|
||||
long mem_size;
|
||||
static dump_mem_chunks_t mem_info;
|
||||
|
||||
char physmem_name[PHYSMEM_NAME_SIZE];
|
||||
int i;
|
||||
|
||||
#ifdef POSTK_DEBUG_ARCH_DEP_34
|
||||
dumpbfd = bfd_fopen(opt.dump_path, NULL, "r", -1);
|
||||
@ -613,32 +629,46 @@ static int setup_dump(char *fname) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
mem_chunks = malloc(PHYS_CHUNKS_DESC_SIZE);
|
||||
if (!mem_chunks) {
|
||||
perror("allocating mem chunks descriptor: ");
|
||||
return 1;
|
||||
}
|
||||
|
||||
dumpscn = bfd_get_section_by_name(dumpbfd, "physchunks");
|
||||
if (!dumpscn) {
|
||||
bfd_perror("bfd_get_section_by_name");
|
||||
return 1;
|
||||
}
|
||||
|
||||
ok = bfd_get_section_contents(dumpbfd, dumpscn, mem_chunks,
|
||||
0, PHYS_CHUNKS_DESC_SIZE);
|
||||
ok = bfd_get_section_contents(dumpbfd, dumpscn, &mem_info,
|
||||
0, sizeof(mem_info));
|
||||
if (!ok) {
|
||||
bfd_perror("read_physmem:bfd_get_section_contents");
|
||||
bfd_perror("read_physmem:bfd_get_section_contents(mem_size)");
|
||||
return 1;
|
||||
}
|
||||
|
||||
mem_size = (sizeof(dump_mem_chunks_t) + (sizeof(struct dump_mem_chunk) * mem_info.nr_chunks));
|
||||
|
||||
mem_chunks = malloc(mem_size);
|
||||
if (!mem_chunks) {
|
||||
perror("allocating mem chunks descriptor: ");
|
||||
return 1;
|
||||
}
|
||||
|
||||
ok = bfd_get_section_contents(dumpbfd, dumpscn, mem_chunks,
|
||||
0, mem_size);
|
||||
if (!ok) {
|
||||
bfd_perror("read_physmem:bfd_get_section_contents(mem_chunks)");
|
||||
return 1;
|
||||
}
|
||||
|
||||
kernel_base = mem_chunks->kernel_base;
|
||||
|
||||
dumpscn = bfd_get_section_by_name(dumpbfd, "physmem");
|
||||
for (i = 0; i < mem_info.nr_chunks; ++i) {
|
||||
memset(physmem_name,0,sizeof(physmem_name));
|
||||
sprintf(physmem_name, "physmem%d",i);
|
||||
|
||||
dumpscn = bfd_get_section_by_name(dumpbfd, physmem_name);
|
||||
if (!dumpscn) {
|
||||
bfd_perror("bfd_get_section_by_name");
|
||||
bfd_perror("read_physmem:bfd_get_section_by_name(physmem)");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
} /* setup_dump() */
|
||||
|
||||
483
executer/user/ldump2mcdump.c
Normal file
483
executer/user/ldump2mcdump.c
Normal file
@ -0,0 +1,483 @@
|
||||
|
||||
#include "../include/defs.h" /* From the crash source top-level directory */
|
||||
#include <bfd.h>
|
||||
#include <pwd.h>
|
||||
|
||||
void ldump2mcdump_init(void); /* constructor function */
|
||||
void ldump2mcdump_fini(void); /* destructor function (optional) */
|
||||
|
||||
void cmd_ldump2mcdump(void); /* Declare the commands and their help data. */
|
||||
char *help_ldump2mcdump[];
|
||||
|
||||
static struct command_table_entry command_table[] = {
|
||||
{ "ldump2mcdump", cmd_ldump2mcdump, help_ldump2mcdump, 0}, /* One or more commands, */
|
||||
{ NULL }, /* terminated by NULL, */
|
||||
};
|
||||
|
||||
|
||||
void __attribute__((constructor))
|
||||
ldump2mcdump_init(void) /* Register the command set. */
|
||||
{
|
||||
register_extension(command_table);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is called if the shared object is unloaded.
|
||||
* If desired, perform any cleanups here.
|
||||
*/
|
||||
void __attribute__((destructor))
|
||||
ldump2mcdump_fini(void) { }
|
||||
|
||||
struct ihk_dump_page {
|
||||
unsigned long start;
|
||||
unsigned long map_count;
|
||||
unsigned long map[0];
|
||||
};
|
||||
|
||||
struct ihk_dump_page_set {
|
||||
unsigned int completion_flag;
|
||||
unsigned int count;
|
||||
unsigned long page_size;
|
||||
unsigned long phy_page;
|
||||
};
|
||||
|
||||
struct dump_mem_chunk {
|
||||
unsigned long addr;
|
||||
unsigned long size;
|
||||
};
|
||||
|
||||
typedef struct dump_mem_chunks_s {
|
||||
int nr_chunks;
|
||||
unsigned long kernel_base;
|
||||
struct dump_mem_chunk chunks[];
|
||||
} dump_mem_chunks_t;
|
||||
|
||||
#define PATH_MAX 4096
|
||||
#define DUMP_MEM_SYMBOL "dump_page_set_addr"
|
||||
#define BOOTSTRAP_MEM_SYMBOL "dump_bootstrap_mem_start"
|
||||
#define MCDUMP_DEFAULT_FILENAME "mcdump"
|
||||
#define PAGE_SHIFT 12
|
||||
#define LARGE_PAGE_SHIFT 21
|
||||
#define LARGE_PAGE_SIZE (1UL << LARGE_PAGE_SHIFT)
|
||||
#define LARGE_PAGE_MASK (~((unsigned long)LARGE_PAGE_SIZE - 1))
|
||||
|
||||
#define PHYSMEM_NAME_SIZE 32
|
||||
|
||||
void cmd_ldump2mcdump(void)
|
||||
{
|
||||
static char path[PATH_MAX];
|
||||
static char hname[HOST_NAME_MAX+1];
|
||||
bfd *abfd = NULL;
|
||||
char *fname;
|
||||
bfd_boolean ok;
|
||||
asection *scn;
|
||||
unsigned long phys_size, phys_offset;
|
||||
int error;
|
||||
size_t bsize;
|
||||
void *buf = NULL;
|
||||
uintptr_t addr;
|
||||
size_t cpsize;
|
||||
time_t t;
|
||||
struct tm *tm;
|
||||
char *date;
|
||||
struct passwd *pw;
|
||||
dump_mem_chunks_t *mem_chunks = NULL;
|
||||
long mem_size;
|
||||
int opt = 0;
|
||||
int read_mem_ret = TRUE;
|
||||
|
||||
ulong symbol_dump_page_set = 0;
|
||||
ulong dump_page_set_addr = 0;
|
||||
ulong symbol_bootstrap_mem = 0;
|
||||
ulong bootstrap_mem = 0;
|
||||
struct ihk_dump_page_set dump_page_set;
|
||||
ulong ihk_dump_page_addr = 0;
|
||||
struct ihk_dump_page ihk_dump_page;
|
||||
ulong *map_buf = NULL;
|
||||
ulong map_size = 0;
|
||||
int i,j,k,index,mem_num;
|
||||
ulong map_start,bit_count;
|
||||
char *physmem_name_buf = NULL;
|
||||
char physmem_name[PHYSMEM_NAME_SIZE];
|
||||
|
||||
ulong read_mem_addr = 0;
|
||||
|
||||
if (argcnt < 2) {
|
||||
perror("argument error");
|
||||
return;
|
||||
}
|
||||
|
||||
strcpy(path,MCDUMP_DEFAULT_FILENAME);
|
||||
|
||||
while ((opt = getopt(argcnt, args, "o:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'o': /* '-o' */
|
||||
strcpy(path,optarg);
|
||||
break;
|
||||
default: /* '?' */
|
||||
fprintf(stderr, "ldump2mcdump os_index [-o file_name]\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
fname = path;
|
||||
symbol_dump_page_set = symbol_value(DUMP_MEM_SYMBOL);
|
||||
readmem(symbol_dump_page_set,KVADDR,&dump_page_set_addr,sizeof(dump_page_set_addr),"",FAULT_ON_ERROR);
|
||||
readmem(dump_page_set_addr,KVADDR,&dump_page_set,sizeof(dump_page_set),"",FAULT_ON_ERROR);
|
||||
|
||||
// DUMP_QUERY_NUM_MEM_AREAS
|
||||
ihk_dump_page_addr = PTOV(dump_page_set.phy_page);
|
||||
for (i = 0, mem_num = 0; i < dump_page_set.count; i++) {
|
||||
|
||||
readmem(ihk_dump_page_addr,KVADDR,&ihk_dump_page,sizeof(ihk_dump_page),"",FAULT_ON_ERROR);
|
||||
map_size = sizeof(unsigned long)*ihk_dump_page.map_count;
|
||||
map_buf = malloc(map_size);
|
||||
if (map_buf != NULL) {
|
||||
memset(map_buf,0x00,map_size);
|
||||
readmem((ihk_dump_page_addr+sizeof(struct ihk_dump_page)),KVADDR,map_buf,map_size,"",FAULT_ON_ERROR);
|
||||
|
||||
for (j = 0, bit_count = 0; j < ihk_dump_page.map_count; j++) {
|
||||
for ( k = 0; k < 64; k++) {
|
||||
if (((ulong)*(map_buf+j) >> k) & 0x1) {
|
||||
bit_count++;
|
||||
} else {
|
||||
if (bit_count) {
|
||||
mem_num++;
|
||||
bit_count = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bit_count) {
|
||||
mem_num++;
|
||||
}
|
||||
free(map_buf);
|
||||
} else {
|
||||
perror("allocating mem buffer: ");
|
||||
return;
|
||||
}
|
||||
|
||||
ihk_dump_page_addr += (sizeof(struct ihk_dump_page)+(sizeof(unsigned long)*ihk_dump_page.map_count));
|
||||
}
|
||||
mem_size = (sizeof(dump_mem_chunks_t) + (sizeof(struct dump_mem_chunk) * mem_num));
|
||||
|
||||
// DUMP_QUERY_MEM_AREAS
|
||||
mem_chunks = malloc(mem_size);
|
||||
if (mem_chunks != NULL) {
|
||||
memset(mem_chunks, 0, mem_size);
|
||||
ihk_dump_page_addr = PTOV(dump_page_set.phy_page);
|
||||
|
||||
for (i = 0, index = 0; i < dump_page_set.count; i++) {
|
||||
|
||||
readmem(ihk_dump_page_addr,KVADDR,&ihk_dump_page,sizeof(ihk_dump_page),"",FAULT_ON_ERROR);
|
||||
map_size = sizeof(unsigned long)*ihk_dump_page.map_count;
|
||||
map_buf = malloc(map_size);
|
||||
if (map_buf != NULL) {
|
||||
memset(map_buf,0x00,map_size);
|
||||
readmem((ihk_dump_page_addr+sizeof(struct ihk_dump_page)),KVADDR,map_buf,map_size,"",FAULT_ON_ERROR);
|
||||
|
||||
for (j = 0, bit_count = 0; j < ihk_dump_page.map_count; j++) {
|
||||
for (k = 0; k < 64; k++) {
|
||||
if (((ulong)*(map_buf+j) >> k) & 0x1) {
|
||||
if (!bit_count) {
|
||||
map_start = (unsigned long)(ihk_dump_page.start + ((unsigned long)j << (PAGE_SHIFT+6)));
|
||||
map_start = map_start + ((unsigned long)k << PAGE_SHIFT);
|
||||
}
|
||||
bit_count++;
|
||||
} else {
|
||||
if (bit_count) {
|
||||
mem_chunks->chunks[index].addr = map_start;
|
||||
mem_chunks->chunks[index].size = (bit_count << PAGE_SHIFT);
|
||||
index++;
|
||||
bit_count = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (bit_count) {
|
||||
mem_chunks->chunks[index].addr = map_start;
|
||||
mem_chunks->chunks[index].size = (bit_count << PAGE_SHIFT);
|
||||
index++;
|
||||
}
|
||||
|
||||
ihk_dump_page_addr += (sizeof(struct ihk_dump_page)+(sizeof(unsigned long)*ihk_dump_page.map_count));
|
||||
free(map_buf);
|
||||
} else {
|
||||
perror("allocating mem buffer: ");
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
mem_chunks->nr_chunks = index;
|
||||
|
||||
symbol_bootstrap_mem = symbol_value(BOOTSTRAP_MEM_SYMBOL);
|
||||
|
||||
readmem(symbol_bootstrap_mem,KVADDR,&bootstrap_mem,sizeof(bootstrap_mem),"",FAULT_ON_ERROR);
|
||||
|
||||
/* See load_file() for the calculation below */
|
||||
mem_chunks->kernel_base =
|
||||
(bootstrap_mem + LARGE_PAGE_SIZE * 2 - 1) & LARGE_PAGE_MASK;
|
||||
} else {
|
||||
perror("allocating mem buffer: ");
|
||||
return;
|
||||
}
|
||||
|
||||
// DUMP_READ
|
||||
phys_size = 0;
|
||||
|
||||
// fprintf(fp,"%s: nr chunks: %d\n", __FUNCTION__, mem_chunks->nr_chunks);
|
||||
for (i = 0; i < mem_chunks->nr_chunks; ++i) {
|
||||
// fprintf(fp,"%s: 0x%lx:0x%lx\n",
|
||||
// __FUNCTION__,
|
||||
// mem_chunks->chunks[i].addr,
|
||||
// mem_chunks->chunks[i].size);
|
||||
phys_size += mem_chunks->chunks[i].size;
|
||||
}
|
||||
|
||||
bsize = 0x100000;
|
||||
buf = malloc(bsize);
|
||||
if (!buf) {
|
||||
perror("malloc");
|
||||
return;
|
||||
}
|
||||
|
||||
bfd_init();
|
||||
|
||||
abfd = bfd_fopen(fname, "elf64-x86-64", "w", -1);
|
||||
if (!abfd) {
|
||||
bfd_perror("bfd_fopen");
|
||||
return;
|
||||
}
|
||||
|
||||
ok = bfd_set_format(abfd, bfd_object);
|
||||
if (!ok) {
|
||||
bfd_perror("bfd_set_format");
|
||||
return;
|
||||
}
|
||||
|
||||
t = time(NULL);
|
||||
if (t == (time_t)-1) {
|
||||
perror("time");
|
||||
return;
|
||||
}
|
||||
|
||||
tm = localtime(&t);
|
||||
if (!tm) {
|
||||
perror("localtime");
|
||||
return;
|
||||
}
|
||||
|
||||
date = asctime(tm);
|
||||
if (date) {
|
||||
cpsize = strlen(date) - 1; /* exclude trailing '\n' */
|
||||
scn = bfd_make_section_anyway(abfd, "date");
|
||||
if (!scn) {
|
||||
bfd_perror("bfd_make_section_anyway(date)");
|
||||
return;
|
||||
}
|
||||
|
||||
ok = bfd_set_section_size(abfd, scn, cpsize);
|
||||
if (!ok) {
|
||||
bfd_perror("bfd_set_section_size");
|
||||
return;
|
||||
}
|
||||
|
||||
ok = bfd_set_section_flags(abfd, scn, SEC_HAS_CONTENTS);
|
||||
if (!ok) {
|
||||
bfd_perror("bfd_set_setction_flags");
|
||||
return;
|
||||
}
|
||||
}
|
||||
error = gethostname(hname, sizeof(hname));
|
||||
if (!error) {
|
||||
cpsize = strlen(hname);
|
||||
scn = bfd_make_section_anyway(abfd, "hostname");
|
||||
if (!scn) {
|
||||
bfd_perror("bfd_make_section_anyway(hostname)");
|
||||
return;
|
||||
}
|
||||
|
||||
ok = bfd_set_section_size(abfd, scn, cpsize);
|
||||
if (!ok) {
|
||||
bfd_perror("bfd_set_section_size");
|
||||
return;
|
||||
}
|
||||
|
||||
ok = bfd_set_section_flags(abfd, scn, SEC_HAS_CONTENTS);
|
||||
if (!ok) {
|
||||
bfd_perror("bfd_set_setction_flags");
|
||||
return;
|
||||
}
|
||||
}
|
||||
pw = getpwuid(getuid());
|
||||
if (pw) {
|
||||
cpsize = strlen(pw->pw_name);
|
||||
scn = bfd_make_section_anyway(abfd, "user");
|
||||
if (!scn) {
|
||||
bfd_perror("bfd_make_section_anyway(user)");
|
||||
return;
|
||||
}
|
||||
|
||||
ok = bfd_set_section_size(abfd, scn, cpsize);
|
||||
if (!ok) {
|
||||
bfd_perror("bfd_set_section_size");
|
||||
return;
|
||||
}
|
||||
|
||||
ok = bfd_set_section_flags(abfd, scn, SEC_HAS_CONTENTS);
|
||||
if (!ok) {
|
||||
bfd_perror("bfd_set_setction_flags");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add section for physical memory chunks information */
|
||||
scn = bfd_make_section_anyway(abfd, "physchunks");
|
||||
if (!scn) {
|
||||
bfd_perror("bfd_make_section_anyway(physchunks)");
|
||||
return;
|
||||
}
|
||||
|
||||
ok = bfd_set_section_size(abfd, scn, mem_size);
|
||||
if (!ok) {
|
||||
bfd_perror("bfd_set_section_size");
|
||||
return;
|
||||
}
|
||||
|
||||
ok = bfd_set_section_flags(abfd, scn, SEC_ALLOC|SEC_HAS_CONTENTS);
|
||||
if (!ok) {
|
||||
bfd_perror("bfd_set_setction_flags");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < mem_chunks->nr_chunks; ++i) {
|
||||
|
||||
physmem_name_buf = malloc(PHYSMEM_NAME_SIZE);
|
||||
memset(physmem_name_buf,0,PHYSMEM_NAME_SIZE);
|
||||
sprintf(physmem_name_buf, "physmem%d",i);
|
||||
|
||||
/* Physical memory contents section */
|
||||
scn = bfd_make_section_anyway(abfd, physmem_name_buf);
|
||||
if (!scn) {
|
||||
bfd_perror("bfd_make_section_anyway(physmem)");
|
||||
return;
|
||||
}
|
||||
|
||||
ok = bfd_set_section_size(abfd, scn, mem_chunks->chunks[i].size);
|
||||
|
||||
if (!ok) {
|
||||
bfd_perror("bfd_set_section_size");
|
||||
return;
|
||||
}
|
||||
|
||||
ok = bfd_set_section_flags(abfd, scn, SEC_ALLOC|SEC_HAS_CONTENTS);
|
||||
if (!ok) {
|
||||
bfd_perror("bfd_set_setction_flags");
|
||||
return;
|
||||
}
|
||||
|
||||
scn->vma = mem_chunks->chunks[i].addr;
|
||||
|
||||
}
|
||||
|
||||
scn = bfd_get_section_by_name(abfd, "date");
|
||||
if (scn) {
|
||||
ok = bfd_set_section_contents(abfd, scn, date, 0, scn->size);
|
||||
if (!ok) {
|
||||
bfd_perror("bfd_set_section_contents(date)");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
scn = bfd_get_section_by_name(abfd, "hostname");
|
||||
if (scn) {
|
||||
ok = bfd_set_section_contents(abfd, scn, hname, 0, scn->size);
|
||||
if (!ok) {
|
||||
bfd_perror("bfd_set_section_contents(hostname)");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
scn = bfd_get_section_by_name(abfd, "user");
|
||||
if (scn) {
|
||||
ok = bfd_set_section_contents(abfd, scn, pw->pw_name, 0, scn->size);
|
||||
if (!ok) {
|
||||
bfd_perror("bfd_set_section_contents(user)");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
scn = bfd_get_section_by_name(abfd, "physchunks");
|
||||
if (scn) {
|
||||
ok = bfd_set_section_contents(abfd, scn, mem_chunks, 0, mem_size);
|
||||
if (!ok) {
|
||||
bfd_perror("bfd_set_section_contents(physchunks)");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < mem_chunks->nr_chunks; ++i) {
|
||||
|
||||
phys_offset = 0;
|
||||
memset(physmem_name,0,sizeof(physmem_name));
|
||||
sprintf(physmem_name, "physmem%d",i);
|
||||
|
||||
scn = bfd_get_section_by_name(abfd, physmem_name);
|
||||
if (!scn) {
|
||||
bfd_perror("err bfd_get_section_by_name(physmem_name)");
|
||||
return ;
|
||||
}
|
||||
|
||||
for (addr = mem_chunks->chunks[i].addr;
|
||||
addr < (mem_chunks->chunks[i].addr + mem_chunks->chunks[i].size);
|
||||
addr += cpsize) {
|
||||
|
||||
cpsize = (mem_chunks->chunks[i].addr + mem_chunks->chunks[i].size) - addr;
|
||||
if (cpsize > bsize) {
|
||||
cpsize = bsize;
|
||||
}
|
||||
|
||||
memset(buf,0x00,cpsize);
|
||||
read_mem_addr = PTOV(addr);
|
||||
read_mem_ret = readmem(read_mem_addr,KVADDR,buf,cpsize,"",FAULT_ON_ERROR|RETURN_ON_ERROR);
|
||||
if (read_mem_ret == TRUE) {
|
||||
ok = bfd_set_section_contents(abfd, scn, buf, phys_offset, cpsize);
|
||||
if (!ok) {
|
||||
bfd_perror("bfd_set_section_contents(physmem)");
|
||||
return;
|
||||
}
|
||||
|
||||
phys_offset += cpsize;
|
||||
} else {
|
||||
fprintf(fp, "readmem error(%d)\n",read_mem_ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ok = bfd_close(abfd);
|
||||
if (!ok) {
|
||||
bfd_perror("bfd_close");
|
||||
return;
|
||||
}
|
||||
|
||||
free(buf);
|
||||
free(mem_chunks);
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
char *help_ldump2mcdump[] = {
|
||||
"ldump2mcdump", /* command name */
|
||||
"dump format conversion", /* short description */
|
||||
"<os_index> [-o <file_name>]", /* argument synopsis, or " " if none */
|
||||
" This command converts the McKernel dump file format.",
|
||||
"\nEXAMPLE",
|
||||
" ldump2mcdump all command arguments:\n",
|
||||
" crash>ldump2mcdump 0 -o /tmp/mcdump",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
43
executer/user/vmcore2mckdump.in
Normal file
43
executer/user/vmcore2mckdump.in
Normal file
@ -0,0 +1,43 @@
|
||||
#!/bin/sh
|
||||
export VMLINUX=/usr/lib/debug/lib/modules/`uname -r`/vmlinux
|
||||
export INSTALLDIR=@prefix@
|
||||
export INFILE=$1
|
||||
export OUTFILE=$2
|
||||
|
||||
if [ "X$INFILE" = X -o "X$OUTFILE" = X -o "X$3" != X ]; then
|
||||
echo "usage: vmcore2mckdump <vmcore> <mckdump>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$INFILE" ]; then
|
||||
echo "$INFILE: not found" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
/usr/bin/expect -c "
|
||||
set timeout 60
|
||||
spawn /usr/bin/crash $VMLINUX $INFILE
|
||||
|
||||
expect \"crash>\"
|
||||
send \"mod -s ihk_smp_x86 $INSTALLDIR/kmod/ihk-smp-x86.ko\n\"
|
||||
|
||||
expect \"crash>\"
|
||||
send \"extend $INSTALLDIR/lib/ldump2mcdump.so\n\"
|
||||
|
||||
expect \"crash>\"
|
||||
send \"ldump2mcdump 0 -o $OUTFILE\n\"
|
||||
|
||||
expect \"crash>\"
|
||||
send \"extend -u $INSTALLDIR/lib/ldump2mcdump.so\n\"
|
||||
|
||||
expect \"crash>\"
|
||||
send \"quit\n\"
|
||||
"
|
||||
if [ -f ${OUTFILE} ]; then
|
||||
echo "mcdump: ${OUTFILE} is extracted."
|
||||
exit 0
|
||||
else
|
||||
echo "Error: failed to extract mcdump."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@ -65,8 +65,10 @@ extern void rb_erase(struct rb_node *, struct rb_root *);
|
||||
|
||||
/* Find logical next and previous nodes in a tree */
|
||||
extern struct rb_node *rb_next(const struct rb_node *);
|
||||
extern struct rb_node *rb_next_safe(const struct rb_node *);
|
||||
extern struct rb_node *rb_prev(const struct rb_node *);
|
||||
extern struct rb_node *rb_first(const struct rb_root *);
|
||||
extern struct rb_node *rb_first_safe(const struct rb_root *);
|
||||
extern struct rb_node *rb_last(const struct rb_root *);
|
||||
|
||||
/* Postorder iteration - always visit the parent after its children */
|
||||
|
||||
@ -48,6 +48,8 @@
|
||||
#define ekprintf(...) do { kprintf(__VA_ARGS__); } while (0)
|
||||
#endif
|
||||
|
||||
#define DUMP_LEVEL_USER_UNUSED_EXCLUDE 24
|
||||
|
||||
int osnum = 0;
|
||||
|
||||
extern struct ihk_kmsg_buf kmsg_buf;
|
||||
@ -426,12 +428,26 @@ int main(void)
|
||||
{
|
||||
char *ptr;
|
||||
int mode = 0;
|
||||
char *key_dump_level = "dump_level=";
|
||||
unsigned int dump_level = DUMP_LEVEL_USER_UNUSED_EXCLUDE;
|
||||
|
||||
ptr = find_command_line("ksyslogd=");
|
||||
if (ptr) {
|
||||
mode = ptr[9] - 0x30;
|
||||
if (mode < 0 || mode > 2) mode = 0;
|
||||
}
|
||||
|
||||
ptr = find_command_line(key_dump_level);
|
||||
if (ptr) {
|
||||
ptr += strlen(key_dump_level);
|
||||
dump_level = 0;
|
||||
while (('0' <= *ptr) && (*ptr <= '9')) {
|
||||
dump_level *= 10;
|
||||
dump_level += *ptr++ - '0';
|
||||
}
|
||||
}
|
||||
ihk_mc_set_dump_level(dump_level);
|
||||
|
||||
kmsg_init(mode);
|
||||
|
||||
kputs("IHK/McKernel started.\n");
|
||||
|
||||
241
kernel/mem.c
241
kernel/mem.c
@ -41,6 +41,7 @@
|
||||
#include <rusage.h>
|
||||
#include <syscall.h>
|
||||
#include <profile.h>
|
||||
#include <process.h>
|
||||
#include <limits.h>
|
||||
#include <sysfs.h>
|
||||
|
||||
@ -114,6 +115,38 @@ struct pagealloc_track_entry {
|
||||
ihk_spinlock_t addr_list_lock;
|
||||
};
|
||||
|
||||
struct page_table {
|
||||
pte_t entry[PT_ENTRIES];
|
||||
};
|
||||
|
||||
struct ihk_dump_page {
|
||||
unsigned long start;
|
||||
unsigned long map_count;
|
||||
unsigned long map[0];
|
||||
};
|
||||
|
||||
struct ihk_dump_page_set {
|
||||
volatile unsigned int completion_flag;
|
||||
unsigned int count;
|
||||
unsigned long page_size;
|
||||
unsigned long phy_page;
|
||||
};
|
||||
|
||||
struct dump_pase_info {
|
||||
struct ihk_dump_page_set *dump_page_set;
|
||||
struct ihk_dump_page *dump_pages;
|
||||
};
|
||||
|
||||
#define IHK_DUMP_PAGE_SET_INCOMPLETE 0
|
||||
#define IHK_DUMP_PAGE_SET_COMPLETED 1
|
||||
#define DUMP_LEVEL_ALL 0
|
||||
#define DUMP_LEVEL_USER_UNUSED_EXCLUDE 24
|
||||
|
||||
/** Get the index in the map array */
|
||||
#define MAP_INDEX(n) ((n) >> 6)
|
||||
/** Get the bit number in a map element */
|
||||
#define MAP_BIT(n) ((n) & 0x3f)
|
||||
|
||||
void pagealloc_track_init(void)
|
||||
{
|
||||
if (!pagealloc_track_initialized) {
|
||||
@ -2241,3 +2274,211 @@ int is_mckernel_memory(unsigned long phys)
|
||||
}
|
||||
#endif /* IHK_RBTREE_ALLOCATOR */
|
||||
#endif /* POSTK_DEBUG_TEMP_FIX_52 */
|
||||
|
||||
void ihk_mc_query_mem_areas(void){
|
||||
|
||||
int cpu_id;
|
||||
struct ihk_dump_page_set *dump_page_set;
|
||||
struct dump_pase_info dump_pase_info;
|
||||
|
||||
/* Performed only for CPU 0 */
|
||||
cpu_id = ihk_mc_get_processor_id();
|
||||
|
||||
if (0 != cpu_id)
|
||||
return;
|
||||
|
||||
dump_page_set = ihk_mc_get_dump_page_set();
|
||||
|
||||
if (DUMP_LEVEL_USER_UNUSED_EXCLUDE == ihk_mc_get_dump_level()) {
|
||||
if (dump_page_set->count) {
|
||||
|
||||
dump_pase_info.dump_page_set = dump_page_set;
|
||||
dump_pase_info.dump_pages = ihk_mc_get_dump_page();
|
||||
|
||||
/* Get user page information */
|
||||
ihk_mc_query_mem_user_page((void *)&dump_pase_info);
|
||||
/* Get unused page information */
|
||||
ihk_mc_query_mem_free_page((void *)&dump_pase_info);
|
||||
}
|
||||
}
|
||||
|
||||
dump_page_set->completion_flag = IHK_DUMP_PAGE_SET_COMPLETED;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void ihk_mc_query_mem_user_page(void *dump_pase_info) {
|
||||
|
||||
struct resource_set *rset = cpu_local_var(resource_set);
|
||||
struct process_hash *phash = rset->process_hash;
|
||||
struct process *p;
|
||||
struct process_vm *vm;
|
||||
int i;
|
||||
|
||||
for (i=0; i<HASH_SIZE; i++) {
|
||||
|
||||
list_for_each_entry(p, &phash->list[i], hash_list){
|
||||
vm = p->vm;
|
||||
if (vm) {
|
||||
if(vm->address_space->page_table) {
|
||||
visit_pte_range_safe(vm->address_space->page_table, 0,
|
||||
(void *)USER_END, 0, 0,
|
||||
&ihk_mc_get_mem_user_page, (void *)dump_pase_info);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void ihk_mc_query_mem_free_page(void *dump_pase_info) {
|
||||
|
||||
struct free_chunk *chunk;
|
||||
struct rb_node *node;
|
||||
struct rb_root *free_chunks;
|
||||
unsigned long phy_start, map_start, map_end, free_pages, free_page_cnt, map_size, set_size, k;
|
||||
int i, j;
|
||||
struct ihk_dump_page_set *dump_page_set;
|
||||
struct ihk_dump_page *dump_page;
|
||||
struct dump_pase_info *dump_pase_in;
|
||||
unsigned long chunk_addr, chunk_size;
|
||||
|
||||
dump_pase_in = (struct dump_pase_info *)dump_pase_info;
|
||||
dump_page_set = dump_pase_in->dump_page_set;
|
||||
|
||||
/* Search all NUMA nodes */
|
||||
for (i = 0; i < ihk_mc_get_nr_numa_nodes(); i++) {
|
||||
|
||||
free_chunks = &memory_nodes[i].free_chunks;
|
||||
free_pages = memory_nodes[i].nr_free_pages;
|
||||
|
||||
/* rb-tree search */
|
||||
for (free_page_cnt = 0, node = rb_first_safe(free_chunks); node; free_page_cnt++, node = rb_next_safe(node)) {
|
||||
|
||||
if (free_page_cnt >= free_pages)
|
||||
break;
|
||||
|
||||
/* Get chunk information */
|
||||
chunk = container_of(node, struct free_chunk, node);
|
||||
|
||||
dump_page = dump_pase_in->dump_pages;
|
||||
chunk_addr = chunk->addr;
|
||||
chunk_size = chunk->size;
|
||||
|
||||
for (j = 0; j < dump_page_set->count; j++) {
|
||||
|
||||
if (j) {
|
||||
dump_page = (struct ihk_dump_page *)((char *)dump_page + ((dump_page->map_count * sizeof(unsigned long)) + sizeof(struct ihk_dump_page)));
|
||||
}
|
||||
|
||||
phy_start = dump_page->start;
|
||||
map_size = (dump_page->map_count << (PAGE_SHIFT+6));
|
||||
|
||||
if ((chunk_addr >= phy_start)
|
||||
&& ((phy_start + map_size) >= chunk_addr)) {
|
||||
|
||||
/* Set free page to page map */
|
||||
map_start = (chunk_addr - phy_start) >> PAGE_SHIFT;
|
||||
|
||||
if ((phy_start + map_size) < (chunk_addr + chunk_size)) {
|
||||
set_size = map_size - (chunk_addr - phy_start);
|
||||
map_end = (map_start + (set_size >> PAGE_SHIFT));
|
||||
chunk_addr += set_size;
|
||||
chunk_size -= set_size;
|
||||
} else {
|
||||
map_end = (map_start + (chunk_size >> PAGE_SHIFT));
|
||||
}
|
||||
|
||||
for (k = map_start; k < map_end; k++) {
|
||||
|
||||
if (MAP_INDEX(k) >= dump_page->map_count) {
|
||||
kprintf("%s:free page is out of range(max:%d): %ld (map_start:0x%lx, map_end:0x%lx) k(0x%lx)\n", __FUNCTION__, dump_page->map_count, MAP_INDEX(k), map_start, map_end, k);
|
||||
break;
|
||||
}
|
||||
|
||||
dump_page->map[MAP_INDEX(k)] &= ~(1UL << MAP_BIT(k));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int ihk_mc_chk_page_address(pte_t mem_addr){
|
||||
|
||||
int i, numa_id;;
|
||||
unsigned long start, end;
|
||||
|
||||
/* Search all NUMA nodes */
|
||||
for (i = 0; i < ihk_mc_get_nr_memory_chunks(); i++) {
|
||||
ihk_mc_get_memory_chunk(i, &start, &end, &numa_id);
|
||||
if ((mem_addr >= start) && (end >= mem_addr))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ihk_mc_get_mem_user_page(void *arg0, page_table_t pt, pte_t *ptep, void *pgaddr, int pgshift)
|
||||
{
|
||||
struct ihk_dump_page_set *dump_page_set;
|
||||
int i;
|
||||
unsigned long j, phy_start, phys, map_start, map_end, map_size, set_size;
|
||||
struct ihk_dump_page *dump_page;
|
||||
struct dump_pase_info *dump_pase_in;
|
||||
unsigned long chunk_addr, chunk_size;
|
||||
|
||||
if (((*ptep) & PTATTR_ACTIVE) && ((*ptep) & PTATTR_USER)) {
|
||||
phys = pte_get_phys(ptep);
|
||||
/* Confirm accessible address */
|
||||
if (-1 != ihk_mc_chk_page_address(phys)) {
|
||||
|
||||
dump_pase_in = (struct dump_pase_info *)arg0;
|
||||
dump_page_set = dump_pase_in->dump_page_set;
|
||||
dump_page = dump_pase_in->dump_pages;
|
||||
|
||||
chunk_addr = phys;
|
||||
chunk_size = (1UL << pgshift);
|
||||
|
||||
for (i = 0; i < dump_page_set->count; i++) {
|
||||
|
||||
if (i) {
|
||||
dump_page = (struct ihk_dump_page *)((char *)dump_page + ((dump_page->map_count * sizeof(unsigned long)) + sizeof(struct ihk_dump_page)));
|
||||
}
|
||||
|
||||
phy_start = dump_page->start;
|
||||
map_size = (dump_page->map_count << (PAGE_SHIFT+6));
|
||||
|
||||
if ((chunk_addr >= phy_start)
|
||||
&& ((phy_start + map_size) >= chunk_addr)) {
|
||||
|
||||
/* Set user page to page map */
|
||||
map_start = (chunk_addr - phy_start) >> PAGE_SHIFT;
|
||||
|
||||
if ((phy_start + map_size) < (chunk_addr + chunk_size)) {
|
||||
set_size = map_size - (chunk_addr - phy_start);
|
||||
map_end = (map_start + (set_size >> PAGE_SHIFT));
|
||||
chunk_addr += set_size;
|
||||
chunk_size -= set_size;
|
||||
} else {
|
||||
map_end = (map_start + (chunk_size >> PAGE_SHIFT));
|
||||
}
|
||||
|
||||
for (j = map_start; j < map_end; j++) {
|
||||
|
||||
if (MAP_INDEX(j) >= dump_page->map_count) {
|
||||
kprintf("%s:user page is out of range(max:%d): %ld (map_start:0x%lx, map_end:0x%lx) j(0x%lx)\n", __FUNCTION__, dump_page->map_count, MAP_INDEX(j), map_start, map_end, j);
|
||||
break;
|
||||
}
|
||||
dump_page->map[MAP_INDEX(j)] &= ~(1UL << MAP_BIT(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -25,6 +25,9 @@
|
||||
|
||||
#define EXPORT_SYMBOL(x)
|
||||
|
||||
extern int ihk_mc_chk_page_address(unsigned long mem_addr);
|
||||
extern unsigned long virt_to_phys(void *v);
|
||||
|
||||
/*
|
||||
* red-black trees properties: http://en.wikipedia.org/wiki/Rbtree
|
||||
*
|
||||
@ -429,6 +432,32 @@ struct rb_node *rb_first(const struct rb_root *root)
|
||||
}
|
||||
EXPORT_SYMBOL(rb_first);
|
||||
|
||||
struct rb_node *rb_first_safe(const struct rb_root *root)
|
||||
{
|
||||
struct rb_node *n;
|
||||
unsigned long phys;
|
||||
|
||||
n = root->rb_node;
|
||||
if (!n)
|
||||
return NULL;
|
||||
|
||||
phys = virt_to_phys(n);
|
||||
if (-1 == ihk_mc_chk_page_address(phys))
|
||||
return NULL;
|
||||
|
||||
while (n->rb_left) {
|
||||
n = n->rb_left;
|
||||
if (!n)
|
||||
return NULL;
|
||||
|
||||
phys = virt_to_phys(n);
|
||||
if (-1 == ihk_mc_chk_page_address(phys))
|
||||
return NULL;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
EXPORT_SYMBOL(rb_first_safe);
|
||||
|
||||
struct rb_node *rb_last(const struct rb_root *root)
|
||||
{
|
||||
struct rb_node *n;
|
||||
@ -474,6 +503,58 @@ struct rb_node *rb_next(const struct rb_node *node)
|
||||
}
|
||||
EXPORT_SYMBOL(rb_next);
|
||||
|
||||
struct rb_node *rb_next_safe(const struct rb_node *node)
|
||||
{
|
||||
struct rb_node *parent;
|
||||
struct rb_node *chk_node;
|
||||
unsigned long phys;
|
||||
|
||||
if (RB_EMPTY_NODE(node))
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* If we have a right-hand child, go down and then left as far
|
||||
* as we can.
|
||||
*/
|
||||
if (node->rb_right) {
|
||||
node = node->rb_right;
|
||||
|
||||
if(!node)
|
||||
return NULL;
|
||||
|
||||
chk_node = (struct rb_node *)node;
|
||||
phys = virt_to_phys(chk_node);
|
||||
if (-1 == ihk_mc_chk_page_address(phys))
|
||||
return NULL;
|
||||
|
||||
while (node->rb_left) {
|
||||
node=node->rb_left;
|
||||
if(!node)
|
||||
return NULL;
|
||||
|
||||
chk_node = (struct rb_node *)node;
|
||||
phys = virt_to_phys(chk_node);
|
||||
if (-1 == ihk_mc_chk_page_address(phys))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (struct rb_node *)node;
|
||||
}
|
||||
|
||||
/*
|
||||
* No right-hand children. Everything down and left is smaller than us,
|
||||
* so any 'next' node must be in the general direction of our parent.
|
||||
* Go up the tree; any time the ancestor is a right-hand child of its
|
||||
* parent, keep going up. First time it's a left-hand child of its
|
||||
* parent, said parent is our 'next' node.
|
||||
*/
|
||||
while ((parent = rb_parent(node)) && node == parent->rb_right)
|
||||
node = parent;
|
||||
|
||||
return parent;
|
||||
}
|
||||
EXPORT_SYMBOL(rb_next_safe);
|
||||
|
||||
struct rb_node *rb_prev(const struct rb_node *node)
|
||||
{
|
||||
struct rb_node *parent;
|
||||
|
||||
@ -189,6 +189,8 @@ typedef int pte_visitor_t(void *arg, page_table_t pt, pte_t *ptep,
|
||||
void *pgaddr, int pgshift);
|
||||
int visit_pte_range(page_table_t pt, void *start, void *end, int pgshift,
|
||||
enum visit_pte_flag flags, pte_visitor_t *funcp, void *arg);
|
||||
int visit_pte_range_safe(page_table_t pt, void *start, void *end, int pgshift,
|
||||
enum visit_pte_flag flags, pte_visitor_t *funcp, void *arg);
|
||||
int move_pte_range(page_table_t pt, struct process_vm *vm,
|
||||
void *src, void *dest, size_t size, struct vm_range *range);
|
||||
|
||||
@ -239,4 +241,14 @@ struct tlb_flush_entry {
|
||||
|
||||
extern struct tlb_flush_entry tlb_flush_vector[IHK_TLB_FLUSH_IRQ_VECTOR_SIZE];
|
||||
|
||||
void ihk_mc_set_dump_level(unsigned int level);
|
||||
unsigned int ihk_mc_get_dump_level(void);
|
||||
struct ihk_dump_page_set *ihk_mc_get_dump_page_set(void);
|
||||
struct ihk_dump_page *ihk_mc_get_dump_page(void);
|
||||
void ihk_mc_query_mem_areas(void);
|
||||
void ihk_mc_query_mem_user_page(void *dump_page_set);
|
||||
void ihk_mc_query_mem_free_page(void *dump_page_set);
|
||||
int ihk_mc_chk_page_address(pte_t mem_addr);
|
||||
int ihk_mc_get_mem_user_page(void *arg0, page_table_t pt, pte_t *ptep, void *pgaddr, int pgshift);
|
||||
|
||||
#endif
|
||||
|
||||
3
test/dump/config
Executable file
3
test/dump/config
Executable file
@ -0,0 +1,3 @@
|
||||
MCMOD_DIR=$HOME/ppos
|
||||
|
||||
export MCMOD_DIR
|
||||
321
test/dump/destroy_mem.patch
Normal file
321
test/dump/destroy_mem.patch
Normal file
@ -0,0 +1,321 @@
|
||||
diff --git a/arch/x86/kernel/include/syscall_list.h b/arch/x86/kernel/include/syscall_list.h
|
||||
index 7c6edcb..f7f709b 100644
|
||||
--- a/arch/x86/kernel/include/syscall_list.h
|
||||
+++ b/arch/x86/kernel/include/syscall_list.h
|
||||
@@ -161,6 +161,9 @@ SYSCALL_HANDLED(__NR_profile, profile)
|
||||
SYSCALL_HANDLED(730, util_migrate_inter_kernel)
|
||||
SYSCALL_HANDLED(731, util_indicate_clone)
|
||||
SYSCALL_HANDLED(732, get_system)
|
||||
+/* McKernel Specific */
|
||||
+SYSCALL_HANDLED(901, usedmem_destroy)
|
||||
+SYSCALL_HANDLED(902, freemem_destroy)
|
||||
|
||||
/* McKernel Specific */
|
||||
SYSCALL_HANDLED(801, swapout)
|
||||
diff --git a/arch/x86/kernel/memory.c b/arch/x86/kernel/memory.c
|
||||
index 293daff..d7f17b9 100644
|
||||
--- a/arch/x86/kernel/memory.c
|
||||
+++ b/arch/x86/kernel/memory.c
|
||||
@@ -36,6 +36,8 @@
|
||||
#define ekprintf(...) do { kprintf(__VA_ARGS__); } while (0)
|
||||
#endif
|
||||
|
||||
+#define MEM_DESTROY_VAL 0xffffffffffffffff
|
||||
+
|
||||
static char *last_page;
|
||||
extern char _head[], _end[];
|
||||
|
||||
@@ -1364,6 +1366,119 @@ int visit_pte_range_safe(page_table_t pt, void *start0, void *end0, int pgshift,
|
||||
return walk_pte_l4_safe(pt, 0, start, end, &visit_pte_l4_safe, &args);
|
||||
}
|
||||
|
||||
+static int visit_pte_l1_dest(void *arg0, pte_t *ptep, uintptr_t base,
|
||||
+ uintptr_t start, uintptr_t end)
|
||||
+{
|
||||
+ if (*ptep == PTE_NULL) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ *ptep = MEM_DESTROY_VAL;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int visit_pte_l2_dest(void *arg0, pte_t *ptep, uintptr_t base,
|
||||
+ uintptr_t start, uintptr_t end)
|
||||
+{
|
||||
+ int error = 0;
|
||||
+ struct visit_pte_args *args = arg0;
|
||||
+ struct page_table *pt;
|
||||
+
|
||||
+ if (*ptep == PTE_NULL) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if ((*ptep & PFL2_SIZE)
|
||||
+ && (start <= base)
|
||||
+ && (((base + PTL2_SIZE) <= end)
|
||||
+ || (end == 0))
|
||||
+ && (!args->pgshift || (args->pgshift == PTL2_SHIFT))) {
|
||||
+
|
||||
+ *ptep = MEM_DESTROY_VAL;
|
||||
+ return error;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ if (*ptep & PFL2_SIZE) {
|
||||
+ ekprintf("visit_pte_l2:split large page\n");
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ pt = phys_to_virt(*ptep & PT_PHYSMASK);
|
||||
+
|
||||
+ error = walk_pte_l1_safe(pt, base, start, end, &visit_pte_l1_dest, arg0);
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
+static int visit_pte_l3_dest(void *arg0, pte_t *ptep, uintptr_t base,
|
||||
+ uintptr_t start, uintptr_t end)
|
||||
+{
|
||||
+ int error = 0;
|
||||
+ struct visit_pte_args *args = arg0;
|
||||
+ struct page_table *pt;
|
||||
+
|
||||
+ if (*ptep == PTE_NULL) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if ((*ptep & PFL3_SIZE)
|
||||
+ && (start <= base)
|
||||
+ && (((base + PTL3_SIZE) <= end)
|
||||
+ || (end == 0))
|
||||
+ && (!args->pgshift || (args->pgshift == PTL3_SHIFT))
|
||||
+ && use_1gb_page) {
|
||||
+
|
||||
+ *ptep =MEM_DESTROY_VAL;
|
||||
+ return error;
|
||||
+ }
|
||||
+
|
||||
+ if (*ptep & PFL3_SIZE) {
|
||||
+ ekprintf("visit_pte_l3:split large page\n");
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ pt = phys_to_virt(*ptep & PT_PHYSMASK);
|
||||
+
|
||||
+ error = walk_pte_l2_safe(pt, base, start, end, &visit_pte_l2_dest, arg0);
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
+static int visit_pte_l4_dest(void *arg0, pte_t *ptep, uintptr_t base,
|
||||
+ uintptr_t start, uintptr_t end)
|
||||
+{
|
||||
+ int error;
|
||||
+ struct page_table *pt;
|
||||
+
|
||||
+ kprintf("%s:Start.\n", __FUNCTION__);
|
||||
+
|
||||
+ if (*ptep == PTE_NULL) {
|
||||
+ kprintf("%s:End.\n", __FUNCTION__);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ pt = phys_to_virt(*ptep & PT_PHYSMASK);
|
||||
+
|
||||
+ error = walk_pte_l3_safe(pt, base, start, end, &visit_pte_l3_dest, arg0);
|
||||
+ kprintf("%s:End.\n", __FUNCTION__);
|
||||
+ return error;
|
||||
+}
|
||||
+
|
||||
+int visit_pte_range_dest(page_table_t pt, void *start0, void *end0, int pgshift,
|
||||
+ enum visit_pte_flag flags, pte_visitor_t *funcp, void *arg)
|
||||
+{
|
||||
+ const uintptr_t start = (uintptr_t)start0;
|
||||
+ const uintptr_t end = (uintptr_t)end0;
|
||||
+ struct visit_pte_args args;
|
||||
+
|
||||
+ args.pt = pt;
|
||||
+ args.flags = flags;
|
||||
+ args.funcp = funcp;
|
||||
+ args.arg = arg;
|
||||
+ args.pgshift = pgshift;
|
||||
+
|
||||
+ return walk_pte_l4_safe(pt, 0, start, end, &visit_pte_l4_dest, &args);
|
||||
+}
|
||||
+
|
||||
struct clear_range_args {
|
||||
int free_physical;
|
||||
struct memobj *memobj;
|
||||
diff --git a/kernel/include/rbtree.h b/kernel/include/rbtree.h
|
||||
index 990f0d7..24d71c2 100644
|
||||
--- a/kernel/include/rbtree.h
|
||||
+++ b/kernel/include/rbtree.h
|
||||
@@ -66,6 +66,7 @@ extern void rb_erase(struct rb_node *, struct rb_root *);
|
||||
/* Find logical next and previous nodes in a tree */
|
||||
extern struct rb_node *rb_next(const struct rb_node *);
|
||||
extern struct rb_node *rb_next_safe(const struct rb_node *);
|
||||
+extern struct rb_node *rb_next_dest(const struct rb_node *);
|
||||
extern struct rb_node *rb_prev(const struct rb_node *);
|
||||
extern struct rb_node *rb_first(const struct rb_root *);
|
||||
extern struct rb_node *rb_first_safe(const struct rb_root *);
|
||||
diff --git a/kernel/mem.c b/kernel/mem.c
|
||||
index 8fe450d..e8e05bd 100644
|
||||
--- a/kernel/mem.c
|
||||
+++ b/kernel/mem.c
|
||||
@@ -2482,3 +2482,28 @@ int ihk_mc_get_mem_user_page(void *arg0, page_table_t pt, pte_t *ptep, void *pga
|
||||
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
+void ihk_mc_mem_free_page_dest(void) {
|
||||
+ struct rb_node *node;
|
||||
+ struct rb_root *free_chunks;
|
||||
+ unsigned long free_pages, free_page_cnt;
|
||||
+ int i;
|
||||
+
|
||||
+ /* Search all NUMA nodes */
|
||||
+ for (i = 0; i < ihk_mc_get_nr_numa_nodes(); i++) {
|
||||
+
|
||||
+ free_chunks = &memory_nodes[i].free_chunks;
|
||||
+ free_pages = memory_nodes[i].nr_free_pages;
|
||||
+
|
||||
+ /* rb-tree search */
|
||||
+ for (free_page_cnt = 0, node = rb_first(free_chunks); node; free_page_cnt++, node = rb_next_dest(node)) {
|
||||
+
|
||||
+ if (free_page_cnt >= free_pages)
|
||||
+ break;
|
||||
+
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
diff --git a/kernel/rbtree.c b/kernel/rbtree.c
|
||||
index 5134a0d..2a0383f 100644
|
||||
--- a/kernel/rbtree.c
|
||||
+++ b/kernel/rbtree.c
|
||||
@@ -25,6 +25,8 @@
|
||||
|
||||
#define EXPORT_SYMBOL(x)
|
||||
|
||||
+#define MEM_DESTROY_VAL 0xffffffffffffffff
|
||||
+
|
||||
extern int ihk_mc_chk_page_address(unsigned long mem_addr);
|
||||
extern unsigned long virt_to_phys(void *v);
|
||||
|
||||
@@ -555,6 +557,47 @@ struct rb_node *rb_next_safe(const struct rb_node *node)
|
||||
}
|
||||
EXPORT_SYMBOL(rb_next_safe);
|
||||
|
||||
+struct rb_node *rb_next_dest(const struct rb_node *node)
|
||||
+{
|
||||
+ struct rb_node *parent;
|
||||
+ struct rb_node *node_tmp = NULL;
|
||||
+
|
||||
+ if (RB_EMPTY_NODE(node))
|
||||
+ return NULL;
|
||||
+
|
||||
+ /*
|
||||
+ * * If we have a right-hand child, go down and then left as far
|
||||
+ * * as we can.
|
||||
+ * */
|
||||
+ if (node->rb_right) {
|
||||
+ node = node->rb_right;
|
||||
+
|
||||
+ while (node->rb_left) {
|
||||
+ node_tmp = (struct rb_node *)node;
|
||||
+ node=node->rb_left;
|
||||
+ }
|
||||
+
|
||||
+ if(node_tmp != NULL) {
|
||||
+ node_tmp->rb_left = (struct rb_node *)MEM_DESTROY_VAL;
|
||||
+ }
|
||||
+
|
||||
+ return (struct rb_node *)node;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * * No right-hand children. Everything down and left is smaller than us,
|
||||
+ * * so any 'next' node must be in the general direction of our parent.
|
||||
+ * * Go up the tree; any time the ancestor is a right-hand child of its
|
||||
+ * * parent, keep going up. First time it's a left-hand child of its
|
||||
+ * * parent, said parent is our 'next' node.
|
||||
+ * */
|
||||
+ while ((parent = rb_parent(node)) && node == parent->rb_right)
|
||||
+ node = parent;
|
||||
+
|
||||
+ return parent;
|
||||
+}
|
||||
+EXPORT_SYMBOL(rb_next_dest);
|
||||
+
|
||||
struct rb_node *rb_prev(const struct rb_node *node)
|
||||
{
|
||||
struct rb_node *parent;
|
||||
diff --git a/kernel/syscall.c b/kernel/syscall.c
|
||||
index 6d23702..5620bf4 100644
|
||||
--- a/kernel/syscall.c
|
||||
+++ b/kernel/syscall.c
|
||||
@@ -9885,6 +9885,43 @@ set_cputime(int mode)
|
||||
}
|
||||
}
|
||||
|
||||
+SYSCALL_DECLARE(usedmem_destroy)
|
||||
+{
|
||||
+ kprintf("usedmem_destroy() call\n");
|
||||
+
|
||||
+ struct resource_set *rset = cpu_local_var(resource_set);
|
||||
+ struct process_hash *phash = rset->process_hash;
|
||||
+ struct process *p;
|
||||
+ struct process_vm *vm;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i=0; i<HASH_SIZE; i++) {
|
||||
+
|
||||
+ list_for_each_entry(p, &phash->list[i], hash_list){
|
||||
+ vm = p->vm;
|
||||
+ if (vm) {
|
||||
+ if(vm->address_space->page_table) {
|
||||
+ visit_pte_range_dest(vm->address_space->page_table, 0,
|
||||
+ (void *)USER_END, 0, 0,
|
||||
+ (void *)NULL, (void *)NULL);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+SYSCALL_DECLARE(freemem_destroy)
|
||||
+{
|
||||
+ kprintf("freemem_destroy() call\n");
|
||||
+
|
||||
+ ihk_mc_mem_free_page_dest();
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
long syscall(int num, ihk_mc_user_context_t *ctx)
|
||||
{
|
||||
long l;
|
||||
diff --git a/lib/include/ihk/mm.h b/lib/include/ihk/mm.h
|
||||
index 5b2aa70..18a5408 100644
|
||||
--- a/lib/include/ihk/mm.h
|
||||
+++ b/lib/include/ihk/mm.h
|
||||
@@ -191,6 +191,8 @@ int visit_pte_range(page_table_t pt, void *start, void *end, int pgshift,
|
||||
enum visit_pte_flag flags, pte_visitor_t *funcp, void *arg);
|
||||
int visit_pte_range_safe(page_table_t pt, void *start, void *end, int pgshift,
|
||||
enum visit_pte_flag flags, pte_visitor_t *funcp, void *arg);
|
||||
+int visit_pte_range_dest(page_table_t pt, void *start, void *end, int pgshift,
|
||||
+ enum visit_pte_flag flags, pte_visitor_t *funcp, void *arg);
|
||||
int move_pte_range(page_table_t pt, struct process_vm *vm,
|
||||
void *src, void *dest, size_t size, struct vm_range *range);
|
||||
|
||||
@@ -250,5 +252,5 @@ void ihk_mc_query_mem_user_page(void *dump_page_set);
|
||||
void ihk_mc_query_mem_free_page(void *dump_page_set);
|
||||
int ihk_mc_chk_page_address(pte_t mem_addr);
|
||||
int ihk_mc_get_mem_user_page(void *arg0, page_table_t pt, pte_t *ptep, void *pgaddr, int pgshift);
|
||||
-
|
||||
+void ihk_mc_mem_free_page_dest(void);
|
||||
#endif
|
||||
0
test/dump/dumps/.gitignore
vendored
Normal file
0
test/dump/dumps/.gitignore
vendored
Normal file
64
test/dump/go_linux_dump_test.sh
Executable file
64
test/dump/go_linux_dump_test.sh
Executable file
@ -0,0 +1,64 @@
|
||||
#!/bin/sh
|
||||
|
||||
source ./config
|
||||
|
||||
FORCE_STOP=${HOME}/tmp/force_stop_linux_dump
|
||||
if [ -e ${FORCE_STOP} ]; then
|
||||
echo "force stopped Linux dump test "
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PANIC_LIST="./panic_list"
|
||||
PROGRESS_FILE="${HOME}/progress_linux_dump_test.txt"
|
||||
|
||||
if [ ! -f ${PANIC_LIST} ]; then
|
||||
cp ${PANIC_LIST}.in ${PANIC_LIST}
|
||||
fi
|
||||
|
||||
# check existing of done_panic
|
||||
if [ -e ./done_panic ]; then
|
||||
# test of ldump2mcdump
|
||||
|
||||
source ./done_panic
|
||||
|
||||
# find latest vmcore file
|
||||
latest_vmcore_dir="/var/crash/`ls -1t /var/crash | head -1`"
|
||||
latest_vmcore="${latest_vmcore_dir}/vmcore"
|
||||
|
||||
if [ ! -e ${latest_vmcore} ]; then
|
||||
echo "Error: latest vmcore is not found."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for case_name in ${BELOW_CASES}
|
||||
do
|
||||
param_file=./linux_testcases/${case_name}.txt
|
||||
mkdir -p "./result/linux_dump"
|
||||
logfile="./result/linux_dump/${case_name}.log"
|
||||
|
||||
./linux_dump_test.sh ${latest_vmcore} ${param_file} &> ${logfile}
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "[OK] ${case_name} is done." >> ${PROGRESS_FILE}
|
||||
else
|
||||
echo "[NG] failed to test ${case_name}, Please check ${logfile}" >> ${PROGRESS_FILE}
|
||||
fi
|
||||
done
|
||||
|
||||
rm ./done_panic
|
||||
# remove vmcore
|
||||
sudo rm -r ${latest_vmcore_dir}
|
||||
|
||||
# remove dump_file
|
||||
sudo rm ./mcdump &> /dev/null
|
||||
sudo rm ./dumps/mcdump_* &> /dev/null
|
||||
fi
|
||||
|
||||
# occur test panic
|
||||
panic_param=`head -1 ./panic_list`
|
||||
if [ "X${panic_param}" = "X" ]; then
|
||||
echo "All panic is done"
|
||||
exit 0
|
||||
fi
|
||||
sed -i -e "/`basename ${panic_param}`/d" ./panic_list
|
||||
./linux_dump_panic.sh ${panic_param}
|
||||
|
||||
25
test/dump/go_mck_dump_test.sh
Executable file
25
test/dump/go_mck_dump_test.sh
Executable file
@ -0,0 +1,25 @@
|
||||
#!/bin/sh
|
||||
|
||||
for test_case in `ls -1 ./mck_testcases/*.txt`
|
||||
do
|
||||
case_name=`basename ${test_case} .txt`
|
||||
|
||||
mkdir -p "./result/mck_dump"
|
||||
|
||||
logfile="./result/mck_dump/${case_name}.log"
|
||||
./mck_dump_test.sh ${test_case} &> ${logfile}
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "[OK] ${case_name} is done."
|
||||
else
|
||||
echo "[NG] failed to test ${case_name}. Please check ${logfile}"
|
||||
fi
|
||||
|
||||
# save dump_file
|
||||
#sudo mv mcdump_* ./result/${case_name}/ &> /dev/null
|
||||
#sudo mv dumps/dumpfile_* ./result/${case_name}/ &> /dev/null
|
||||
|
||||
# remove dump_file
|
||||
sudo rm ./mcdump_* &> /dev/null
|
||||
sudo rm ./dumps/dumpfile_* &> /dev/null
|
||||
done
|
||||
25
test/dump/go_mck_dump_test_ofp.sh
Executable file
25
test/dump/go_mck_dump_test_ofp.sh
Executable file
@ -0,0 +1,25 @@
|
||||
#!/bin/sh
|
||||
|
||||
for test_case in `ls -1 ./mck_testcases_ofp/*.txt`
|
||||
do
|
||||
case_name=`basename ${test_case} .txt`
|
||||
|
||||
mkdir -p "./result/mck_dump"
|
||||
|
||||
logfile="./result/mck_dump/${case_name}.log"
|
||||
./mck_dump_test.sh ${test_case} &> ${logfile}
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "[OK] ${case_name} is done."
|
||||
else
|
||||
echo "[NG] failed to test ${case_name}. Please check ${logfile}"
|
||||
fi
|
||||
|
||||
# save dump_file
|
||||
#sudo mv mcdump_* ./result/${case_name}/ &> /dev/null
|
||||
#sudo mv dumps/dumpfile_* ./result/${case_name}/ &> /dev/null
|
||||
|
||||
# remove dump_file
|
||||
sudo rm ./mcdump_* &> /dev/null
|
||||
sudo rm ./dumps/dumpfile_* &> /dev/null
|
||||
done
|
||||
51
test/dump/linux_dump_panic.sh
Executable file
51
test/dump/linux_dump_panic.sh
Executable file
@ -0,0 +1,51 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ $# -lt 1 ]; then
|
||||
echo "Error: too few arguments."
|
||||
echo "usage: `basename $0` <param_file>"
|
||||
fi
|
||||
|
||||
# read config
|
||||
source ./config
|
||||
|
||||
# read testcase param
|
||||
source $1
|
||||
|
||||
echo `grep "BELOW_CASES" $1` > ./done_panic
|
||||
|
||||
# mcexec processのkill
|
||||
./utils/kill_mcexec.sh &> /dev/null
|
||||
|
||||
# stop mckernel
|
||||
#echo "${MCMOD_DIR}/sbin/mcstop+release.sh"
|
||||
sudo ${MCMOD_DIR}/sbin/mcstop+release.sh
|
||||
|
||||
# boot mckernel
|
||||
#echo "${MCMOD_DIR}/sbin/mcreboot.sh ${MCRBT_OPT%,}"
|
||||
sudo ${MCMOD_DIR}/sbin/mcreboot.sh ${MCRBT_OPT%,} ${DUMP_OPT}
|
||||
|
||||
sleep 1
|
||||
|
||||
if [ ! -e "/dev/mcos0" ]; then
|
||||
echo "Error: failed to mcreboot"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# exec mckernel test program
|
||||
for mc_proc in ${USR_PROC}
|
||||
do
|
||||
echo "${MCMOD_DIR}/bin/mcexec ${mc_proc}"
|
||||
${MCMOD_DIR}/bin/mcexec ${mc_proc} &
|
||||
done
|
||||
|
||||
# wait mmap
|
||||
sleep 10
|
||||
|
||||
echo `grep "BELOW_CASES" $1` > ./done_panic
|
||||
sleep 1
|
||||
|
||||
# do panic
|
||||
sudo sh -c "echo 1 > /proc/sys/kernel/sysrq"
|
||||
sudo sh -c "echo c > /proc/sysrq-trigger"
|
||||
|
||||
exit 0
|
||||
41
test/dump/linux_dump_test.sh
Executable file
41
test/dump/linux_dump_test.sh
Executable file
@ -0,0 +1,41 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ $# -lt 2 ]; then
|
||||
echo "Error: too few arguments"
|
||||
echo "usage: `basename $0` <vmcore> <test_param_file>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# read test_param_file
|
||||
source $2
|
||||
|
||||
VMCORE=$1
|
||||
|
||||
sudo sh -c "env MCMOD_DIR=${MCMOD_DIR} ./utils/extract_mckdump.sh ${VMCORE} ${OUTFILE}"
|
||||
sleep 1
|
||||
|
||||
if [ "X${OUTFILE}" = "X" ]; then
|
||||
out_mckdump="./mcdump"
|
||||
else
|
||||
out_mckdump="${OUTFILE}"
|
||||
fi
|
||||
|
||||
if [ "X${ERROR_CASE}" = "X" ]; then
|
||||
# Normal case
|
||||
if [ ! -f ${out_mckdump} ]; then
|
||||
echo "Error: ${out_mckdump} is not created."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# show dump_file info
|
||||
./utils/show_mckdump.sh ${out_mckdump}
|
||||
|
||||
else
|
||||
# Error case
|
||||
if [ -f ${out_mckdump} ]; then
|
||||
echo "Error: ${out_mckdump} is created."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
exit 0
|
||||
1
test/dump/linux_testcases/0001_linux.txt
Normal file
1
test/dump/linux_testcases/0001_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE="./dumps/mcdump_0001.dmp"
|
||||
1
test/dump/linux_testcases/0002_linux.txt
Normal file
1
test/dump/linux_testcases/0002_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE=""
|
||||
1
test/dump/linux_testcases/0003_linux.txt
Normal file
1
test/dump/linux_testcases/0003_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE="./dumps/mcdump_0003.dmp"
|
||||
1
test/dump/linux_testcases/0004_linux.txt
Normal file
1
test/dump/linux_testcases/0004_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE=""
|
||||
1
test/dump/linux_testcases/0005_linux.txt
Normal file
1
test/dump/linux_testcases/0005_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE="./dumps/mcdump_0005.dmp"
|
||||
1
test/dump/linux_testcases/0006_linux.txt
Normal file
1
test/dump/linux_testcases/0006_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE=""
|
||||
1
test/dump/linux_testcases/0007_linux.txt
Normal file
1
test/dump/linux_testcases/0007_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE="./dumps/mcdump_0007.dmp"
|
||||
1
test/dump/linux_testcases/0008_linux.txt
Normal file
1
test/dump/linux_testcases/0008_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE=""
|
||||
1
test/dump/linux_testcases/0009_linux.txt
Normal file
1
test/dump/linux_testcases/0009_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE="./dumps/mcdump_0009.dmp"
|
||||
1
test/dump/linux_testcases/0010_linux.txt
Normal file
1
test/dump/linux_testcases/0010_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE=""
|
||||
1
test/dump/linux_testcases/0011_linux.txt
Normal file
1
test/dump/linux_testcases/0011_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE="./dumps/mcdump_0011.dmp"
|
||||
1
test/dump/linux_testcases/0012_linux.txt
Normal file
1
test/dump/linux_testcases/0012_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE=""
|
||||
1
test/dump/linux_testcases/0013_linux.txt
Normal file
1
test/dump/linux_testcases/0013_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE="./dumps/mcdump_0013.dmp"
|
||||
1
test/dump/linux_testcases/0014_linux.txt
Normal file
1
test/dump/linux_testcases/0014_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE=""
|
||||
1
test/dump/linux_testcases/0015_linux.txt
Normal file
1
test/dump/linux_testcases/0015_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE="./dumps/mcdump_0015.dmp"
|
||||
1
test/dump/linux_testcases/0016_linux.txt
Normal file
1
test/dump/linux_testcases/0016_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE=""
|
||||
1
test/dump/linux_testcases/0017_linux.txt
Normal file
1
test/dump/linux_testcases/0017_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE="./dumps/mcdump_0017.dmp"
|
||||
1
test/dump/linux_testcases/0018_linux.txt
Normal file
1
test/dump/linux_testcases/0018_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE=""
|
||||
1
test/dump/linux_testcases/0019_linux.txt
Normal file
1
test/dump/linux_testcases/0019_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE="./dumps/mcdump_0019.dmp"
|
||||
1
test/dump/linux_testcases/0020_linux.txt
Normal file
1
test/dump/linux_testcases/0020_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE=""
|
||||
1
test/dump/linux_testcases/0021_linux.txt
Normal file
1
test/dump/linux_testcases/0021_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE="./dumps/mcdump_0021.dmp"
|
||||
1
test/dump/linux_testcases/0022_linux.txt
Normal file
1
test/dump/linux_testcases/0022_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE=""
|
||||
1
test/dump/linux_testcases/0023_linux.txt
Normal file
1
test/dump/linux_testcases/0023_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE="./dumps/mcdump_0023.dmp"
|
||||
1
test/dump/linux_testcases/0024_linux.txt
Normal file
1
test/dump/linux_testcases/0024_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE=""
|
||||
1
test/dump/linux_testcases/0025_linux.txt
Normal file
1
test/dump/linux_testcases/0025_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE="./dumps/mcdump_0025.dmp"
|
||||
1
test/dump/linux_testcases/0026_linux.txt
Normal file
1
test/dump/linux_testcases/0026_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE=""
|
||||
1
test/dump/linux_testcases/0027_linux.txt
Normal file
1
test/dump/linux_testcases/0027_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE="./dumps/mcdump_0027.dmp"
|
||||
1
test/dump/linux_testcases/0028_linux.txt
Normal file
1
test/dump/linux_testcases/0028_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE=""
|
||||
1
test/dump/linux_testcases/0029_linux.txt
Normal file
1
test/dump/linux_testcases/0029_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE="./dumps/mcdump_0029.dmp"
|
||||
1
test/dump/linux_testcases/0030_linux.txt
Normal file
1
test/dump/linux_testcases/0030_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE=""
|
||||
1
test/dump/linux_testcases/0031_linux.txt
Normal file
1
test/dump/linux_testcases/0031_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE="./dumps/mcdump_0031.dmp"
|
||||
1
test/dump/linux_testcases/0032_linux.txt
Normal file
1
test/dump/linux_testcases/0032_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE=""
|
||||
1
test/dump/linux_testcases/0033_linux.txt
Normal file
1
test/dump/linux_testcases/0033_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE="./dumps/mcdump_0033.dmp"
|
||||
1
test/dump/linux_testcases/0034_linux.txt
Normal file
1
test/dump/linux_testcases/0034_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE=""
|
||||
1
test/dump/linux_testcases/0035_linux.txt
Normal file
1
test/dump/linux_testcases/0035_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE="./dumps/mcdump_0035.dmp"
|
||||
1
test/dump/linux_testcases/0036_linux.txt
Normal file
1
test/dump/linux_testcases/0036_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE=""
|
||||
1
test/dump/linux_testcases/0037_linux.txt
Normal file
1
test/dump/linux_testcases/0037_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE="./dumps/mcdump_0037.dmp"
|
||||
1
test/dump/linux_testcases/0038_linux.txt
Normal file
1
test/dump/linux_testcases/0038_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE=""
|
||||
1
test/dump/linux_testcases/0039_linux.txt
Normal file
1
test/dump/linux_testcases/0039_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE="./dumps/mcdump_0039.dmp"
|
||||
1
test/dump/linux_testcases/0040_linux.txt
Normal file
1
test/dump/linux_testcases/0040_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE=""
|
||||
1
test/dump/linux_testcases/0041_linux.txt
Normal file
1
test/dump/linux_testcases/0041_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE="./dumps/mcdump_0041.dmp"
|
||||
1
test/dump/linux_testcases/0042_linux.txt
Normal file
1
test/dump/linux_testcases/0042_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE=""
|
||||
1
test/dump/linux_testcases/0043_linux.txt
Normal file
1
test/dump/linux_testcases/0043_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE="./dumps/mcdump_0043.dmp"
|
||||
1
test/dump/linux_testcases/0044_linux.txt
Normal file
1
test/dump/linux_testcases/0044_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE=""
|
||||
1
test/dump/linux_testcases/0045_linux.txt
Normal file
1
test/dump/linux_testcases/0045_linux.txt
Normal file
@ -0,0 +1 @@
|
||||
OUTFILE="./dumps/mcdump_0045.dmp"
|
||||
2
test/dump/linux_testcases/0046_linux.txt
Normal file
2
test/dump/linux_testcases/0046_linux.txt
Normal file
@ -0,0 +1,2 @@
|
||||
OUTFILE="./not_exist_dir/file"
|
||||
ERROR_CASE="yes"
|
||||
2
test/dump/linux_testcases/0047_linux.txt
Normal file
2
test/dump/linux_testcases/0047_linux.txt
Normal file
@ -0,0 +1,2 @@
|
||||
OUTFILE="${HOME}/testdump"
|
||||
ERROR_CASE="yes"
|
||||
4
test/dump/linux_testcases/panic_0001.txt
Normal file
4
test/dump/linux_testcases/panic_0001.txt
Normal file
@ -0,0 +1,4 @@
|
||||
MCRBT_OPT="-m 32M@0"
|
||||
DUMP_OPT=""
|
||||
USR_PROC="mcexec_test_proc/test_pt_1kb_1time"
|
||||
BELOW_CASES="0001_linux 0002_linux"
|
||||
4
test/dump/linux_testcases/panic_0002.txt
Normal file
4
test/dump/linux_testcases/panic_0002.txt
Normal file
@ -0,0 +1,4 @@
|
||||
MCRBT_OPT="-m 32M@0"
|
||||
DUMP_OPT="-d 0"
|
||||
USR_PROC="mcexec_test_proc/test_pt_1mb_10times"
|
||||
BELOW_CASES="0003_linux 0004_linux"
|
||||
4
test/dump/linux_testcases/panic_0003.txt
Normal file
4
test/dump/linux_testcases/panic_0003.txt
Normal file
@ -0,0 +1,4 @@
|
||||
MCRBT_OPT="-m 2G@0"
|
||||
DUMP_OPT="-d 24"
|
||||
USR_PROC="mcexec_test_proc/test_pt_1gb_1time"
|
||||
BELOW_CASES="0005_linux 0006_linux"
|
||||
4
test/dump/linux_testcases/panic_0004.txt
Normal file
4
test/dump/linux_testcases/panic_0004.txt
Normal file
@ -0,0 +1,4 @@
|
||||
MCRBT_OPT="-m `./utils/gen_mem_chunks.sh "0" 20M 128`"
|
||||
DUMP_OPT=""
|
||||
USR_PROC="mcexec_test_proc/test_pt_1kb_1time"
|
||||
BELOW_CASES="0007_linux 0008_linux"
|
||||
4
test/dump/linux_testcases/panic_0005.txt
Normal file
4
test/dump/linux_testcases/panic_0005.txt
Normal file
@ -0,0 +1,4 @@
|
||||
MCRBT_OPT="-m `./utils/gen_mem_chunks.sh "0" 20M 128`"
|
||||
DUMP_OPT="-d 0"
|
||||
USR_PROC="mcexec_test_proc/test_pt_1mb_10times"
|
||||
BELOW_CASES="0009_linux 0010_linux"
|
||||
4
test/dump/linux_testcases/panic_0006.txt
Normal file
4
test/dump/linux_testcases/panic_0006.txt
Normal file
@ -0,0 +1,4 @@
|
||||
MCRBT_OPT="-m `./utils/gen_mem_chunks.sh "0" 20M 128`"
|
||||
DUMP_OPT="-d 24"
|
||||
USR_PROC="mcexec_test_proc/test_pt_1gb_1time"
|
||||
BELOW_CASES="0011_linux 0012_linux"
|
||||
4
test/dump/linux_testcases/panic_0007.txt
Normal file
4
test/dump/linux_testcases/panic_0007.txt
Normal file
@ -0,0 +1,4 @@
|
||||
MCRBT_OPT="-m `./utils/gen_mem_chunks.sh "0" 20M 512`"
|
||||
DUMP_OPT=""
|
||||
USR_PROC="mcexec_test_proc/test_pt_1mb_10times"
|
||||
BELOW_CASES="0013_linux 0014_linux"
|
||||
4
test/dump/linux_testcases/panic_0008.txt
Normal file
4
test/dump/linux_testcases/panic_0008.txt
Normal file
@ -0,0 +1,4 @@
|
||||
MCRBT_OPT="-m `./utils/gen_mem_chunks.sh "0" 20M 512`"
|
||||
DUMP_OPT="-d 0"
|
||||
USR_PROC="mcexec_test_proc/test_pt_1gb_1time"
|
||||
BELOW_CASES="0015_linux 0016_linux"
|
||||
4
test/dump/linux_testcases/panic_0009.txt
Normal file
4
test/dump/linux_testcases/panic_0009.txt
Normal file
@ -0,0 +1,4 @@
|
||||
MCRBT_OPT="-m `./utils/gen_mem_chunks.sh "0" 48M 512`"
|
||||
DUMP_OPT="-d 24"
|
||||
USR_PROC="mcexec_test_proc/test_pt_20mb_1000times"
|
||||
BELOW_CASES="0017_linux 0018_linux"
|
||||
4
test/dump/linux_testcases/panic_0010.txt
Normal file
4
test/dump/linux_testcases/panic_0010.txt
Normal file
@ -0,0 +1,4 @@
|
||||
MCRBT_OPT="-m `./utils/gen_mem_chunks.sh "0 1" 32M 1`"
|
||||
DUMP_OPT=""
|
||||
USR_PROC="mcexec_test_proc/test_pt_1kb_1time"
|
||||
BELOW_CASES="0019_linux 0020_linux"
|
||||
4
test/dump/linux_testcases/panic_0011.txt
Normal file
4
test/dump/linux_testcases/panic_0011.txt
Normal file
@ -0,0 +1,4 @@
|
||||
MCRBT_OPT="-m `./utils/gen_mem_chunks.sh "0 1" 32M 1`"
|
||||
DUMP_OPT="-d 0"
|
||||
USR_PROC="mcexec_test_proc/test_pt_1mb_10times"
|
||||
BELOW_CASES="0021_linux 0022_linux"
|
||||
4
test/dump/linux_testcases/panic_0012.txt
Normal file
4
test/dump/linux_testcases/panic_0012.txt
Normal file
@ -0,0 +1,4 @@
|
||||
MCRBT_OPT="-m `./utils/gen_mem_chunks.sh "0 1" 1G 1`"
|
||||
DUMP_OPT="-d 24"
|
||||
USR_PROC="mcexec_test_proc/test_pt_1gb_1time"
|
||||
BELOW_CASES="0023_linux 0024_linux"
|
||||
4
test/dump/linux_testcases/panic_0013.txt
Normal file
4
test/dump/linux_testcases/panic_0013.txt
Normal file
@ -0,0 +1,4 @@
|
||||
MCRBT_OPT="-m `./utils/gen_mem_chunks.sh "0 1" 20M 64`"
|
||||
DUMP_OPT=""
|
||||
USR_PROC="mcexec_test_proc/test_pt_1kb_1time"
|
||||
BELOW_CASES="0025_linux 0026_linux"
|
||||
4
test/dump/linux_testcases/panic_0014.txt
Normal file
4
test/dump/linux_testcases/panic_0014.txt
Normal file
@ -0,0 +1,4 @@
|
||||
MCRBT_OPT="-m `./utils/gen_mem_chunks.sh "0 1" 20M 64`"
|
||||
DUMP_OPT="-d 0"
|
||||
USR_PROC="mcexec_test_proc/test_pt_1mb_10times"
|
||||
BELOW_CASES="0027_linux 0028_linux"
|
||||
4
test/dump/linux_testcases/panic_0015.txt
Normal file
4
test/dump/linux_testcases/panic_0015.txt
Normal file
@ -0,0 +1,4 @@
|
||||
MCRBT_OPT="-m `./utils/gen_mem_chunks.sh "0 1" 20M 64`"
|
||||
DUMP_OPT="-d 24"
|
||||
USR_PROC="mcexec_test_proc/test_pt_1gb_1time"
|
||||
BELOW_CASES="0029_linux 0030_linux"
|
||||
4
test/dump/linux_testcases/panic_0016.txt
Normal file
4
test/dump/linux_testcases/panic_0016.txt
Normal file
@ -0,0 +1,4 @@
|
||||
MCRBT_OPT="-m `./utils/gen_mem_chunks.sh "0 1" 20M 256`"
|
||||
DUMP_OPT=""
|
||||
USR_PROC="mcexec_test_proc/test_pt_1mb_10times"
|
||||
BELOW_CASES="0031_linux 0032_linux"
|
||||
4
test/dump/linux_testcases/panic_0017.txt
Normal file
4
test/dump/linux_testcases/panic_0017.txt
Normal file
@ -0,0 +1,4 @@
|
||||
MCRBT_OPT="-m `./utils/gen_mem_chunks.sh "0 1" 20M 256`"
|
||||
DUMP_OPT="-d 0"
|
||||
USR_PROC="mcexec_test_proc/test_pt_1gb_1time"
|
||||
BELOW_CASES="0033_linux 0034_linux"
|
||||
4
test/dump/linux_testcases/panic_0018.txt
Normal file
4
test/dump/linux_testcases/panic_0018.txt
Normal file
@ -0,0 +1,4 @@
|
||||
MCRBT_OPT="-m `./utils/gen_mem_chunks.sh "0 1" 48M 256`"
|
||||
DUMP_OPT="-d 24"
|
||||
USR_PROC="mcexec_test_proc/test_pt_20mb_1000times"
|
||||
BELOW_CASES="0035_linux 0036_linux"
|
||||
4
test/dump/linux_testcases/panic_0019.txt
Normal file
4
test/dump/linux_testcases/panic_0019.txt
Normal file
@ -0,0 +1,4 @@
|
||||
MCRBT_OPT="-c 4,12 -m `./utils/gen_mem_chunks.sh "0 1" 1G 1`"
|
||||
DUMP_OPT="-d 24"
|
||||
USR_PROC="mcexec_test_proc/test_pt_1kb_1time mcexec_test_proc/test_pt_1gb_1time"
|
||||
BELOW_CASES="0037_linux 0038_linux"
|
||||
4
test/dump/linux_testcases/panic_0020.txt
Normal file
4
test/dump/linux_testcases/panic_0020.txt
Normal file
@ -0,0 +1,4 @@
|
||||
MCRBT_OPT="-c 4,12 -m `./utils/gen_mem_chunks.sh "0 1" 32M 64`"
|
||||
DUMP_OPT="-d 24"
|
||||
USR_PROC="mcexec_test_proc/test_pt_1kb_1time mcexec_test_proc/test_pt_1gb_1time"
|
||||
BELOW_CASES="0039_linux 0040_linux"
|
||||
4
test/dump/linux_testcases/panic_0021.txt
Normal file
4
test/dump/linux_testcases/panic_0021.txt
Normal file
@ -0,0 +1,4 @@
|
||||
MCRBT_OPT="-c 4,12 -m `./utils/gen_mem_chunks.sh "0 1" 20M 256`"
|
||||
DUMP_OPT="-d 24"
|
||||
USR_PROC="mcexec_test_proc/test_pt_1kb_1time mcexec_test_proc/test_pt_1gb_1time"
|
||||
BELOW_CASES="0041_linux 0042_linux"
|
||||
4
test/dump/linux_testcases/panic_0022.txt
Normal file
4
test/dump/linux_testcases/panic_0022.txt
Normal file
@ -0,0 +1,4 @@
|
||||
MCRBT_OPT="-m 32M@0"
|
||||
DUMP_OPT="-d 24"
|
||||
USR_PROC="mcexec_test_proc/test_pt_1mb_10times mcexec_test_proc/memtest_used_destroy"
|
||||
BELOW_CASES="0043_linux"
|
||||
4
test/dump/linux_testcases/panic_0023.txt
Normal file
4
test/dump/linux_testcases/panic_0023.txt
Normal file
@ -0,0 +1,4 @@
|
||||
MCRBT_OPT="-m 32M@0"
|
||||
DUMP_OPT="-d 24"
|
||||
USR_PROC="mcexec_test_proc/test_pt_1mb_10times mcexec_test_proc/memtest_free_destroy"
|
||||
BELOW_CASES="0044_linux 0045_linux 0046_linux 0047_linux"
|
||||
4
test/dump/linux_testcases/panic_0024.txt
Normal file
4
test/dump/linux_testcases/panic_0024.txt
Normal file
@ -0,0 +1,4 @@
|
||||
MCRBT_OPT="-m 32M@0"
|
||||
DUMP_OPT="-d 99"
|
||||
USR_PROC="mcexec_test_proc/test_pt_1mb_10times"
|
||||
BELOW_CASES="0045_linux 0046_linux 0047_linux"
|
||||
6
test/dump/mcexec_test_proc/Makefile
Normal file
6
test/dump/mcexec_test_proc/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
OBJS = test_pt_1gb_10times test_pt_1gb_1time test_pt_1kb_1time test_pt_1mb_10times test_pt_20mb_1000times memtest_free_destroy memtest_used_destroy
|
||||
|
||||
all: $(OBJS)
|
||||
|
||||
clean:
|
||||
rm $(OBJS)
|
||||
14
test/dump/mcexec_test_proc/memtest_free_destroy.c
Normal file
14
test/dump/mcexec_test_proc/memtest_free_destroy.c
Normal file
@ -0,0 +1,14 @@
|
||||
#include <stdio.h>
|
||||
#define _GNU_SOURCE
|
||||
#include <unistd.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
main() {
|
||||
|
||||
int rst = 0;
|
||||
|
||||
rst = syscall(902);
|
||||
printf("freemem_destroy result:%d\n",rst);
|
||||
|
||||
return;
|
||||
}
|
||||
14
test/dump/mcexec_test_proc/memtest_used_destroy.c
Normal file
14
test/dump/mcexec_test_proc/memtest_used_destroy.c
Normal file
@ -0,0 +1,14 @@
|
||||
#include <stdio.h>
|
||||
#define _GNU_SOURCE
|
||||
#include <unistd.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
main() {
|
||||
|
||||
int rst = 0;
|
||||
|
||||
rst = syscall(901);
|
||||
printf("usedmem_destroy result:%d\n",rst);
|
||||
|
||||
return;
|
||||
}
|
||||
30
test/dump/mcexec_test_proc/test_pt_1gb_10times.c
Normal file
30
test/dump/mcexec_test_proc/test_pt_1gb_10times.c
Normal file
@ -0,0 +1,30 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#define MEM_SIZE (1024*1024*1024)
|
||||
#define LOOP_MAX 10
|
||||
#define SLEEP_TIME 30
|
||||
|
||||
main()
|
||||
{
|
||||
|
||||
int *buf,buf_size,index;
|
||||
|
||||
buf_size = MEM_SIZE;
|
||||
|
||||
for (index = 0; index < LOOP_MAX; index++) {
|
||||
buf = mmap(0, buf_size, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
|
||||
if (NULL != buf) {
|
||||
memset(buf, 1, buf_size);
|
||||
} else {
|
||||
printf("[%d] mmap error!!! buf_size:%d(0x%x)\n", index, buf_size, buf_size);
|
||||
}
|
||||
}
|
||||
printf("mmap is done\n");
|
||||
|
||||
sleep(SLEEP_TIME);
|
||||
|
||||
return 0;
|
||||
}
|
||||
30
test/dump/mcexec_test_proc/test_pt_1gb_1time.c
Normal file
30
test/dump/mcexec_test_proc/test_pt_1gb_1time.c
Normal file
@ -0,0 +1,30 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#define MEM_SIZE (1024*1024*1024)
|
||||
#define LOOP_MAX 1
|
||||
#define SLEEP_TIME 30
|
||||
|
||||
main()
|
||||
{
|
||||
|
||||
int *buf,buf_size,index;
|
||||
|
||||
buf_size = MEM_SIZE;
|
||||
|
||||
for (index = 0; index < LOOP_MAX; index++) {
|
||||
buf = mmap(0, buf_size, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
|
||||
if (NULL != buf) {
|
||||
memset(buf, 1, buf_size);
|
||||
} else {
|
||||
printf("[%d] mmap error!!! buf_size:%d(0x%x)\n", index, buf_size, buf_size);
|
||||
}
|
||||
}
|
||||
printf("mmap is done\n");
|
||||
|
||||
sleep(SLEEP_TIME);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user