Blackfin: finish_atomic_sections: optimize the RTS step
Mike Frysinger [Thu, 19 Nov 2009 19:15:26 +0000 (19:15 +0000)]
No point in returning to userspace just to have it immediately perform the
RTS step.  We have to update the PC anyways, so do the RTS too.

Signed-off-by: Mike Frysinger <vapier@gentoo.org>

arch/blackfin/kernel/process.c

index a577238..b56b0e4 100644 (file)
@@ -258,9 +258,12 @@ void finish_atomic_sections (struct pt_regs *regs)
        int __user *up0 = (int __user *)regs->p0;
 
        switch (regs->pc) {
+       default:
+               /* not in middle of an atomic step, so resume like normal */
+               return;
+
        case ATOMIC_XCHG32 + 2:
                put_user(regs->r1, up0);
-               regs->pc = ATOMIC_XCHG32 + 4;
                break;
 
        case ATOMIC_CAS32 + 2:
@@ -268,7 +271,6 @@ void finish_atomic_sections (struct pt_regs *regs)
                if (regs->r0 == regs->r1)
        case ATOMIC_CAS32 + 6:
                        put_user(regs->r2, up0);
-               regs->pc = ATOMIC_CAS32 + 8;
                break;
 
        case ATOMIC_ADD32 + 2:
@@ -276,7 +278,6 @@ void finish_atomic_sections (struct pt_regs *regs)
                /* fall through */
        case ATOMIC_ADD32 + 4:
                put_user(regs->r0, up0);
-               regs->pc = ATOMIC_ADD32 + 6;
                break;
 
        case ATOMIC_SUB32 + 2:
@@ -284,7 +285,6 @@ void finish_atomic_sections (struct pt_regs *regs)
                /* fall through */
        case ATOMIC_SUB32 + 4:
                put_user(regs->r0, up0);
-               regs->pc = ATOMIC_SUB32 + 6;
                break;
 
        case ATOMIC_IOR32 + 2:
@@ -292,7 +292,6 @@ void finish_atomic_sections (struct pt_regs *regs)
                /* fall through */
        case ATOMIC_IOR32 + 4:
                put_user(regs->r0, up0);
-               regs->pc = ATOMIC_IOR32 + 6;
                break;
 
        case ATOMIC_AND32 + 2:
@@ -300,7 +299,6 @@ void finish_atomic_sections (struct pt_regs *regs)
                /* fall through */
        case ATOMIC_AND32 + 4:
                put_user(regs->r0, up0);
-               regs->pc = ATOMIC_AND32 + 6;
                break;
 
        case ATOMIC_XOR32 + 2:
@@ -308,9 +306,15 @@ void finish_atomic_sections (struct pt_regs *regs)
                /* fall through */
        case ATOMIC_XOR32 + 4:
                put_user(regs->r0, up0);
-               regs->pc = ATOMIC_XOR32 + 6;
                break;
        }
+
+       /*
+        * We've finished the atomic section, and the only thing left for
+        * userspace is to do a RTS, so we might as well handle that too
+        * since we need to update the PC anyways.
+        */
+       regs->pc = regs->rets;
 }
 
 static inline