freebsd_network: Move segment array allocation in bus_dma to dmamap_create().
It seems that some drivers (e.g. broadcom43xx) create a parent DMA tag with nsegments set to BUS_SPACE_UNRESTRICTED, i.e. MAX_INT, which of course fails allocation, expecting to never allocate memory for this tag, only for child tags. So in order to handle this, we have to delay allocating the segment array until we are certain that the nsegments value is the "real deal". Doing it in dmamap_load would be fine, but as there is more than one entry point to that, we would have to allocate this in multiple places. dmamap_create() must be called and there is only one way through it, so put the allocation there. Fixes #15500 (i.e. both the KDL and the underlying problem that led to it; it only crashed because the wrong pointer was passed to kernel_free, whoops.)
This commit is contained in:
parent
70cdd7d4f5
commit
7100b1e1f5
|
@ -84,14 +84,6 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, bus_size_t bounda
|
|||
newtag->maxsegsz = maxsegsz;
|
||||
newtag->ref_count = 1;
|
||||
|
||||
newtag->segments = (bus_dma_segment_t*)kernel_malloc(
|
||||
sizeof(bus_dma_segment_t) * newtag->nsegments, M_DEVBUF,
|
||||
M_NOWAIT);
|
||||
if (newtag->segments == NULL) {
|
||||
kernel_free(dmat, M_DEVBUF);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
if (newtag->parent != NULL) {
|
||||
atomic_add(&parent->ref_count, 1);
|
||||
|
||||
|
@ -147,6 +139,17 @@ bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t* mapp)
|
|||
{
|
||||
// We never bounce, so we do not need maps.
|
||||
*mapp = NULL;
|
||||
|
||||
// However, since bus_dmamap_create() must be called before buffers
|
||||
// are loaded, we allocate the "segments" field (if not yet done.)
|
||||
if (dmat->segments == NULL) {
|
||||
dmat->segments = (bus_dma_segment_t*)kernel_malloc(
|
||||
sizeof(bus_dma_segment_t) * dmat->nsegments, M_DEVBUF,
|
||||
M_ZERO | M_NOWAIT);
|
||||
if (dmat->segments == NULL)
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue