bus_dmamem_alloc() can't handle large NOWAIT requests

John Baldwin john at baldwin.cx
Tue Jan 11 07:10:45 PST 2005


On Jan 9, 2005, at 5:15 AM, Peter Jeremy wrote:

> 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.

Unforunately, "sleep" is a bit of an overloaded term in the kernel.  
Blocking on a mutex is not considered a "sleep" quite like msleep() or 
cv_wait() in that a mutex will eventually be released (barring an 
infinite loop bug) and thus a thread blocked on a lock won't sleep 
forever.  msleep() and cv_wait() on the other hand do not have the same 
guarantee.  M_NOWAIT means that msleep() and cv_wait() won't be called; 
it is ok to block on a mutex with M_NOWAIT however.  I tried to explain 
this difference in semantics some in the glossary of the SMP chapter in 
the kernel devbook.
>
-- 

John Baldwin <jhb at FreeBSD.org>  <><  http://www.FreeBSD.org/~jhb/
"Power Users Use the Power to Serve"  =  http://www.FreeBSD.org



More information about the freebsd-current mailing list