Pārlūkot izejas kodu

optimize locking against vm changes for mmap/munmap

the whole point of this locking is to prevent munmap, or mmap with
MAP_FIXED, from deallocating virtual addresses, or changing the
backing a given virtual address refers to, during certain race windows
involving self-synchronized unmapping or destruction of pthread
synchronization objects. there is no need for exclusion in the other
direction, so it suffices to take the lock momentarily and release it
before making the syscall, rather than holding it across the syscall.
Rich Felker 10 gadi atpakaļ
vecāks
revīzija
25d12fc0fc
2 mainītis faili ar 7 papildinājumiem un 8 dzēšanām
  1. 6 7
      src/mman/mmap.c
  2. 1 1
      src/mman/munmap.c

+ 6 - 7
src/mman/mmap.c

@@ -16,8 +16,6 @@ weak_alias(dummy0, __vm_unlock);
 
 void *__mmap(void *start, size_t len, int prot, int flags, int fd, off_t off)
 {
-	void *ret;
-
 	if (off & OFF_MASK) {
 		errno = EINVAL;
 		return MAP_FAILED;
@@ -26,14 +24,15 @@ void *__mmap(void *start, size_t len, int prot, int flags, int fd, off_t off)
 		errno = ENOMEM;
 		return MAP_FAILED;
 	}
-	if (flags & MAP_FIXED) __vm_lock(-1);
+	if (flags & MAP_FIXED) {
+		__vm_lock(-1);
+		__vm_unlock();
+	}
 #ifdef SYS_mmap2
-	ret = (void *)syscall(SYS_mmap2, start, len, prot, flags, fd, off/UNIT);
+	return (void *)syscall(SYS_mmap2, start, len, prot, flags, fd, off/UNIT);
 #else
-	ret = (void *)syscall(SYS_mmap, start, len, prot, flags, fd, off);
+	return (void *)syscall(SYS_mmap, start, len, prot, flags, fd, off);
 #endif
-	if (flags & MAP_FIXED) __vm_unlock();
-	return ret;
 }
 
 weak_alias(__mmap, mmap);

+ 1 - 1
src/mman/munmap.c

@@ -11,8 +11,8 @@ int __munmap(void *start, size_t len)
 {
 	int ret;
 	__vm_lock(-1);
-	ret = syscall(SYS_munmap, start, len);
 	__vm_unlock();
+	ret = syscall(SYS_munmap, start, len);
 	return ret;
 }