Changeset View
Changeset View
Standalone View
Standalone View
sys/x86/x86/busdma_bounce.c
Show First 20 Lines • Show All 428 Lines • ▼ Show 20 Lines | bounce_bus_dmamem_alloc(bus_dma_tag_t dmat, void **vaddr, int flags, | ||||
if (flags & BUS_DMA_NOCACHE) | if (flags & BUS_DMA_NOCACHE) | ||||
attr = VM_MEMATTR_UNCACHEABLE; | attr = VM_MEMATTR_UNCACHEABLE; | ||||
else | else | ||||
attr = VM_MEMATTR_DEFAULT; | attr = VM_MEMATTR_DEFAULT; | ||||
/* | /* | ||||
* Allocate the buffer from the malloc(9) allocator if... | * Allocate the buffer from the malloc(9) allocator if... | ||||
* - It's small enough to fit into a single power of two sized bucket. | * - 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 | * - The alignment is less than or equal to the maximum size | ||||
andrew: This comment needs to be updated. | |||||
* - The low address requirement is fulfilled. | * - The low address requirement is fulfilled. | ||||
* else allocate non-contiguous pages if... | * else allocate non-contiguous pages if... | ||||
* - The page count that could get allocated doesn't exceed | * - The page count that could get allocated doesn't exceed | ||||
* nsegments also when the maximum segment size is less | * nsegments also when the maximum segment size is less | ||||
* than PAGE_SIZE. | * than PAGE_SIZE. | ||||
* - The alignment constraint isn't larger than a page boundary. | * - The alignment constraint isn't larger than a page boundary. | ||||
* - There are no boundary-crossing constraints. | * - There are no boundary-crossing constraints. | ||||
* else allocate a block of contiguous pages because one or more of the | * else allocate a block of contiguous pages because one or more of the | ||||
* constraints is something that only the contig allocator can fulfill. | * constraints is something that only the contig allocator can fulfill. | ||||
* | * | ||||
* NOTE: The (dmat->common.alignment <= dmat->maxsize) check | * Warn the user if malloc gets it wrong. | ||||
* 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. | |||||
*/ | */ | ||||
if (dmat->common.maxsize <= PAGE_SIZE && | if (dmat->common.maxsize <= PAGE_SIZE && | ||||
dmat->common.alignment <= dmat->common.maxsize && | |||||
dmat->common.lowaddr >= ptoa((vm_paddr_t)Maxmem) && | dmat->common.lowaddr >= ptoa((vm_paddr_t)Maxmem) && | ||||
Not Done Inline ActionsWe'll need a check that the alignment isn't too large for malloc_domainset_aligned. andrew: We'll need a check that the alignment isn't too large for `malloc_domainset_aligned`. | |||||
Done Inline ActionsThere is KASSERT() in malloc_aligned, and I really do not expect small allocations (less than page size) to request large alignment. Another issue is that there is no way to report the alignment limits, except perhaps adding a function to return just the limit. kib: There is KASSERT() in malloc_aligned, and I really do not expect small allocations (less than… | |||||
attr == VM_MEMATTR_DEFAULT) { | attr == VM_MEMATTR_DEFAULT) { | ||||
*vaddr = malloc_domainset(dmat->common.maxsize, M_DEVBUF, | *vaddr = malloc_domainset_aligned(dmat->common.maxsize, | ||||
DOMAINSET_PREF(dmat->common.domain), mflags); | dmat->common.alignment, | ||||
M_DEVBUF, DOMAINSET_PREF(dmat->common.domain), mflags); | |||||
} else if (dmat->common.nsegments >= | } else if (dmat->common.nsegments >= | ||||
howmany(dmat->common.maxsize, MIN(dmat->common.maxsegsz, | howmany(dmat->common.maxsize, MIN(dmat->common.maxsegsz, | ||||
PAGE_SIZE)) && | PAGE_SIZE)) && | ||||
dmat->common.alignment <= PAGE_SIZE && | dmat->common.alignment <= PAGE_SIZE && | ||||
(dmat->common.boundary % PAGE_SIZE) == 0) { | (dmat->common.boundary % PAGE_SIZE) == 0) { | ||||
/* Page-based multi-segment allocations allowed */ | /* Page-based multi-segment allocations allowed */ | ||||
*vaddr = (void *)kmem_alloc_attr_domainset( | *vaddr = (void *)kmem_alloc_attr_domainset( | ||||
DOMAINSET_PREF(dmat->common.domain), dmat->common.maxsize, | DOMAINSET_PREF(dmat->common.domain), dmat->common.maxsize, | ||||
▲ Show 20 Lines • Show All 879 Lines • Show Last 20 Lines |
This comment needs to be updated.