Messages in this thread | | | Date | Tue, 17 Feb 1998 01:42:49 +0200 | From | Itai Nahshon <> | Subject | Re: 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
| |