Hi Mikael,
On Fri, Mar 8, 2013 at 3:03 PM, Mikael Pettersson <[email protected]> wrote:
> Linux/M68K currently doesn't support robust futexes or PI mutexes.
> The problem is that the futex code needs to perform certain ops
> (cmpxchg, set, add, or, andn, xor) atomically on user-space
> addresses, and M68K's lack of a futex.h causes those operations
> to be unsupported and disabled.
>
> This patch adds that support, but only for uniprocessor machines,
> which is adequate for M68K. For UP it's enough to disable preemption
> to ensure mutual exclusion (futexes don't need to care about other
> hardware agents), and the mandatory pagefault_disable() does just that.
>
> This patch is closely based on the one I co-wrote for UP ARM back
> in August 2008. The main change is that this patch uses the C
> get_user/put_user accessors instead of inline assembly code with
> exception table fixups.
>
> For non-MMU machines the new futex.h simply redirects to the generic
> futex.h, so there is no functional change for them.
>
> Tested on aranym with the glibc-2.17 test suite: no regressions, and
> a number of mutex/condvar test cases went from failing to succeeding
> (tst-mutexpi{5,5a,6,9}, tst-cond2[45], tst-robust[1-9], tst-robustpi[1-8]).
> Also tested with glibc-2.18 HEAD and a local glibc patch to enable PI
> mutexes: no regressions.
I'm a bit puzzled by this, so see my questions below...
> --- linux-3.8/arch/m68k/include/asm/futex.h.~1~ 1970-01-01 01:00:00.000000000
> +0100
> +++ linux-3.8/arch/m68k/include/asm/futex.h 2013-02-20 22:07:23.459917612
> +0100
> @@ -0,0 +1,94 @@
> +#ifndef _ASM_M68K_FUTEX_H
> +#define _ASM_M68K_FUTEX_H
> +
> +#ifdef __KERNEL__
> +#if !defined(CONFIG_MMU)
> +#include <asm-generic/futex.h>
> +#else /* CONFIG_MMU */
Why would you not use the version below on nommu?
It doesn't seem to have any real dependencies on MMU support?
What am I missing?
> +#include <linux/futex.h>
> +#include <linux/uaccess.h>
> +#include <asm/errno.h>
> +
> +static inline int
> +futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
> + u32 oldval, u32 newval)
> +{
> + u32 val;
> +
> + if (unlikely(get_user(val, uaddr) != 0))
> + return -EFAULT;
> +
> + if (val == oldval && unlikely(put_user(newval, uaddr) != 0))
> + return -EFAULT;
> +
> + *uval = val;
> +
> + return 0;
> +}
This is purely generic, so it could move to the asm-generic version,
also fixing blackfin, c6x, metag, openrisc, um, unicore32, and xtensa?
> +static inline int
> +futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
> +{
> + int op = (encoded_op >> 28) & 7;
> + int cmp = (encoded_op >> 24) & 15;
> + int oparg = (encoded_op << 8) >> 20;
> + int cmparg = (encoded_op << 20) >> 20;
> + int oldval, ret;
> + u32 tmp;
> +
> + if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
> + oparg = 1 << oparg;
> +
> + pagefault_disable(); /* implies preempt_disable() */
> +
> + ret = -EFAULT;
> + if (unlikely(get_user(oldval, uaddr) != 0))
> + goto out_pagefault_enable;
> +
> + ret = 0;
> + tmp = oldval;
> +
> + switch (op) {
> + case FUTEX_OP_SET:
> + tmp = oparg;
> + break;
> + case FUTEX_OP_ADD:
> + tmp += oparg;
> + break;
> + case FUTEX_OP_OR:
> + tmp |= oparg;
> + break;
> + case FUTEX_OP_ANDN:
> + tmp &= ~oparg;
> + break;
> + case FUTEX_OP_XOR:
> + tmp ^= oparg;
> + break;
> + default:
> + ret = -ENOSYS;
> + }
> +
> + if (ret == 0 && unlikely(put_user(tmp, uaddr) != 0))
> + ret = -EFAULT;
> +
> +out_pagefault_enable:
> + pagefault_enable(); /* subsumes preempt_enable() */
> +
> + if (ret == 0) {
> + switch (cmp) {
> + case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;
> + case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;
> + case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;
> + case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;
> + case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;
> + case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;
> + default: ret = -ENOSYS;
> + }
> + }
> + return ret;
> +}
This is also purely generic?
Do you know why the current version in asm-generic doesn't do the
{get,put}_user()?
Thanks for your answers!
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
--
To unsubscribe from this list: send the line "unsubscribe linux-m68k" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html