X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fllite%2Fllite_mmap.c;h=673ff2c0c22dc48d61ae049988bdca8a787f7536;hp=65e4af685cb817ffa597bdc17e489901f9d10169;hb=9e5cb57addbb5d7bc1596096821ad8dcac7a939b;hpb=f172b116885753d0f316549a2fb9d451e9b4bd2e diff --git a/lustre/llite/llite_mmap.c b/lustre/llite/llite_mmap.c index 65e4af6..673ff2c 100644 --- a/lustre/llite/llite_mmap.c +++ b/lustre/llite/llite_mmap.c @@ -119,7 +119,7 @@ restart: rc = cl_io_init(env, io, CIT_FAULT, io->ci_obj); if (rc == 0) { struct vvp_io *vio = vvp_env_io(env); - struct ll_file_data *fd = LUSTRE_FPRIVATE(file); + struct ll_file_data *fd = file->private_data; LASSERT(vio->vui_cl.cis_io == io); @@ -261,7 +261,7 @@ static inline int to_fault_error(int result) * \retval VM_FAULT_ERROR on general error * \retval NOPAGE_OOM not have memory for allocate new page */ -static int ll_fault0(struct vm_area_struct *vma, struct vm_fault *vmf) +static vm_fault_t ll_fault0(struct vm_area_struct *vma, struct vm_fault *vmf) { struct lu_env *env; struct cl_io *io; @@ -340,26 +340,29 @@ out: } #ifdef HAVE_VM_OPS_USE_VM_FAULT_ONLY -static int ll_fault(struct vm_fault *vmf) +static vm_fault_t ll_fault(struct vm_fault *vmf) { struct vm_area_struct *vma = vmf->vma; #else -static int ll_fault(struct vm_area_struct *vma, struct vm_fault *vmf) +static vm_fault_t ll_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { #endif int count = 0; bool printed = false; - int result; + bool cached; + vm_fault_t result; + ktime_t kstart = ktime_get(); sigset_t set; + result = pcc_fault(vma, vmf, &cached); + if (cached) + goto out; + /* Only SIGKILL and SIGTERM is allowed for fault/nopage/mkwrite * so that it can be killed by admin but not cause segfault by * other signals. */ set = cfs_block_sigsinv(sigmask(SIGKILL) | sigmask(SIGTERM)); - ll_stats_ops_tally(ll_i2sbi(file_inode(vma->vm_file)), - LPROC_LL_FAULT, 1); - /* make sure offset is not a negative number */ if (vmf->pgoff > (MAX_LFS_FILESIZE >> PAGE_SHIFT)) return VM_FAULT_SIGBUS; @@ -367,84 +370,109 @@ restart: result = ll_fault0(vma, vmf); if (vmf->page && !(result & (VM_FAULT_RETRY | VM_FAULT_ERROR | VM_FAULT_LOCKED))) { - struct page *vmpage = vmf->page; + struct page *vmpage = vmf->page; - /* check if this page has been truncated */ - lock_page(vmpage); - if (unlikely(vmpage->mapping == NULL)) { /* unlucky */ - unlock_page(vmpage); + /* check if this page has been truncated */ + lock_page(vmpage); + if (unlikely(vmpage->mapping == NULL)) { /* unlucky */ + unlock_page(vmpage); put_page(vmpage); - vmf->page = NULL; + vmf->page = NULL; - if (!printed && ++count > 16) { - CWARN("the page is under heavy contention," - "maybe your app(%s) needs revising :-)\n", - current->comm); - printed = true; - } + if (!printed && ++count > 16) { + CWARN("the page is under heavy contention, maybe your app(%s) needs revising :-)\n", + current->comm); + printed = true; + } - goto restart; - } + goto restart; + } - result |= VM_FAULT_LOCKED; - } + result |= VM_FAULT_LOCKED; + } cfs_restore_sigs(set); - return result; + +out: + if (vmf->page && result == VM_FAULT_LOCKED) { + ll_rw_stats_tally(ll_i2sbi(file_inode(vma->vm_file)), + current->pid, vma->vm_file->private_data, + cl_offset(NULL, vmf->page->index), PAGE_SIZE, + READ); + ll_stats_ops_tally(ll_i2sbi(file_inode(vma->vm_file)), + LPROC_LL_FAULT, + ktime_us_delta(ktime_get(), kstart)); + } + + return result; } #ifdef HAVE_VM_OPS_USE_VM_FAULT_ONLY -static int ll_page_mkwrite(struct vm_fault *vmf) +static vm_fault_t ll_page_mkwrite(struct vm_fault *vmf) { struct vm_area_struct *vma = vmf->vma; #else -static int ll_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) +static vm_fault_t ll_page_mkwrite(struct vm_area_struct *vma, + struct vm_fault *vmf) { #endif int count = 0; bool printed = false; bool retry; - int result; + bool cached; + ktime_t kstart = ktime_get(); + vm_fault_t result; - ll_stats_ops_tally(ll_i2sbi(file_inode(vma->vm_file)), - LPROC_LL_MKWRITE, 1); + result = pcc_page_mkwrite(vma, vmf, &cached); + if (cached) + goto out; file_update_time(vma->vm_file); - do { - retry = false; - result = ll_page_mkwrite0(vma, vmf->page, &retry); + do { + retry = false; + result = ll_page_mkwrite0(vma, vmf->page, &retry); - if (!printed && ++count > 16) { + if (!printed && ++count > 16) { const struct dentry *de = file_dentry(vma->vm_file); - CWARN("app(%s): the page %lu of file "DFID" is under" - " heavy contention\n", + CWARN("app(%s): the page %lu of file "DFID" is under heavy contention\n", current->comm, vmf->pgoff, PFID(ll_inode2fid(de->d_inode))); - printed = true; - } - } while (retry); - - switch(result) { - case 0: - LASSERT(PageLocked(vmf->page)); - result = VM_FAULT_LOCKED; - break; - case -ENODATA: - case -EFAULT: - result = VM_FAULT_NOPAGE; - break; - case -ENOMEM: - result = VM_FAULT_OOM; - break; - case -EAGAIN: - result = VM_FAULT_RETRY; - break; - default: - result = VM_FAULT_SIGBUS; - break; - } + printed = true; + } + } while (retry); + + switch (result) { + case 0: + LASSERT(PageLocked(vmf->page)); + result = VM_FAULT_LOCKED; + break; + case -ENODATA: + case -EFAULT: + result = VM_FAULT_NOPAGE; + break; + case -ENOMEM: + result = VM_FAULT_OOM; + break; + case -EAGAIN: + result = VM_FAULT_RETRY; + break; + default: + result = VM_FAULT_SIGBUS; + break; + } + +out: + if (result == VM_FAULT_LOCKED) { + ll_rw_stats_tally(ll_i2sbi(file_inode(vma->vm_file)), + current->pid, vma->vm_file->private_data, + cl_offset(NULL, vmf->page->index), PAGE_SIZE, + WRITE); + ll_stats_ops_tally(ll_i2sbi(file_inode(vma->vm_file)), + LPROC_LL_MKWRITE, + ktime_us_delta(ktime_get(), kstart)); + } - return result; + return result; } /** @@ -459,6 +487,7 @@ static void ll_vm_open(struct vm_area_struct * vma) ENTRY; LASSERT(atomic_read(&vob->vob_mmap_cnt) >= 0); atomic_inc(&vob->vob_mmap_cnt); + pcc_vm_open(vma); EXIT; } @@ -473,6 +502,7 @@ static void ll_vm_close(struct vm_area_struct *vma) ENTRY; atomic_dec(&vob->vob_mmap_cnt); LASSERT(atomic_read(&vob->vob_mmap_cnt) >= 0); + pcc_vm_close(vma); EXIT; } @@ -487,7 +517,7 @@ int ll_teardown_mmaps(struct address_space *mapping, __u64 first, __u64 last) if (mapping_mapped(mapping)) { rc = 0; unmap_mapping_range(mapping, first + PAGE_SIZE - 1, - last - first + 1, 0); + last - first + 1, 1); } RETURN(rc); @@ -503,29 +533,31 @@ static const struct vm_operations_struct ll_file_vm_ops = { int ll_file_mmap(struct file *file, struct vm_area_struct * vma) { struct inode *inode = file_inode(file); - int rc; - struct ll_file_data *fd = LUSTRE_FPRIVATE(file); - struct file *pcc_file = fd->fd_pcc_file.pccf_file; + ktime_t kstart = ktime_get(); + bool cached; + int rc; - ENTRY; + ENTRY; - /* pcc cache path */ - if (pcc_file) { - vma->vm_file = pcc_file; - return file_inode(pcc_file)->i_fop->mmap(pcc_file, vma); - } + if (ll_file_nolock(file)) + RETURN(-EOPNOTSUPP); - if (ll_file_nolock(file)) - RETURN(-EOPNOTSUPP); + rc = pcc_file_mmap(file, vma, &cached); + if (cached && rc != 0) + RETURN(rc); - ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_MAP, 1); - rc = generic_file_mmap(file, vma); - if (rc == 0) { + rc = generic_file_mmap(file, vma); + if (rc == 0) { vma->vm_ops = &ll_file_vm_ops; - vma->vm_ops->open(vma); - /* update the inode's size and mtime */ - rc = ll_glimpse_size(inode); - } + vma->vm_ops->open(vma); + /* update the inode's size and mtime */ + if (!cached) + rc = ll_glimpse_size(inode); + } - RETURN(rc); + if (!rc) + ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_MMAP, + ktime_us_delta(ktime_get(), kstart)); + + RETURN(rc); }