Carsten Otte | d763b7a | 2005-06-23 22:05:31 -0700 | [diff] [blame] | 1 | Execute-in-place for file mappings |
| 2 | ---------------------------------- |
| 3 | |
| 4 | Motivation |
| 5 | ---------- |
| 6 | File mappings are performed by mapping page cache pages to userspace. In |
| 7 | addition, read&write type file operations also transfer data from/to the page |
| 8 | cache. |
| 9 | |
| 10 | For memory backed storage devices that use the block device interface, the page |
| 11 | cache pages are in fact copies of the original storage. Various approaches |
| 12 | exist to work around the need for an extra copy. The ramdisk driver for example |
| 13 | does read the data into the page cache, keeps a reference, and discards the |
| 14 | original data behind later on. |
| 15 | |
| 16 | Execute-in-place solves this issue the other way around: instead of keeping |
| 17 | data in the page cache, the need to have a page cache copy is eliminated |
| 18 | completely. With execute-in-place, read&write type operations are performed |
| 19 | directly from/to the memory backed storage device. For file mappings, the |
| 20 | storage device itself is mapped directly into userspace. |
| 21 | |
Matt LaPlante | a982ac0 | 2007-05-09 07:35:06 +0200 | [diff] [blame] | 22 | This implementation was initially written for shared memory segments between |
Carsten Otte | d763b7a | 2005-06-23 22:05:31 -0700 | [diff] [blame] | 23 | different virtual machines on s390 hardware to allow multiple machines to |
| 24 | share the same binaries and libraries. |
| 25 | |
| 26 | Implementation |
| 27 | -------------- |
| 28 | Execute-in-place is implemented in three steps: block device operation, |
| 29 | address space operation, and file operations. |
| 30 | |
| 31 | A block device operation named direct_access is used to retrieve a |
| 32 | reference (pointer) to a block on-disk. The reference is supposed to be |
| 33 | cpu-addressable, physical address and remain valid until the release operation |
| 34 | is performed. A struct block_device reference is used to address the device, |
| 35 | and a sector_t argument is used to identify the individual block. As an |
| 36 | alternative, memory technology devices can be used for this. |
| 37 | |
| 38 | The block device operation is optional, these block devices support it as of |
| 39 | today: |
| 40 | - dcssblk: s390 dcss block device driver |
| 41 | |
Marco Stornelli | 084c304 | 2008-11-12 13:26:56 -0800 | [diff] [blame] | 42 | An address space operation named get_xip_mem is used to retrieve references |
| 43 | to a page frame number and a kernel address. To obtain these values a reference |
| 44 | to an address_space is provided. This function assigns values to the kmem and |
| 45 | pfn parameters. The third argument indicates whether the function should allocate |
| 46 | blocks if needed. |
Carsten Otte | d763b7a | 2005-06-23 22:05:31 -0700 | [diff] [blame] | 47 | |
| 48 | This address space operation is mutually exclusive with readpage&writepage that |
| 49 | do page cache read/write operations. |
| 50 | The following filesystems support it as of today: |
| 51 | - ext2: the second extended filesystem, see Documentation/filesystems/ext2.txt |
| 52 | |
| 53 | A set of file operations that do utilize get_xip_page can be found in |
| 54 | mm/filemap_xip.c . The following file operation implementations are provided: |
| 55 | - aio_read/aio_write |
| 56 | - readv/writev |
| 57 | - sendfile |
| 58 | |
| 59 | The generic file operations do_sync_read/do_sync_write can be used to implement |
| 60 | classic synchronous IO calls. |
| 61 | |
| 62 | Shortcomings |
| 63 | ------------ |
| 64 | This implementation is limited to storage devices that are cpu addressable at |
| 65 | all times (no highmem or such). It works well on rom/ram, but enhancements are |
| 66 | needed to make it work with flash in read+write mode. |
| 67 | Putting the Linux kernel and/or its modules on a xip filesystem does not mean |
| 68 | they are not copied. |