Fix deadlock involving mmap_sem and memory_range_lock
Change-Id: I187246271163e708af6542c057d0a8dfde5b211e Fujitsu: TEMP_FIX_1 Refs: #986
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user