dump: rewrite NMI handling (for resume) and fix PANIC register saving
Change-Id: I360e9aa8efa64b6ebd99b209a5dd4ee0dc7806cf
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
#include <ihk/monitor.h>
|
||||
#include <init.h>
|
||||
|
||||
extern int nmi_mode;
|
||||
extern void mod_nmi_ctx(void *, void(*)());
|
||||
extern void lapic_ack();
|
||||
extern void __freeze();
|
||||
@@ -70,3 +71,48 @@ freeze_thaw(void *nmi_ctx)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern void arch_save_panic_regs(void *irq_regs);
|
||||
extern void arch_clear_panic(void);
|
||||
|
||||
void
|
||||
multi_nm_interrupt_handler(void *irq_regs)
|
||||
{
|
||||
dkprintf("%s: ...\n", __func__);
|
||||
switch (nmi_mode) {
|
||||
case 1:
|
||||
case 2:
|
||||
/* mode == 1 or 2, for FREEZER NMI */
|
||||
dkprintf("%s: freeze mode NMI catch. (nmi_mode=%d)\n",
|
||||
__func__, nmi_mode);
|
||||
freeze_thaw(NULL);
|
||||
break;
|
||||
|
||||
case 0:
|
||||
/* mode == 0, for MEMDUMP NMI */
|
||||
arch_save_panic_regs(irq_regs);
|
||||
ihk_mc_query_mem_areas();
|
||||
/* memdump-nmi is halted McKernel, break is unnecessary. */
|
||||
/* fall through */
|
||||
case 3:
|
||||
/* mode == 3, for SHUTDOWN-WAIT NMI */
|
||||
kprintf("%s: STOP\n", __func__);
|
||||
while (nmi_mode != 4)
|
||||
cpu_halt();
|
||||
break;
|
||||
|
||||
case 4:
|
||||
/* mode == 4, continue NMI */
|
||||
arch_clear_panic();
|
||||
if (!ihk_mc_get_processor_id()) {
|
||||
ihk_mc_clear_dump_page_completion();
|
||||
}
|
||||
kprintf("%s: RESUME, nmi_mode: %d\n", __func__, nmi_mode);
|
||||
break;
|
||||
|
||||
default:
|
||||
ekprintf("%s: Unknown nmi-mode(%d) detected.\n",
|
||||
__func__, nmi_mode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
35
kernel/mem.c
35
kernel/mem.c
@@ -44,6 +44,7 @@
|
||||
#include <limits.h>
|
||||
#include <sysfs.h>
|
||||
#include <ihk/debug.h>
|
||||
#include <bootparam.h>
|
||||
|
||||
//#define DEBUG_PRINT_MEM
|
||||
|
||||
@@ -114,29 +115,11 @@ struct pagealloc_track_entry {
|
||||
ihk_spinlock_t addr_list_lock;
|
||||
};
|
||||
|
||||
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 */
|
||||
@@ -2512,10 +2495,13 @@ void ihk_mc_query_mem_areas(void){
|
||||
struct ihk_dump_page_set *dump_page_set;
|
||||
struct dump_pase_info dump_pase_info;
|
||||
|
||||
/* Performed only for CPU 0 */
|
||||
/*
|
||||
* Performed only on the last CPU to make sure
|
||||
* all other cores are already stopped.
|
||||
*/
|
||||
cpu_id = ihk_mc_get_processor_id();
|
||||
|
||||
if (0 != cpu_id)
|
||||
if (num_processors - 1 != cpu_id)
|
||||
return;
|
||||
|
||||
dump_page_set = ihk_mc_get_dump_page_set();
|
||||
@@ -2534,10 +2520,19 @@ void ihk_mc_query_mem_areas(void){
|
||||
}
|
||||
|
||||
dump_page_set->completion_flag = IHK_DUMP_PAGE_SET_COMPLETED;
|
||||
dkprintf("%s: IHK_DUMP_PAGE_SET_COMPLETED\n", __func__);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void ihk_mc_clear_dump_page_completion(void)
|
||||
{
|
||||
struct ihk_dump_page_set *dump_page_set;
|
||||
|
||||
dump_page_set = ihk_mc_get_dump_page_set();
|
||||
dump_page_set->completion_flag = IHK_DUMP_PAGE_SET_INCOMPLETE;
|
||||
}
|
||||
|
||||
void ihk_mc_query_mem_user_page(void *dump_pase_info) {
|
||||
|
||||
struct resource_set *rset = cpu_local_var(resource_set);
|
||||
|
||||
Reference in New Issue
Block a user