看板 DFBSD_bugs 關於我們 聯絡資訊
On Wed, Oct 06, 2004 at 07:57:20PM -0700, Matthew Dillon wrote: .... > This looks like a custom driver that we do not have source for (you > should have said that at the beginning!). Sorry for not being more clear about this. The driver does nothing very interesting, but I'd be happy to post/email it if you'd like. > The panic in free() is definitely due to some sort of corruption, > either a double-free or some other memory corruption is occuring. > That's my best guess. I did some debugging today and this is what I found. The panic occurs because of an assert in kern_slaballoc.c:free() /* * Zone case. Figure out the zone based on the fact that it is * ZoneSize aligned. */ z = (SLZone *)((uintptr_t)ptr & ~(uintptr_t)ZoneMask); KKASSERT(z->z_Magic == ZALLOC_SLAB_MAGIC); The problem is that this memory isn't a zone, it's a chunk whose ku_pagecnt is zero and thus fails the previous block ("Handle oversized allocations. ...") { struct kmemusage *kup; unsigned long size; kup = btokup(ptr); if (kup->ku_pagecnt) { ... 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. 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. 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