Page MenuHomeFreeBSD

Better handling for alignment requirements in x86 busdma bounce.
ClosedPublic

Authored by kib on Sep 24 2021, 7:53 PM.

Details

Summary
malloc_aligned(9): allow zero size and alignment

For alignment we do not need to do anything to make it operational.
For size, upgrade zero sized request to one byte so that we do not
request insane amount of memory for placeholder.
x86 bounce_bus_dmamem_alloc(): use malloc_aligned() only when possible

malloc_domainset_aligned() requires that alignment is less than
page size. Fall back to other allocation methods, most likely
kmem_alloc_contig(), when malloc_aligned() cannot fullfill the driver
request.

Diff Detail

Repository
R10 FreeBSD src repository
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

kib requested review of this revision.Sep 24 2021, 7:53 PM
kib created this revision.
sys/kern/kern_malloc.c
815

s/size/align/

sys/x86/x86/busdma_bounce.c
456 ↗(On Diff #95669)
sys/kern/kern_malloc.c
815

Why? The only interesting case is size == align == 0, and flsl(0) == 0, so asize would be 1.

kib marked an inline comment as done.Sep 24 2021, 8:05 PM
markj added inline comments.
sys/kern/kern_malloc.c
815

Ah, I see.

This revision is now accepted and ready to land.Sep 24 2021, 8:09 PM

Thinking about it further, I suspect the alignment == 0 case should indeed by handled by the caller. The fact that bus_dma_tag_create() tolerates alignment == 0 is the real problem. Most if not all bus_dma_tag_create() callers that I can see do specify alignment >= 1, so probably there is just some small set of drivers which need to be fixed, and in the meantime common_bus_dma_tag_create() can fix up bogus values.

Thinking about it further, I suspect the alignment == 0 case should indeed by handled by the caller. The fact that bus_dma_tag_create() tolerates alignment == 0 is the real problem. Most if not all bus_dma_tag_create() callers that I can see do specify alignment >= 1, so probably there is just some small set of drivers which need to be fixed, and in the meantime common_bus_dma_tag_create() can fix up bogus values.

The change is about malloc_aligned interface. I do not see it too useful to be so strict there. We do accept align == 1 after all, which effectively means "fall back to malloc()". So since align == 0 does not make any sense, it is fine IMO to put a sense we want. It is similar to the interpretation of size == 0, which also does not make sense without explicit agreement on its meaning.

In D32127#724969, @kib wrote:

Thinking about it further, I suspect the alignment == 0 case should indeed by handled by the caller. The fact that bus_dma_tag_create() tolerates alignment == 0 is the real problem. Most if not all bus_dma_tag_create() callers that I can see do specify alignment >= 1, so probably there is just some small set of drivers which need to be fixed, and in the meantime common_bus_dma_tag_create() can fix up bogus values.

The change is about malloc_aligned interface. I do not see it too useful to be so strict there. We do accept align == 1 after all, which effectively means "fall back to malloc()". So since align == 0 does not make any sense, it is fine IMO to put a sense we want. It is similar to the interpretation of size == 0, which also does not make sense without explicit agreement on its meaning.

It is not really useful to be strict, sure, it is just consistent with other VM interfaces that accept an alignment parameter. As a matter of principle I would prefer not to have extra logic to handle callers that do not respect the documented interface ("align must be a power of 2"). But it is not harmful here, so I don't mean this as an objection to the diff.