vm->exiting: deal with exit_group() and concurrent page faults
This commit is contained in:
committed by
Balazs Gerofi
parent
fbb776e4fb
commit
4ebe778ede
@ -431,6 +431,7 @@ struct process_vm {
|
|||||||
|
|
||||||
cpu_set_t cpu_set;
|
cpu_set_t cpu_set;
|
||||||
ihk_spinlock_t cpu_set_lock;
|
ihk_spinlock_t cpu_set_lock;
|
||||||
|
int exiting;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
15
kernel/mem.c
15
kernel/mem.c
@ -370,10 +370,25 @@ static void page_fault_handler(void *fault_addr, uint64_t reason, void *regs)
|
|||||||
dkprintf("[%d]page_fault_handler(%p,%lx,%p)\n",
|
dkprintf("[%d]page_fault_handler(%p,%lx,%p)\n",
|
||||||
ihk_mc_get_processor_id(), fault_addr, reason, regs);
|
ihk_mc_get_processor_id(), fault_addr, reason, regs);
|
||||||
|
|
||||||
|
cpu_enable_interrupt();
|
||||||
|
|
||||||
error = page_fault_process_vm(proc->vm, fault_addr, reason);
|
error = page_fault_process_vm(proc->vm, fault_addr, reason);
|
||||||
if (error) {
|
if (error) {
|
||||||
struct siginfo info;
|
struct siginfo info;
|
||||||
|
|
||||||
|
if (error == -ECANCELED) {
|
||||||
|
kprintf("process is exiting, terminate.\n");
|
||||||
|
|
||||||
|
ihk_mc_spinlock_lock_noirq(&proc->ftn->lock);
|
||||||
|
proc->ftn->status = PS_ZOMBIE;
|
||||||
|
ihk_mc_spinlock_unlock_noirq(&proc->ftn->lock);
|
||||||
|
release_fork_tree_node(proc->ftn->parent);
|
||||||
|
release_fork_tree_node(proc->ftn);
|
||||||
|
//release_process(proc);
|
||||||
|
|
||||||
|
schedule();
|
||||||
|
}
|
||||||
|
|
||||||
kprintf("[%d]page_fault_handler(%p,%lx,%p):"
|
kprintf("[%d]page_fault_handler(%p,%lx,%p):"
|
||||||
"fault vm failed. %d\n",
|
"fault vm failed. %d\n",
|
||||||
ihk_mc_get_processor_id(), fault_addr,
|
ihk_mc_get_processor_id(), fault_addr,
|
||||||
|
|||||||
@ -137,6 +137,7 @@ static int init_process_vm(struct process *owner, struct process_vm *vm)
|
|||||||
vm->owner_process = owner;
|
vm->owner_process = owner;
|
||||||
memset(&vm->cpu_set, 0, sizeof(cpu_set_t));
|
memset(&vm->cpu_set, 0, sizeof(cpu_set_t));
|
||||||
ihk_mc_spinlock_init(&vm->cpu_set_lock);
|
ihk_mc_spinlock_init(&vm->cpu_set_lock);
|
||||||
|
vm->exiting = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1526,6 +1527,11 @@ static int do_page_fault_process_vm(struct process_vm *vm, void *fault_addr0, ui
|
|||||||
|
|
||||||
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
|
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
|
||||||
|
|
||||||
|
if (vm->exiting) {
|
||||||
|
error = -ECANCELED;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
range = lookup_process_memory_range(vm, fault_addr, fault_addr+1);
|
range = lookup_process_memory_range(vm, fault_addr, fault_addr+1);
|
||||||
if (range == NULL) {
|
if (range == NULL) {
|
||||||
error = -EFAULT;
|
error = -EFAULT;
|
||||||
@ -1854,6 +1860,8 @@ void flush_process_memory(struct process *proc)
|
|||||||
|
|
||||||
dkprintf("flush_process_memory(%p)\n", proc);
|
dkprintf("flush_process_memory(%p)\n", proc);
|
||||||
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
|
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
|
||||||
|
/* Let concurrent page faults know the VM will be gone */
|
||||||
|
vm->exiting = 1;
|
||||||
list_for_each_entry_safe(range, next, &vm->vm_range_list, list) {
|
list_for_each_entry_safe(range, next, &vm->vm_range_list, list) {
|
||||||
if (range->memobj) {
|
if (range->memobj) {
|
||||||
// XXX: temporary of temporary
|
// XXX: temporary of temporary
|
||||||
|
|||||||
@ -3604,8 +3604,9 @@ SYSCALL_DECLARE(exit)
|
|||||||
|
|
||||||
proc->ftn->status = PS_ZOMBIE;
|
proc->ftn->status = PS_ZOMBIE;
|
||||||
|
|
||||||
|
release_fork_tree_node(proc->ftn->parent);
|
||||||
release_fork_tree_node(proc->ftn);
|
release_fork_tree_node(proc->ftn);
|
||||||
release_process(proc);
|
//release_process(proc);
|
||||||
|
|
||||||
schedule();
|
schedule();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user