Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 11 Jan 2005 10:08:13 -0500
From:      John Baldwin <john@baldwin.cx>
To:        Peter Jeremy <PeterJeremy@optushome.com.au>
Cc:        Scott Long <scottl@freebsd.org>
Subject:   Re: bus_dmamem_alloc() can't handle large NOWAIT requests
Message-ID:  <9D0B94DA-63E2-11D9-A25E-000393921CC4@baldwin.cx>
In-Reply-To: <20050109101529.GM39552@cirb503493.alcatel.com.au>
References:  <20050109011132.GJ39552@cirb503493.alcatel.com.au> <41E0C02F.60100@freebsd.org> <20050109101529.GM39552@cirb503493.alcatel.com.au>

next in thread | previous in thread | raw e-mail | index | archive | help

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@FreeBSD.org>  <><  http://www.FreeBSD.org/~jhb/
"Power Users Use the Power to Serve"  =  http://www.FreeBSD.org



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?9D0B94DA-63E2-11D9-A25E-000393921CC4>