mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-12 14:29:28 +00:00
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:
parent
5365c4e788
commit
dd2622a8cd
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=44438
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user