lkml.org 
[lkml]   [2017]   [Nov]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: [RFC PATCH for 4.15 v3 15/22] rseq: selftests: Provide self-tests
On Tue, Nov 21, 2017 at 09:18:53AM -0500, Mathieu Desnoyers wrote:
> +int percpu_list_push(struct percpu_list *list, struct percpu_list_node *node)
> +{
> + intptr_t *targetptr, newval, expect;
> + int cpu, ret;
> +
> + /* Try fast path. */
> + cpu = rseq_cpu_start();

> + /* Load list->c[cpu].head with single-copy atomicity. */
> + expect = (intptr_t)READ_ONCE(list->c[cpu].head);
> + newval = (intptr_t)node;
> + targetptr = (intptr_t *)&list->c[cpu].head;
> + node->next = (struct percpu_list_node *)expect;

> + ret = rseq_cmpeqv_storev(targetptr, expect, newval, cpu);

> + if (likely(!ret))
> + return cpu;

> + return cpu;
> +}

> +static inline __attribute__((always_inline))
> +int rseq_cmpeqv_storev(intptr_t *v, intptr_t expect, intptr_t newv,
> + int cpu)
> +{
> + __asm__ __volatile__ goto (
> + RSEQ_ASM_DEFINE_TABLE(3, __rseq_table, 0x0, 0x0, 1f, 2f-1f, 4f)
> + RSEQ_ASM_STORE_RSEQ_CS(1, 3b, rseq_cs)

> + RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)

So the actual C part of the RSEQ is subject to an ABA, right? We can get
migrated to another CPU and back again without then failing here.

It used to be that this was caught by the sequence count, but that is
now gone.

The thing that makes it work is the compare against @v:

> + "cmpq %[v], %[expect]\n\t"
> + "jnz 5f\n\t"

That then ensures things are still as we observed them before (although
this itself is also subject to ABA).

This means all RSEQ primitives that have a C part must have a cmp-and-
form, but I suppose that was already pretty much the case anyway. I just
don't remember seeing that spelled out anywhere. Then again, I've not
yet read that manpage.

> + /* final store */
> + "movq %[newv], %[v]\n\t"
> + "2:\n\t"
> + RSEQ_ASM_DEFINE_ABORT(4, __rseq_failure, RSEQ_SIG, "", abort)
> + RSEQ_ASM_DEFINE_CMPFAIL(5, __rseq_failure, "", cmpfail)
> + : /* gcc asm goto does not allow outputs */
> + : [cpu_id]"r"(cpu),
> + [current_cpu_id]"m"(__rseq_abi.cpu_id),
> + [rseq_cs]"m"(__rseq_abi.rseq_cs),
> + [v]"m"(*v),
> + [expect]"r"(expect),
> + [newv]"r"(newv)
> + : "memory", "cc", "rax"
> + : abort, cmpfail
> + );
> + return 0;
> +abort:
> + return -1;
> +cmpfail:
> + return 1;
> +}

\
 
 \ /
  Last update: 2017-11-23 09:56    [W:0.237 / U:3.536 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site