memobj: transform memobj lock to refcounting
We had a deadlock between: - free_process_memory_range (take lock) -> ihk_mc_pt_free_range -> ... -> remote_flush_tlb_array_cpumask -> "/* Wait for all cores */" and - obj_list_lookup() under fileobj_list_lock that disabled irqs and thus never ack'd the remote flush The rework is quite big but removes the need for the big lock, although devobj and shmobj needed a new smaller lock to be introduced - the new locks are used much more locally and should not cause problems. On the bright side, refcounting being moved to memobj level means we could remove refcounting implemented separately in all object types and simplifies code a bit. Change-Id: I6bc8438a98b1d8edddc91c4ac33c11b88e097ebb
This commit is contained in:
@@ -882,7 +882,7 @@ int join_process_memory_range(struct process_vm *vm,
|
||||
surviving->end = merging->end;
|
||||
|
||||
if (merging->memobj) {
|
||||
memobj_release(merging->memobj);
|
||||
memobj_unref(merging->memobj);
|
||||
}
|
||||
rb_erase(&merging->vm_rb_node, &vm->vm_range_tree);
|
||||
for (i = 0; i < VM_RANGE_CACHE_SIZE; ++i) {
|
||||
@@ -955,13 +955,13 @@ int free_process_memory_range(struct process_vm *vm, struct vm_range *range)
|
||||
|
||||
ihk_mc_spinlock_lock_noirq(&vm->page_table_lock);
|
||||
if (range->memobj) {
|
||||
memobj_lock(range->memobj);
|
||||
memobj_ref(range->memobj);
|
||||
}
|
||||
error = ihk_mc_pt_free_range(vm->address_space->page_table, vm,
|
||||
(void *)start, (void *)end,
|
||||
(range->flag & VR_PRIVATE)? NULL: range->memobj);
|
||||
if (range->memobj) {
|
||||
memobj_unlock(range->memobj);
|
||||
memobj_unref(range->memobj);
|
||||
}
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->page_table_lock);
|
||||
if (error && (error != -ENOENT)) {
|
||||
@@ -988,7 +988,7 @@ int free_process_memory_range(struct process_vm *vm, struct vm_range *range)
|
||||
}
|
||||
|
||||
if (range->memobj) {
|
||||
memobj_release(range->memobj);
|
||||
memobj_unref(range->memobj);
|
||||
}
|
||||
|
||||
rb_erase(&range->vm_rb_node, &vm->vm_range_tree);
|
||||
@@ -1520,7 +1520,7 @@ int remap_process_memory_range(struct process_vm *vm, struct vm_range *range,
|
||||
dkprintf("remap_process_memory_range(%p,%p,%#lx,%#lx,%#lx)\n",
|
||||
vm, range, start, end, off);
|
||||
ihk_mc_spinlock_lock_noirq(&vm->page_table_lock);
|
||||
memobj_lock(range->memobj);
|
||||
memobj_ref(range->memobj);
|
||||
|
||||
args.start = start;
|
||||
args.off = off;
|
||||
@@ -1545,7 +1545,7 @@ int remap_process_memory_range(struct process_vm *vm, struct vm_range *range,
|
||||
|
||||
error = 0;
|
||||
out:
|
||||
memobj_unlock(range->memobj);
|
||||
memobj_unref(range->memobj);
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->page_table_lock);
|
||||
dkprintf("remap_process_memory_range(%p,%p,%#lx,%#lx,%#lx):%d\n",
|
||||
vm, range, start, end, off, error);
|
||||
@@ -1610,7 +1610,7 @@ int sync_process_memory_range(struct process_vm *vm, struct vm_range *range,
|
||||
ihk_mc_spinlock_lock_noirq(&vm->page_table_lock);
|
||||
|
||||
if (!(range->memobj->flags & MF_ZEROFILL)) {
|
||||
memobj_lock(range->memobj);
|
||||
memobj_ref(range->memobj);
|
||||
}
|
||||
|
||||
error = visit_pte_range(vm->address_space->page_table, (void *)start,
|
||||
@@ -1618,7 +1618,7 @@ int sync_process_memory_range(struct process_vm *vm, struct vm_range *range,
|
||||
&sync_one_page, &args);
|
||||
|
||||
if (!(range->memobj->flags & MF_ZEROFILL)) {
|
||||
memobj_unlock(range->memobj);
|
||||
memobj_unref(range->memobj);
|
||||
}
|
||||
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->page_table_lock);
|
||||
@@ -1700,11 +1700,11 @@ int invalidate_process_memory_range(struct process_vm *vm,
|
||||
args.range = range;
|
||||
|
||||
ihk_mc_spinlock_lock_noirq(&vm->page_table_lock);
|
||||
memobj_lock(range->memobj);
|
||||
memobj_ref(range->memobj);
|
||||
error = visit_pte_range(vm->address_space->page_table, (void *)start,
|
||||
(void *)end, range->pgshift, VPTEF_SKIP_NULL,
|
||||
&invalidate_one_page, &args);
|
||||
memobj_unlock(range->memobj);
|
||||
memobj_unref(range->memobj);
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->page_table_lock);
|
||||
if (error) {
|
||||
ekprintf("invalidate_process_memory_range(%p,%p,%#lx,%#lx):"
|
||||
|
||||
Reference in New Issue
Block a user