fork: copy_user_ranges: rollback on error
Change-Id: Icdb8399cbce31835abcaeb783dde3ff14d30af6a
This commit is contained in:
committed by
Masamichi Takagi
parent
58f4593478
commit
3e9fdfc0f1
@ -1,4 +1,4 @@
|
|||||||
/* process.c COPYRIGHT FUJITSU LIMITED 2015-2018 */
|
/* process.c COPYRIGHT FUJITSU LIMITED 2015-2019 */
|
||||||
/**
|
/**
|
||||||
* \file process.c
|
* \file process.c
|
||||||
* License details are found in the file LICENSE.
|
* License details are found in the file LICENSE.
|
||||||
@ -82,6 +82,9 @@ int ptrace_detach(int pid, int data);
|
|||||||
extern void procfs_create_thread(struct thread *);
|
extern void procfs_create_thread(struct thread *);
|
||||||
extern void procfs_delete_thread(struct thread *);
|
extern void procfs_delete_thread(struct thread *);
|
||||||
|
|
||||||
|
static int free_process_memory_range(struct process_vm *vm,
|
||||||
|
struct vm_range *range);
|
||||||
|
|
||||||
struct list_head resource_set_list;
|
struct list_head resource_set_list;
|
||||||
mcs_rwlock_lock_t resource_set_lock;
|
mcs_rwlock_lock_t resource_set_lock;
|
||||||
ihk_spinlock_t runq_reservation_lock;
|
ihk_spinlock_t runq_reservation_lock;
|
||||||
@ -740,12 +743,14 @@ static int copy_user_ranges(struct process_vm *vm, struct process_vm *orgvm)
|
|||||||
int error;
|
int error;
|
||||||
struct vm_range *src_range;
|
struct vm_range *src_range;
|
||||||
struct vm_range *range;
|
struct vm_range *range;
|
||||||
|
struct vm_range *last_insert;
|
||||||
struct copy_args args;
|
struct copy_args args;
|
||||||
unsigned long irqflags;
|
unsigned long irqflags;
|
||||||
|
|
||||||
memory_range_write_lock(orgvm, &irqflags);
|
memory_range_write_lock(orgvm, &irqflags);
|
||||||
|
|
||||||
/* Iterate original process' vm_range list and take a copy one-by-one */
|
/* Iterate original process' vm_range list and take a copy one-by-one */
|
||||||
|
last_insert = NULL;
|
||||||
src_range = NULL;
|
src_range = NULL;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (!src_range) {
|
if (!src_range) {
|
||||||
@ -778,6 +783,9 @@ static int copy_user_ranges(struct process_vm *vm, struct process_vm *orgvm)
|
|||||||
memobj_ref(range->memobj);
|
memobj_ref(range->memobj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vm_range_insert(vm, range);
|
||||||
|
last_insert = src_range;
|
||||||
|
|
||||||
/* Copy actual mappings */
|
/* Copy actual mappings */
|
||||||
args.new_vrflag = range->flag;
|
args.new_vrflag = range->flag;
|
||||||
args.new_vm = vm;
|
args.new_vm = vm;
|
||||||
@ -796,27 +804,39 @@ static int copy_user_ranges(struct process_vm *vm, struct process_vm *orgvm)
|
|||||||
range->start, range->end,
|
range->start, range->end,
|
||||||
range->flag, args.fault_addr);
|
range->flag, args.fault_addr);
|
||||||
}
|
}
|
||||||
goto err_free_range_rollback;
|
goto err_rollback;
|
||||||
}
|
}
|
||||||
// memory_stat_rss_add() is called in child-node, i.e. copy_user_pte()
|
// memory_stat_rss_add() is called in child-node, i.e. copy_user_pte()
|
||||||
|
|
||||||
vm_range_insert(vm, range);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memory_range_write_unlock(orgvm, &irqflags);
|
memory_range_write_unlock(orgvm, &irqflags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_free_range_rollback:
|
|
||||||
kfree(range);
|
|
||||||
|
|
||||||
err_rollback:
|
err_rollback:
|
||||||
|
if (last_insert) {
|
||||||
|
src_range = lookup_process_memory_range(orgvm, 0, -1);
|
||||||
|
while (src_range) {
|
||||||
|
struct vm_range *dest_range;
|
||||||
|
|
||||||
/* TODO: implement rollback */
|
if (src_range->flag & VR_DONTFORK)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
|
||||||
|
dest_range = lookup_process_memory_range(vm,
|
||||||
|
src_range->start,
|
||||||
|
src_range->end);
|
||||||
|
if (dest_range) {
|
||||||
|
free_process_memory_range(vm, dest_range);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src_range == last_insert) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
src_range = next_process_memory_range(orgvm, src_range);
|
||||||
|
}
|
||||||
|
}
|
||||||
memory_range_write_unlock(orgvm, &irqflags);
|
memory_range_write_unlock(orgvm, &irqflags);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -953,7 +973,8 @@ out:
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
int free_process_memory_range(struct process_vm *vm, struct vm_range *range)
|
static int free_process_memory_range(struct process_vm *vm,
|
||||||
|
struct vm_range *range)
|
||||||
{
|
{
|
||||||
const intptr_t start0 = range->start;
|
const intptr_t start0 = range->start;
|
||||||
const intptr_t end0 = range->end;
|
const intptr_t end0 = range->end;
|
||||||
|
|||||||
Reference in New Issue
Block a user