bus_dmamap_sync() for bounced client buffers from user address space

Jason Harmening jason.harmening at gmail.com
Sat Apr 25 17:06:16 UTC 2015


On 04/25/15 11:34, Konstantin Belousov wrote:
> On Sat, Apr 25, 2015 at 09:02:12AM -0500, Jason Harmening wrote:
>> It seems like in general it is too hard for drivers using busdma to deal
>> with usermode memory in a way that's both safe and efficient:
>> --bus_dmamap_load_uio + UIO_USERSPACE is apparently really unsafe
>> --if they do things the other way and allocate in the kernel, then then
>> they better either be willing to do extra copying, or create and
>> refcount their own vm_objects and use d_mmap_single (I still haven't
>> seen a good example of that), or leak a bunch of memory (if they use
>> d_mmap), because the old device pager is also really unsafe.
> munmap(2) does not free the pages, it removes the mapping and dereferences
> the backing vm object.  If the region was wired, munmap would decrement
> the wiring count for the pages.  So if a kernel code wired the regions
> pages, they are kept wired, but no longer mapped into the userspace.
> So bcopy() still does not work.
Ok, my question wasn't whether munmap frees the pages, but whether it
accounts for wire count when attempting to remove the mapping.  It
doesn't, so yes bcopy will be unsafe.

>
> d_mmap_single() is used by GPU, definitely by GEM and TTM code, and possibly
> by the proprietary nvidia driver.
>
> I believe UIO_USERSPACE is almost unused, it might be there for some
> obscure (and buggy) driver.
It may be nearly unused, but we still document it in busdma.9, and we
still explicitly check for it when setting the pmap in
_bus_dmamap_load_uio.  If it's not safe to use, then it's not OK for us
to do that.
We need to either a) remove support for it by adding a failure/KASSERT
on UIO_USERSPACE in _busdmamap_load_uio() and remove the paragraph on it
from busdma.9, or b) make it safe.

I'd be in favor of b), because I think it is still valid to support some
non-painful way of using DMA with userspace buffers.  Right now, the
only safe way to do that seems to be:
1) vm_fault_quick_hold_pages
2) kva_alloc
3) pmap_qenter
4) bus_dmamap_load

That seems both unnecessarily complex and wasteful of KVA space.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 603 bytes
Desc: OpenPGP digital signature
URL: <http://lists.freebsd.org/pipermail/freebsd-arch/attachments/20150425/e571d42f/attachment.sig>


More information about the freebsd-arch mailing list