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