From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
To: Peter Zijlstra <peterz@infradead.org>
Cc: linux-kernel@vger.kernel.org, Aaron Lu <aaron.lu@intel.com>
Subject: Re: [RFC PATCH v3] sched: Fix performance regression introduced by mm_cid
Date: Wed, 5 Apr 2023 16:37:42 -0400 [thread overview]
Message-ID: <386a6e32-a746-9eb1-d5ae-e5bedaa8fc75@efficios.com> (raw)
In-Reply-To: <20230405162635.225245-1-mathieu.desnoyers@efficios.com>
On 2023-04-05 12:26, Mathieu Desnoyers wrote:
[...]
> #ifdef CONFIG_SCHED_MM_CID
> +/*
> + * Migration from src cpu. Called from set_task_cpu(). There are no guarantees
> + * that the rq lock is held.
> + */
> +void sched_mm_cid_migrate_from(struct task_struct *t)
> +{
> + int src_cid, *src_pcpu_cid, last_mm_cid;
> + struct mm_struct *mm = t->mm;
> + struct rq *src_rq;
> + struct task_struct *src_task;
> +
> + if (!mm)
> + return;
> +
> + last_mm_cid = t->last_mm_cid;
> + /*
> + * If the migrated task has no last cid, or if the current
> + * task on src rq uses the cid, it means the destination cpu
> + * does not have to reallocate its cid to keep the cid allocation
> + * compact.
> + */
> + if (last_mm_cid == -1)
> + return;
> +
> + src_rq = task_rq(t);
> + src_pcpu_cid = per_cpu_ptr(mm->pcpu_cid, cpu_of(src_rq));
> + src_cid = READ_ONCE(*src_pcpu_cid);
> +
> + if (!mm_cid_is_valid(src_cid) || last_mm_cid != src_cid)
> + return;
> +
> + /*
> + * If we observe an active task using the mm on this rq, it means we
> + * are not the last task to be migrated from this cpu for this mm, so
> + * there is no need to clear the src_cid.
> + */
> + rcu_read_lock();
> + src_task = rcu_dereference(src_rq->curr);
> + if (src_task->mm_cid_active && src_task->mm == mm) {
> + rcu_read_unlock();
> + t->last_mm_cid = -1;
> + return;
> + }
> + rcu_read_unlock();
> +
> + /*
> + * If the source cpu cid is set, and matches the last cid of the
> + * migrated task, clear the source cpu cid to keep cid allocation
> + * compact to cover the case where this task is the last task using
> + * this mm on the source cpu. If there happens to be other tasks left
> + * on the source cpu using this mm, the next task using this mm will
> + * reallocate its cid on context switch.
> + *
> + * We cannot keep ownership of concurrency ID without runqueue
> + * lock held when it is not used by a current task, because it
> + * would lead to allocation of more concurrency ids than there
> + * are possible cpus in the system. The last_mm_cid is used as
> + * a hint to conditionally unset the dst cpu cid, keeping
> + * allocated concurrency ids compact.
> + */
> + if (cmpxchg(src_pcpu_cid, src_cid, mm_cid_set_lazy_put(src_cid)) != src_cid)
> + return;
> +
> + /*
> + * The implicit barrier after cmpxchg per-mm/cpu cid before loading
> + * rq->curr->mm matches the scheduler barrier in context_switch()
> + * between store to rq->curr and load of prev and next task's
> + * per-mm/cpu cid.
Thinking about it further, I suspect the transition:
* user -> kernel lazy + mmgrab() active
in context_switch() lacks a memory barrier we need here (it's only an
atomic_inc with mmgrab()).
The scenario is a transition from user to kernel thread happening
concurrently with migrate-from.
Because there is no memory barrier between set rq->curr to a value that
has a NULL mm and loading per-mm/cpu cid value in mm_cid_put_lazy() for
the prev task, nothing guarantees that the following src_rq->curr rcu
dereference here will observe the store.
Or am I missing something ?
Thanks,
Mathieu
> + *
> + * The implicit barrier after cmpxchg per-mm/cpu cid before loading
> + * rq->curr->mm_cid_active matches the barrier in
> + * sched_mm_cid_exit_signals(), sched_mm_cid_before_execve(), and
> + * sched_mm_cid_after_execve() between store to t->mm_cid_active and
> + * load of per-mm/cpu cid.
> + */
> +
> + /*
> + * If we observe an active task using the mm on this rq after setting the lazy-put
> + * flag, this task will be responsible for transitioning from lazy-put
> + * flag set to MM_CID_UNSET.
> + */
> + rcu_read_lock();
> + src_task = rcu_dereference(src_rq->curr);
> + if (src_task->mm_cid_active && src_task->mm == mm) {
> + rcu_read_unlock();
> + /*
> + * We observed an active task for this mm, clearing the destination
> + * cpu mm_cid is not relevant for compactness.
> + */
> + t->last_mm_cid = -1;
> + return;
> + }
> + rcu_read_unlock();
> +
> + /*
> + * The src_cid is unused, so it can be unset.
> + */
> + if (cmpxchg(src_pcpu_cid, mm_cid_set_lazy_put(src_cid), MM_CID_UNSET) != mm_cid_set_lazy_put(src_cid))
> + return;
> + __mm_cid_put(mm, src_cid);
> +}
--
Mathieu Desnoyers
EfficiOS Inc.
https://www.efficios.com
next prev parent reply other threads:[~2023-04-05 20:37 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-04-05 16:26 [RFC PATCH v3] sched: Fix performance regression introduced by mm_cid Mathieu Desnoyers
2023-04-05 20:37 ` Mathieu Desnoyers [this message]
2023-04-06 9:51 ` Peter Zijlstra
2023-04-07 23:50 ` Mathieu Desnoyers
2023-04-08 1:14 ` Mathieu Desnoyers
2023-04-11 9:37 ` Peter Zijlstra
2023-04-11 10:25 ` Peter Zijlstra
2023-04-11 13:10 ` Mathieu Desnoyers
2023-04-11 12:57 ` Mathieu Desnoyers
2023-04-11 11:03 ` Peter Zijlstra
2023-04-11 11:53 ` Peter Zijlstra
2023-04-11 8:46 ` Peter Zijlstra
2023-04-11 12:38 ` Mathieu Desnoyers
2023-04-11 8:53 ` Peter Zijlstra
2023-04-11 12:41 ` Mathieu Desnoyers
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=386a6e32-a746-9eb1-d5ae-e5bedaa8fc75@efficios.com \
--to=mathieu.desnoyers@efficios.com \
--cc=aaron.lu@intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=peterz@infradead.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.