Skip to content

Commit

Permalink
parisc: Don't disable interrupts in cmpxchg and futex operations
Browse files Browse the repository at this point in the history
I no longer think interrupts can be disabled in the futex and cmpxchg
operations because of COW breaks.  This not ideal but I suspect it's the
best we can do.

For the cmpxchg operations in syscall.S, we rely on the code to not
schedule off the gateway page.  For the futex, I added code to disable
preemption.

So far, I haven't seen the warnings with the attached change but the
change is only lightly tested.

Signed-off-by: Dave Anglin <[email protected]>
Signed-off-by: Helge Deller <[email protected]>
  • Loading branch information
danglin44 authored and hdeller committed Nov 4, 2021
1 parent 014966d commit 7e99271
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 23 deletions.
24 changes: 11 additions & 13 deletions arch/parisc/include/asm/futex.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,35 +11,34 @@
sixteen four-word locks. */

static inline void
_futex_spin_lock_irqsave(u32 __user *uaddr, unsigned long int *flags)
_futex_spin_lock(u32 __user *uaddr)
{
extern u32 lws_lock_start[];
long index = ((long)uaddr & 0x3f8) >> 1;
arch_spinlock_t *s = (arch_spinlock_t *)&lws_lock_start[index];
local_irq_save(*flags);
preempt_disable();
arch_spin_lock(s);
}

static inline void
_futex_spin_unlock_irqrestore(u32 __user *uaddr, unsigned long int *flags)
_futex_spin_unlock(u32 __user *uaddr)
{
extern u32 lws_lock_start[];
long index = ((long)uaddr & 0x3f8) >> 1;
arch_spinlock_t *s = (arch_spinlock_t *)&lws_lock_start[index];
arch_spin_unlock(s);
local_irq_restore(*flags);
preempt_enable();
}

static inline int
arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
{
unsigned long int flags;
int oldval, ret;
u32 tmp;

_futex_spin_lock_irqsave(uaddr, &flags);

ret = -EFAULT;

_futex_spin_lock(uaddr);
if (unlikely(get_user(oldval, uaddr) != 0))
goto out_pagefault_enable;

Expand Down Expand Up @@ -70,7 +69,7 @@ arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
ret = -EFAULT;

out_pagefault_enable:
_futex_spin_unlock_irqrestore(uaddr, &flags);
_futex_spin_unlock(uaddr);

if (!ret)
*oval = oldval;
Expand All @@ -83,7 +82,6 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
u32 oldval, u32 newval)
{
u32 val;
unsigned long flags;

/* futex.c wants to do a cmpxchg_inatomic on kernel NULL, which is
* our gateway page, and causes no end of trouble...
Expand All @@ -100,19 +98,19 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
* address. This should scale to a couple of CPUs.
*/

_futex_spin_lock_irqsave(uaddr, &flags);
_futex_spin_lock(uaddr);
if (unlikely(get_user(val, uaddr) != 0)) {
_futex_spin_unlock_irqrestore(uaddr, &flags);
_futex_spin_unlock(uaddr);
return -EFAULT;
}

if (val == oldval && unlikely(put_user(newval, uaddr) != 0)) {
_futex_spin_unlock_irqrestore(uaddr, &flags);
_futex_spin_unlock(uaddr);
return -EFAULT;
}

*uval = val;
_futex_spin_unlock_irqrestore(uaddr, &flags);
_futex_spin_unlock(uaddr);

return 0;
}
Expand Down
10 changes: 0 additions & 10 deletions arch/parisc/kernel/syscall.S
Original file line number Diff line number Diff line change
Expand Up @@ -597,13 +597,11 @@ cas_nocontend:
# endif
/* ENABLE_LWS_DEBUG */

rsm PSW_SM_I, %r0 /* Disable interrupts */
/* COW breaks can cause contention on UP systems */
LDCW 0(%sr2,%r20), %r28 /* Try to acquire the lock */
cmpb,<>,n %r0, %r28, cas_action /* Did we get it? */
cas_wouldblock:
ldo 2(%r0), %r28 /* 2nd case */
ssm PSW_SM_I, %r0
b lws_exit /* Contended... */
ldo -EAGAIN(%r0), %r21 /* Spin in userspace */

Expand Down Expand Up @@ -639,8 +637,6 @@ cas_action:
/* Clear thread register indicator */
stw %r0, 4(%sr2,%r20)
#endif
/* Enable interrupts */
ssm PSW_SM_I, %r0
/* Return to userspace, set no error */
b lws_exit
copy %r0, %r21
Expand All @@ -652,7 +648,6 @@ cas_action:
#if ENABLE_LWS_DEBUG
stw %r0, 4(%sr2,%r20)
#endif
ssm PSW_SM_I, %r0
b lws_exit
ldo -EFAULT(%r0),%r21 /* set errno */
nop
Expand Down Expand Up @@ -764,13 +759,11 @@ cas2_lock_start:
shlw %r20, 4, %r20
add %r20, %r28, %r20

rsm PSW_SM_I, %r0 /* Disable interrupts */
/* COW breaks can cause contention on UP systems */
LDCW 0(%sr2,%r20), %r28 /* Try to acquire the lock */
cmpb,<>,n %r0, %r28, cas2_action /* Did we get it? */
cas2_wouldblock:
ldo 2(%r0), %r28 /* 2nd case */
ssm PSW_SM_I, %r0
b lws_exit /* Contended... */
ldo -EAGAIN(%r0), %r21 /* Spin in userspace */

Expand Down Expand Up @@ -850,8 +843,6 @@ cas2_action:
cas2_end:
/* Free lock */
stw,ma %r20, 0(%sr2,%r20)
/* Enable interrupts */
ssm PSW_SM_I, %r0
/* Return to userspace, set no error */
b lws_exit
copy %r0, %r21
Expand All @@ -860,7 +851,6 @@ cas2_end:
/* Error occurred on load or store */
/* Free lock */
stw,ma %r20, 0(%sr2,%r20)
ssm PSW_SM_I, %r0
ldo 1(%r0),%r28
b lws_exit
ldo -EFAULT(%r0),%r21 /* set errno */
Expand Down

0 comments on commit 7e99271

Please sign in to comment.