linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Peter Oskolkov <posk@posk.io>
To: Tao Zhou <tao.zhou@linux.dev>
Cc: Peter Zijlstra <peterz@infradead.org>,
	Ingo Molnar <mingo@redhat.com>,
	 Thomas Gleixner <tglx@linutronix.de>,
	Andrew Morton <akpm@linux-foundation.org>,
	 Dave Hansen <dave.hansen@linux.intel.com>,
	Andy Lutomirski <luto@kernel.org>,
	linux-mm@kvack.org,
	 Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	linux-api@vger.kernel.org,  Paul Turner <pjt@google.com>,
	Ben Segall <bsegall@google.com>, Peter Oskolkov <posk@google.com>,
	 Andrei Vagin <avagin@google.com>, Jann Horn <jannh@google.com>,
	 Thierry Delisle <tdelisle@uwaterloo.ca>
Subject: Re: [PATCH v0.8 3/6] sched/umcg: implement UMCG syscalls
Date: Sun, 7 Nov 2021 10:26:34 -0800	[thread overview]
Message-ID: <CAFTs51UD_gCFRWe8+14WG3nALQNRdoa322Wcr=RUPbSOpOf6qQ@mail.gmail.com> (raw)
In-Reply-To: <YYa5WjXTrhYKmoze@geo.homenetwork>

On Sat, Nov 6, 2021 at 10:19 AM Tao Zhou <tao.zhou@linux.dev> wrote:
>
> Hi Peter,
>
> On Thu, Nov 04, 2021 at 12:58:01PM -0700, Peter Oskolkov wrote:
>
> > +/**
> > + * umcg_update_state: atomically update umcg_task.state_ts, set new timestamp.
> > + * @state_ts   - points to the state_ts member of struct umcg_task to update;
> > + * @expected   - the expected value of state_ts, including the timestamp;
> > + * @desired    - the desired value of state_ts, state part only;
> > + * @may_fault  - whether to use normal or _nofault cmpxchg.
> > + *
> > + * The function is basically cmpxchg(state_ts, expected, desired), with extra
> > + * code to set the timestamp in @desired.
> > + */
> > +static int umcg_update_state(u64 __user *state_ts, u64 *expected, u64 desired,
> > +                             bool may_fault)
> > +{
> > +     u64 curr_ts = (*expected) >> (64 - UMCG_STATE_TIMESTAMP_BITS);
> > +     u64 next_ts = ktime_get_ns() >> UMCG_STATE_TIMESTAMP_GRANULARITY;
> > +
> > +     /* Cut higher order bits. */
> > +     next_ts &= UMCG_TASK_STATE_MASK_FULL;
>
> next_ts &= (1 << UMCG_STATE_TIMESTAMP_BITS) - 1; or am I wrong.

Right, thanks. I'll fix it in the next patchset version, if any. But
at the moment I don't think this is bad enough to prevent merging, if
the maintainers feel like it - basically, the condition below will
always be false, so if the state is updated within 16 nanoseconds, the
timestamps may sometimes match. For this to be an issue, this should
result in ABA updates, so two state changes should happen in 16
nanoseconds, which is extremely unlikely (impossible?), as most state
changes are accompanied by other atomic ops.

>
> > +     if (next_ts == curr_ts)
> > +             ++next_ts;
> > +
> > +     /* Remove an old timestamp, if any. */
> > +     desired &= UMCG_TASK_STATE_MASK_FULL;
> > +
> > +     /* Set the new timestamp. */
> > +     desired |= (next_ts << (64 - UMCG_STATE_TIMESTAMP_BITS));
> > +
> > +     if (may_fault)
> > +             return cmpxchg_user_64(state_ts, expected, desired);
> > +
> > +     return cmpxchg_user_64_nofault(state_ts, expected, desired);
> > +}
> > +
> > +/**
> > + * sys_umcg_ctl: (un)register the current task as a UMCG task.
> > + * @flags:       ORed values from enum umcg_ctl_flag; see below;
> > + * @self:        a pointer to struct umcg_task that describes this
> > + *               task and governs the behavior of sys_umcg_wait if
> > + *               registering; must be NULL if unregistering.
> > + *
> > + * @flags & UMCG_CTL_REGISTER: register a UMCG task:
> > + *         UMCG workers:
> > + *              - @flags & UMCG_CTL_WORKER
> > + *              - self->state must be UMCG_TASK_BLOCKED
> > + *         UMCG servers:
> > + *              - !(@flags & UMCG_CTL_WORKER)
> > + *              - self->state must be UMCG_TASK_RUNNING
> > + *
> > + *         All tasks:
> > + *              - self->next_tid must be zero
> > + *
> > + *         If the conditions above are met, sys_umcg_ctl() immediately returns
> > + *         if the registered task is a server; a worker will be added to
> > + *         idle_workers_ptr, and the worker put to sleep; an idle server
> > + *         from idle_server_tid_ptr will be woken, if present.
> > + *
> > + * @flags == UMCG_CTL_UNREGISTER: unregister a UMCG task. If the current task
> > + *           is a UMCG worker, the userspace is responsible for waking its
> > + *           server (before or after calling sys_umcg_ctl).
> > + *
> > + * Return:
> > + * 0                - success
> > + * -EFAULT          - failed to read @self
> > + * -EINVAL          - some other error occurred
> > + */
> > +SYSCALL_DEFINE2(umcg_ctl, u32, flags, struct umcg_task __user *, self)
> > +{
> > +     struct umcg_task ut;
> > +
> > +     if (flags == UMCG_CTL_UNREGISTER) {
> > +             if (self || !current->umcg_task)
> > +                     return -EINVAL;
> > +
> > +             if (current->flags & PF_UMCG_WORKER)
> > +                     umcg_handle_exiting_worker();
> > +             else
> > +                     umcg_clear_task(current);
> > +
> > +             return 0;
> > +     }
> > +
> > +     if (!(flags & UMCG_CTL_REGISTER))
> > +             return -EINVAL;
> > +
> > +     flags &= ~UMCG_CTL_REGISTER;
> > +     if (flags && flags != UMCG_CTL_WORKER)
> > +             return -EINVAL;
> > +
> > +     if (current->umcg_task || !self)
> > +             return -EINVAL;
> > +
> > +     if (copy_from_user(&ut, self, sizeof(ut)))
> > +             return -EFAULT;
> > +
> > +     if (ut.next_tid)
> > +             return -EINVAL;
> > +
> > +     if (flags == UMCG_CTL_WORKER) {
> > +             if ((ut.state_ts & UMCG_TASK_STATE_MASK_FULL) != UMCG_TASK_BLOCKED)
>
> Or use UMCG_TASK_STATE_MASK that is enough.

Do you have a use case for this (i.e. when state flags can be
legitimately set here)? At the moment I can't think of it, and I'd
rather keep things more strict to avoid dealing with unexpected use
cases in the future.

>
> > +                     return -EINVAL;
> > +
> > +             WRITE_ONCE(current->umcg_task, self);
> > +             current->flags |= PF_UMCG_WORKER;
> > +
> > +             /* Trigger umcg_handle_resuming_worker() */
> > +             set_tsk_thread_flag(current, TIF_NOTIFY_RESUME);
> > +     } else {
> > +             if ((ut.state_ts & UMCG_TASK_STATE_MASK_FULL) != UMCG_TASK_RUNNING)
>
> The same here.

Yes, the same here - why do you think task state flags should be allowed here?


>
> > +                     return -EINVAL;
> > +
> > +             WRITE_ONCE(current->umcg_task, self);
> > +     }
> > +
> > +     return 0;
> > +}
> > +
>
>
> Thanks,
> Tao


  reply	other threads:[~2021-11-07 18:26 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-04 19:57 [PATCH v0.8 0/6] sched,mm,x86/uaccess: implement User Managed Concurrency Groups Peter Oskolkov
2021-11-04 19:57 ` [PATCH v0.8 1/6] sched/umcg: add WF_CURRENT_CPU and externise ttwu Peter Oskolkov
2021-11-04 19:58 ` [PATCH v0.8 2/6] mm, x86/uaccess: add userspace atomic helpers Peter Oskolkov
2021-11-05  6:10   ` kernel test robot
2021-11-09  4:18   ` Tao Zhou
2021-11-04 19:58 ` [PATCH v0.8 3/6] sched/umcg: implement UMCG syscalls Peter Oskolkov
2021-11-05 12:55   ` kernel test robot
2021-11-05 23:48   ` Thierry Delisle
2021-11-08  4:09     ` Peter Oskolkov
2021-11-06 17:20   ` Tao Zhou
2021-11-07 18:26     ` Peter Oskolkov [this message]
2021-11-08  6:57       ` Tao Zhou
2021-11-15 20:11   ` kernel test robot
2021-11-21 21:08     ` Peter Oskolkov
2021-11-04 19:58 ` [PATCH v0.8 4/6] sched/umcg, lib/umcg: implement libumcg Peter Oskolkov
2021-11-07 16:34   ` Tao Zhou
2021-11-07 18:27     ` Peter Oskolkov
2021-11-08  7:12       ` Tao Zhou
2021-11-04 19:58 ` [PATCH v0.8 5/6] sched/umcg: add Documentation/userspace-api/umcg.txt Peter Oskolkov
2021-11-04 19:58 ` [PATCH v0.8 6/6] sched/umcg, lib/umcg: add tools/lib/umcg/libumcg.txt Peter Oskolkov
2021-11-09  8:55 ` [PATCH v0.8 0/6] sched,mm,x86/uaccess: implement User Managed Concurrency Groups Barry Song
2021-11-09 16:31   ` Peter Oskolkov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAFTs51UD_gCFRWe8+14WG3nALQNRdoa322Wcr=RUPbSOpOf6qQ@mail.gmail.com' \
    --to=posk@posk.io \
    --cc=akpm@linux-foundation.org \
    --cc=avagin@google.com \
    --cc=bsegall@google.com \
    --cc=dave.hansen@linux.intel.com \
    --cc=jannh@google.com \
    --cc=linux-api@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=luto@kernel.org \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=pjt@google.com \
    --cc=posk@google.com \
    --cc=tao.zhou@linux.dev \
    --cc=tdelisle@uwaterloo.ca \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox