2003-07-08 14:36:10

by Alan Shih

[permalink] [raw]
Subject: Question regarding DMA xfer to user space directly

Is there a provision in MM for DMA transfer to user space directly without
allocating a kernel buffer?

TIA

Alan


2003-07-08 15:12:26

by Alan

[permalink] [raw]
Subject: Re: Question regarding DMA xfer to user space directly

On Maw, 2003-07-08 at 15:50, Alan Shih wrote:
> Is there a provision in MM for DMA transfer to user space directly without
> allocating a kernel buffer?

Yes. Its used both for O_DIRECT I/O (direct to disk I/O from userspace)
and for things like tv capture cards. The kernel allows a driver to pin
user pages and obtain mappings for them. Note that for large systems
user pages may be above the 32bit boundary so you need DAC capable
hardware to get the best results

2003-07-09 17:20:40

by Alan Shih

[permalink] [raw]
Subject: RE: Question regarding DMA xfer to user space directly

Next question would be what are the steps that the driver need to ping user
pages before setting up the xfer?

Thanks.

-----Original Message-----
From: Alan Cox [mailto:[email protected]]
Sent: Tuesday, July 08, 2003 8:22 AM
To: Alan Shih
Cc: Linux Kernel Mailing List
Subject: Re: Question regarding DMA xfer to user space directly


On Maw, 2003-07-08 at 15:50, Alan Shih wrote:
> Is there a provision in MM for DMA transfer to user space directly without
> allocating a kernel buffer?

Yes. Its used both for O_DIRECT I/O (direct to disk I/O from userspace)
and for things like tv capture cards. The kernel allows a driver to pin
user pages and obtain mappings for them. Note that for large systems
user pages may be above the 32bit boundary so you need DAC capable
hardware to get the best results

2003-07-10 05:08:45

by Mikael Starvik

[permalink] [raw]
Subject: RE: Question regarding DMA xfer to user space directly

Hi,

Use map_user_kiobuf to do this. There are several examples
in the kernel tree. One of the simplest may be
arch/cris/drivers/examples/kiobuftest.c.

/Mikael

-----Original Message-----
From: [email protected]
[mailto:[email protected]] On Behalf Of Alan Shih
Sent: Wednesday, July 09, 2003 7:35 PM
To: Alan Cox
Cc: Linux Kernel Mailing List
Subject: RE: Question regarding DMA xfer to user space directly


Next question would be what are the steps that the driver need to ping user
pages before setting up the xfer?

Thanks.

-----Original Message-----
From: Alan Cox [mailto:[email protected]]
Sent: Tuesday, July 08, 2003 8:22 AM
To: Alan Shih
Cc: Linux Kernel Mailing List
Subject: Re: Question regarding DMA xfer to user space directly


On Maw, 2003-07-08 at 15:50, Alan Shih wrote:
> Is there a provision in MM for DMA transfer to user space directly
> without allocating a kernel buffer?

Yes. Its used both for O_DIRECT I/O (direct to disk I/O from userspace) and
for things like tv capture cards. The kernel allows a driver to pin user
pages and obtain mappings for them. Note that for large systems user pages
may be above the 32bit boundary so you need DAC capable hardware to get the
best results

2003-07-10 10:13:00

by Jens Axboe

[permalink] [raw]
Subject: Re: Question regarding DMA xfer to user space directly

On Thu, Jul 10 2003, Mikael Starvik wrote:
> Hi,
>
> Use map_user_kiobuf to do this. There are several examples
> in the kernel tree. One of the simplest may be
> arch/cris/drivers/examples/kiobuftest.c.

get_user_pages() is a much better idea, considering 2.5/6 has no concept
of kiobufs.

--
Jens Axboe

2003-07-10 20:41:00

by Lee, Shuyu

[permalink] [raw]
Subject: RE: Question regarding DMA xfer to user space directly

Alan(Shih),

I have also struggled with the same issue - how to DMA data to a user buffer
directly. The following is my solution. Hopefully it will make your life
easier. Based on the inquiries I received privately since I posted my
questions, you are not the only one who is stuck on this issue.

Here is the pseudo code:

User code:
pUsrVirt = malloc(bufSize);
pass pUsrVirt and bufSize to driver via an ioctl call;

Driver code;
receive pUsrVirt and bufSize from user via an ioctl call;
alloc_kiovec(1, &iobuf);
map_user_kiobuf(READ, iobuf, (unsigned long)pUsrVirt, bufSize);
physAddr = page_to_bus(iobuf->maplist[idx])
+ ((unsigned long)pUsrVirt & OFFMASK);
Once you get the physical address, physAddr, for a particular memory page,
you can then construct the DMA chain.

A few things you should be aware of:
1) If you use RedHat7.2 or RedHat8.0, make sure that you compile your driver
using the gcc comes with them (gcc2.96 and gcc3.2 respectively). gcc2.95 and
gcc3.2.1 will NOT work.
2) If you use RedHat7.2, add the following define in your code.
#if (__GNUC__ == 2 && __GNUC_MINOR__ == 96)
#define page_to_bus(page) \
(ULONG)(((page) - mem_map) << PAGE_SHIFT)
#endif

Hope that helps.
Shuyu
PS. I'd like to take this opportunity to thank everyone who helped me
solving this problem.

-----Original Message-----
From: Alan Shih [mailto:[email protected]]
Sent: Wednesday, July 09, 2003 1:35 PM
To: Alan Cox
Cc: Linux Kernel Mailing List
Subject: RE: Question regarding DMA xfer to user space directly

Next question would be what are the steps that the driver need to ping user
pages before setting up the xfer?

Thanks.

-----Original Message-----
From: Alan Cox [mailto:[email protected]]
Sent: Tuesday, July 08, 2003 8:22 AM
To: Alan Shih
Cc: Linux Kernel Mailing List
Subject: Re: Question regarding DMA xfer to user space directly


On Maw, 2003-07-08 at 15:50, Alan Shih wrote:
> Is there a provision in MM for DMA transfer to user space directly without
> allocating a kernel buffer?

Yes. Its used both for O_DIRECT I/O (direct to disk I/O from userspace)
and for things like tv capture cards. The kernel allows a driver to pin
user pages and obtain mappings for them. Note that for large systems
user pages may be above the 32bit boundary so you need DAC capable
hardware to get the best results