Improve memory pinning.

This commit is contained in:
Cristiano Giuffrida 2010-07-01 08:54:25 +00:00
parent 4690e8b015
commit 9e4312453d
2 changed files with 17 additions and 18 deletions

View File

@ -431,7 +431,10 @@ struct rproc *rp;
return(EPERM); return(EPERM);
} }
/* Now fork and branch for parent and child process (and check for error). */ /* Now fork and branch for parent and child process (and check for error).
* After fork()ing, we need to pin RS memory again or pagefaults will occur
* on future writes.
*/
if(rs_verbose) if(rs_verbose)
printf("RS: forking child with srv_fork()...\n"); printf("RS: forking child with srv_fork()...\n");
child_pid= srv_fork(); child_pid= srv_fork();
@ -467,6 +470,7 @@ struct rproc *rp;
|| (s = sys_getpriv(&rp->r_priv, child_proc_nr_e)) != OK) { || (s = sys_getpriv(&rp->r_priv, child_proc_nr_e)) != OK) {
printf("unable to set privilege structure: %d\n", s); printf("unable to set privilege structure: %d\n", s);
cleanup_service(rp); cleanup_service(rp);
vm_memctl(RS_PROC_NR, VM_RS_MEM_PIN);
return ENOMEM; return ENOMEM;
} }
@ -474,13 +478,12 @@ struct rproc *rp;
if ((s = sched_init_proc(rp)) != OK) { if ((s = sched_init_proc(rp)) != OK) {
printf("unable to start scheduling: %d\n", s); printf("unable to start scheduling: %d\n", s);
cleanup_service(rp); cleanup_service(rp);
vm_memctl(RS_PROC_NR, VM_RS_MEM_PIN);
return s; return s;
} }
/* Copy the executable image into the child process. If this call /* Copy the executable image into the child process. If no copy exists,
* fails, the child process may or may not be killed already. If it is * allocate one and free it right after exec completes.
* not killed, it's blocked because of NO_PRIV. Kill it now either way.
* If no copy exists, allocate one and free it right after exec completes.
*/ */
if(use_copy) { if(use_copy) {
if(rs_verbose) if(rs_verbose)
@ -491,6 +494,7 @@ struct rproc *rp;
if ((s = read_exec(rp)) != OK) { if ((s = read_exec(rp)) != OK) {
printf("read_exec failed: %d\n", s); printf("read_exec failed: %d\n", s);
cleanup_service(rp); cleanup_service(rp);
vm_memctl(RS_PROC_NR, VM_RS_MEM_PIN);
return s; return s;
} }
} }
@ -498,6 +502,7 @@ struct rproc *rp;
printf("RS: execing child with srv_execve()...\n"); printf("RS: execing child with srv_execve()...\n");
s = srv_execve(child_proc_nr_e, rp->r_exec, rp->r_exec_len, rp->r_argv, s = srv_execve(child_proc_nr_e, rp->r_exec, rp->r_exec_len, rp->r_argv,
environ); environ);
vm_memctl(RS_PROC_NR, VM_RS_MEM_PIN);
if (s != OK) { if (s != OK) {
printf("srv_execve failed: %d\n", s); printf("srv_execve failed: %d\n", s);
@ -963,6 +968,8 @@ PRIVATE int run_script(struct rproc *rp)
if ((r = sys_privctl(endpoint, SYS_PRIV_ALLOW, NULL)) != OK) { if ((r = sys_privctl(endpoint, SYS_PRIV_ALLOW, NULL)) != OK) {
return kill_service(rp,"can't let the script run",r); return kill_service(rp,"can't let the script run",r);
} }
/* Pin RS memory again after fork()ing. */
vm_memctl(RS_PROC_NR, VM_RS_MEM_PIN);
} }
return OK; return OK;
} }

View File

@ -1122,22 +1122,14 @@ int write;
PUBLIC int map_pin_memory(struct vmproc *vmp) PUBLIC int map_pin_memory(struct vmproc *vmp)
{ {
struct vir_region *vr; struct vir_region *vr;
int offset, r; int r;
/* Scan all memory regions. */ /* Scan all memory regions. */
for(vr = vmp->vm_regions; vr; vr = vr->next) { for(vr = vmp->vm_regions; vr; vr = vr->next) {
vir_bytes offset; /* Make sure region is mapped to physical memory and writable.*/
/* Skip regions that can't pagefault. */ r = map_handle_memory(vmp, vr, 0, vr->length, 1);
if((vr->flags & VR_NOPF) || (vr->flags & VR_SHARED)) { if(r != OK) {
continue; panic("map_pin_memory: map_handle_memory failed: %d", r);
}
/* Map other regions. */
for(offset=0;offset<vr->length;offset += VM_PAGE_SIZE) {
if((r=map_pf(vmp, vr, offset, 1 /* write */))
!= OK) {
printf("VM: map_pf failed\n");
return r;
}
} }
} }