aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorLuke Browning <lukebr@linux.vnet.ibm.com>2008-04-28 03:35:56 -0400
committerJeremy Kerr <jk@ozlabs.org>2008-05-04 23:33:44 -0400
commitde1028927ae3487e2e450dacf50fbf32042aee18 (patch)
tree615b7c5fa3526ccf11b63be88c8978180df0bee8 /arch/powerpc
parentf3d69e0507f84903059d456c5d19f10b2df3ac69 (diff)
[POWERPC] spufs: handle faults while the context switch pending flag is set
Currently, page fault handlers don't issue a mfc restart if the context switch pending flag is set, which can leave us with a hanging DMA after a context restore. This patch introduces fault pending flag that is set by the fault handler and read by the context switch code, so that the latter can add the restart bit at the right spot, after it has successfuly saved the state of the mfc control register. Signed-off-by: Luke Browning <lukebr@linux.vnet.ibm.com> Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/platforms/cell/spu_base.c4
-rw-r--r--arch/powerpc/platforms/cell/spufs/switch.c23
2 files changed, 18 insertions, 9 deletions
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index b9ae675640d0..70c660121ec4 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -141,6 +141,10 @@ static void spu_restart_dma(struct spu *spu)
141 141
142 if (!test_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags)) 142 if (!test_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags))
143 out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESTART_DMA_COMMAND); 143 out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESTART_DMA_COMMAND);
144 else {
145 set_bit(SPU_CONTEXT_FAULT_PENDING, &spu->flags);
146 mb();
147 }
144} 148}
145 149
146static inline void spu_load_slb(struct spu *spu, int slbe, struct spu_slb *slb) 150static inline void spu_load_slb(struct spu *spu, int slbe, struct spu_slb *slb)
diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c
index 47c658051fcb..3df9a36eb2f5 100644
--- a/arch/powerpc/platforms/cell/spufs/switch.c
+++ b/arch/powerpc/platforms/cell/spufs/switch.c
@@ -139,6 +139,7 @@ static inline void disable_interrupts(struct spu_state *csa, struct spu *spu)
139 * via a simple load. 139 * via a simple load.
140 */ 140 */
141 set_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags); 141 set_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags);
142 clear_bit(SPU_CONTEXT_FAULT_PENDING, &spu->flags);
142 synchronize_irq(spu->irqs[0]); 143 synchronize_irq(spu->irqs[0]);
143 synchronize_irq(spu->irqs[1]); 144 synchronize_irq(spu->irqs[1]);
144 synchronize_irq(spu->irqs[2]); 145 synchronize_irq(spu->irqs[2]);
@@ -739,10 +740,14 @@ static inline void set_switch_active(struct spu_state *csa, struct spu *spu)
739 /* Save, Step 48: 740 /* Save, Step 48:
740 * Restore, Step 23. 741 * Restore, Step 23.
741 * Change the software context switch pending flag 742 * Change the software context switch pending flag
742 * to context switch active. 743 * to context switch active. This implementation does
744 * not uses a switch active flag.
743 * 745 *
744 * This implementation does not uses a switch active flag. 746 * Now that we have saved the mfc in the csa, we can add in the
747 * restart command if an exception occurred.
745 */ 748 */
749 if (test_bit(SPU_CONTEXT_FAULT_PENDING, &spu->flags))
750 csa->priv2.mfc_control_RW |= MFC_CNTL_RESTART_DMA_COMMAND;
746 clear_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags); 751 clear_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags);
747 mb(); 752 mb();
748} 753}
@@ -1742,15 +1747,15 @@ static inline void restore_mfc_cntl(struct spu_state *csa, struct spu *spu)
1742 */ 1747 */
1743 out_be64(&priv2->mfc_control_RW, csa->priv2.mfc_control_RW); 1748 out_be64(&priv2->mfc_control_RW, csa->priv2.mfc_control_RW);
1744 eieio(); 1749 eieio();
1750
1745 /* 1751 /*
1746 * FIXME: this is to restart a DMA that we were processing 1752 * The queue is put back into the same state that was evident prior to
1747 * before the save. better remember the fault information 1753 * the context switch. The suspend flag is added to the saved state in
1748 * in the csa instead. 1754 * the csa, if the operational state was suspending or suspended. In
1755 * this case, the code that suspended the mfc is responsible for
1756 * continuing it. Note that SPE faults do not change the operational
1757 * state of the spu.
1749 */ 1758 */
1750 if ((csa->priv2.mfc_control_RW & MFC_CNTL_SUSPEND_DMA_QUEUE_MASK)) {
1751 out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESTART_DMA_COMMAND);
1752 eieio();
1753 }
1754} 1759}
1755 1760
1756static inline void enable_user_access(struct spu_state *csa, struct spu *spu) 1761static inline void enable_user_access(struct spu_state *csa, struct spu *spu)