From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mtao05.charter.net (mtao05.charter.net [209.225.8.179]) by ozlabs.org (Postfix) with ESMTP id E7943DDE08 for ; Fri, 2 Nov 2007 08:03:47 +1100 (EST) Received: from aa04.charter.net ([10.20.200.156]) by mtao05.charter.net (InterMail vM.7.08.02.00 201-2186-121-20061213) with ESMTP id <20071101210345.URDE29426.mtao05.charter.net@aa04.charter.net> for ; Thu, 1 Nov 2007 17:03:45 -0400 Received: from DCOGLEYNEW ([71.93.35.174]) by aa04.charter.net with ESMTP id <20071101210344.LPEE1254.aa04.charter.net@DCOGLEYNEW> for ; Thu, 1 Nov 2007 17:03:44 -0400 From: "Dave Cogley" To: Subject: Kernel malloc buffers how to make contiguous in user space? Date: Thu, 1 Nov 2007 14:03:10 -0700 Message-ID: <008101c81cca$9c95be90$2001a8c0@DCOGLEYNEW> MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----=_NextPart_000_0082_01C81C8F.F036E690" List-Id: Linux on Embedded PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , This is a multi-part message in MIME format. ------=_NextPart_000_0082_01C81C8F.F036E690 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Hello, I am using a scatter gather DMA operation provided on the PPC44EPx to handle a large data move of 2MB from sixteen 128k kmalloc buffers. I have sixteen scatter / gather descriptors pointing to the allocated memory which will be transferred to a peripheral on the EBC. This all appears to be setup and working correctly. Now I want to provide these 16 kmalloc buffers to a user space process and make them all appear as a contiguous 2MB buffer. When the handler is called pageptr appears to be a valid page but the kernel traps with "Bad page state" "Trying to fix it up, but a reboot is needed" when returned from the handler. Am I missing something required to modify the page state for the requested page? Am I even handling the nopage request correctly? I notice the nopage handler gets called for every 4096 byte page it is trying to map. How do I map my 128k memory area into the 4k page requests? Is there example code somewhere that demonstrates using a contiguous memory buffer in user space when it is comprised of multiple buffers in the kernel space? First I am allocating 16 buffers using kmalloc: #define DMABLOCKSIZE 1024 * 128 for (I = 0; I < 16; i++) { device->dma_buf[i] = kmalloc(DMABLOCKSIZE, GFP_DMA | GFP_KERNEL); sgl->phyaddress = virt_to_phys(device->dma_buf[i]); } Then I am doing the following in the nopage handler: page* nopage_handler(struct vma, ul address, int* type) { unsigned long physaddr = address - vma->start; int index = physaddr / DMABLOCKSIZE; int off = physaddr % DMABLOCKSIZE; struct page* pageptr = virt_to_page(device->dma_buf[index] + off); get_page(pageptr); if (type) *type = VM_FAULT_MINOR; return pageptr; } Dave Cogley Software Engineer Ultra Stereo Labs, Inc. (805) 549-0161 mailto:dcogley@uslinc.com ------=_NextPart_000_0082_01C81C8F.F036E690 Content-Type: text/html; charset="us-ascii" Content-Transfer-Encoding: quoted-printable

Hello,

 

I am using a scatter gather DMA operation provided on = the PPC44EPx to handle a large data move of 2MB from sixteen 128k kmalloc = buffers.  I have sixteen scatter / gather descriptors pointing to the allocated = memory which will be transferred to a peripheral on the EBC.  This all = appears to be setup and working correctly.  Now I want to provide these 16 = kmalloc buffers to a user space process and make them all appear as a contiguous = 2MB buffer.

 

When the handler is called pageptr appears to be a = valid page but the kernel traps with “Bad page state” = “Trying to fix it up, but a reboot is needed” when returned from the = handler.  Am I missing something required to modify the page state for the = requested page?  Am I even handling the nopage request correctly?  I = notice the nopage handler gets called for every 4096 byte page it is trying to = map.  How do I map my 128k memory area into the 4k page requests?  Is = there example code somewhere that demonstrates using a contiguous memory buffer in = user space when it is comprised of multiple buffers in the kernel = space?

 

 

First I am allocating 16 buffers using = kmalloc:

 

#define = DMABLOCKSIZE          1024 * 128

 

for (I =3D 0; I < 16; = i++)

{

         =    device->dma_buf[i] =3D kmalloc(DMABLOCKSIZE, GFP_DMA | = GFP_KERNEL);

         =    sgl->phyaddress =3D virt_to_phys(device->dma_buf[i]);

}

 

Then I am doing the following in the nopage = handler:

 

page* nopage_handler(struct vma, ul address, int* = type)

{

         =    unsigned long physaddr =3D address – = vma->start;

         =    int index =3D physaddr / DMABLOCKSIZE;

         =    int off =3D physaddr % DMABLOCKSIZE;

         =    struct page* pageptr =3D virt_to_page(device->dma_buf[index] + = off);

 

         =    get_page(pageptr);

         =    if (type)

         =    =             *type =3D VM_FAULT_MINOR;

 

         =    return pageptr;

}

 

 

Dave Cogley

Software Engineer

Ultra Stereo Labs, Inc.

(805) 549-0161

mailto:dcogley@uslinc.com

 

------=_NextPart_000_0082_01C81C8F.F036E690--