Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/uvm Avoid locking issues when copying out requires takin...
details: https://anonhg.NetBSD.org/src/rev/901bead239d4
branches: trunk
changeset: 815691:901bead239d4
user: christos <christos%NetBSD.org@localhost>
date: Wed Jun 01 00:49:44 2016 +0000
description:
Avoid locking issues when copying out requires taking a fault and we are
finding out our own maps, by allocating a buffer and copying out after
we collected the information.
diffstat:
sys/uvm/uvm_map.c | 39 ++++++++++++++++++++++++++++-----------
1 files changed, 28 insertions(+), 11 deletions(-)
diffs (91 lines):
diff -r f3e28360a98b -r 901bead239d4 sys/uvm/uvm_map.c
--- a/sys/uvm/uvm_map.c Wed Jun 01 00:47:16 2016 +0000
+++ b/sys/uvm/uvm_map.c Wed Jun 01 00:49:44 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_map.c,v 1.337 2016/05/25 17:43:58 christos Exp $ */
+/* $NetBSD: uvm_map.c,v 1.338 2016/06/01 00:49:44 christos Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -66,7 +66,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 1.337 2016/05/25 17:43:58 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 1.338 2016/06/01 00:49:44 christos Exp $");
#include "opt_ddb.h"
#include "opt_uvmhist.h"
@@ -4877,14 +4877,18 @@
{
int error;
struct proc *p;
- struct kinfo_vmentry vme;
+ struct kinfo_vmentry *vme;
struct vmspace *vm;
struct vm_map *map;
struct vm_map_entry *entry;
char *dp;
- size_t count;
-
+ size_t count, vmesize;
+
+ vme = NULL;
+ vmesize = *oldlenp;
count = 0;
+ if (oldp && *oldlenp > 1024 * 1024)
+ return E2BIG;
if ((error = proc_find_locked(l, &p, pid)) != 0)
return error;
@@ -4896,31 +4900,44 @@
vm_map_lock_read(map);
dp = oldp;
+ if (oldp)
+ vme = kmem_alloc(vmesize, KM_SLEEP);
for (entry = map->header.next; entry != &map->header;
entry = entry->next) {
if (oldp && (dp - (char *)oldp) < *oldlenp + elem_size) {
- error = fill_vmentry(l, p, &vme, map, entry);
+ error = fill_vmentry(l, p, &vme[count], map, entry);
if (error)
- break;
- error = sysctl_copyout(l, &vme, dp,
- min(elem_size, sizeof(vme)));
- if (error)
- break;
+ goto out;
dp += elem_size;
}
count++;
}
vm_map_unlock_read(map);
uvmspace_free(vm);
+
out:
if (pid != -1)
mutex_exit(p->p_lock);
if (error == 0) {
+ const u_int esize = min(sizeof(*vme), elem_size);
+ dp = oldp;
+ for (size_t i = 0; i < count; i++) {
+ if (oldp && (dp - (char *)oldp) < *oldlenp + elem_size)
+ {
+ error = sysctl_copyout(l, &vme[i], dp, esize);
+ if (error)
+ break;
+ dp += elem_size;
+ } else
+ break;
+ }
count *= elem_size;
if (oldp != NULL && *oldlenp < count)
error = ENOSPC;
*oldlenp = count;
}
+ if (vme)
+ kmem_free(vme, vmesize);
return error;
}
Home |
Main Index |
Thread Index |
Old Index