diff options
| author | James Morris <james.l.morris@oracle.com> | 2012-05-04 12:46:40 +1000 | 
|---|---|---|
| committer | James Morris <james.l.morris@oracle.com> | 2012-05-04 12:46:40 +1000 | 
| commit | 898bfc1d46bd76f8ea2a0fbd239dd2073efe2aa3 (patch) | |
| tree | e6e666085abe674dbf6292555961fe0a0f2e2d2f /arch/sparc/mm/fault_32.c | |
| parent | 08162e6a23d476544adfe1164afe9ea8b34ab859 (diff) | |
| parent | 69964ea4c7b68c9399f7977aa5b9aa6539a6a98a (diff) | |
| download | olio-linux-3.10-898bfc1d46bd76f8ea2a0fbd239dd2073efe2aa3.tar.xz olio-linux-3.10-898bfc1d46bd76f8ea2a0fbd239dd2073efe2aa3.zip  | |
Merge tag 'v3.4-rc5' into next
Linux 3.4-rc5
Merge to pull in prerequisite change for Smack:
86812bb0de1a3758dc6c7aa01a763158a7c0638a
Requested by Casey.
Diffstat (limited to 'arch/sparc/mm/fault_32.c')
| -rw-r--r-- | arch/sparc/mm/fault_32.c | 37 | 
1 files changed, 30 insertions, 7 deletions
diff --git a/arch/sparc/mm/fault_32.c b/arch/sparc/mm/fault_32.c index 7705c6731e2..df3155a1799 100644 --- a/arch/sparc/mm/fault_32.c +++ b/arch/sparc/mm/fault_32.c @@ -225,6 +225,8 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,  	unsigned long g2;  	int from_user = !(regs->psr & PSR_PS);  	int fault, code; +	unsigned int flags = (FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | +			      (write ? FAULT_FLAG_WRITE : 0));  	if(text_fault)  		address = regs->pc; @@ -251,6 +253,7 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,  	perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address); +retry:  	down_read(&mm->mmap_sem);  	/* @@ -289,7 +292,11 @@ good_area:  	 * make sure we exit gracefully rather than endlessly redo  	 * the fault.  	 */ -	fault = handle_mm_fault(mm, vma, address, write ? FAULT_FLAG_WRITE : 0); +	fault = handle_mm_fault(mm, vma, address, flags); + +	if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) +		return; +  	if (unlikely(fault & VM_FAULT_ERROR)) {  		if (fault & VM_FAULT_OOM)  			goto out_of_memory; @@ -297,13 +304,29 @@ good_area:  			goto do_sigbus;  		BUG();  	} -	if (fault & VM_FAULT_MAJOR) { -		current->maj_flt++; -		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, regs, address); -	} else { -		current->min_flt++; -		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, regs, address); + +	if (flags & FAULT_FLAG_ALLOW_RETRY) { +		if (fault & VM_FAULT_MAJOR) { +			current->maj_flt++; +			perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, +				      1, regs, address); +		} else { +			current->min_flt++; +			perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, +				      1, regs, address); +		} +		if (fault & VM_FAULT_RETRY) { +			flags &= ~FAULT_FLAG_ALLOW_RETRY; + +			/* No need to up_read(&mm->mmap_sem) as we would +			 * have already released it in __lock_page_or_retry +			 * in mm/filemap.c. +			 */ + +			goto retry; +		}  	} +  	up_read(&mm->mmap_sem);  	return;  |