lkml.org 
[lkml]   [1998]   [Feb]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: The Ultra Sound Driver
Alessandro gives a basic implementation for mmap and vm_ops.
(off course this is outdated... the vma now holds the dentry and not the
inode pointer).

The problem is that the device release function is called when the count
on the file structure drops to 0 (last close). We need to postpone it
until the last vma which points to this inode (indirectly through the
dentry) is closed. The way that things are implemented now it cannot be
done cleanly.

The vma_close functions are called each time when a vma is unmapped,
but it is impossible to know when is the really last close. This is
because
when part of a vma is unmapped, it will call vma_close and immediately
vma_open. A naive counter will decrement to 0 and increment again.

IMHO, the right way to do it (but that is a major change) is to move
the file_ops pointer from the file struct to the inode (or to the
dentry?).
and call the device release only when the inode (dentry?) are released.
I think this will also eliminate some of the need for private file
structured.

Alternately, a simpler solution is to add a boolean parameter to
vma_close,
telling it if this is really the last close.

Itai

Alessandro Rubini wrote:
>
> > If file was closed mmaped area can still exist,
> > but I (probably wrong) free DMA buffer when file is closing (releasing).
>
> Yes, this *is* wrong.
>
> > My question is: Can I detect at which point application unmap memory
> > area? Is there any callback for it or some like this?
>
> There are the "virtual memory operations", that are meant just for that
> purpose: give a driver some control over its memory mapped regions.
>
> You can implement a usage count in virtual memory areas with code like
> this one:
>
> static struct vm_operations_struct simple_vm_ops = {
> simple_vma_open,
> simple_vma_close, /* no more fields */
> };
>
> void simple_vma_open(struct vm_area_struct * area)
> { MOD_INC_USE_COUNT; }
>
> void simple_vma_close(struct vm_area_struct * area)
> { MOD_DEC_USE_COUNT; }
>
> int simple_mmap(struct inode *inode, struct file *filp,
> struct vm_area_struct *vma)
> {
> /* int remap_page_range(virt_add, phys_add, size, protection); */
> if (remap_page_range(vma->vm_start, vma->vm_offset,
> vma->vm_end-vma->vm_start, vma->vm_page_prot))
> return -EAGAIN;
> if (vma->vm_ops)
> return -EINVAL; /* Hmm... shouldn't happen */
> vma->vm_ops = &simple_vm_ops;
> MOD_INC_USE_COUNT; /* open(vma) wasn't called this time */
> vma->vm_inode = inode;
> inode->i_count++;
> return 0;
> }
>
> Best
> /alessandro
> --
> __ o Tu vuo` fa` l'americano: sient'a me chi t'o fa fa`.
> _`\<, (Renato Carosone)
> __( )/( )__ alessandro.rubini@linux.it +39-382-529554
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.rutgers.edu

--
Itai Nahshon nahshon@actcom.co.il
Also nahshon@vnet.ibm.com

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu

\
 
 \ /
  Last update: 2005-03-22 13:41    [W:0.412 / U:0.048 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site