To avoid a conflict for the vm_map's lock with vm_fault, release

the read lock around the subyte operations in mincore.  After the lock is
reacquired, use the map's timestamp to determine if we need to restart
the scan.
This commit is contained in:
Alan Cox 1999-03-02 22:55:02 +00:00
parent 5365c4e788
commit dd2622a8cd
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=44438

View File

@ -38,7 +38,7 @@
* from: Utah $Hdr: vm_mmap.c 1.6 91/10/21$
*
* @(#)vm_mmap.c 8.4 (Berkeley) 1/12/94
* $Id: vm_mmap.c,v 1.90 1999/02/19 14:25:36 luoqi Exp $
* $Id: vm_mmap.c,v 1.91 1999/03/01 20:42:16 alc Exp $
*/
/*
@ -675,6 +675,7 @@ mincore(p, uap)
register vm_map_entry_t current;
vm_map_entry_t entry;
int mincoreinfo;
unsigned int timestamp;
/*
* Make sure that the addresses presented are valid for user
@ -696,6 +697,8 @@ mincore(p, uap)
pmap = vmspace_pmap(p->p_vmspace);
vm_map_lock_read(map);
RestartScan:
timestamp = map->timestamp;
if (!vm_map_lookup_entry(map, addr, &entry))
entry = entry->next;
@ -765,6 +768,12 @@ mincore(p, uap)
}
}
/*
* subyte may page fault. In case it needs to modify
* the map, we release the lock.
*/
vm_map_unlock_read(map);
/*
* calculate index into user supplied byte vector
*/
@ -777,7 +786,6 @@ mincore(p, uap)
while((lastvecindex + 1) < vecindex) {
error = subyte( vec + lastvecindex, 0);
if (error) {
vm_map_unlock_read(map);
return (EFAULT);
}
++lastvecindex;
@ -788,14 +796,28 @@ mincore(p, uap)
*/
error = subyte( vec + vecindex, mincoreinfo);
if (error) {
vm_map_unlock_read(map);
return (EFAULT);
}
/*
* If the map has changed, due to the subyte, the previous
* output may be invalid.
*/
vm_map_lock_read(map);
if (timestamp != map->timestamp)
goto RestartScan;
lastvecindex = vecindex;
addr += PAGE_SIZE;
}
}
/*
* subyte may page fault. In case it needs to modify
* the map, we release the lock.
*/
vm_map_unlock_read(map);
/*
* Zero the last entries in the byte vector.
*/
@ -803,13 +825,20 @@ mincore(p, uap)
while((lastvecindex + 1) < vecindex) {
error = subyte( vec + lastvecindex, 0);
if (error) {
vm_map_unlock_read(map);
return (EFAULT);
}
++lastvecindex;
}
/*
* If the map has changed, due to the subyte, the previous
* output may be invalid.
*/
vm_map_lock_read(map);
if (timestamp != map->timestamp)
goto RestartScan;
vm_map_unlock_read(map);
return (0);
}