1471 Memory Mapped IO
A request to memory-map a file into an address space is handled by the file systenanode method vop_map() and theseg_vn memory segment driver (see Section 14.7.4). A process requests that a file be mapped into its address space. Once the mapping is established, the address space represented by the file appears as regular memory and the file system can perform I/O by simply accessing that memory.
Memory mapping of files hides the real work of reading and writing the file because the seg_vn memory segment driver quietly works with the file system to perform the l/Os without the need for process-initiated system calls. I/O is performed, in units of pages, upon reference to the pages mapped into the address space; reads are initiated by a memory access; writes are initiated as the VM system finds dirty pages in the mapped address space.
The system call mmap() calls the file system for the requested file with the/node's vop_map() method. In turn, the file system calls the address space map function for the current address space, and the mapping is created. The protection flags passed into the mmap() system call are reduced to the subset allowed by the file permissions. If mandatory locking is set for the file, then mmap() returns an error.
Once the file mapping is created in the process's address space, file pages are read when a fault occurs in the address space. A fault occurs the first time a memory address within the mapped segment is accessed because at this point, no physical page of memory is at that location. The memory management unit causes a hardware trap for that memory segment; the memory segment calls its fault function to handle the I/O for that address. The segvn_fault() routine handles a fault for a file mapping in a process address space and then calls the file system to read in the page for the faulted address, as shown below.
advise = lookup_advise (page); /* Look up madvise settings for page */ if (advise == MADV_SEQUENTIAL) free_all_pages_up_to (page);
/* Segvn will read at most 64k ahead */ if ( len > PVN_GETPAGE_SZ) len = PVN_GETPAGE_SZ;
/* Read 64k at a time if the next page is not in memory, * else just a page
if (hat_probe (addr+PAGESIZE)==TRUE) len=PAGESIZE;
/* Ask the file system for the next 64k of pages if the next*/ VOP_GETPAGE(vp, vp_off, len,
&vpprot, pip, plsz, seg, addr + (vp_off- off), arw, cred)
See usr/src/uts/common/vm/seg_vn.c
For each page fault, seg_vn reads in an 8-Kbyte page at the fault location. In addition,seg_vn initiates a read-ahead of the next eight pages at each 64-Kbyte boundary. Memory mapped read-ahead uses the file system cluster size (used by the read() and write() system calls) unless the segment is mapped MA_SHARED or memory advice MADV_RANDOM is set.
Recall that you can provide paging advice to the pages within a memory mapped segment by using the madvise system call. The madvise system call and (as in the example) the advice information are used to decide when to free behind as the file is read.
Modified pages remain unwritten to disk until the fsflush daemon passes over the page, at which point they will be written out to disk. You can also use the memcntl() system call to initiate a synchronous or asynchronous write of pages.
Post a comment