When forking a vm space that has wired map entries, do not forget to
charge the objects created by vm_fault_copy_entry. The object charge was set, but reserve not incremented. Reported by: Greg Rivers <gcr+freebsd-current tharned org> Reviewed by: alc (previous version) Approved by: re (kensmith)
This commit is contained in:
parent
9e760f2578
commit
121fd46175
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=195329
@ -55,7 +55,8 @@ vm_map_t kmem_suballoc(vm_map_t, vm_offset_t *, vm_offset_t *, vm_size_t,
|
||||
void swapout_procs(int);
|
||||
int useracc(void *, int, int);
|
||||
int vm_fault(vm_map_t, vm_offset_t, vm_prot_t, int);
|
||||
void vm_fault_copy_entry(vm_map_t, vm_map_t, vm_map_entry_t, vm_map_entry_t);
|
||||
void vm_fault_copy_entry(vm_map_t, vm_map_t, vm_map_entry_t, vm_map_entry_t,
|
||||
vm_ooffset_t *);
|
||||
void vm_fault_unwire(vm_map_t, vm_offset_t, vm_offset_t, boolean_t);
|
||||
int vm_fault_wire(vm_map_t, vm_offset_t, vm_offset_t, boolean_t, boolean_t);
|
||||
int vm_forkproc(struct thread *, struct proc *, struct thread *, struct vmspace *, int);
|
||||
|
@ -1126,11 +1126,9 @@ vm_fault_unwire(vm_map_t map, vm_offset_t start, vm_offset_t end,
|
||||
* entry corresponding to a main map entry that is wired down).
|
||||
*/
|
||||
void
|
||||
vm_fault_copy_entry(dst_map, src_map, dst_entry, src_entry)
|
||||
vm_map_t dst_map;
|
||||
vm_map_t src_map;
|
||||
vm_map_entry_t dst_entry;
|
||||
vm_map_entry_t src_entry;
|
||||
vm_fault_copy_entry(vm_map_t dst_map, vm_map_t src_map,
|
||||
vm_map_entry_t dst_entry, vm_map_entry_t src_entry,
|
||||
vm_ooffset_t *fork_charge)
|
||||
{
|
||||
vm_object_t backing_object, dst_object, object;
|
||||
vm_object_t src_object;
|
||||
@ -1161,13 +1159,16 @@ vm_fault_copy_entry(dst_map, src_map, dst_entry, src_entry)
|
||||
#endif
|
||||
|
||||
VM_OBJECT_LOCK(dst_object);
|
||||
KASSERT(dst_entry->object.vm_object == NULL,
|
||||
("vm_fault_copy_entry: vm_object not NULL"));
|
||||
dst_entry->object.vm_object = dst_object;
|
||||
dst_entry->offset = 0;
|
||||
if (dst_entry->uip != NULL) {
|
||||
dst_object->uip = dst_entry->uip;
|
||||
dst_object->charge = dst_entry->end - dst_entry->start;
|
||||
dst_entry->uip = NULL;
|
||||
}
|
||||
dst_object->uip = curthread->td_ucred->cr_ruidinfo;
|
||||
uihold(dst_object->uip);
|
||||
dst_object->charge = dst_entry->end - dst_entry->start;
|
||||
KASSERT(dst_entry->uip == NULL,
|
||||
("vm_fault_copy_entry: leaked swp charge"));
|
||||
*fork_charge += dst_object->charge;
|
||||
prot = dst_entry->max_protection;
|
||||
|
||||
/*
|
||||
|
@ -2909,7 +2909,8 @@ vm_map_copy_entry(
|
||||
* Cause wired pages to be copied into the new map by
|
||||
* simulating faults (the new pages are pageable)
|
||||
*/
|
||||
vm_fault_copy_entry(dst_map, src_map, dst_entry, src_entry);
|
||||
vm_fault_copy_entry(dst_map, src_map, dst_entry, src_entry,
|
||||
fork_charge);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3073,6 +3074,7 @@ vmspace_fork(struct vmspace *vm1, vm_ooffset_t *fork_charge)
|
||||
MAP_ENTRY_IN_TRANSITION);
|
||||
new_entry->wired_count = 0;
|
||||
new_entry->object.vm_object = NULL;
|
||||
new_entry->uip = NULL;
|
||||
vm_map_entry_link(new_map, new_map->header.prev,
|
||||
new_entry);
|
||||
vmspace_map_entry_forked(vm1, vm2, new_entry);
|
||||
|
Loading…
Reference in New Issue
Block a user