Module Name:    src
Committed By:   drochner
Date:           Mon Feb  6 12:13:44 UTC 2012

Modified Files:
        src/sys/kern: kern_malloc.c

Log Message:
align allocations >=pagesize at a page boundary, to preserve traditional
malloc(9) semantics
fixes dri mappings shared per mmap (at least on i945)
approved by releng


To generate a diff of this commit:
cvs rdiff -u -r1.137 -r1.138 src/sys/kern/kern_malloc.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/kern_malloc.c
diff -u src/sys/kern/kern_malloc.c:1.137 src/sys/kern/kern_malloc.c:1.138
--- src/sys/kern/kern_malloc.c:1.137	Mon Jan 30 05:42:54 2012
+++ src/sys/kern/kern_malloc.c	Mon Feb  6 12:13:44 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_malloc.c,v 1.137 2012/01/30 05:42:54 mrg Exp $	*/
+/*	$NetBSD: kern_malloc.c,v 1.138 2012/02/06 12:13:44 drochner Exp $	*/
 
 /*
  * Copyright (c) 1987, 1991, 1993
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_malloc.c,v 1.137 2012/01/30 05:42:54 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_malloc.c,v 1.138 2012/02/06 12:13:44 drochner Exp $");
 
 #include <sys/param.h>
 #include <sys/proc.h>
@@ -108,10 +108,18 @@ kern_malloc(unsigned long size, struct m
 #endif /* MALLOCLOG */
 {
 	const int kmflags = (flags & M_NOWAIT) ? KM_NOSLEEP : KM_SLEEP;
-	const size_t allocsize = sizeof(struct malloc_header) + size;
+	size_t allocsize, hdroffset;
 	struct malloc_header *mh;
 	void *p;
 
+	if (size >= PAGE_SIZE) {
+		allocsize = PAGE_SIZE + size; /* for page alignment */
+		hdroffset = PAGE_SIZE - sizeof(struct malloc_header);
+	} else {
+		allocsize = sizeof(struct malloc_header) + size;
+		hdroffset = 0;
+	}
+
 	p = kmem_intr_alloc(allocsize, kmflags);
 	if (p == NULL)
 		return NULL;
@@ -119,8 +127,8 @@ kern_malloc(unsigned long size, struct m
 	if ((flags & M_ZERO) != 0) {
 		memset(p, 0, allocsize);
 	}
-	mh = (void *)p;
-	mh->mh_size = allocsize;
+	mh = (void *)((char *)p + hdroffset);
+	mh->mh_size = allocsize - hdroffset;
 
 	return mh + 1;
 }
@@ -141,7 +149,11 @@ kern_free(void *addr, struct malloc_type
 	mh = addr;
 	mh--;
 
-	kmem_intr_free(mh, mh->mh_size);
+	if (mh->mh_size >= PAGE_SIZE + sizeof(struct malloc_header))
+		kmem_intr_free((char *)addr - PAGE_SIZE,
+		    mh->mh_size + PAGE_SIZE - sizeof(struct malloc_header));
+	else
+		kmem_intr_free(mh, mh->mh_size);
 }
 
 /*

Reply via email to