* DMA to User-Space
@ 2009-11-03 23:37 Jonathan Haws
2009-11-04 2:19 ` Tonyliu
2009-11-23 17:11 ` Sergey Temerkhanov
0 siblings, 2 replies; 10+ messages in thread
From: Jonathan Haws @ 2009-11-03 23:37 UTC (permalink / raw)
To: linuxppc-dev@lists.ozlabs.org
All,
I have what may be an unconventional question:
Our application consists of data being captured by an FPGA, processed, and =
transferred to SDRAM. I simply give the FPGA an address of where I want it=
stored in SDRAM and it simply DMAs the data over and interrupts me when fi=
nished. I then take that data and store it to disk.
I have code in user space that handles all of the writing to disk nicely an=
d fast enough for my application (I am capturing data at about 35-40 Mbytes=
/sec).
My question is this: is it possible to give a user-space pointer to the FP=
GA to DMA to? It seems like I would have problems with alignment, address =
manipulation, and a whole slew of other issues.
What would be the best way to accomplish something like that? I want to ha=
ndle all the disk access in user-space, but I do not want to have to copy 4=
0 MB/s from kernel space to user-space either.
I can maintain an allocated, DMA-safe buffer in kernel space if needed. Ca=
n I simply get a user-space pointer to that buffer? What calls are needed =
to translate addresses?
Thanks for the help! I am still a newbie when it comes to kernel programmi=
ng, so I really appreciate the help!
Jonathan
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: DMA to User-Space
2009-11-03 23:37 DMA to User-Space Jonathan Haws
@ 2009-11-04 2:19 ` Tonyliu
2009-11-04 17:40 ` Jonathan Haws
2009-11-23 17:11 ` Sergey Temerkhanov
1 sibling, 1 reply; 10+ messages in thread
From: Tonyliu @ 2009-11-04 2:19 UTC (permalink / raw)
To: Jonathan Haws; +Cc: linuxppc-dev@lists.ozlabs.org
Jonathan Haws wrote:
> All,
>
> I have what may be an unconventional question:
>
> Our application consists of data being captured by an FPGA, processed, and transferred to SDRAM. I simply give the FPGA an address of where I want it stored in SDRAM and it simply DMAs the data over and interrupts me when finished. I then take that data and store it to disk.
>
> I have code in user space that handles all of the writing to disk nicely and fast enough for my application (I am capturing data at about 35-40 Mbytes/sec).
>
> My question is this: is it possible to give a user-space pointer to the FPGA to DMA to? It seems like I would have problems with alignment, address manipulation, and a whole slew of other issues.
>
> What would be the best way to accomplish something like that? I want to handle all the disk access in user-space, but I do not want to have to copy 40 MB/s from kernel space to user-space either.
>
You can maintain a DMA buffer in kernel, then mmap to user space. And
maybe you need some handshake between FPGA and the apps to balance input
datas with datas to disk.
> I can maintain an allocated, DMA-safe buffer in kernel space if needed. Can I simply get a user-space pointer to that buffer? What calls are needed to translate addresses?
>
Use remap_pfn_range() in your kernel DMA buffer manipulation driver
.mmap() handler to export DMA buffer address to user space.
Tony
> Thanks for the help! I am still a newbie when it comes to kernel programming, so I really appreciate the help!
>
> Jonathan
>
>
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
>
>
--
Tony Liu | Liu Bo
-------------------------------------------------------------
WIND RIVER | China Development Center
Tel: 86-10-8477-8542 ext: 8542 | Fax: 86-10-64790367
(M): 86-136-7117-3612
Address: 15/F, Wangjing TowerB, Chaoyang District, Beijing, P.R.China
^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: DMA to User-Space
2009-11-04 2:19 ` Tonyliu
@ 2009-11-04 17:40 ` Jonathan Haws
2009-11-04 17:50 ` Jonathan Haws
2009-11-04 19:02 ` john.p.price
0 siblings, 2 replies; 10+ messages in thread
From: Jonathan Haws @ 2009-11-04 17:40 UTC (permalink / raw)
To: Bo.Liu@windriver.com; +Cc: linuxppc-dev@lists.ozlabs.org
> Jonathan Haws wrote:
> > All,
> >
> > I have what may be an unconventional question:
> >
> > Our application consists of data being captured by an FPGA,
> processed, and transferred to SDRAM. I simply give the FPGA an
> address of where I want it stored in SDRAM and it simply DMAs the
> data over and interrupts me when finished. I then take that data
> and store it to disk.
> >
> > I have code in user space that handles all of the writing to disk
> nicely and fast enough for my application (I am capturing data at
> about 35-40 Mbytes/sec).
> >
> > My question is this: is it possible to give a user-space pointer
> to the FPGA to DMA to? It seems like I would have problems with
> alignment, address manipulation, and a whole slew of other issues.
> >
> > What would be the best way to accomplish something like that? I
> want to handle all the disk access in user-space, but I do not want
> to have to copy 40 MB/s from kernel space to user-space either.
> >
> You can maintain a DMA buffer in kernel, then mmap to user space.
> And
> maybe you need some handshake between FPGA and the apps to balance
> input
> datas with datas to disk.
> > I can maintain an allocated, DMA-safe buffer in kernel space if
> needed. Can I simply get a user-space pointer to that buffer? What
> calls are needed to translate addresses?
> >
> Use remap_pfn_range() in your kernel DMA buffer manipulation driver
> .mmap() handler to export DMA buffer address to user space.
>=20
Can you provide an example for how to do that? I have an mmap routine to m=
ap BARs that the FPGA maintains and I can access those, however when I try =
to map the DMA buffer and access what is in it, the system crashes. Here i=
s the mmap function I have right now:
/* fpga_mmap()
*
* Description:
* The purpose of this function is to serve as a 'file_operation'
* which maps different PCI resources into the calling processes
* memory space.
*
* NOTE: The file offset are in page size; i.e.:
* offset 0 in process's mmap syscall -> BAR0
* offset 4096 in process's mmap syscall -> BAR1
* offset 8192 in process's mmap syscall -> BAR2
* offset 12288 -> Streaming DMA buffer
*
* Arguments:
* struct file *filp -- struct representing an open file
* struct vm_area_struct *vma -- struct representing memory 'segme=
nt'
*
* Returns:
* int -- indication of success or failure
*
*/
int fpga_mmap(struct file *filp, struct vm_area_struct *vma)
{
struct pci_dev *dev;
unsigned long addressToMap;
uint8_t mapType =3D 0; /* 0 =3D IO, 1 =3D memory */
/* Get the PCI device */
dev =3D (struct pci_dev*)(filp->private_data);
/* Map in the appropriate BAR based on page offset */
if (vma->vm_pgoff =3D=3D FPGA_CONFIG_SPACE)
{
/* Map BAR1 (the CONFIG area) */
printk(KERN_ALERT "FPGA: Mapping BAR1 (CONFIG BAR).\n");
addressToMap =3D pci_resource_start(dev, FPGA_CONFIG_SPACE);
printk(KERN_ALERT "FPGA: PCI BAR1 (CONFIG BAR) Size -> %#08x.\n",
pci_resource_len(dev, FPGA_CONFIG_SPACE));
mapType =3D 0;
}
else if(vma->vm_pgoff =3D=3D FPGA_TEST_SPACE)
{
/* Map BAR2 (the TEST area) */
printk(KERN_ALERT "FPGA: Mapping BAR2 (TEST BAR).\n");
addressToMap =3D (pci_resource_start(dev, FPGA_TEST_SPACE) +
pci_resource_len(dev, FPGA_TEST_SPACE)) - FPGA_TEST_LENGTH;
printk(KERN_ALERT "FPGA: PCI BAR2 (TEST BAR) Size -> %#08x.\n",
pci_resource_len(dev, FPGA_TEST_SPACE));
mapType =3D 0;
}
else if(vma->vm_pgoff =3D=3D 3)
{
addressToMap =3D (unsigned long)&fpga_drv.strmData[0];
mapType =3D 1;
}
else
{
printk(KERN_ALERT " FPGA: Invalid BAR mapping specified.\n");
return ERROR;
}
/* Execute the mapping */
vma->vm_flags |=3D VM_IO;
vma->vm_flags |=3D VM_RESERVED;
vma->vm_page_prot =3D pgprot_noncached(vma->vm_page_prot);
printk(KERN_ALERT "FPGA: vmSize -> 0x%x.\n",
(unsigned int)(vma->vm_end - vma->vm_start));
if( mapType =3D=3D 0 )
{
if(io_remap_pfn_range(vma, vma->vm_start, addressToMap >> PAGE_SHIFT,
vma->vm_end - vma->vm_start, vma->vm_page_prot) !=3D 0)
{
printk(KERN_ALERT "FPGA: Failed to map BAR PCI space to user space.\n");
return ERROR;
}
}
else
{
printk(KERN_NOTICE "FPGA: Mapping stream ptr (%#08x) to user space\n",(ui=
nt32_t)&fpga_drv.strmData[0]);
printk(KERN_NOTICE "FPGA: Setting strmData[0][0] to 0x37\n");
fpga_drv.strmData[0][0] =3D 0x37;
if(remap_pfn_range(vma, vma->vm_start, addressToMap >> PAGE_SHIFT,
vma->vm_end - vma->vm_start, vma->vm_page_prot) !=3D 0)
{
printk(KERN_ALERT "FPGA: Failed to map BAR PCI space to user space.\n");
return ERROR;
}
}
return OK;
}
And here is the failure:
~ # ./main
FPGA: vmSize -> 0x4000.
FPGA: Mapping stream ptr (0xd10613bc) to user space
FPGA: Setting strmData[0][0] to 0x37
Unable to handle kernel paging request for data at address 0x00000000
Faulting instruction address: 0xd105f5e0
Oops: Kernel access of bad area, sig: 11 [#1]
PREEMPT Kilauea
Modules linked in: fpgaDriver
NIP: d105f5e0 LR: d105f5d8 CTR: c003fff4
REGS: cf86dde0 TRAP: 0300 Not tainted (2.6.30.3-wolverine-dirty)
MSR: 00029030 <EE,ME,CE,IR,DR> CR: 24008022 XER: 0000005f
DEAR: 00000000, ESR: 00800000
TASK =3D cf873950[281] 'main' THREAD: cf86c000
GPR00: 00000037 cf86de90 cf873950 00000028 17d78400 c0302028 c0302068 00000=
000
GPR08: 00000000 00000000 00000003 c0300000 24008024 100e89c8 100d6590 10091=
7d8
GPR16: 100d0000 100d0000 c0320000 cfaca07c 00000001 cf8c0230 00000003 00000=
0fb
GPR24: 00000000 cf8a6840 cfaca07c 00000000 d10613bc d106128c 00000004 cfaca=
07c
NIP [d105f5e0] fpga_mmap+0x9c/0x214 [fpgaDriver]
LR [d105f5d8] fpga_mmap+0x94/0x214 [fpgaDriver]
Call Trace:
[cf86de90] [d105f5d8] fpga_mmap+0x94/0x214 [fpgaDriver] (unreliable)
[cf86deb0] [c00c1a4c] mmap_region+0x29c/0x408
[cf86df10] [c000377c] sys_mmap+0x78/0x100
[cf86df40] [c00103fc] ret_from_syscall+0x0/0x3c
Instruction dump:
386302a8 48000735 3b9d0130 3c60d106 7f84e378 386302c4 48000721 3c60d106
386302f8 48000715 813d0130 38000037 <98090000> 7fe3fb78 809f0004 80df0008
---[ end trace 4393e8cf23caef19 ]---
Where am I going wrong?
Using mmap() would work well for me.
Also, what about this:
1. I open /dev/mem and get a file descriptor
2. I use mmap to reserve some physical addresses for my buffers in user spa=
ce.
3. I give that address to the FPGA for DMA use.
4. When I get the FPGA interrupt, I invalidate the data cache and write the=
data to disk
Does that sound like it would work? Would the address I receive from mmap(=
) and pass to the FPGA be the actual physical address, or would I need to s=
end the physical address to the FPGA and use the mmap() address to access a=
nd write to disk?
Thanks for the help!
Jonathan
^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: DMA to User-Space
2009-11-04 17:40 ` Jonathan Haws
@ 2009-11-04 17:50 ` Jonathan Haws
2009-11-06 6:05 ` Chris Friesen
2009-11-04 19:02 ` john.p.price
1 sibling, 1 reply; 10+ messages in thread
From: Jonathan Haws @ 2009-11-04 17:50 UTC (permalink / raw)
To: Jonathan Haws, Bo.Liu@windriver.com; +Cc: linuxppc-dev@lists.ozlabs.org
> 1. I open /dev/mem and get a file descriptor
> 2. I use mmap to reserve some physical addresses for my buffers in
> user space.
> 3. I give that address to the FPGA for DMA use.
> 4. When I get the FPGA interrupt, I invalidate the data cache and
> write the data to disk
>=20
> Does that sound like it would work? Would the address I receive
> from mmap() and pass to the FPGA be the actual physical address, or
> would I need to send the physical address to the FPGA and use the
> mmap() address to access and write to disk?
One more question about this approach: does the mmap() call prevent the ker=
nel from using this memory for other purposes? Will the kernel be able to =
"move" this memory elsewhere? I guess what I am asking is if this memory i=
s locked for all other purposes?
^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: DMA to User-Space
2009-11-04 17:40 ` Jonathan Haws
2009-11-04 17:50 ` Jonathan Haws
@ 2009-11-04 19:02 ` john.p.price
1 sibling, 0 replies; 10+ messages in thread
From: john.p.price @ 2009-11-04 19:02 UTC (permalink / raw)
To: Jonathan Haws, Bo.Liu; +Cc: linuxppc-dev
Jonathan, what kind of memory is fpga_drv.strmdata? memory from the
kernel stack, something you allocated? You'll notice you were trying to
access location 0.
To use dma streaming memory you must call dma_map_single() to get the
physical address of fpga_drv.strmdata. That memory must be contiguous.
Then you may call remap_pfn_range with the page offset of the physical
address returned from the dma_map_single() call. Then when the cpu
accesses that region you must sync the region for with dma direction for
cpu or when the device needs to access it, for the device.
LDD3 seems a bit dated on this topic it says to use nopage instead of
remap_pfn_range(), in my experiments remap_pfn_range seemed ok. I would
ask others on the list for their experience on the topic.
Ultimately I went with mapping user space provided address and
implementing dma with scatter-gather.
-----Original Message-----
From: linuxppc-dev-bounces+john.p.price=3Dl-3com.com@lists.ozlabs.org
[mailto:linuxppc-dev-bounces+john.p.price=3Dl-3com.com@lists.ozlabs.org]
On Behalf Of Jonathan Haws
Sent: Wednesday, November 04, 2009 12:40 PM
To: Bo.Liu@windriver.com
Cc: linuxppc-dev@lists.ozlabs.org
Subject: RE: DMA to User-Space
> Jonathan Haws wrote:
> > All,
> >
> > I have what may be an unconventional question:
> >
> > Our application consists of data being captured by an FPGA,
> processed, and transferred to SDRAM. I simply give the FPGA an
> address of where I want it stored in SDRAM and it simply DMAs the
> data over and interrupts me when finished. I then take that data
> and store it to disk.
> >
> > I have code in user space that handles all of the writing to disk
> nicely and fast enough for my application (I am capturing data at
> about 35-40 Mbytes/sec).
> >
> > My question is this: is it possible to give a user-space pointer
> to the FPGA to DMA to? It seems like I would have problems with
> alignment, address manipulation, and a whole slew of other issues.
> >
> > What would be the best way to accomplish something like that? I
> want to handle all the disk access in user-space, but I do not want
> to have to copy 40 MB/s from kernel space to user-space either.
> >
> You can maintain a DMA buffer in kernel, then mmap to user space.
> And
> maybe you need some handshake between FPGA and the apps to balance
> input
> datas with datas to disk.
> > I can maintain an allocated, DMA-safe buffer in kernel space if
> needed. Can I simply get a user-space pointer to that buffer? What
> calls are needed to translate addresses?
> >
> Use remap_pfn_range() in your kernel DMA buffer manipulation driver
> .mmap() handler to export DMA buffer address to user space.
>=20
Can you provide an example for how to do that? I have an mmap routine
to map BARs that the FPGA maintains and I can access those, however when
I try to map the DMA buffer and access what is in it, the system
crashes. Here is the mmap function I have right now:
/* fpga_mmap()
*
* Description:
* The purpose of this function is to serve as a 'file_operation'
* which maps different PCI resources into the calling processes
* memory space.
*
* NOTE: The file offset are in page size; i.e.:
* offset 0 in process's mmap syscall -> BAR0
* offset 4096 in process's mmap syscall -> BAR1
* offset 8192 in process's mmap syscall -> BAR2
* offset 12288 -> Streaming DMA buffer
*
* Arguments:
* struct file *filp -- struct representing an open
file
* struct vm_area_struct *vma -- struct representing memory
'segment'
*
* Returns:
* int -- indication of success or failure
*
*/
int fpga_mmap(struct file *filp, struct vm_area_struct *vma)
{
struct pci_dev *dev;
unsigned long addressToMap;
uint8_t mapType =3D 0; /* 0 =3D IO, 1 =3D memory */
/* Get the PCI device */
dev =3D (struct pci_dev*)(filp->private_data);
/* Map in the appropriate BAR based on page offset */
if (vma->vm_pgoff =3D=3D FPGA_CONFIG_SPACE)
{
/* Map BAR1 (the CONFIG area) */
printk(KERN_ALERT "FPGA: Mapping BAR1 (CONFIG BAR).\n");
addressToMap =3D pci_resource_start(dev,
FPGA_CONFIG_SPACE);
printk(KERN_ALERT "FPGA: PCI BAR1 (CONFIG BAR) Size ->
%#08x.\n",
pci_resource_len(dev, FPGA_CONFIG_SPACE));
mapType =3D 0;
}
else if(vma->vm_pgoff =3D=3D FPGA_TEST_SPACE)
{
/* Map BAR2 (the TEST area) */
printk(KERN_ALERT "FPGA: Mapping BAR2 (TEST BAR).\n");
addressToMap =3D (pci_resource_start(dev, FPGA_TEST_SPACE)
+
pci_resource_len(dev, FPGA_TEST_SPACE)) -
FPGA_TEST_LENGTH;
printk(KERN_ALERT "FPGA: PCI BAR2 (TEST BAR) Size ->
%#08x.\n",
pci_resource_len(dev, FPGA_TEST_SPACE));
mapType =3D 0;
}
else if(vma->vm_pgoff =3D=3D 3)
{
addressToMap =3D (unsigned long)&fpga_drv.strmData[0];
mapType =3D 1;
}
else
{
printk(KERN_ALERT " FPGA: Invalid BAR mapping
specified.\n");
return ERROR;
}
/* Execute the mapping */
vma->vm_flags |=3D VM_IO;
vma->vm_flags |=3D VM_RESERVED;
vma->vm_page_prot =3D pgprot_noncached(vma->vm_page_prot);
printk(KERN_ALERT "FPGA: vmSize -> 0x%x.\n",
(unsigned int)(vma->vm_end - vma->vm_start));
if( mapType =3D=3D 0 )
{
if(io_remap_pfn_range(vma, vma->vm_start, addressToMap
>> PAGE_SHIFT,
vma->vm_end - vma->vm_start,
vma->vm_page_prot) !=3D 0)
{
printk(KERN_ALERT "FPGA: Failed to map BAR PCI
space to user space.\n");
return ERROR;
}
}
else
{
printk(KERN_NOTICE "FPGA: Mapping stream ptr (%#08x) to
user space\n",(uint32_t)&fpga_drv.strmData[0]);
printk(KERN_NOTICE "FPGA: Setting strmData[0][0] to
0x37\n");
fpga_drv.strmData[0][0] =3D 0x37;
if(remap_pfn_range(vma, vma->vm_start, addressToMap >>
PAGE_SHIFT,
vma->vm_end - vma->vm_start,
vma->vm_page_prot) !=3D 0)
{
printk(KERN_ALERT "FPGA: Failed to map BAR PCI
space to user space.\n");
return ERROR;
}
}
return OK;
}
And here is the failure:
~ # ./main
FPGA: vmSize -> 0x4000.
FPGA: Mapping stream ptr (0xd10613bc) to user space
FPGA: Setting strmData[0][0] to 0x37
Unable to handle kernel paging request for data at address 0x00000000
Faulting instruction address: 0xd105f5e0
Oops: Kernel access of bad area, sig: 11 [#1]
PREEMPT Kilauea
Modules linked in: fpgaDriver
NIP: d105f5e0 LR: d105f5d8 CTR: c003fff4
REGS: cf86dde0 TRAP: 0300 Not tainted (2.6.30.3-wolverine-dirty)
MSR: 00029030 <EE,ME,CE,IR,DR> CR: 24008022 XER: 0000005f
DEAR: 00000000, ESR: 00800000
TASK =3D cf873950[281] 'main' THREAD: cf86c000
GPR00: 00000037 cf86de90 cf873950 00000028 17d78400 c0302028 c0302068
00000000
GPR08: 00000000 00000000 00000003 c0300000 24008024 100e89c8 100d6590
100917d8
GPR16: 100d0000 100d0000 c0320000 cfaca07c 00000001 cf8c0230 00000003
000000fb
GPR24: 00000000 cf8a6840 cfaca07c 00000000 d10613bc d106128c 00000004
cfaca07c
NIP [d105f5e0] fpga_mmap+0x9c/0x214 [fpgaDriver]
LR [d105f5d8] fpga_mmap+0x94/0x214 [fpgaDriver]
Call Trace:
[cf86de90] [d105f5d8] fpga_mmap+0x94/0x214 [fpgaDriver] (unreliable)
[cf86deb0] [c00c1a4c] mmap_region+0x29c/0x408
[cf86df10] [c000377c] sys_mmap+0x78/0x100
[cf86df40] [c00103fc] ret_from_syscall+0x0/0x3c
Instruction dump:
386302a8 48000735 3b9d0130 3c60d106 7f84e378 386302c4 48000721 3c60d106
386302f8 48000715 813d0130 38000037 <98090000> 7fe3fb78 809f0004
80df0008
---[ end trace 4393e8cf23caef19 ]---
Where am I going wrong?
Using mmap() would work well for me.
Also, what about this:
1. I open /dev/mem and get a file descriptor
2. I use mmap to reserve some physical addresses for my buffers in user
space.
3. I give that address to the FPGA for DMA use.
4. When I get the FPGA interrupt, I invalidate the data cache and write
the data to disk
Does that sound like it would work? Would the address I receive from
mmap() and pass to the FPGA be the actual physical address, or would I
need to send the physical address to the FPGA and use the mmap() address
to access and write to disk?
Thanks for the help!
Jonathan
_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: DMA to User-Space
2009-11-04 17:50 ` Jonathan Haws
@ 2009-11-06 6:05 ` Chris Friesen
2009-11-06 16:34 ` Jonathan Haws
0 siblings, 1 reply; 10+ messages in thread
From: Chris Friesen @ 2009-11-06 6:05 UTC (permalink / raw)
To: Jonathan Haws; +Cc: Bo.Liu@windriver.com, linuxppc-dev@lists.ozlabs.org
On 11/04/2009 11:50 AM, Jonathan Haws wrote:
> One more question about this approach: does the mmap() call prevent
> the kernel from using this memory for other purposes? Will the
> kernel be able to "move" this memory elsewhere? I guess what I am
> asking is if this memory is locked for all other purposes?
You've allocated the memory in the kernel and mapped it to userspace.
If the kernel uses that memory for anything else it will be visible to
userspace.
Chris
^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: DMA to User-Space
2009-11-06 6:05 ` Chris Friesen
@ 2009-11-06 16:34 ` Jonathan Haws
2009-11-06 17:07 ` Alan Nishioka
0 siblings, 1 reply; 10+ messages in thread
From: Jonathan Haws @ 2009-11-06 16:34 UTC (permalink / raw)
To: Chris Friesen; +Cc: Bo.Liu@windriver.com, linuxppc-dev@lists.ozlabs.org
> > One more question about this approach: does the mmap() call
> prevent
> > the kernel from using this memory for other purposes? Will the
> > kernel be able to "move" this memory elsewhere? I guess what I am
> > asking is if this memory is locked for all other purposes?
>=20
> You've allocated the memory in the kernel and mapped it to
> userspace.
> If the kernel uses that memory for anything else it will be visible
> to
> userspace.
So, does that mean that the kernel could use that memory for something else=
? I was under the impression that locking the memory prevented the kernel =
from swapping it out, moving it, *and* using it for other purposes.
This memory that I am mapping is reserved for DMA buffers. If anything els=
e uses it, then that will corrupt my buffer and make it worthless. So basi=
cally I want user space to tell the kernel that that portion of memory is o=
ut of bounds. Is that possible?
Thanks,
Jonathan
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: DMA to User-Space
2009-11-06 16:34 ` Jonathan Haws
@ 2009-11-06 17:07 ` Alan Nishioka
2009-11-06 18:47 ` Jonathan Haws
0 siblings, 1 reply; 10+ messages in thread
From: Alan Nishioka @ 2009-11-06 17:07 UTC (permalink / raw)
To: linuxppc-dev
you can also reserve some physical memory at the top of memory and dma
into that.
of course, this means you have to know how much memory you need before
booting the kernel.
^ permalink raw reply [flat|nested] 10+ messages in thread
* RE: DMA to User-Space
2009-11-06 17:07 ` Alan Nishioka
@ 2009-11-06 18:47 ` Jonathan Haws
0 siblings, 0 replies; 10+ messages in thread
From: Jonathan Haws @ 2009-11-06 18:47 UTC (permalink / raw)
To: Alan Nishioka, linuxppc-dev@lists.ozlabs.org
> you can also reserve some physical memory at the top of memory and
> dma
> into that.
> of course, this means you have to know how much memory you need
> before
> booting the kernel.
I had thought about that, however can I mmap into memory that area if I hav=
e set mem=3D250M in the boot arguments? I would plan to DMA to above 250M =
(up to 256M). I know that would keep the kernel out of it, but will /dev/m=
em be able to "see" that memory if I had told the kernel it was not there?
Thanks for the help!
Jonathan
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: DMA to User-Space
2009-11-03 23:37 DMA to User-Space Jonathan Haws
2009-11-04 2:19 ` Tonyliu
@ 2009-11-23 17:11 ` Sergey Temerkhanov
1 sibling, 0 replies; 10+ messages in thread
From: Sergey Temerkhanov @ 2009-11-23 17:11 UTC (permalink / raw)
To: linuxppc-dev
On Wednesday 04 November 2009 02:37:38 Jonathan Haws wrote:
> All,
>
> I have what may be an unconventional question:
>
> Our application consists of data being captured by an FPGA, processed, and
> transferred to SDRAM. I simply give the FPGA an address of where I want
> it stored in SDRAM and it simply DMAs the data over and interrupts me when
> finished. I then take that data and store it to disk.
>
> I have code in user space that handles all of the writing to disk nicely
> and fast enough for my application (I am capturing data at about 35-40
> Mbytes/sec).
>
> My question is this: is it possible to give a user-space pointer to the
> FPGA to DMA to? It seems like I would have problems with alignment,
> address manipulation, and a whole slew of other issues.
Well, it's possible: you'll have to use zero-copy I/O. Here's an article on
this subject: http://lwn.net/Articles/28548/.
Have a look at drivers/scsi/st.c at sgl_get_user_pages() or
drivers/infiniband/hw/ipath/ipath_user_pages.c for example of how to use that.
Regards, Sergey Temerkhanov.
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2009-11-23 17:17 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-11-03 23:37 DMA to User-Space Jonathan Haws
2009-11-04 2:19 ` Tonyliu
2009-11-04 17:40 ` Jonathan Haws
2009-11-04 17:50 ` Jonathan Haws
2009-11-06 6:05 ` Chris Friesen
2009-11-06 16:34 ` Jonathan Haws
2009-11-06 17:07 ` Alan Nishioka
2009-11-06 18:47 ` Jonathan Haws
2009-11-04 19:02 ` john.p.price
2009-11-23 17:11 ` Sergey Temerkhanov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).