Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc
Browse files Browse the repository at this point in the history
Pull sparc fixes from David Miller:

1) Build fix for LEON, from Sam Ravnborg.

2) Make the sparc side changes that go along with the infrastructure to
   retry faults when blocking on a disk transfer.  From Kautuk Consul.

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc:
  sparc32,leon: fix leon build
  sparc/mm/fault_32.c: Port OOM changes to do_sparc_fault
  sparc/mm/fault_64.c: Port OOM changes to do_sparc64_fault
  • Loading branch information
torvalds committed Apr 10, 2012
2 parents 53cb430 + d657784 commit a9e1e53
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 27 deletions.
13 changes: 0 additions & 13 deletions arch/sparc/kernel/leon_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info)

void __devinit pcibios_fixup_bus(struct pci_bus *pbus)
{
struct leon_pci_info *info = pbus->sysdata;
struct pci_dev *dev;
int i, has_io, has_mem;
u16 cmd;
Expand Down Expand Up @@ -111,18 +110,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
return pci_enable_resources(dev, mask);
}

struct device_node *pci_device_to_OF_node(struct pci_dev *pdev)
{
/*
* Currently the OpenBoot nodes are not connected with the PCI device,
* this is because the LEON PROM does not create PCI nodes. Eventually
* this will change and the same approach as pcic.c can be used to
* match PROM nodes with pci devices.
*/
return NULL;
}
EXPORT_SYMBOL(pci_device_to_OF_node);

void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
{
#ifdef CONFIG_PCI_DEBUG
Expand Down
37 changes: 30 additions & 7 deletions arch/sparc/mm/fault_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);

/*
Expand Down Expand Up @@ -289,21 +292,41 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
* 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;
else if (fault & VM_FAULT_SIGBUS)
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;

Expand Down
37 changes: 30 additions & 7 deletions arch/sparc/mm/fault_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
unsigned int insn = 0;
int si_code, fault_code, fault;
unsigned long address, mm_rss;
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;

fault_code = get_thread_fault_code();

Expand Down Expand Up @@ -333,6 +334,8 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
insn = get_fault_insn(regs, insn);
goto handle_kernel_fault;
}

retry:
down_read(&mm->mmap_sem);
}

Expand Down Expand Up @@ -423,20 +426,40 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
goto bad_area;
}

fault = handle_mm_fault(mm, vma, address, (fault_code & FAULT_CODE_WRITE) ? FAULT_FLAG_WRITE : 0);
flags |= ((fault_code & FAULT_CODE_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;
else if (fault & VM_FAULT_SIGBUS)
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);

Expand Down

0 comments on commit a9e1e53

Please sign in to comment.