Fix deadlock involving mmap_sem and memory_range_lock

Change-Id: I187246271163e708af6542c057d0a8dfde5b211e
Fujitsu: TEMP_FIX_1
Refs: #986
This commit is contained in:
Masamichi Takagi
2018-09-03 13:54:40 +09:00
parent b080e0f301
commit 567dcd3846
4 changed files with 52 additions and 19 deletions

View File

@@ -1952,11 +1952,28 @@ static int do_page_fault_process_vm(struct process_vm *vm, void *fault_addr0, ui
int error;
const uintptr_t fault_addr = (uintptr_t)fault_addr0;
struct vm_range *range;
struct thread *thread = cpu_local_var(current);
int locked = 0;
dkprintf("[%d]do_page_fault_process_vm(%p,%lx,%lx)\n",
ihk_mc_get_processor_id(), vm, fault_addr0, reason);
ihk_mc_spinlock_lock_noirq(&vm->memory_range_lock);
if (!thread->vm->is_memory_range_lock_taken) {
/* For the case where is_memory_range_lock_taken is incremented after memory_range_lock is taken. */
while (1) {
if (thread->vm->is_memory_range_lock_taken) {
goto skip;
}
if (ihk_mc_spinlock_trylock_noirq(&vm->memory_range_lock)) {
locked = 1;
break;
}
}
} else {
skip:;
dkprintf("%s: INFO: skip locking of memory_range_lock,pid=%d,tid=%d\n",
__func__, thread->proc->pid, thread->tid);
}
if (vm->exiting) {
error = -ECANCELED;
@@ -2065,7 +2082,9 @@ static int do_page_fault_process_vm(struct process_vm *vm, void *fault_addr0, ui
error = 0;
out:
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
if (locked) {
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
}
dkprintf("[%d]do_page_fault_process_vm(%p,%lx,%lx): %d\n",
ihk_mc_get_processor_id(), vm, fault_addr0,
reason, error);