tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Implement mmap for PUD



On Wed, Sep 07, 2011 at 10:33:54AM +0200, Roger Pau Monné wrote:
> Hello,
> 
> Since there is no mmap implementation for PUD devices I began working
> on one. I would like to make an implementation that avoids copying
> buffers around user-space and kernel memory, since mmap is usually
> used for fast applications. I began working on pud_dev.c file, that
> contains the kernel implementation of the mmap call, which is then
> passed to user space. My mmap function looks like:
> 
> 
> static paddr_t
> pud_cdev_mmap(dev_t dev, off_t off, int flag)
> {
>       struct pud_creq_mmap pc_mmap;
>       struct vmspace *vm;
>       int error;
>       int num;
>       paddr_t pa;
> 
>       pc_mmap.pm_flag  = flag;
>       pc_mmap.pm_pageoff = off;
> 
>       printf("Inside mmap, off: %jd flag: %d\n", (intmax_t) off, flag);
> 
>       error = pud_request(dev, &pc_mmap, sizeof(pc_mmap),
>           PUD_REQ_CDEV, PUD_CDEV_MMAP);
>       if (error)
>               return (paddr_t) -1;
> 
>       mutex_enter(proc_lock);
>       pc_mmap.pm_proc = proc_find(pc_mmap.pid);
>       mutex_exit(proc_lock);
>       /* Catch error? */
> 
>       error = proc_vmspace_getref(pc_mmap.pm_proc, &vm);
>       if (error)
>               panic("Unable to get vmspace");
> 
>       /* Try to read the value */
>       if(copyin_proc(pc_mmap.pm_proc, (void *) pc_mmap.pm_addr, &num,
> sizeof(num)) == EFAULT)
>               panic("Unable to read value from user-space");
>       printf("Read: %d from addr: %" PRIxPADDR "\n", num, pc_mmap.pm_addr);
> 
>       if ((vaddr_t)pc_mmap.pm_addr & PAGE_MASK)
>               panic("pud_cdev_mmap: memory not page aligned");
> 
>       if (pmap_extract(vm->vm_map.pmap,
>           (vaddr_t) pc_mmap.pm_addr + (u_int) off, &pa) == FALSE)
>               panic("pud_cdev_mmap: memory page not mapped");
> 
>       uvmspace_free(vm);
>       printf("Inside mmap, returning: %" PRIxPADDR "\n", pa);
> 
>       return pa;
> }

I think that you need to return atop(pa) instead of pa.  I.e., a
driver's mmap() returns a physical page number, not a physical address.
Is this unnecessarily confusing?  Yes. :-)  Documented in any manual
page?  Maybe not.

I'm curious whether the pa -> atop(pa) change helps.

> void * memory;
> 
> vaddr_t
> test_mmap(dev_t dev, off_t off, int flag, void *auxdata)
> {
>       int *num;
>       if (off > 0)
>               return (vaddr_t)-1;
>       if (memory == NULL)
>       {
>               memory = malloc(PAGE_SIZE);
>               if (mlock(memory, PAGE_SIZE) < 0)
>                       err(EXIT_FAILURE, "Unable to lock pages");

It's probably not desirable to mlock() every PUD device page, but if the
PUD device page gets paged out, what do the userspace device and/or the
kernel need to do about paging it back in?

Dave

-- 
David Young             OJC Technologies
dyoung%ojctech.com@localhost      Urbana, IL * (217) 344-0444 x24


Home | Main Index | Thread Index | Old Index