]> git.hungrycats.org Git - linux/commitdiff
[PATCH] pagefault accounting fix
authorAndrew Morton <akpm@osdl.org>
Mon, 29 Dec 2003 13:48:41 +0000 (05:48 -0800)
committerLinus Torvalds <torvalds@home.osdl.org>
Mon, 29 Dec 2003 13:48:41 +0000 (05:48 -0800)
From: William Lee Irwin III <wli@holomorphy.com>

Our accounting of minor faults versus major faults is currently quite wrong.

To fix it up we need to propagate the actual fault type back to the
higher-level code.  Repurpose the currently-unused third arg to ->nopage
for this.

21 files changed:
Documentation/filesystems/Locking
arch/i386/mm/hugetlbpage.c
arch/ia64/ia32/binfmt_elf32.c
arch/ia64/mm/hugetlbpage.c
arch/ppc64/mm/hugetlbpage.c
arch/sparc64/mm/hugetlbpage.c
drivers/char/agp/alpha-agp.c
drivers/char/drm/drmP.h
drivers/char/drm/drm_vm.h
drivers/ieee1394/dma.c
drivers/media/video/video-buf.c
drivers/scsi/sg.c
fs/ncpfs/mmap.c
include/linux/mm.h
kernel/sys.c
mm/filemap.c
mm/memory.c
mm/shmem.c
sound/core/pcm_native.c
sound/oss/emu10k1/audio.c
sound/oss/via82cxxx_audio.c

index 4c426bdaca02bf52d6ac130f4ad3d7452722b92c..83e6a8f83ce85a6da75dee59454e4207cd47b43c 100644 (file)
@@ -420,7 +420,7 @@ transfer:   no
 prototypes:
        void (*open)(struct vm_area_struct*);
        void (*close)(struct vm_area_struct*);
-       struct page *(*nopage)(struct vm_area_struct*, unsigned long, int);
+       struct page *(*nopage)(struct vm_area_struct*, unsigned long, int *);
 
 locking rules:
                BKL     mmap_sem
index 207be11de2a98037fa830f7ea68b412089a1db5d..48deeb0caaf9461e0cbef4fa1baae19ea52b6651 100644 (file)
@@ -534,7 +534,7 @@ int is_hugepage_mem_enough(size_t size)
  * this far.
  */
 static struct page *hugetlb_nopage(struct vm_area_struct *vma,
-                               unsigned long address, int unused)
+                               unsigned long address, int *unused)
 {
        BUG();
        return NULL;
index 6511c85a26e752034f3a75c12dc7180bbc939036..3fafb0d7b8badf00c6f693e8eb403fbe2bf93f8b 100644 (file)
@@ -60,10 +60,12 @@ extern struct page *ia32_shared_page[];
 extern unsigned long *ia32_gdt;
 
 struct page *
-ia32_install_shared_page (struct vm_area_struct *vma, unsigned long address, int no_share)
+ia32_install_shared_page (struct vm_area_struct *vma, unsigned long address, int *type)
 {
        struct page *pg = ia32_shared_page[smp_processor_id()];
        get_page(pg);
+       if (type)
+               *type = VM_FAULT_MINOR;
        return pg;
 }
 
index 9e366cb1029734ad3b65b707d68b10dd270efba7..668b351a0bdf60482b808263573d3a30cc3e9b88 100644 (file)
@@ -518,7 +518,7 @@ int is_hugepage_mem_enough(size_t size)
        return 1;
 }
 
-static struct page *hugetlb_nopage(struct vm_area_struct * area, unsigned long address, int unused)
+static struct page *hugetlb_nopage(struct vm_area_struct * area, unsigned long address, int *unused)
 {
        BUG();
        return NULL;
index dac306c5343ad4f550db796c76fabdd9b998f5c0..061b6f0c14bb6d0cb5242a5145a62657194f04a1 100644 (file)
@@ -921,7 +921,7 @@ int is_hugepage_mem_enough(size_t size)
  * this far.
  */
 static struct page *hugetlb_nopage(struct vm_area_struct *vma,
-                               unsigned long address, int unused)
+                               unsigned long address, int *unused)
 {
        BUG();
        return NULL;
index ed4967a44e5dbd09dcc7349f8ad3c73916d23301..db74fddd5dc32e22b7c75c22565af614445fba90 100644 (file)
@@ -504,7 +504,7 @@ int is_hugepage_mem_enough(size_t size)
  * this far.
  */
 static struct page *hugetlb_nopage(struct vm_area_struct *vma,
-                                  unsigned long address, int unused)
+                                  unsigned long address, int *unused)
 {
        BUG();
        return NULL;
index 803e1c4d7ec9f3e9398628c13d8e10975b712a63..edca77d1df7cf8eeeb6457c210e2b056ebde1576 100644 (file)
@@ -13,7 +13,7 @@
 
 static struct page *alpha_core_agp_vm_nopage(struct vm_area_struct *vma,
                                             unsigned long address,
-                                            int write_access)
+                                            int *type)
 {
        alpha_agp_info *agp = agp_bridge->dev_private_data;
        dma_addr_t dma_addr;
@@ -30,6 +30,8 @@ static struct page *alpha_core_agp_vm_nopage(struct vm_area_struct *vma,
         */
        page = virt_to_page(__va(pa));
        get_page(page);
+       if (type)
+               *type = VM_FAULT_MINOR;
        return page;
 }
 
index 3b40405c75d10a0365bd0a88cb70b320e7a7d16e..2c9d6b6517d059dbdc2270c0e10c5772b34f8f93 100644 (file)
@@ -760,16 +760,16 @@ extern int             DRM(fasync)(int fd, struct file *filp, int on);
                                /* Mapping support (drm_vm.h) */
 extern struct page *DRM(vm_nopage)(struct vm_area_struct *vma,
                                   unsigned long address,
-                                  int write_access);
+                                  int *type);
 extern struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
                                       unsigned long address,
-                                      int write_access);
+                                      int *type);
 extern struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma,
                                       unsigned long address,
-                                      int write_access);
+                                      int *type);
 extern struct page *DRM(vm_sg_nopage)(struct vm_area_struct *vma,
                                      unsigned long address,
-                                     int write_access);
+                                     int *type);
 extern void         DRM(vm_open)(struct vm_area_struct *vma);
 extern void         DRM(vm_close)(struct vm_area_struct *vma);
 extern void         DRM(vm_shm_close)(struct vm_area_struct *vma);
index 1c84dca2b48a3b8919045d4f91b9a00673a54c58..cf641664a92cebe79ae136a7f2068f3773fdd84e 100644 (file)
@@ -76,7 +76,7 @@ struct vm_operations_struct   DRM(vm_sg_ops) = {
  */
 struct page *DRM(vm_nopage)(struct vm_area_struct *vma,
                            unsigned long address,
-                           int write_access)
+                           int *type)
 {
 #if __REALLY_HAVE_AGP
        drm_file_t *priv  = vma->vm_file->private_data;
@@ -133,6 +133,8 @@ struct page *DRM(vm_nopage)(struct vm_area_struct *vma,
                          baddr, __va(agpmem->memory->memory[offset]), offset,
                          atomic_read(&page->count));
 
+               if (type)
+                       *type = VM_FAULT_MINOR;
                return page;
         }
 vm_nopage_error:
@@ -154,7 +156,7 @@ vm_nopage_error:
  */
 struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
                                unsigned long address,
-                               int write_access)
+                               int *type)
 {
        drm_map_t        *map    = (drm_map_t *)vma->vm_private_data;
        unsigned long    offset;
@@ -170,6 +172,8 @@ struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
        if (!page)
                return NOPAGE_OOM;
        get_page(page);
+       if (type)
+               *type = VM_FAULT_MINOR;
 
        DRM_DEBUG("shm_nopage 0x%lx\n", address);
        return page;
@@ -268,7 +272,7 @@ void DRM(vm_shm_close)(struct vm_area_struct *vma)
  */
 struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma,
                                unsigned long address,
-                               int write_access)
+                               int *type)
 {
        drm_file_t       *priv   = vma->vm_file->private_data;
        drm_device_t     *dev    = priv->dev;
@@ -287,6 +291,8 @@ struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma,
                             (offset & (~PAGE_MASK))));
 
        get_page(page);
+       if (type)
+               *type = VM_FAULT_MINOR;
 
        DRM_DEBUG("dma_nopage 0x%lx (page %lu)\n", address, page_nr);
        return page;
@@ -304,7 +310,7 @@ struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma,
  */
 struct page *DRM(vm_sg_nopage)(struct vm_area_struct *vma,
                               unsigned long address,
-                              int write_access)
+                              int *type)
 {
        drm_map_t        *map    = (drm_map_t *)vma->vm_private_data;
        drm_file_t *priv = vma->vm_file->private_data;
@@ -325,6 +331,8 @@ struct page *DRM(vm_sg_nopage)(struct vm_area_struct *vma,
        page_offset = (offset >> PAGE_SHIFT) + (map_offset >> PAGE_SHIFT);
        page = entry->pagelist[page_offset];
        get_page(page);
+       if (type)
+               *type = VM_FAULT_MINOR;
 
        return page;
 }
index 25db9c4348d530eea255b91c67fdee389c35884a..75c6320d668f6270a8c6dbdda8aa734fa193534c 100644 (file)
@@ -187,7 +187,7 @@ void dma_region_sync(struct dma_region *dma, unsigned long offset, unsigned long
 /* nopage() handler for mmap access */
 
 static struct page*
-dma_region_pagefault(struct vm_area_struct *area, unsigned long address, int write_access)
+dma_region_pagefault(struct vm_area_struct *area, unsigned long address, int *type)
 {
        unsigned long offset;
        unsigned long kernel_virt_addr;
@@ -202,6 +202,8 @@ dma_region_pagefault(struct vm_area_struct *area, unsigned long address, int wri
            (address > (unsigned long) area->vm_start + (PAGE_SIZE * dma->n_pages)) )
                goto out;
 
+       if (type)
+               *type = VM_FAULT_MINOR;
        offset = address - area->vm_start;
        kernel_virt_addr = (unsigned long) dma->kvirt + offset;
        ret = vmalloc_to_page((void*) kernel_virt_addr);
index 5afc77fabfa1b29e79af4f3557a9c39725082f01..bac87d09db2849410fede1216bb0d2c4284836b4 100644 (file)
@@ -1078,7 +1078,7 @@ videobuf_vm_close(struct vm_area_struct *vma)
  */
 static struct page*
 videobuf_vm_nopage(struct vm_area_struct *vma, unsigned long vaddr,
-                 int write_access)
+                 int *type)
 {
        struct page *page;
 
@@ -1090,6 +1090,8 @@ videobuf_vm_nopage(struct vm_area_struct *vma, unsigned long vaddr,
        if (!page)
                return NOPAGE_OOM;
        clear_user_page(page_address(page), vaddr, page);
+       if (type)
+               *type = VM_FAULT_MINOR;
        return page;
 }
 
index d4b4330c2887deaf3a20c87801e29da7d8c948a2..a75ad800a8c6233ee10e9f64304805f930b583a3 100644 (file)
@@ -1118,7 +1118,7 @@ sg_rb_correct4mmap(Sg_scatter_hold * rsv_schp, int startFinish)
 }
 
 static struct page *
-sg_vma_nopage(struct vm_area_struct *vma, unsigned long addr, int unused)
+sg_vma_nopage(struct vm_area_struct *vma, unsigned long addr, int *type)
 {
        Sg_fd *sfp;
        struct page *page = NOPAGE_SIGBUS;
@@ -1158,6 +1158,8 @@ sg_vma_nopage(struct vm_area_struct *vma, unsigned long addr, int unused)
                page = virt_to_page(page_ptr);
                get_page(page); /* increment page count */
        }
+       if (type)
+               *type = VM_FAULT_MINOR;
        return page;
 }
 
index 6c067d6536f062a1eb6ad7734a30d10fef53607e..5fb8e87164873fdaae4da07d77452a9ccec74ebd 100644 (file)
@@ -26,7 +26,7 @@
  * Fill in the supplied page for mmap
  */
 static struct page* ncp_file_mmap_nopage(struct vm_area_struct *area,
-                                    unsigned long address, int write_access)
+                                    unsigned long address, int *type)
 {
        struct file *file = area->vm_file;
        struct dentry *dentry = file->f_dentry;
@@ -85,6 +85,15 @@ static struct page* ncp_file_mmap_nopage(struct vm_area_struct *area,
                memset(pg_addr + already_read, 0, PAGE_SIZE - already_read);
        flush_dcache_page(page);
        kunmap(page);
+
+       /*
+        * If I understand ncp_read_kernel() properly, the above always
+        * fetches from the network, here the analogue of disk.
+        * -- wli
+        */
+       if (type)
+               *type = VM_FAULT_MAJOR;
+       inc_page_state(pgmajfault);
        return page;
 }
 
index 9aa07674aaf58a5f13c1daf46797eaba5f86dbc8..881091514f01423ff8011a42cd846ca7a6d2f765 100644 (file)
@@ -143,7 +143,7 @@ extern pgprot_t protection_map[16];
 struct vm_operations_struct {
        void (*open)(struct vm_area_struct * area);
        void (*close)(struct vm_area_struct * area);
-       struct page * (*nopage)(struct vm_area_struct * area, unsigned long address, int unused);
+       struct page * (*nopage)(struct vm_area_struct * area, unsigned long address, int *type);
        int (*populate)(struct vm_area_struct * area, unsigned long address, unsigned long len, pgprot_t prot, unsigned long pgoff, int nonblock);
 };
 
@@ -407,7 +407,7 @@ static inline int page_mapped(struct page *page)
 extern void show_free_areas(void);
 
 struct page *shmem_nopage(struct vm_area_struct * vma,
-                       unsigned long address, int unused);
+                       unsigned long address, int *type);
 struct file *shmem_file_setup(char * name, loff_t size, unsigned long flags);
 void shmem_lock(struct file * file, int lock);
 int shmem_zero_setup(struct vm_area_struct *);
@@ -565,7 +565,7 @@ extern unsigned long page_unuse(struct page *);
 extern void truncate_inode_pages(struct address_space *, loff_t);
 
 /* generic vm_area_ops exported for stackable file systems */
-extern struct page *filemap_nopage(struct vm_area_struct *, unsigned long, int);
+struct page *filemap_nopage(struct vm_area_struct *, unsigned long, int *);
 
 /* mm/page-writeback.c */
 int write_one_page(struct page *page, int wait);
index f25fc2166ee0903b345b3d54cd75eb8c3f949dc0..9aa8ad493460c817d3e5d2c17130a48e71cdfbb9 100644 (file)
@@ -1323,8 +1323,6 @@ asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit __user *rlim)
  * either stopped or zombied.  In the zombied case the task won't get
  * reaped till shortly after the call to getrusage(), in both cases the
  * task being examined is in a frozen state so the counters won't change.
- *
- * FIXME! Get the fault counts properly!
  */
 int getrusage(struct task_struct *p, int who, struct rusage __user *ru)
 {
index 7891fef5399b751f1731d22f95efde385b310179..21dfbeaaf58c2a4048daee1522bf96d10f803d12 100644 (file)
@@ -990,7 +990,7 @@ static int page_cache_read(struct file * file, unsigned long offset)
  * it in the page cache, and handles the special cases reasonably without
  * having a lot of duplicated code.
  */
-struct page * filemap_nopage(struct vm_area_struct * area, unsigned long address, int unused)
+struct page * filemap_nopage(struct vm_area_struct * area, unsigned long address, int *type)
 {
        int error;
        struct file *file = area->vm_file;
@@ -999,7 +999,7 @@ struct page * filemap_nopage(struct vm_area_struct * area, unsigned long address
        struct inode *inode = mapping->host;
        struct page *page;
        unsigned long size, pgoff, endoff;
-       int did_readaround = 0;
+       int did_readaround = 0, majmin = VM_FAULT_MINOR;
 
        pgoff = ((address - area->vm_start) >> PAGE_CACHE_SHIFT) + area->vm_pgoff;
        endoff = ((area->vm_end - area->vm_start) >> PAGE_CACHE_SHIFT) + area->vm_pgoff;
@@ -1048,6 +1048,14 @@ retry_find:
                if (ra->mmap_miss > ra->mmap_hit + MMAP_LOTSAMISS)
                        goto no_cached_page;
 
+               /*
+                * To keep the pgmajfault counter straight, we need to
+                * check did_readaround, as this is an inner loop.
+                */
+               if (!did_readaround) {
+                       majmin = VM_FAULT_MAJOR;
+                       inc_page_state(pgmajfault);
+               }
                did_readaround = 1;
                do_page_cache_readahead(mapping, file,
                                pgoff & ~(MMAP_READAROUND-1), MMAP_READAROUND);
@@ -1069,6 +1077,8 @@ success:
         * Found the page and have a reference on it.
         */
        mark_page_accessed(page);
+       if (type)
+               *type = majmin;
        return page;
 
 outside_data_content:
@@ -1104,7 +1114,10 @@ no_cached_page:
        return NULL;
 
 page_not_uptodate:
-       inc_page_state(pgmajfault);
+       if (!did_readaround) {
+               majmin = VM_FAULT_MAJOR;
+               inc_page_state(pgmajfault);
+       }
        lock_page(page);
 
        /* Did it get unhashed while we waited for it? */
index 9339b54847be4a743201dafbe3ab5a5faa635293..16fe20a03cc147841daf21ec7c47e9835558281b 100644 (file)
@@ -1400,7 +1400,7 @@ do_no_page(struct mm_struct *mm, struct vm_area_struct *vma,
        pte_t entry;
        struct pte_chain *pte_chain;
        int sequence = 0;
-       int ret;
+       int ret = VM_FAULT_MINOR;
 
        if (!vma->vm_ops || !vma->vm_ops->nopage)
                return do_anonymous_page(mm, vma, page_table,
@@ -1414,7 +1414,7 @@ do_no_page(struct mm_struct *mm, struct vm_area_struct *vma,
        }
        smp_rmb();  /* Prevent CPU from reordering lock-free ->nopage() */
 retry:
-       new_page = vma->vm_ops->nopage(vma, address & PAGE_MASK, 0);
+       new_page = vma->vm_ops->nopage(vma, address & PAGE_MASK, &ret);
 
        /* no page was available -- either SIGBUS or OOM */
        if (new_page == NOPAGE_SIGBUS)
@@ -1483,14 +1483,12 @@ retry:
                pte_unmap(page_table);
                page_cache_release(new_page);
                spin_unlock(&mm->page_table_lock);
-               ret = VM_FAULT_MINOR;
                goto out;
        }
 
        /* no need to invalidate: a not-present page shouldn't be cached */
        update_mmu_cache(vma, address, entry);
        spin_unlock(&mm->page_table_lock);
-       ret = VM_FAULT_MAJOR;
        goto out;
 oom:
        ret = VM_FAULT_OOM;
index 13bb8a4135482679cebb0b7b3cf45d37b1bdc093..3be833299acc45ab6d20102ae5577d127c2228d0 100644 (file)
@@ -71,7 +71,7 @@ enum sgp_type {
 };
 
 static int shmem_getpage(struct inode *inode, unsigned long idx,
-                        struct page **pagep, enum sgp_type sgp);
+                        struct page **pagep, enum sgp_type sgp, int *type);
 
 static inline struct page *shmem_dir_alloc(unsigned int gfp_mask)
 {
@@ -540,7 +540,7 @@ static int shmem_notify_change(struct dentry *dentry, struct iattr *attr)
                        if (attr->ia_size & (PAGE_CACHE_SIZE-1)) {
                                (void) shmem_getpage(inode,
                                        attr->ia_size>>PAGE_CACHE_SHIFT,
-                                               &page, SGP_READ);
+                                               &page, SGP_READ, NULL);
                        }
                        /*
                         * Reset SHMEM_PAGEIN flag so that shmem_truncate can
@@ -765,7 +765,7 @@ redirty:
  * vm. If we swap it in we mark it dirty since we also free the swap
  * entry since a page cannot live in both the swap and page cache
  */
-static int shmem_getpage(struct inode *inode, unsigned long idx, struct page **pagep, enum sgp_type sgp)
+static int shmem_getpage(struct inode *inode, unsigned long idx, struct page **pagep, enum sgp_type sgp, int *type)
 {
        struct address_space *mapping = inode->i_mapping;
        struct shmem_inode_info *info = SHMEM_I(inode);
@@ -774,7 +774,7 @@ static int shmem_getpage(struct inode *inode, unsigned long idx, struct page **p
        struct page *swappage;
        swp_entry_t *entry;
        swp_entry_t swap;
-       int error;
+       int error, majmin = VM_FAULT_MINOR;
 
        if (idx >= SHMEM_MAX_INDEX)
                return -EFBIG;
@@ -811,6 +811,10 @@ repeat:
                if (!swappage) {
                        shmem_swp_unmap(entry);
                        spin_unlock(&info->lock);
+                       /* here we actually do the io */
+                       if (majmin == VM_FAULT_MINOR && type)
+                               inc_page_state(pgmajfault);
+                       majmin = VM_FAULT_MAJOR;
                        swapin_readahead(swap);
                        swappage = read_swap_cache_async(swap);
                        if (!swappage) {
@@ -959,6 +963,8 @@ done:
                } else
                        *pagep = ZERO_PAGE(0);
        }
+       if (type)
+               *type = majmin;
        return 0;
 
 failed:
@@ -969,7 +975,7 @@ failed:
        return error;
 }
 
-struct page *shmem_nopage(struct vm_area_struct *vma, unsigned long address, int unused)
+struct page *shmem_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
 {
        struct inode *inode = vma->vm_file->f_dentry->d_inode;
        struct page *page = NULL;
@@ -980,7 +986,7 @@ struct page *shmem_nopage(struct vm_area_struct *vma, unsigned long address, int
        idx += vma->vm_pgoff;
        idx >>= PAGE_CACHE_SHIFT - PAGE_SHIFT;
 
-       error = shmem_getpage(inode, idx, &page, SGP_CACHE);
+       error = shmem_getpage(inode, idx, &page, SGP_CACHE, type);
        if (error)
                return (error == -ENOMEM)? NOPAGE_OOM: NOPAGE_SIGBUS;
 
@@ -1007,7 +1013,7 @@ static int shmem_populate(struct vm_area_struct *vma,
                /*
                 * Will need changing if PAGE_CACHE_SIZE != PAGE_SIZE
                 */
-               err = shmem_getpage(inode, pgoff, &page, sgp);
+               err = shmem_getpage(inode, pgoff, &page, sgp, NULL);
                if (err)
                        return err;
                if (page) {
@@ -1157,7 +1163,7 @@ static int
 shmem_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to)
 {
        struct inode *inode = page->mapping->host;
-       return shmem_getpage(inode, page->index, &page, SGP_WRITE);
+       return shmem_getpage(inode, page->index, &page, SGP_WRITE, NULL);
 }
 
 static ssize_t
@@ -1214,7 +1220,7 @@ shmem_file_write(struct file *file, const char __user *buf, size_t count, loff_t
                 * But it still may be a good idea to prefault below.
                 */
 
-               err = shmem_getpage(inode, index, &page, SGP_WRITE);
+               err = shmem_getpage(inode, index, &page, SGP_WRITE, NULL);
                if (err)
                        break;
 
@@ -1296,7 +1302,7 @@ static void do_shmem_file_read(struct file *filp, loff_t *ppos, read_descriptor_
                                break;
                }
 
-               desc->error = shmem_getpage(inode, index, &page, SGP_READ);
+               desc->error = shmem_getpage(inode, index, &page, SGP_READ, NULL);
                if (desc->error) {
                        if (desc->error == -EINVAL)
                                desc->error = 0;
@@ -1552,7 +1558,7 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s
                        iput(inode);
                        return -ENOMEM;
                }
-               error = shmem_getpage(inode, 0, &page, SGP_WRITE);
+               error = shmem_getpage(inode, 0, &page, SGP_WRITE, NULL);
                if (error) {
                        vm_unacct_memory(VM_ACCT(1));
                        iput(inode);
@@ -1590,7 +1596,7 @@ static int shmem_follow_link_inline(struct dentry *dentry, struct nameidata *nd)
 static int shmem_readlink(struct dentry *dentry, char __user *buffer, int buflen)
 {
        struct page *page = NULL;
-       int res = shmem_getpage(dentry->d_inode, 0, &page, SGP_READ);
+       int res = shmem_getpage(dentry->d_inode, 0, &page, SGP_READ, NULL);
        if (res)
                return res;
        res = vfs_readlink(dentry, buffer, buflen, kmap(page));
@@ -1603,7 +1609,7 @@ static int shmem_readlink(struct dentry *dentry, char __user *buffer, int buflen
 static int shmem_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
        struct page *page = NULL;
-       int res = shmem_getpage(dentry->d_inode, 0, &page, SGP_READ);
+       int res = shmem_getpage(dentry->d_inode, 0, &page, SGP_READ, NULL);
        if (res)
                return res;
        res = vfs_follow_link(nd, kmap(page));
index 2dd650feb464b61bdc7032b9c1886614c537888d..053d7b38a56c1b4bd0f368481485748cf8ef3c08 100644 (file)
@@ -2779,7 +2779,7 @@ unsigned int snd_pcm_capture_poll(struct file *file, poll_table * wait)
        return mask;
 }
 
-static struct page * snd_pcm_mmap_status_nopage(struct vm_area_struct *area, unsigned long address, int no_share)
+static struct page * snd_pcm_mmap_status_nopage(struct vm_area_struct *area, unsigned long address, int *type)
 {
        snd_pcm_substream_t *substream = (snd_pcm_substream_t *)area->vm_private_data;
        snd_pcm_runtime_t *runtime;
@@ -2791,6 +2791,8 @@ static struct page * snd_pcm_mmap_status_nopage(struct vm_area_struct *area, uns
        page = virt_to_page(runtime->status);
        if (!PageReserved(page))
                get_page(page);
+       if (type)
+               *type = VM_FAULT_MINOR;
        return page;
 }
 
@@ -2817,7 +2819,7 @@ int snd_pcm_mmap_status(snd_pcm_substream_t *substream, struct file *file,
        return 0;
 }
 
-static struct page * snd_pcm_mmap_control_nopage(struct vm_area_struct *area, unsigned long address, int no_share)
+static struct page * snd_pcm_mmap_control_nopage(struct vm_area_struct *area, unsigned long address, int *type)
 {
        snd_pcm_substream_t *substream = (snd_pcm_substream_t *)area->vm_private_data;
        snd_pcm_runtime_t *runtime;
@@ -2829,6 +2831,8 @@ static struct page * snd_pcm_mmap_control_nopage(struct vm_area_struct *area, un
        page = virt_to_page(runtime->control);
        if (!PageReserved(page))
                get_page(page);
+       if (type)
+               *type = VM_FAULT_MINOR;
        return page;
 }
 
@@ -2867,7 +2871,7 @@ static void snd_pcm_mmap_data_close(struct vm_area_struct *area)
        atomic_dec(&substream->runtime->mmap_count);
 }
 
-static struct page * snd_pcm_mmap_data_nopage(struct vm_area_struct *area, unsigned long address, int no_share)
+static struct page * snd_pcm_mmap_data_nopage(struct vm_area_struct *area, unsigned long address, int *type)
 {
        snd_pcm_substream_t *substream = (snd_pcm_substream_t *)area->vm_private_data;
        snd_pcm_runtime_t *runtime;
@@ -2895,6 +2899,8 @@ static struct page * snd_pcm_mmap_data_nopage(struct vm_area_struct *area, unsig
        }
        if (!PageReserved(page))
                get_page(page);
+       if (type)
+               *type = VM_FAULT_MINOR;
        return page;
 }
 
index c5a00377a5e18e74c3c8327137bb2d3bd8f0772a..42fae03b16a7e6745de4920304058fbef9f484c4 100644 (file)
@@ -989,7 +989,7 @@ static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned
        return 0;
 }
 
-static struct page *emu10k1_mm_nopage (struct vm_area_struct * vma, unsigned long address, int write_access)
+static struct page *emu10k1_mm_nopage (struct vm_area_struct * vma, unsigned long address, int *type)
 {
        struct emu10k1_wavedevice *wave_dev = vma->vm_private_data;
        struct woinst *woinst = wave_dev->woinst;
@@ -1032,6 +1032,8 @@ static struct page *emu10k1_mm_nopage (struct vm_area_struct * vma, unsigned lon
        get_page (dmapage);
 
        DPD(3, "page: %#lx\n", (unsigned long) dmapage);
+       if (type)
+               *type = VM_FAULT_MINOR;
        return dmapage;
 }
 
index 68b8e396bc038afec2f4c3ec34676c5fc492730a..d22cc14e7eb95cd56baa7d5dbfb0ca36e81163a2 100644 (file)
@@ -2116,7 +2116,7 @@ static void via_dsp_cleanup (struct via_info *card)
 
 
 static struct page * via_mm_nopage (struct vm_area_struct * vma,
-                                   unsigned long address, int write_access)
+                                   unsigned long address, int *type)
 {
        struct via_info *card = vma->vm_private_data;
        struct via_channel *chan = &card->ch_out;
@@ -2124,12 +2124,11 @@ static struct page * via_mm_nopage (struct vm_area_struct * vma,
        unsigned long pgoff;
        int rd, wr;
 
-       DPRINTK ("ENTER, start %lXh, ofs %lXh, pgoff %ld, addr %lXh, wr %d\n",
+       DPRINTK ("ENTER, start %lXh, ofs %lXh, pgoff %ld, addr %lXh\n",
                 vma->vm_start,
                 address - vma->vm_start,
                 (address - vma->vm_start) >> PAGE_SHIFT,
-                address,
-                write_access);
+                address);
 
         if (address > vma->vm_end) {
                DPRINTK ("EXIT, returning NOPAGE_SIGBUS\n");
@@ -2167,6 +2166,8 @@ static struct page * via_mm_nopage (struct vm_area_struct * vma,
        DPRINTK ("EXIT, returning page %p for cpuaddr %lXh\n",
                 dmapage, (unsigned long) chan->pgtbl[pgoff].cpuaddr);
        get_page (dmapage);
+       if (type)
+               *type = VM_FAULT_MINOR;
        return dmapage;
 }