static int ll_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { int count = 0; bool printed = false; int result; sigset_t set; /* 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); restart: result = ll_fault0(vma, vmf); if (!(result & (VM_FAULT_RETRY | VM_FAULT_ERROR | VM_FAULT_LOCKED))) { struct page *vmpage = vmf->page; /* 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; if (!printed && ++count > 16) { CWARN("the page is under heavy contention," "maybe your app(%s) needs revising :-)\n", current->comm); printed = true; } goto restart; } result |= VM_FAULT_LOCKED; } cfs_restore_sigs(set); return result; }
static int ll_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { int count = 0; bool printed = false; int result; sigset_t set; /* Only SIGKILL and SIGTERM are 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)); restart: result = ll_fault0(vma, vmf); LASSERT(!(result & VM_FAULT_LOCKED)); if (result == 0) { struct page *vmpage = vmf->page; /* check if this page has been truncated */ lock_page(vmpage); if (unlikely(!vmpage->mapping)) { /* unlucky */ unlock_page(vmpage); page_cache_release(vmpage); 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; } goto restart; } result = VM_FAULT_LOCKED; } cfs_restore_sigs(set); return result; }