Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}