bus_dmamap_load_uio() and user data

Max Laier max at love2party.net
Sun Jan 10 20:13:02 UTC 2010


On Friday 08 January 2010 17:13:29 John Baldwin wrote:
> On Friday 08 January 2010 9:14:36 am Mark Tinguely wrote:
> > >  You should use the pmap from the thread in the uio structure.  Similar
> > > to this from the x86 bus_dma code:
> > >
> > >          if (uio->uio_segflg == UIO_USERSPACE) {
> > >                  KASSERT(uio->uio_td != NULL,
> > >                          ("bus_dmamap_load_uio: USERSPACE but no
> > > proc")); pmap = vmspace_pmap(uio->uio_td->td_proc->p_vmspace); } else
> > >                  pmap = NULL;
> > >
> > >  Later when doing VA -> PA conversions the code does this:
> > >
> > >                          if (pmap)
> > >                                  paddr = pmap_extract(pmap, vaddr);
> > >                          else
> > >                                  paddr = pmap_kextract(vaddr);
> >
> > We do that, but I notice that all the architecture that implement
> > bounce buffers assume the VA is in the current map. Most of the
> > addresses are KVA, but bus_dmamap_load_uio() can be in the user space.
> >
> > I was wondering about the sequence:
> >
> >  bus_dmamap_load_uio() user space
> >    dma_load_buffer()
> >      add bounce page save UVA (in caller user map)
> >
> > later:
> >
> >  bus_dma_sync
> >    copies bounce buffer from saved UVA. <- here is my concern. The user
> > pmap is not remembered use current pmap.
> >
> > Since the bounce buffer copy routines have been running in other 
> > architectures for years without corruption, I was wondering we can safely 
> > assume that the dma sync is running in the same thread/address space as 
> > the bus_dmamap_load_uio call. I was hoping you would say, don't worry the 
> > scheduler would always reload the same thread to execute the dma sync code 
> > ...
> 
> Ahh.  I think bus_dmamap_load_uio() doesn't do deferred callbacks (i.e.
> mandates BUS_DMA_NOWAIT), and probably is always invoked from curthread. 
>  Even in the case of aio, the thread's vmspace is the effective one at the
>  time bus_dmamap_load_uio() would be invoked, so in practice it is safe.

I ran into ?this? problem with bus_dmamap_sync and bounce buffers while trying 
to do a BUS_DMASYNC_POSTREAD in interrupt context.  The sync code was trying 
to copy from bounce buffer to the UVA without proper context -> SEGFAULT.  I 
tried to move the sync to the ioctl context that is used by the userland to 
figure out which part of the buffer is "ready" ... this /kind of/ worked, but 
lead to DMA problems in ata (which I didn't yet investigate) when trying to 
write the buffer to disk.

I meanwhile moved to exporting a kernel buffer instead, using OBJT_SG - which 
is a bit more work and eats KVA, but at least on amd64 there is no shortage of 
that.

--
  Max


More information about the freebsd-hackers mailing list