* DMA transfer with kiobuf, kernel 2.4.21
@ 2005-11-15 17:39 sej
2005-11-15 17:49 ` Arjan van de Ven
0 siblings, 1 reply; 5+ messages in thread
From: sej @ 2005-11-15 17:39 UTC (permalink / raw)
To: linux-kernel
Hi,
I allocate a big chunck of memory from user space with :
#define MEM_SIZE_DMA (128*1024*1024)
// allocate 128MB of memory
void *_pVirtualMem = memalign(sysconf(_SC_PAGESIZE), MEM_SIZE_DMA);
// Reserve memory
memset(_pVirtualMem, 0, MEM_SIZE_DMA);
// Lock memory
if (!mlock(_pVirtualMem, MEM_SIZE_DMA ))
{
free(_pVirtualMem);
return false;
}
Then I call an IOCTL from my driver (DmaMapDescrpImg) to create a DMA
scatter gather list.
This solution works when I have 1GB of memory. If I put 2GB of memory,
it won't work because I can't resolve the physical address of my User
memory area.
My configuration is a Redhat enterprise 3.3 SMP on Xeon 3.2GHz.
The kernel is configured for 64GB support.
So the kernel only have access to LOW part of memory.
How can I force my User allocation in LOW part, or how can I replace
map_user_from_kiobuf() to support this memory ?
With kiobuf, I make DMA scatter gather list at the opening of the card
and then I use it to perform DMA transfer. With get_user_pages(), I must
make a scatter gather list for each transfer, and make pages dirty after
each transfer ?
I am not sure that get_user_pages() is the good solution.
Is there another method to perform my DMA transfer.
I must allocate my memory in user space, and I can't copy it from kernel
to user because I'll have a big overhead.
Regards.
Sebastien
Kernel IOCTL :
int DmaMapDescrpImg (int board_num, u32 arg)
{
struct kiobuf *iobuf;
// get parameters
get_user ( ... );
// Create kiovec into decriptor pointer registers
// Map kiovec into descriptor pointer register
result = alloc_kiovec(1, &iobuf);
if (result)
{
TRACE_ERR("alloc_kiovec failed\n");
return 1;
}
result = map_user_kiobuf(READ,
iobuf, // struct kiobuf
arg, // user addr (buffer passed from user)
iSize);// size
if (result)
{
TRACE_ERR("map_user_kiobuf failed\n");
free_kiovec(1, &iobuf);
return 1;
}
// ************************* Build descriptors
transfer = &(pdx[board_num].ReadTransfer);
// Number of descriptor needed
nbDescrpImg = iSize/PAGE_SIZE + ((iSize%PAGE_SIZE) ? 1 : 0);
// Index of the first descriptor in transfer->Descript[]
idxDescrpImg = nImage * nbDescrpImg;
transfer->image[nImage].Descript = &(transfer->Descript[idxDescrpImg]);
transfer->imageInfo->flag[nImage] = IMG_UNUSED; //IMG_UNLOCK;
for(i=idxDescrpImg, idxIobuf = 0 ; i < idxDescrpImg + nbDescrpImg - 1
; i++, idxIobuf++)
{
transfer->Descript[i].size = PAGE_SIZE;
transfer->Descript[i].pciaddr = (ULONG)
virt_to_phys(page_address(iobuf->maplist[idxIobuf]));
transfer->Descript[i].localaddr = localaddr;
transfer->Descript[i].next = (ULONG)
virt_to_phys(&(transfer->Descript[i+1])) | PLX_PCI | PLX_READ;
}
// End Of Chain
transfer->Descript[i].size = PAGE_SIZE;
transfer->Descript[i].pciaddr = (ULONG)
virt_to_phys(page_address(iobuf->maplist[idxIobuf]));
transfer->Descript[i].localaddr = localaddr;
transfer->Descript[i].next = PLX_PCI | (bRead ? PLX_READ :
PLX_WRITE)
| PLX_EOC;
// ******************************************
// unmap and free kiobuf
unmap_kiobuf(iobuf);
free_kiovec(1, &iobuf);
return 0;
}
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: DMA transfer with kiobuf, kernel 2.4.21
2005-11-15 17:39 DMA transfer with kiobuf, kernel 2.4.21 sej
@ 2005-11-15 17:49 ` Arjan van de Ven
2005-11-15 17:53 ` sej
0 siblings, 1 reply; 5+ messages in thread
From: Arjan van de Ven @ 2005-11-15 17:49 UTC (permalink / raw)
To: sej; +Cc: linux-kernel
On Tue, 2005-11-15 at 18:39 +0100, sej wrote:
> Hi,
> I allocate a big chunck of memory from user space with :
>
> #define MEM_SIZE_DMA (128*1024*1024)
> // allocate 128MB of memory
> void *_pVirtualMem = memalign(sysconf(_SC_PAGESIZE), MEM_SIZE_DMA);
>
> // Reserve memory
> memset(_pVirtualMem, 0, MEM_SIZE_DMA);
>
> // Lock memory
> if (!mlock(_pVirtualMem, MEM_SIZE_DMA ))
> {
> free(_pVirtualMem);
> return false;
> }
>
> Then I call an IOCTL from my driver (DmaMapDescrpImg) to create a DMA
> scatter gather list.
that sounds the wrong approach.. why don't you make your device driver
export an mmap function.. and let the userspace app use that ?
>
> transfer->Descript[i].size = PAGE_SIZE;
> transfer->Descript[i].pciaddr = (ULONG)
> virt_to_phys(page_address(iobuf->maplist[idxIobuf]));
you really need to use the PCI DMA mapping api!
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: DMA transfer with kiobuf, kernel 2.4.21
2005-11-15 17:49 ` Arjan van de Ven
@ 2005-11-15 17:53 ` sej
2005-11-15 18:01 ` Arjan van de Ven
0 siblings, 1 reply; 5+ messages in thread
From: sej @ 2005-11-15 17:53 UTC (permalink / raw)
To: Arjan van de Ven; +Cc: linux-kernel
> that sounds the wrong approach.. why don't you make your device driver
> export an mmap function.. and let the userspace app use that ?
I can't because I need to allocate 128MB of memory per PCI card and if I put for example 4 cards, I'll have 512MB in kernel memory, and I think there will be some problem in kernel.
>transfer->Descript[i].size = PAGE_SIZE;
>transfer->Descript[i].pciaddr = (ULONG)
>virt_to_phys(page_address(iobuf->maplist[idxIobuf]));
>
>
> you really need to use the PCI DMA mapping api!
I have a plx bridge PCI9656 with a DMA controler. So I have to make a
descriptor table with physical address and size.
I work in 32 bits address mode, but I don't know which function to call
to get a 36bits address for my controler.
Regards.
Sebastien
>On Tue, 2005-11-15 at 18:39 +0100, sej wrote:
>
>
>>Hi,
>>I allocate a big chunck of memory from user space with :
>>
>>#define MEM_SIZE_DMA (128*1024*1024)
>>// allocate 128MB of memory
>>void *_pVirtualMem = memalign(sysconf(_SC_PAGESIZE), MEM_SIZE_DMA);
>>
>>// Reserve memory
>>memset(_pVirtualMem, 0, MEM_SIZE_DMA);
>>
>>// Lock memory
>>if (!mlock(_pVirtualMem, MEM_SIZE_DMA ))
>>{
>>free(_pVirtualMem);
>>return false;
>>}
>>
>>Then I call an IOCTL from my driver (DmaMapDescrpImg) to create a DMA
>>scatter gather list.
>>
>>
>
>that sounds the wrong approach.. why don't you make your device driver
>export an mmap function.. and let the userspace app use that ?
>
>
>
>
>>transfer->Descript[i].size = PAGE_SIZE;
>>transfer->Descript[i].pciaddr = (ULONG)
>>virt_to_phys(page_address(iobuf->maplist[idxIobuf]));
>>
>>
>
>you really need to use the PCI DMA mapping api!
>
>
>
>
>
>
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: DMA transfer with kiobuf, kernel 2.4.21
2005-11-15 17:53 ` sej
@ 2005-11-15 18:01 ` Arjan van de Ven
2005-11-16 8:35 ` sej
0 siblings, 1 reply; 5+ messages in thread
From: Arjan van de Ven @ 2005-11-15 18:01 UTC (permalink / raw)
To: sej; +Cc: linux-kernel
On Tue, 2005-11-15 at 18:53 +0100, sej wrote:
> > that sounds the wrong approach.. why don't you make your device driver
> > export an mmap function.. and let the userspace app use that ?
>
> I can't because I need to allocate 128MB of memory per PCI card and if I put for example 4 cards, I'll have 512MB in kernel memory, and I think there will be some problem in kernel.
no there isn't.. there is no rule that memory you allocate for this as
to be lowmem... at all.
>
>
>
> >transfer->Descript[i].size = PAGE_SIZE;
> >transfer->Descript[i].pciaddr = (ULONG)
> >virt_to_phys(page_address(iobuf->maplist[idxIobuf]));
> >
> >
>
> > you really need to use the PCI DMA mapping api!
>
> I have a plx bridge PCI9656 with a DMA controler. So I have to make a
> descriptor table with physical address and size.
> I work in 32 bits address mode, but I don't know which function to call
> to get a 36bits address for my controler.
see the PCI DMA mapping api. the docs for it are in Documentation/
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: DMA transfer with kiobuf, kernel 2.4.21
2005-11-15 18:01 ` Arjan van de Ven
@ 2005-11-16 8:35 ` sej
0 siblings, 0 replies; 5+ messages in thread
From: sej @ 2005-11-16 8:35 UTC (permalink / raw)
To: Arjan van de Ven; +Cc: linux-kernel
Hi,
thank you for your help.
I will read the DMA documentation. But I need to make DMA on User memory
space allocated in user space. Because I don't want the kernel to make
allocation and deallocation during execution for stability.
Best regards.
Sebastien
Arjan van de Ven wrote :
>On Tue, 2005-11-15 at 18:53 +0100, sej wrote:
>
>
>>>that sounds the wrong approach.. why don't you make your device driver
>>>export an mmap function.. and let the userspace app use that ?
>>>
>>>
>>I can't because I need to allocate 128MB of memory per PCI card and if I put for example 4 cards, I'll have 512MB in kernel memory, and I think there will be some problem in kernel.
>>
>>
>
>no there isn't.. there is no rule that memory you allocate for this as
>to be lowmem... at all.
>
>
>
>>
>>
>>
>>>transfer->Descript[i].size = PAGE_SIZE;
>>>transfer->Descript[i].pciaddr = (ULONG)
>>>virt_to_phys(page_address(iobuf->maplist[idxIobuf]));
>>>
>>>
>>>
>>>
>>>you really need to use the PCI DMA mapping api!
>>>
>>>
>>I have a plx bridge PCI9656 with a DMA controler. So I have to make a
>>descriptor table with physical address and size.
>>I work in 32 bits address mode, but I don't know which function to call
>>to get a 36bits address for my controler.
>>
>>
>
>see the PCI DMA mapping api. the docs for it are in Documentation/
>
>
>
>-
>To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
>the body of a message to majordomo@vger.kernel.org
>More majordomo info at http://vger.kernel.org/majordomo-info.html
>Please read the FAQ at http://www.tux.org/lkml/
>
>
>
>
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2005-11-16 8:36 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-11-15 17:39 DMA transfer with kiobuf, kernel 2.4.21 sej
2005-11-15 17:49 ` Arjan van de Ven
2005-11-15 17:53 ` sej
2005-11-15 18:01 ` Arjan van de Ven
2005-11-16 8:35 ` sej
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox