panic in bus_dma_tag_destroy()

Matthew Dillon dillon at apollo.backplane.com
Sun Oct 10 12:14:43 PDT 2004


:This is how we got here. The driver creates a DMA tag with the max #
:of segments set to BUS_SPACE_MAXSIZE_32BIT. bus_dma_tag_create() uses
:this value to malloc newtag->segments. The number of bytes it asks
:malloc to allocate is (# segments * sizeof(bus_dma_segment_t)) = -8 or
:0xfffffff8. malloc() sees this as a large allocation and allocates a
:chunk (comment reads "Handle large allocations directly"), ie.

    It is quite illegal to ask malloc() to allocate that much space.

:
:    if (size >= ZoneLimit || (size & PAGE_MASK) == 0) {
:
:Here, size (0xfffffff8) is set to zero by the round_page() macro
:which is stored in kup->ku_pagecnt which later causes the panic.

    Ah, now I see.  But while malloc() should probably return a
    failure here, nothing should ever call it with such a huge size.
    It's way out of malloc()'s design spec.

:Probably, this is a driver bug, which is fine by me, but there are a
:couple of disk drivers which do something similar (adv_pci.c,
:adw_pci.c, bt_pci.c, mpt_pci.c) and maybe some other non-disk drivers
:(didn't look).
:
:-- 
:Chuck Tuffli
:Agilent Technologies

     No, these guys are doing something different.  Their malloc()'s,
     are based on the maximum number of requests, which is some fairly
     small number, not on the maximum size of the DMA space.

     e.g. the MPT driver:

     #define MPT_MAX_REQUESTS(mpt)   ((mpt)->is_fc? 1024 : 256)
     #define MPT_REQUEST_AREA 512
     #define MPT_REQ_MEM_SIZE(mpt)   (MPT_MAX_REQUESTS(mpt) * MPT_REQUEST_AREA)

     len = sizeof (request_t *) * MPT_REQ_MEM_SIZE(mpt);
     ...  malloc(len)

     The DMA code doesn't malloc()'s the actual dma space (well, except for
     bounce buffers, but that is something else), it malloc's the space 
     required to hold the dma request structure chain.

					-Matt
					Matthew Dillon 
					<dillon at xxxxxxxxxxxxx>





More information about the Bugs mailing list