Page MenuHomeFreeBSD

D28147.id82305.diff
No OneTemporary

D28147.id82305.diff

diff --git a/sys/kern/kern_malloc.c b/sys/kern/kern_malloc.c
--- a/sys/kern/kern_malloc.c
+++ b/sys/kern/kern_malloc.c
@@ -763,6 +763,28 @@
return (malloc_large(&size, mtp, ds, flags DEBUG_REDZONE_ARG));
}
+void *
+malloc_domainset_aligned(size_t size, size_t align,
+ struct malloc_type *mtp, struct domainset *ds, int flags)
+{
+ void *res;
+
+ KASSERT(align != 0 && powerof2(align),
+ ("malloc_domainset_aligned: wrong alig %#zx size %#zx",
+ align, size));
+ KASSERT(align <= kmemzones[nitems(kmemzones) - 2].kz_size,
+ ("malloc_domainset_aligned: align %#zx (size %#zx) too large",
+ align, size));
+
+ if (size < align)
+ size = align;
+ res = malloc_domainset(size, mtp, ds, flags);
+ KASSERT(res == NULL || ((uintptr_t)res & (align - 1)) == 0,
+ ("malloc_domainset_aligned: result not aligned %p size %#zx "
+ "align %#zx", res, size, align));
+ return (res);
+}
+
void *
mallocarray(size_t nmemb, size_t size, struct malloc_type *type, int flags)
{
@@ -1146,8 +1168,12 @@
for (i = 0, indx = 0; kmemzones[indx].kz_size != 0; indx++) {
int size = kmemzones[indx].kz_size;
const char *name = kmemzones[indx].kz_name;
+ size_t align;
int subzone;
+ align = UMA_ALIGN_PTR;
+ if (powerof2(size) && size > sizeof(void *))
+ align = size - 1;
for (subzone = 0; subzone < numzones; subzone++) {
kmemzones[indx].kz_zone[subzone] =
uma_zcreate(name, size,
@@ -1156,7 +1182,7 @@
#else
NULL, NULL, NULL, NULL,
#endif
- UMA_ALIGN_PTR, UMA_ZONE_MALLOC);
+ align, UMA_ZONE_MALLOC);
}
for (;i <= size; i+= KMEM_ZBASE)
kmemsize[i >> KMEM_ZSHIFT] = indx;
diff --git a/sys/sys/malloc.h b/sys/sys/malloc.h
--- a/sys/sys/malloc.h
+++ b/sys/sys/malloc.h
@@ -261,6 +261,9 @@
__result_use_check __alloc_size(2);
void *reallocf(void *addr, size_t size, struct malloc_type *type, int flags)
__result_use_check __alloc_size(2);
+void *malloc_domainset_aligned(size_t size, size_t align,
+ struct malloc_type *mtp, struct domainset *ds, int flags)
+ __malloc_like __result_use_check __alloc_size(1);
struct malloc_type *malloc_desc2type(const char *desc);
diff --git a/sys/x86/x86/busdma_bounce.c b/sys/x86/x86/busdma_bounce.c
--- a/sys/x86/x86/busdma_bounce.c
+++ b/sys/x86/x86/busdma_bounce.c
@@ -433,9 +433,9 @@
/*
* Allocate the buffer from the malloc(9) allocator if...
- * - It's small enough to fit into a single power of two sized bucket.
- * - The alignment is less than or equal to the maximum size
+ * - It's small enough to fit into a single page.
* - The low address requirement is fulfilled.
+ * - Default cache attributes are requested (WB).
* else allocate non-contiguous pages if...
* - The page count that could get allocated doesn't exceed
* nsegments also when the maximum segment size is less
@@ -445,19 +445,19 @@
* else allocate a block of contiguous pages because one or more of the
* constraints is something that only the contig allocator can fulfill.
*
- * NOTE: The (dmat->common.alignment <= dmat->maxsize) check
- * below is just a quick hack. The exact alignment guarantees
- * of malloc(9) need to be nailed down, and the code below
- * should be rewritten to take that into account.
- *
- * In the meantime warn the user if malloc gets it wrong.
+ * Warn the user if malloc gets it wrong.
*/
if (dmat->common.maxsize <= PAGE_SIZE &&
- dmat->common.alignment <= dmat->common.maxsize &&
dmat->common.lowaddr >= ptoa((vm_paddr_t)Maxmem) &&
attr == VM_MEMATTR_DEFAULT) {
- *vaddr = malloc_domainset(dmat->common.maxsize, M_DEVBUF,
+ *vaddr = malloc_domainset_aligned(dmat->common.maxsize,
+ dmat->common.alignment, M_DEVBUF,
DOMAINSET_PREF(dmat->common.domain), mflags);
+ KASSERT(*vaddr == NULL || ((uintptr_t)*vaddr & PAGE_MASK) +
+ dmat->common.maxsize <= PAGE_SIZE,
+ ("bounce_bus_dmamem_alloc: multi-page alloc %p maxsize "
+ "%#jx align %#jx", *vaddr, (uintptr_t)dmat->common.maxsize,
+ (uintptr_t)dmat->common.alignment));
} else if (dmat->common.nsegments >=
howmany(dmat->common.maxsize, MIN(dmat->common.maxsegsz,
PAGE_SIZE)) &&

File Metadata

Mime Type
text/plain
Expires
Thu, Jan 16, 12:13 AM (17 h, 42 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15817727
Default Alt Text
D28147.id82305.diff (4 KB)

Event Timeline