Unmap shared page manually before doing vm_map_remove() on exit or exec

This allows the pmap_remove(min, max) call to see empty pmap and exploit
empty pmap optimization.

Reviewed by:	markj
Tested by:	markj
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D32569
This commit is contained in:
Konstantin Belousov 2021-10-20 23:32:59 +03:00
parent 0b3bc72889
commit 1c69690319
3 changed files with 27 additions and 0 deletions

View File

@ -1104,6 +1104,30 @@ exec_onexec_old(struct thread *td)
umtx_exec(td->td_proc);
}
/*
* This is an optimization which removes the unmanaged shared page
* mapping. In combination with pmap_remove_pages(), which cleans all
* managed mappings in the process' vmspace pmap, no work will be left
* for pmap_remove(min, max).
*/
void
exec_free_abi_mappings(struct proc *p)
{
struct vmspace *vmspace;
struct sysentvec *sv;
vmspace = p->p_vmspace;
if (refcount_load(&vmspace->vm_refcnt) != 1)
return;
sv = p->p_sysent;
if (sv->sv_shared_page_obj == NULL)
return;
pmap_remove(vmspace_pmap(vmspace), sv->sv_shared_page_base,
sv->sv_shared_page_base + sv->sv_shared_page_len);
}
/*
* Destroy old address space, and allocate a new stack.
* The new stack is only sgrowsiz large because it is grown
@ -1146,6 +1170,7 @@ exec_new_vmspace(struct image_params *imgp, struct sysentvec *sv)
vm_map_min(map) == sv_minuser &&
vm_map_max(map) == sv->sv_maxuser &&
cpu_exec_vmspace_reuse(p, map)) {
exec_free_abi_mappings(p);
shmexit(vmspace);
pmap_remove_pages(vmspace_pmap(vmspace));
vm_map_remove(map, vm_map_min(map), vm_map_max(map));

View File

@ -417,6 +417,7 @@ exit1(struct thread *td, int rval, int signo)
mtx_unlock(&ppeers_lock);
}
exec_free_abi_mappings(p);
vmspace_exit(td);
(void)acct_process(td);

View File

@ -324,6 +324,7 @@ void exec_sysvec_init_secondary(struct sysentvec *sv, struct sysentvec *sv2);
void exec_inittk(void);
void exit_onexit(struct proc *p);
void exec_free_abi_mappings(struct proc *p);
void exec_onexec_old(struct thread *td);
#define INIT_SYSENTVEC(name, sv) \