vm_store
Subsystems (10)
RFC PATCH 1/1 vm_store
This patch creates the the abstraction of a vm_store, allowing the page cache to be seperated from the vfs layer.
It also seperates out what is the page cache, from filemap.c into mm/vm_store.c
The only vm_store operation implemented in this patch is clear_page. Allowing delete_from_swap_cache to stop being a special case.
Note: This is on top of some other patches, to see my whole series see:
http://www.ccr.net/ebiederm/files/patches9.tar.gz
arch/m68k/atari/stram.c +1 -1
@@ -944,7 +944,7 @@/* Now get rid of the extra reference to the temporary page we've been using. */ if (PageSwapCache (page_map)) -delete_from_swap_cache (page_map); +remove_store_page (page_map);__free_page (page_map);#ifdef DO_PROC stat_swap_force++;
fs/dcache.c +1 -1
@@ -236,7 +236,7 @@* (We skip inodes that aren't immediately available.) */ if (inode) { - value = inode->i_nrpages; + value = inode->vm_store->st_nrpages;if (value >= max_value)continue ;if (inode->i_state || inode->i_count >1 )
fs/exec.c +1 -0
@@ -316,6 +316,7 @@ mpnt->vm_ops =NULL ; mpnt->vm_index =0 ; mpnt->vm_file =NULL ; + mpnt->vm_store =NULL ; mpnt->vm_pte =0 ;insert_vm_struct (current->mm, mpnt); current->mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >>PAGE_SHIFT ;
fs/inode.c +5 -3
@@ -231,14 +231,12 @@*/ void clear_inode (struct inode *inode) { -if (inode->i_nrpages) -truncate_inode_pages (inode,0 );wait_on_inode (inode);if (IS_QUOTAINIT (inode))DQUOT_DROP (inode);if (inode->i_sb && inode->i_sb->s_op && inode->i_sb->s_op->clear_inode) inode->i_sb->s_op->clear_inode (inode); - +zap_inode_pages (inode); inode->i_state =0 ; }
@@ -549,6 +547,8 @@ inode = list_entry(tmp, struct inode, i_list); add_new_inode:list_add (&inode->i_list, &inode_in_use); + inode->vm_store->st_id =0 ; + inode->vm_store->generic_stp = &inode; inode->i_sb =NULL ; inode->i_dev =0 ; inode->i_ino = ++last_ino;
@@ -589,6 +589,8 @@ add_new_inode:list_add (&inode->i_list, &inode_in_use);list_add (&inode->i_hash, head); + inode->vm_store->st_id =0 ; + inode->vm_store->generic_stp = &inode; inode->i_sb = sb; inode->i_dev = sb->s_dev; inode->i_ino = ino;
fs/locks.c +2 -2
@@ -403,8 +403,8 @@*/ if (IS_MANDLOCK (inode) && (inode->i_mode & (S_ISGID |S_IXGRP )) ==S_ISGID && - inode->i_mmap) { -struct vm_area_struct *vma = inode->i_mmap; + inode->vm_store->st_mmap) { +struct vm_area_struct *vma = inode->vm_store->st_mmap; error = -EAGAIN ; do { if (vma->vm_flags & VM_MAYSHARE)
include/linux/fs.h +2 -4
@@ -18,6 +18,7 @@#include <linux/list.h> #include <linux/dcache.h> #include <linux/stat.h> +#include <linux/vm_store.h> #include <asm/atomic.h> #include <asm/bitops.h>
@@ -356,17 +357,15 @@unsigned long i_blksize;unsigned long i_blocks;unsigned long i_version; -unsigned long i_nrpages;struct semaphore i_sem;struct semaphore i_atomic_write;struct inode_operations *i_op;struct super_block *i_sb;wait_queue_head_t i_wait;struct file_lock *i_flock; -struct vm_area_struct *i_mmap; -struct page *i_pages;struct dquot *i_dquot[MAXQUOTAS ]; +struct vm_store vm_store[1 ];unsigned long i_state;unsigned int i_flags;
@@ -788,7 +787,6 @@extern int check_disk_change (kdev_t dev);extern int invalidate_inodes (struct super_block * sb); -extern void invalidate_inode_pages (struct inode *);extern void invalidate_buffers (kdev_t dev);extern int floppy_is_wp (int minor);extern void sync_inodes (kdev_t dev);
include/linux/mm.h +11 -2
@@ -16,6 +16,8 @@#include <asm/page.h> #include <asm/atomic.h> +struct vm_store ; +/* * Linux kernel virtual memory manager primitives. * The idea being to have a "virtual" mm in the same way
@@ -60,6 +62,7 @@* except the value is potentially too large for the old vm_offset field. */ struct file * vm_file; +struct vm_store *vm_store;unsigned long vm_pte;/* shared mem */ };
@@ -85,6 +88,10 @@#define VM_LOCKED 0x2000#define VM_IO 0x4000/* Memory mapped I/O or similar */ +#define VM_SPARSE_MERGE 0x8000/* Sparce VMA's with non continous +* indecies may be merged +*/ +#define VM_STACK_FLAGS 0x0177/*
@@ -126,7 +133,7 @@/* these must be first (free area handling) */ struct page *next;struct page *prev; -struct inode *inode; +struct vm_store *store;unsigned long key;struct page *next_hash;atomic_t count;
@@ -325,10 +332,12 @@extern int do_munmap (unsigned long ,size_t );/* filemap.c */ -extern void remove_inode_page (struct page *);extern unsigned long page_unuse (struct page *);extern int shrink_mmap (int ,int );extern void truncate_inode_pages (struct inode *,loff_t ); +extern void invalidate_inode_pages (struct inode *); +extern void zap_inode_pages (struct inode *); +extern void update_vm_cache (struct inode *,loff_t ,const char *,int );extern unsigned long get_cached_page (struct inode *,unsigned long ,int );extern void put_cached_page (unsigned long );
include/linux/pagemap.h +25 -22
107 lines not on this page · raw message
include/linux/swap.h +1 -2
@@ -66,7 +66,7 @@extern int nr_swap_pages;extern int nr_free_pages;extern atomic_t nr_async_pages; -extern struct inode swapper_inode; +extern struct vm_store swapper_store;extern unsigned long page_cache_size;extern int buffermem;
@@ -107,7 +107,6 @@/* * Make these inline later once they are working properly. */ -extern void delete_from_swap_cache (struct page *page);extern void free_page_and_swap_cache (unsigned long addr);/* linux/mm/swapfile.c */
include/linux/vm_store.h +52 -0
52 lines not on this page · raw message
ipc/shm.c +1 -0
@@ -513,6 +513,7 @@ | VM_MAYREAD | VM_MAYEXEC | VM_READ | VM_EXEC | ((shmflg &SHM_RDONLY ) ?0 :VM_MAYWRITE |VM_WRITE ); shmd->vm_file =NULL ; + shmd->vm_store =NULL ; shmd->vm_index =0 ; shmd->vm_ops = &shm_vm_ops;
mm/Makefile +2 -1
@@ -10,7 +10,8 @@ O_TARGET := mm.o O_OBJS := memory.o mmap.o filemap.o mprotect.o mlock.o mremap.o \ vmalloc.o slab.o \ - swap.o vmscan.o page_io.o page_alloc.o swap_state.o swapfile.o + swap.o vmscan.o page_io.o page_alloc.o swap_state.o swapfile.o \ + vm_store.o OX_OBJS := swap_syms.o
mm/filemap.c +78 -290
536 lines not on this page · raw message
mm/memory.c +3 -3
@@ -649,7 +649,7 @@break ;if (swap_count (page_map->key) !=1 )break ; -delete_from_swap_cache (page_map); +remove_store_page (page_map);/* FallThrough */ case 1 :/* We can release the kernel lock now.. */
@@ -740,13 +740,13 @@struct vm_area_struct * mpnt;truncate_inode_pages (inode, offset); -if ((!inode->i_mmap) || (offset >PAGE_MAX_FILE_OFFSET )) { +if ((!inode->vm_store->st_mmap) || (offset >PAGE_MAX_FILE_OFFSET )) {return ; } index = offset >>PAGE_CACHE_SHIFT ; partial = offset &PAGE_CACHE_MASK ; trunk_index = index + (partial)?1 :0 ; - mpnt = inode->i_mmap; + mpnt = inode->vm_store->st_mmap; do { struct mm_struct *mm = mpnt->vm_mm; unsigned long start = mpnt->vm_start;
mm/mmap.c +17 -7
@@ -74,10 +74,13 @@static inline void remove_shared_vm_struct (struct vm_area_struct *vma) {struct file * file = vma->vm_file; +struct vm_store *store = vma->vm_store;if (file) {if (vma->vm_flags &VM_DENYWRITE ) file->f_dentry->d_inode->i_writecount++; + } +if (store) {if (vma->vm_next_share) vma->vm_next_share->vm_pprev_share = vma->vm_pprev_share; *vma->vm_pprev_share = vma->vm_next_share;
@@ -280,6 +283,7 @@ vma->vm_ops =NULL ; vma->vm_index =0 ; vma->vm_file =NULL ; + vma->vm_store =NULL ; vma->vm_pte =0 ;/* Clear old maps */
@@ -530,6 +534,7 @@ mpnt->vm_ops = area->vm_ops; mpnt->vm_index = area->vm_index + ((end - area->vm_start) >>PAGE_SHIFT ); mpnt->vm_file = area->vm_file; + mpnt->vm_store = area->vm_store; mpnt->vm_pte = area->vm_pte;if (mpnt->vm_file) mpnt->vm_file->f_count++;
@@ -755,6 +760,7 @@ {struct vm_area_struct **pprev;struct file * file; +struct vm_store *store;if (!mm->mmap_avl) { pprev = &mm->mmap;
@@ -779,12 +785,14 @@struct inode * inode = file->f_dentry->d_inode;if (vmp->vm_flags &VM_DENYWRITE ) inode->i_writecount--; - -/* insert vmp into inode's share list */ -if ((vmp->vm_next_share = inode->i_mmap) !=NULL ) - inode->i_mmap->vm_pprev_share = &vmp->vm_next_share; - inode->i_mmap = vmp; - vmp->vm_pprev_share = &inode->i_mmap; + } + store = vmp->vm_store; +if (store) { +/* insert vmp into store's share list */ +if ((vmp->vm_next_share = store->st_mmap) !=NULL ) + store->st_mmap->vm_pprev_share = &vmp->vm_next_share; + store->st_mmap = vmp; + vmp->vm_pprev_share = &store->st_mmap; } }
@@ -818,7 +826,8 @@ next = mpnt->vm_next;/* To share, we must have the same file, operations.. */ - if ((mpnt->vm_file != prev->vm_file)|| + if ((mpnt->vm_file != prev->vm_file) || + (mpnt->vm_store != prev->vm_store) || (mpnt->vm_pte != prev->vm_pte) || (mpnt->vm_ops != prev->vm_ops) || (mpnt->vm_flags != prev->vm_flags) ||
@@ -829,6 +838,7 @@* If we have a file or it's a shared memory area * the offsets must be contiguous.. */ +/* use VM_SPARCE_MERGE here? */ if ((mpnt->vm_file !=NULL ) || (mpnt->vm_flags &VM_SHM )) {unsigned long off = prev->vm_index + ((prev->vm_end - prev->vm_start) >>PAGE_SHIFT );
mm/page_alloc.c +1 -1
@@ -425,7 +425,7 @@* down the swap cache and give exclusive access to the page to * this process. */ -delete_from_swap_cache (page_map); +remove_store_page (page_map);set_pte (page_table,pte_mkwrite (pte_mkdirty (mk_pte (page, vma->vm_page_prot))));return ; }
mm/page_io.c +4 -4
@@ -237,7 +237,7 @@ {struct page *page = mem_map +MAP_NR (buf); -if (page->inode && page->inode != &swapper_inode) +if (page->store && page->store != &swapper_store)panic ("Tried to swap a non-swapper page" );/*
@@ -274,16 +274,16 @@printk ("VM: read_swap_page: page already in swap cache!\n" );return ; } -if (page->inode) { +if (page->store) {printk ("VM: read_swap_page: page already in page cache!\n" );return ; } - page->inode = &swapper_inode; + page->store = &swapper_store; page->key = entry;atomic_inc (&page->count);/* Protect from shrink_mmap() */ rw_swap_page (rw, entry, buffer,1 );atomic_dec (&page->count); - page->inode =0 ; + page->store =0 ;clear_bit (PG_swap_cache, &page->flags); }
mm/swap_state.c +21 -45
115 lines not on this page · raw message
mm/swap_syms.c +1 -1
@@ -13,4 +13,4 @@EXPORT_SYMBOL (si_swapinfo);EXPORT_SYMBOL (register_swap_unuse_function);EXPORT_SYMBOL (unregister_swap_unuse_function); -EXPORT_SYMBOL (swapper_inode); +EXPORT_SYMBOL (swapper_store);
mm/swapfile.c +1 -1
@@ -447,7 +447,7 @@/* Now get rid of the extra reference to the temporary page we've been using. */ if (PageSwapCache (page_map)) -delete_from_swap_cache (page_map); +remove_store_page (page_map);__free_page (page_map);/* * Check for and clear any overflowed swap map counts.
mm/vm_store.c +254 -0
254 lines not on this page · raw message
--
To unsubscribe, send a message with 'unsubscribe linux-mm my@address' in the body to [email protected]. For more info on Linux MM,
see: http://humbolt.geo.uu.nl/Linux-MM/
Quoted 3 lines · Eric W. Biederman
This patch creates the the abstraction of a
vm_store, allowing the page cache to be seperated from the vfs layer.
I don't think vm_store is very interesting, unless it can be made to contain the current "vm_ops" structure. At the very least you should move vm_ops into vm_store, I feel - before that is done I don't see any reason for vm_store existing at all..
I _assume_ that was the plan all along?
Linus
--
To unsubscribe, send a message with 'unsubscribe linux-mm my@address' in the body to [email protected]. For more info on Linux MM,
see: http://humbolt.geo.uu.nl/Linux-MM/