[issue1884] System completely freezes while listening music (devbuf: malloc limit exceeded)

Matthew Dillon dillon at apollo.backplane.com
Tue Nov 16 10:17:57 PST 2010


:vasily postnicov <shamaz.mazum at gmail.com> added the comment:
:
:Some code from usb_mem.c:
:
:/*
: * Do not free the memory unconditionally since we might be called
: * from an interrupt context and that is BAD.
: * XXX when should we really free?
: */
:static void
:usb_block_freemem(usb_dma_block_t *p)
:{
:	DPRINTFN(6, ("usb_block_freemem: size=%lu\n", (u_long)p->size));
:	logmemory(blkfree, p, NULL, p->size, p->align);
:	crit_enter();
:	LIST_INSERT_HEAD(&usb_blk_freelist, p, next);
:	usb_blk_nfree++;
:	crit_exit();
:}
:
:So it, actually, does not free memory, does it?

    Hmm.  Well, usb_block_allocmem() will reuse it, theoretically, but
    that assumes the bus_dma_tag_t is not reallocated in the mean time.
    If it is then any related memory on usb_blk_freelist will just languish
    there and never get reused.

:Here is some code from NetBSD I found:
:
:http://fxr.watson.org/fxr/source/dev/usb/usb_mem.c?v=NETBSD;im=10
:
:As you can see, there is some function called usb_block_real_freemem, but (as I
:understand) it is never compiled (it is between #if 0/#endif).
:
:What is "interrupt context" and why it is so dangerous?

    The 'interrupt context' has evolved significantly over the years.
    In fact on today's operating systems most interrupt contexts are
    actually interrupt threads and it is in fact ok to free memory
    from them.

    The netbsd usb_block_real_freemem() function is enclosed in
    an #if 0/#endif, so the routine is not being used.

    In anycase, the usb_allocmem()/usb_freemem() code does look mighty
    suspicious to me.  There are two layers of caches in there (there is
    also a layer in usb_allocmem() and usb_freemem()... something called
    a usb_frag_freelist).

    Also I don't like the way it handles dma tags in p->tag.  There's this
    comment in our usb_mem.c code:

	 /* XXX - override the tag, ok since we never free it */
	 p->tag = tag;
	 ...

					-Matt
					Matthew Dillon 
					<dillon at backplane.com>





More information about the Bugs mailing list