bus_dmamem_alloc() can't handle large NOWAIT requests

Peter Jeremy PeterJeremy at optushome.com.au
Sun Jan 9 02:15:32 PST 2005


On Sat, 2005-Jan-08 22:25:03 -0700, Scott Long wrote:
>>According to bus_dma(9), bus_dmamem_alloc() can be invoked with a
>>flag BUS_DMA_NOWAIT to indicate that sleep()ing is not allowed.
>>
>>At least on the i386, if the requested size exceeds 1 page (or some
>>other cases), the requested memory will be allocated via contigmalloc().
...
>Will contigmalloc() actually sleep?  If so, then this is something that
>needs to be addressed in contigmalloc.

I have not actually seen this occur.  If I get some time, I might see
if I can force the issue.  Reading the code, I believe it can.

Firstly:
1) if (vm_old_contigmalloc), contigmalloc1() locks vm_page_queue_mtx
   via vm_page_lock_queues().
2) Otherwise, contigmalloc2() calls vm_map_lock() which locks
   kernel_map->system_mtx

Both these mutexes are MTX_DEF (sleepable) and there doesn't appear
to be anything preventing them from sleeping.

There are other theoretical code paths that end in sleeps (eg the
following), though I suspect this path can never occur:

contigmalloc() =>
vm_contig.c:552:      contigmalloc1() =>
vm_contig.c:222,227:  vm_contig_launder() =>
vm_contig.c:141:      vm_contig_launder_page() =>
vm_contig.c:98:       vm_page_sleep_if_busy() =>
vm_page.c:440:        msleep()

-- 
Peter Jeremy


More information about the freebsd-current mailing list