Re: bus_dmamem_alloc() can't handle large NOWAIT requests

From: John Baldwin <john_at_baldwin.cx>
Date: Tue, 11 Jan 2005 10:08:13 -0500
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
Received on Tue Jan 11 2005 - 14:10:44 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:38:26 UTC