Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F146970704
D17175.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
D17175.diff
View Options
Index: sys/vm/memguard.c
===================================================================
--- sys/vm/memguard.c
+++ sys/vm/memguard.c
@@ -64,6 +64,13 @@
#include <vm/uma_int.h>
#include <vm/memguard.h>
+#if VM_NRESERVLEVEL > 0
+#define MEMGUARD_SHIFT (VM_LEVEL_0_ORDER + PAGE_SHIFT)
+#else
+#define MEMGUARD_SHIFT PAGE_SHIFT
+#endif
+#define MEMGUARD_ALIGN (1 << MEMGUARD_SHIFT)
+
static SYSCTL_NODE(_vm, OID_AUTO, memguard, CTLFLAG_RW, NULL, "MemGuard data");
/*
* The vm_memguard_divisor variable controls how much of kernel_arena should be
@@ -194,6 +201,7 @@
memguard_mapsize = mem_pgs * 2 * PAGE_SIZE;
if (km_size + memguard_mapsize > parent_size)
memguard_mapsize = 0;
+ memguard_mapsize = roundup2(memguard_mapsize, MEMGUARD_ALIGN);
return (km_size + memguard_mapsize);
}
@@ -206,7 +214,8 @@
{
vm_offset_t base;
- vmem_alloc(parent, memguard_mapsize, M_BESTFIT | M_WAITOK, &base);
+ vmem_xalloc(parent, memguard_mapsize, MEMGUARD_ALIGN, 0, 0,
+ VMEM_ADDR_MIN, VMEM_ADDR_MAX, M_BESTFIT | M_WAITOK, &base);
vmem_init(memguard_arena, "memguard arena", base, memguard_mapsize,
PAGE_SIZE, 0, M_WAITOK);
memguard_cursor = base;
@@ -286,9 +295,10 @@
void *
memguard_alloc(unsigned long req_size, int flags)
{
- vm_offset_t addr, origaddr;
+ vm_offset_t addr, next, origaddr;
u_long size_p, size_v;
- int do_guard, rv;
+ int domain, rv;
+ bool do_guard;
size_p = round_page(req_size);
if (size_p == 0)
@@ -332,6 +342,7 @@
memguard_cursor, VMEM_ADDR_MAX,
M_BESTFIT | M_NOWAIT, &origaddr) == 0)
break;
+
/*
* The map has no space. This may be due to
* fragmentation, or because the cursor is near the
@@ -348,14 +359,38 @@
addr = origaddr;
if (do_guard)
addr += PAGE_SIZE;
- rv = kmem_back(kernel_object, addr, size_p, flags);
+
+ /*
+ * The kmem_* API uses per-domain vmem arenas to ensure that pages
+ * backing a large virtual page all come from the same domain. We must
+ * provide the same guarantee.
+ */
+ domain = 0;
+#if VM_NRESERVLEVEL > 0
+ if (vm_ndomains > 1)
+ domain = (addr >> MEMGUARD_SHIFT) % vm_ndomains;
+#endif
+ rv = kmem_back_domain(domain, kernel_object, addr, size_p, flags);
if (rv != KERN_SUCCESS) {
vmem_xfree(memguard_arena, origaddr, size_v);
memguard_fail_pgs++;
addr = (vm_offset_t)NULL;
+#if VM_NRESERVLEVEL > 0
+ /*
+ * Select a different domain for subsequent allocations by
+ * advancing the cursor to the next superpage boundary. This
+ * may be undone by the non-atomic cursor update following a
+ * concurrent successful allocation.
+ */
+ if (vm_ndomains > 1) {
+ next = roundup2(memguard_cursor, MEMGUARD_ALIGN);
+ (void)atomic_cmpset_long(&memguard_cursor,
+ memguard_cursor, next);
+ }
+#endif
goto out;
}
- memguard_cursor = addr + size_v;
+ memguard_cursor = origaddr + size_v;
*v2sizep(trunc_page(addr)) = req_size;
*v2sizev(trunc_page(addr)) = size_v;
memguard_succ++;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Mar 8, 6:22 AM (48 m, 57 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29397409
Default Alt Text
D17175.diff (2 KB)
Attached To
Mode
D17175: Fix memguard when options NUMA is configured.
Attached
Detach File
Event Timeline
Log In to Comment