Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 12 Jul 2012 08:26:05 -0400
From:      John Baldwin <jhb@freebsd.org>
To:        freebsd-hackers@freebsd.org
Cc:        Alan Cox <alc@freebsd.org>, Warner Losh <imp@freebsd.org>
Subject:   Re: contigmalloc() breaking Xorg
Message-ID:  <201207120826.05577.jhb@freebsd.org>
In-Reply-To: <20120708110516.GA38312@server.rulingia.com>
References:  <20120703111753.GB72292@server.rulingia.com> <20120708110516.GA38312@server.rulingia.com>

next in thread | previous in thread | raw e-mail | index | archive | help
[ Adding alc@ for VM stuff, Warner for arm/mips bus dma brokenness ]

On Sunday, July 08, 2012 7:05:16 am Peter Jeremy wrote:
> On 2012-Jul-03 21:17:53 +1000, Peter Jeremy <peter@server.rulingia.com> 
wrote:
> >I have a reasonably recent 8-stable/amd64 system (r237444) with a "ATI
> >Radeon HD 2400 Pro", xorg-server-1.10.6,1 and xf86-video-ati-6.14.3_1
> >8GB RAM and ZFS.  I'm seeing fairly consistent problems with Xorg
> ...
> >How difficult would it be to modify bus_dmamem_alloc() [at least on
> >x86] to handle multi-segment allocations?
> 
> I think I've managed to create an amd64 bus_dmamem_alloc() that allows
> page-sized allocations as long as no boundary condition is specified
> and no more than page-sized alignment is required (porting it to other
> architectures would be trivial).  I've given it a quick whirl inside a
> VBox and no smoke came out but I'd appreciate someone with a better
> understanding of bus_dma(9) and vm/vm_contig.c giving
> http://www.rulingia.com/bugs/patch-wiredmalloc a once-over.  Note that
> this patch is against 8.x but there's only a trivial difference to head.
> 
> BTW, the comment in busdma_machdep.c:bus_dmamem_alloc()
> 	 * XXX Use Contigmalloc until it is merged into this facility
> 	 *     and handles multi-seg allocations.  Nobody is doing
> 	 *     multi-seg allocations yet though.
> 	 * XXX Certain AGP hardware does.
> does not appear to be accurate.  Apart from drm, quite a few drivers
> call bus_dma_tag_create(9) with multiple segments and also call
> bus_dmamem_alloc(9) [though I haven't verified that the calls share
> the same bus_dma_tag, so I can't be absolutely certain].

I do think that all tags currently used with bus_dmamem_alloc() only use a 
single segment.  It's a bit of an unfortunate part of the bus_dmamem API
that the size of the allocate is determined by the tag (the tag should be
used for determining the features and constraints of a DMA engine, not really 
the amount of memory to allocate).

However, rather add a wiredmalloc(), I think you should just have 
bus_dmamem_alloc() call kmem_alloc_attr() directly in this case.  One of the 
things I've been meaning to add to bus_dma is a way to allocate other memory 
types (e.g. WC memory), and in that case it would be best to just call 
kmem_alloc_attr() directly instead.

> BTW(2): Whilst studying busdma_machdep.c for arm and mips, I've
> noticed they appear to potentially allocate substantial kernel stack
> under some conditions as several bus_dma(9) functions include:
>     bus_dma_segment_t dm_segments[dmat->nsegments];
> What prevents this overflowing the kernel stack?

That does seem dubious.  x86 stores the array in the tag instead.

-- 
John Baldwin



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201207120826.05577.jhb>