diff options
| author | Arnd Bergmann <arnd@arndb.de> | 2006-04-28 20:40:21 -0400 |
|---|---|---|
| committer | Paul Mackerras <paulus@samba.org> | 2006-04-29 01:11:25 -0400 |
| commit | f807221dedbd30726c5dffcd5b5d22ce0ea683cb (patch) | |
| tree | 7cc1f027c09c6265887711969b728d4cbf1dfe6d | |
| parent | 03054d51a70e8c273df5d9bc31fea6c843eaa1c3 (diff) | |
[PATCH] spufs: Disable local interrupts for SPE hash_page calls.
This patch disables and saves local interrupts during
hash_page processing for SPE contexts.
We have to do it explicitly in the spu_irq_class_1_bottom
function. For the interrupt handlers, we get the behaviour
implicitly by using SA_INTERRUPT to disable interrupts while
in the handler.
Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
| -rw-r--r-- | arch/powerpc/platforms/cell/spu_base.c | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index 269dda4fd0b4..ef47a6239d48 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c | |||
| @@ -306,19 +306,19 @@ spu_request_irqs(struct spu *spu) | |||
| 306 | 306 | ||
| 307 | snprintf(spu->irq_c0, sizeof (spu->irq_c0), "spe%02d.0", spu->number); | 307 | snprintf(spu->irq_c0, sizeof (spu->irq_c0), "spe%02d.0", spu->number); |
| 308 | ret = request_irq(irq_base + spu->isrc, | 308 | ret = request_irq(irq_base + spu->isrc, |
| 309 | spu_irq_class_0, 0, spu->irq_c0, spu); | 309 | spu_irq_class_0, SA_INTERRUPT, spu->irq_c0, spu); |
| 310 | if (ret) | 310 | if (ret) |
| 311 | goto out; | 311 | goto out; |
| 312 | 312 | ||
| 313 | snprintf(spu->irq_c1, sizeof (spu->irq_c1), "spe%02d.1", spu->number); | 313 | snprintf(spu->irq_c1, sizeof (spu->irq_c1), "spe%02d.1", spu->number); |
| 314 | ret = request_irq(irq_base + IIC_CLASS_STRIDE + spu->isrc, | 314 | ret = request_irq(irq_base + IIC_CLASS_STRIDE + spu->isrc, |
| 315 | spu_irq_class_1, 0, spu->irq_c1, spu); | 315 | spu_irq_class_1, SA_INTERRUPT, spu->irq_c1, spu); |
| 316 | if (ret) | 316 | if (ret) |
| 317 | goto out1; | 317 | goto out1; |
| 318 | 318 | ||
| 319 | snprintf(spu->irq_c2, sizeof (spu->irq_c2), "spe%02d.2", spu->number); | 319 | snprintf(spu->irq_c2, sizeof (spu->irq_c2), "spe%02d.2", spu->number); |
| 320 | ret = request_irq(irq_base + 2*IIC_CLASS_STRIDE + spu->isrc, | 320 | ret = request_irq(irq_base + 2*IIC_CLASS_STRIDE + spu->isrc, |
| 321 | spu_irq_class_2, 0, spu->irq_c2, spu); | 321 | spu_irq_class_2, SA_INTERRUPT, spu->irq_c2, spu); |
| 322 | if (ret) | 322 | if (ret) |
| 323 | goto out2; | 323 | goto out2; |
| 324 | goto out; | 324 | goto out; |
| @@ -487,10 +487,14 @@ int spu_irq_class_1_bottom(struct spu *spu) | |||
| 487 | ea = spu->dar; | 487 | ea = spu->dar; |
| 488 | dsisr = spu->dsisr; | 488 | dsisr = spu->dsisr; |
| 489 | if (dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED)) { | 489 | if (dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED)) { |
| 490 | u64 flags; | ||
| 491 | |||
| 490 | access = (_PAGE_PRESENT | _PAGE_USER); | 492 | access = (_PAGE_PRESENT | _PAGE_USER); |
| 491 | access |= (dsisr & MFC_DSISR_ACCESS_PUT) ? _PAGE_RW : 0UL; | 493 | access |= (dsisr & MFC_DSISR_ACCESS_PUT) ? _PAGE_RW : 0UL; |
| 494 | local_irq_save(flags); | ||
| 492 | if (hash_page(ea, access, 0x300) != 0) | 495 | if (hash_page(ea, access, 0x300) != 0) |
| 493 | error |= CLASS1_ENABLE_STORAGE_FAULT_INTR; | 496 | error |= CLASS1_ENABLE_STORAGE_FAULT_INTR; |
| 497 | local_irq_restore(flags); | ||
| 494 | } | 498 | } |
| 495 | if (error & CLASS1_ENABLE_STORAGE_FAULT_INTR) { | 499 | if (error & CLASS1_ENABLE_STORAGE_FAULT_INTR) { |
| 496 | if ((ret = spu_handle_mm_fault(spu)) != 0) | 500 | if ((ret = spu_handle_mm_fault(spu)) != 0) |
