From: Vineeth Pillai <viremana@linux.microsoft.com>
To: Peter Zijlstra <peterz@infradead.org>,
Julien Desfossez <jdesfossez@digitalocean.com>
Cc: Joel Fernandes <joelaf@google.com>,
Tim Chen <tim.c.chen@linux.intel.com>,
Aaron Lu <aaron.lwe@gmail.com>,
Aubrey Li <aubrey.intel@gmail.com>,
Dhaval Giani <dhaval.giani@oracle.com>,
Chris Hyser <chris.hyser@oracle.com>,
Nishanth Aravamudan <naravamudan@digitalocean.com>,
mingo@kernel.org, tglx@linutronix.de, pjt@google.com,
torvalds@linux-foundation.org, linux-kernel@vger.kernel.org,
fweisbec@gmail.com, keescook@chromium.org, kerrnel@google.com,
Phil Auld <pauld@redhat.com>,
Valentin Schneider <valentin.schneider@arm.com>,
Mel Gorman <mgorman@techsingularity.net>,
Pawan Gupta <pawan.kumar.gupta@linux.intel.com>,
Paolo Bonzini <pbonzini@redhat.com>,
joel@joelfernandes.org, vineeth@bitbyteword.org,
Chen Yu <yu.c.chen@intel.com>,
Christian Brauner <christian.brauner@ubuntu.com>,
Agata Gruza <agata.gruza@intel.com>,
Antonio Gomez Iglesias <antonio.gomez.iglesias@intel.com>,
graf@amazon.com, konrad.wilk@oracle.com, dfaggioli@suse.com,
rostedt@goodmis.org, derkling@google.com, benbjiang@tencent.com,
Aaron Lu <ziqian.lzq@antfin.com>
Subject: Re: [RFC PATCH v7 11/23] sched/fair: core wide cfs task priority comparison
Date: Thu, 17 Sep 2020 10:15:31 -0400 [thread overview]
Message-ID: <8b9f28f2-7f21-b7da-1056-732b6227ea25@linux.microsoft.com> (raw)
In-Reply-To: <20200828212927.GE29142@worktop.programming.kicks-ass.net>
Hi Peter,
On 8/28/20 5:29 PM, Peter Zijlstra wrote:
>
> This is still a horrible patch..
I was working on your idea of using the lag as a tool to compare vruntime
across cpus:
https://lwn.net/ml/linux-kernel/20200506143506.GH5298@hirez.programming.kicks-ass.net/
https://lwn.net/ml/linux-kernel/20200514130248.GD2940@hirez.programming.kicks-ass.net/
Basically, I record the clock time when a sibling is force idled. And before
comparison, if the sibling is still force idled, take the weighted delta
of time
the sibling was force idled and then decrement it from the vruntime. The
lag is computed in pick_task_fair as we do cross-cpu comparison only after
a task_pick.
I think this can solve the SMTn issues since we are doing a one-sided
comaprison.
I have done some initial testing and looks good. Need to do some deep
analysis
and check the fairness cases. Thought of sharing the prototype and get
feedback
as I am doing further testing. Please have a look and let me know your
thoughts.
The git tree is here:
https://github.com/vineethrp/linux/tree/coresched/pre-v8-v5.9-rc-lagfix
It has the review comments addressed since v8 was posted.
Thanks,
Vineeth
---
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index cea9a63c2e7a..52b3e7b356e9 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -136,19 +136,8 @@ static inline bool prio_less(struct task_struct *a,
struct task_struct *b)
if (pa == -1) /* dl_prio() doesn't work because of stop_class
above */
return !dl_time_before(a->dl.deadline, b->dl.deadline);
- if (pa == MAX_RT_PRIO + MAX_NICE) { /* fair */
- u64 vruntime = b->se.vruntime;
-
- /*
- * Normalize the vruntime if tasks are in different cpus.
- */
- if (task_cpu(a) != task_cpu(b)) {
- vruntime -= task_cfs_rq(b)->min_vruntime;
- vruntime += task_cfs_rq(a)->min_vruntime;
- }
-
- return !((s64)(a->se.vruntime - vruntime) <= 0);
- }
+ if (pa == MAX_RT_PRIO + MAX_NICE) /* fair */
+ return cfs_prio_less(a, b);
return false;
}
@@ -235,6 +224,13 @@ static void sched_core_dequeue(struct rq *rq,
struct task_struct *p)
rb_erase(&p->core_node, &rq->core_tree);
RB_CLEAR_NODE(&p->core_node);
+
+ /*
+ * Reset last force idle time if this rq will be
+ * empty after this dequeue.
+ */
+ if (rq->nr_running == 1)
+ rq->core_fi_time = 0;
}
/*
@@ -310,8 +306,10 @@ static int __sched_core_stopper(void *data)
* cgroup tags. However, dying tasks could still be
* left in core queue. Flush them here.
*/
- if (!enabled)
+ if (!enabled) {
sched_core_flush(cpu);
+ rq->core_fi_time = 0;
+ }
rq->core_enabled = enabled;
}
@@ -5181,9 +5179,17 @@ next_class:;
if (!rq_i->core_pick)
continue;
- if (is_task_rq_idle(rq_i->core_pick) && rq_i->nr_running &&
- !rq_i->core->core_forceidle) {
- rq_i->core->core_forceidle = true;
+ if (is_task_rq_idle(rq_i->core_pick) && rq_i->nr_running) {
+
+ if (!rq_i->core->core_forceidle)
+ rq_i->core->core_forceidle = true;
+
+ /*
+ * XXX: Should we record force idled time a bit
later on the
+ * pick_next_task of this sibling when it forces
itself idle?
+ */
+ rq_i->core_fi_time = rq_clock_task(rq_i);
+ trace_printk("force idle(cpu=%d) TS=%llu\n", i,
rq_i->core_fi_time);
}
rq_i->core_pick->core_occupation = occ;
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index eadc62930336..7f62a50e23e1 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -389,6 +389,12 @@ static inline struct sched_entity
*parent_entity(struct sched_entity *se)
return se->parent;
}
+static inline bool
+is_same_tg(struct sched_entity *se, struct sched_entity *pse)
+{
+ return se->cfs_rq->tg == pse->cfs_rq->tg;
+}
+
static void
find_matching_se(struct sched_entity **se, struct sched_entity **pse)
{
@@ -453,6 +459,12 @@ static inline struct sched_entity
*parent_entity(struct sched_entity *se)
return NULL;
}
+static inline bool
+is_same_tg(struct sched_entity *se, struct sched_entity *pse)
+{
+ return true;
+}
+
static inline void
find_matching_se(struct sched_entity **se, struct sched_entity **pse)
{
@@ -6962,13 +6974,26 @@ static struct task_struct *pick_task_fair(struct
rq *rq)
{
struct cfs_rq *cfs_rq = &rq->cfs;
struct sched_entity *se;
+ u64 lag = 0;
if (!cfs_rq->nr_running)
return NULL;
+ /*
+ * Calculate the lag caused due to force idle on this
+ * sibling. Since we do cross-cpu comparison of vruntime
+ * only after a task pick, it should be safe to compute
+ * the lag here.
+ */
+ if (rq->core_fi_time) {
+ lag = rq_clock_task(rq) - rq->core_fi_time;
+ if ((s64)lag < 0)
+ lag = 0;
+ }
do {
struct sched_entity *curr = cfs_rq->curr;
+
se = pick_next_entity(cfs_rq, NULL);
if (curr) {
@@ -6977,11 +7002,15 @@ static struct task_struct *pick_task_fair(struct
rq *rq)
if (!se || entity_before(curr, se))
se = curr;
+
+ cfs_rq->core_lag += lag;
}
cfs_rq = group_cfs_rq(se);
} while (cfs_rq);
+ rq->core_fi_time = 0;
+
return task_of(se);
}
#endif
@@ -10707,6 +10736,41 @@ static inline void task_tick_core(struct rq
*rq, struct task_struct *curr)
__entity_slice_used(&curr->se))
resched_curr(rq);
}
+
+bool cfs_prio_less(struct task_struct *a, struct task_struct *b)
+{
+ struct sched_entity *se_a = &a->se, *se_b = &b->se;
+ struct cfs_rq *cfs_rq_a, *cfs_rq_b;
+ u64 vruntime_a, vruntime_b;
+
+#ifdef CONFIG_FAIR_GROUP_SCHED
+ while (!is_same_tg(se_a, se_b)) {
+ int se_a_depth = se_a->depth;
+ int se_b_depth = se_b->depth;
+
+ if (se_a_depth <= se_b_depth)
+ se_b = parent_entity(se_b);
+ if (se_a_depth >= se_b_depth)
+ se_a = parent_entity(se_a);
+ }
+#endif
+
+ cfs_rq_a = cfs_rq_of(se_a);
+ cfs_rq_b = cfs_rq_of(se_b);
+
+ vruntime_a = se_a->vruntime - cfs_rq_a->min_vruntime;
+ vruntime_b = se_b->vruntime - cfs_rq_b->min_vruntime;
+
+ trace_printk("(%s/%d;%Ld,%Lu) ?< (%s/%d;%Ld,%Lu)\n",
+ a->comm, a->pid, vruntime_a, cfs_rq_a->core_lag,
+ b->comm, b->pid, vruntime_b, cfs_rq_b->core_lag);
+ if (cfs_rq_a != cfs_rq_b) {
+ vruntime_a -= calc_delta_fair(cfs_rq_a->core_lag, &a->se);
+ vruntime_b -= calc_delta_fair(cfs_rq_b->core_lag, &b->se);
+ }
+
+ return !((s64)(vruntime_a - vruntime_b) <= 0);
+}
#else
static inline void task_tick_core(struct rq *rq, struct task_struct
*curr) {}
#endif
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index 5374ace195b9..a1c15edf8dd5 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -607,6 +607,10 @@ struct cfs_rq {
struct list_head throttled_list;
#endif /* CONFIG_CFS_BANDWIDTH */
#endif /* CONFIG_FAIR_GROUP_SCHED */
+
+#ifdef CONFIG_SCHED_CORE
+ u64 core_lag;
+#endif
};
static inline int rt_bandwidth_enabled(void)
@@ -1056,6 +1060,7 @@ struct rq {
#ifdef CONFIG_SCHED_CORE
/* per rq */
struct rq *core;
+ u64 core_fi_time; /* Last forced idle TS */
struct task_struct *core_pick;
unsigned int core_enabled;
unsigned int core_sched_seq;
vineeth@vinstation340u:~/WS/kernel_test/linux-qemu/out$ git show > log
vineeth@vinstation340u:~/WS/kernel_test/linux-qemu/out$ cat log
commit e97ec4d317ac01cabbcdcb1ac8a315a02b3e39f6
Author: Vineeth Pillai <viremana@linux.microsoft.com>
Date: Wed Sep 16 11:35:37 2020 -0400
sched/coresched: lag based cross cpu vruntime comparison
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index cea9a63c2e7a..52b3e7b356e9 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -136,19 +136,8 @@ static inline bool prio_less(struct task_struct *a,
struct task_struct *b)
if (pa == -1) /* dl_prio() doesn't work because of stop_class above */
return !dl_time_before(a->dl.deadline, b->dl.deadline);
- if (pa == MAX_RT_PRIO + MAX_NICE) { /* fair */
- u64 vruntime = b->se.vruntime;
-
- /*
- * Normalize the vruntime if tasks are in different cpus.
- */
- if (task_cpu(a) != task_cpu(b)) {
- vruntime -= task_cfs_rq(b)->min_vruntime;
- vruntime += task_cfs_rq(a)->min_vruntime;
- }
-
- return !((s64)(a->se.vruntime - vruntime) <= 0);
- }
+ if (pa == MAX_RT_PRIO + MAX_NICE) /* fair */
+ return cfs_prio_less(a, b);
return false;
}
@@ -235,6 +224,13 @@ static void sched_core_dequeue(struct rq *rq,
struct task_struct *p)
rb_erase(&p->core_node, &rq->core_tree);
RB_CLEAR_NODE(&p->core_node);
+
+ /*
+ * Reset last force idle time if this rq will be
+ * empty after this dequeue.
+ */
+ if (rq->nr_running == 1)
+ rq->core_fi_time = 0;
}
/*
@@ -310,8 +306,10 @@ static int __sched_core_stopper(void *data)
* cgroup tags. However, dying tasks could still be
* left in core queue. Flush them here.
*/
- if (!enabled)
+ if (!enabled) {
sched_core_flush(cpu);
+ rq->core_fi_time = 0;
+ /* XXX Reset cfs_rq->core_lag? */
+ }
rq->core_enabled = enabled;
}
@@ -5181,9 +5179,17 @@ next_class:;
if (!rq_i->core_pick)
continue;
- if (is_task_rq_idle(rq_i->core_pick) && rq_i->nr_running &&
- !rq_i->core->core_forceidle) {
- rq_i->core->core_forceidle = true;
+ if (is_task_rq_idle(rq_i->core_pick) && rq_i->nr_running) {
+
+ if (!rq_i->core->core_forceidle)
+ rq_i->core->core_forceidle = true;
+
+ /*
+ * XXX: Should we record force idled time a bit later on the
+ * pick_next_task of this sibling when it forces itself idle?
+ */
+ rq_i->core_fi_time = rq_clock_task(rq_i);
+ trace_printk("force idle(cpu=%d) TS=%llu\n", i,
rq_i->core_fi_time);
}
rq_i->core_pick->core_occupation = occ;
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index eadc62930336..7f62a50e23e1 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -389,6 +389,12 @@ static inline struct sched_entity
*parent_entity(struct sched_entity *se)
return se->parent;
}
+static inline bool
+is_same_tg(struct sched_entity *se, struct sched_entity *pse)
+{
+ return se->cfs_rq->tg == pse->cfs_rq->tg;
+}
+
static void
find_matching_se(struct sched_entity **se, struct sched_entity **pse)
{
@@ -453,6 +459,12 @@ static inline struct sched_entity
*parent_entity(struct sched_entity *se)
return NULL;
}
+static inline bool
+is_same_tg(struct sched_entity *se, struct sched_entity *pse)
+{
+ return true;
+}
+
static inline void
find_matching_se(struct sched_entity **se, struct sched_entity **pse)
{
@@ -6962,13 +6974,26 @@ static struct task_struct *pick_task_fair(struct
rq *rq)
{
struct cfs_rq *cfs_rq = &rq->cfs;
struct sched_entity *se;
+ u64 lag = 0;
if (!cfs_rq->nr_running)
return NULL;
+ /*
+ * Calculate the lag caused due to force idle on this
+ * sibling. Since we do cross-cpu comparison of vruntime
+ * only after a task pick, it should be safe to compute
+ * the lag here.
+ */
+ if (rq->core_fi_time) {
+ lag = rq_clock_task(rq) - rq->core_fi_time;
+ if ((s64)lag < 0)
+ lag = 0;
+ }
do {
struct sched_entity *curr = cfs_rq->curr;
+
se = pick_next_entity(cfs_rq, NULL);
if (curr) {
@@ -6977,11 +7002,15 @@ static struct task_struct *pick_task_fair(struct
rq *rq)
if (!se || entity_before(curr, se))
se = curr;
+
+ cfs_rq->core_lag += lag;
}
cfs_rq = group_cfs_rq(se);
} while (cfs_rq);
+ rq->core_fi_time = 0;
+
return task_of(se);
}
#endif
@@ -10707,6 +10736,41 @@ static inline void task_tick_core(struct rq
*rq, struct task_struct *curr)
__entity_slice_used(&curr->se))
resched_curr(rq);
}
+
+bool cfs_prio_less(struct task_struct *a, struct task_struct *b)
+{
+ struct sched_entity *se_a = &a->se, *se_b = &b->se;
+ struct cfs_rq *cfs_rq_a, *cfs_rq_b;
+ u64 vruntime_a, vruntime_b;
+
+#ifdef CONFIG_FAIR_GROUP_SCHED
+ while (!is_same_tg(se_a, se_b)) {
+ int se_a_depth = se_a->depth;
+ int se_b_depth = se_b->depth;
+
+ if (se_a_depth <= se_b_depth)
+ se_b = parent_entity(se_b);
+ if (se_a_depth >= se_b_depth)
+ se_a = parent_entity(se_a);
+ }
+#endif
+
+ cfs_rq_a = cfs_rq_of(se_a);
+ cfs_rq_b = cfs_rq_of(se_b);
+
+ vruntime_a = se_a->vruntime - cfs_rq_a->min_vruntime;
+ vruntime_b = se_b->vruntime - cfs_rq_b->min_vruntime;
+
+ trace_printk("(%s/%d;%Ld,%Lu) ?< (%s/%d;%Ld,%Lu)\n",
+ a->comm, a->pid, vruntime_a, cfs_rq_a->core_lag,
+ b->comm, b->pid, vruntime_b, cfs_rq_b->core_lag);
+ if (cfs_rq_a != cfs_rq_b) {
+ vruntime_a -= calc_delta_fair(cfs_rq_a->core_lag, &a->se);
+ vruntime_b -= calc_delta_fair(cfs_rq_b->core_lag, &b->se);
+ }
+
+ return !((s64)(vruntime_a - vruntime_b) <= 0);
+}
#else
static inline void task_tick_core(struct rq *rq, struct task_struct
*curr) {}
#endif
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index 5374ace195b9..a1c15edf8dd5 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -607,6 +607,10 @@ struct cfs_rq {
struct list_head throttled_list;
#endif /* CONFIG_CFS_BANDWIDTH */
#endif /* CONFIG_FAIR_GROUP_SCHED */
+
+#ifdef CONFIG_SCHED_CORE
+ u64 core_lag;
+#endif
};
static inline int rt_bandwidth_enabled(void)
@@ -1056,6 +1060,7 @@ struct rq {
#ifdef CONFIG_SCHED_CORE
/* per rq */
struct rq *core;
+ u64 core_fi_time; /* Last forced idle TS */
struct task_struct *core_pick;
unsigned int core_enabled;
unsigned int core_sched_seq;
next prev parent reply other threads:[~2020-09-17 14:43 UTC|newest]
Thread overview: 66+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-08-28 19:51 [RFC PATCH v7 00/23] Core scheduling v7 Julien Desfossez
2020-08-28 19:51 ` [RFC PATCH v7 01/23] sched: Wrap rq::lock access Julien Desfossez
2020-08-28 19:51 ` [RFC PATCH v7 02/23] sched: Introduce sched_class::pick_task() Julien Desfossez
2020-08-28 19:51 ` [RFC PATCH v7 03/23] sched: Core-wide rq->lock Julien Desfossez
2020-08-28 19:51 ` [RFC PATCH v7 04/23] sched/fair: Add a few assertions Julien Desfossez
2020-08-28 19:51 ` [RFC PATCH v7 05/23] sched: Basic tracking of matching tasks Julien Desfossez
2020-08-28 19:51 ` [RFC PATCH v7 06/23] bitops: Introduce find_next_or_bit Julien Desfossez
2020-09-03 5:13 ` Randy Dunlap
2020-08-28 19:51 ` [RFC PATCH v7 07/23] cpumask: Introduce a new iterator for_each_cpu_wrap_or Julien Desfossez
2020-08-28 19:51 ` [RFC PATCH v7 08/23] sched: Add core wide task selection and scheduling Julien Desfossez
2020-08-28 20:51 ` Peter Zijlstra
2020-08-28 22:02 ` Vineeth Pillai
2020-08-28 22:23 ` Joel Fernandes
2020-08-29 7:47 ` peterz
2020-08-31 13:01 ` Vineeth Pillai
2020-08-31 14:24 ` Joel Fernandes
2020-09-01 3:38 ` Joel Fernandes
2020-09-01 5:10 ` Joel Fernandes
2020-09-01 12:34 ` Vineeth Pillai
2020-09-01 17:30 ` Joel Fernandes
2020-09-01 21:23 ` Vineeth Pillai
2020-09-02 1:11 ` Joel Fernandes
2020-08-28 20:55 ` Peter Zijlstra
2020-08-28 22:15 ` Vineeth Pillai
2020-09-15 20:08 ` Joel Fernandes
2020-08-28 19:51 ` [RFC PATCH v7 09/23] sched/fair: Fix forced idle sibling starvation corner case Julien Desfossez
2020-08-28 21:25 ` Peter Zijlstra
2020-08-28 23:24 ` Vineeth Pillai
2020-08-28 19:51 ` [RFC PATCH v7 10/23] sched/fair: wrapper for cfs_rq->min_vruntime Julien Desfossez
2020-08-28 19:51 ` [RFC PATCH v7 11/23] sched/fair: core wide cfs task priority comparison Julien Desfossez
2020-08-28 21:29 ` Peter Zijlstra
2020-09-17 14:15 ` Vineeth Pillai [this message]
2020-09-17 20:39 ` Vineeth Pillai
2020-09-23 1:46 ` Joel Fernandes
2020-09-23 1:52 ` Joel Fernandes
2020-09-25 15:02 ` Joel Fernandes
2020-09-15 21:49 ` chris hyser
[not found] ` <81b208ad-b9e6-bfbf-631e-02e9f75d73a2@linux.intel.com>
2020-09-16 14:24 ` chris hyser
2020-09-16 20:53 ` chris hyser
2020-09-17 1:09 ` Li, Aubrey
2020-08-28 19:51 ` [RFC PATCH v7 12/23] sched: Trivial forced-newidle balancer Julien Desfossez
2020-09-02 7:08 ` Pavan Kondeti
2020-08-28 19:51 ` [RFC PATCH v7 13/23] sched: migration changes for core scheduling Julien Desfossez
2020-08-28 19:51 ` [RFC PATCH v7 14/23] irq_work: Add support to detect if work is pending Julien Desfossez
2020-08-28 19:51 ` [RFC PATCH v7 15/23] entry/idle: Add a common function for activites during idle entry/exit Julien Desfossez
2020-08-28 19:51 ` [RFC PATCH v7 16/23] arch/x86: Add a new TIF flag for untrusted tasks Julien Desfossez
2020-08-28 19:51 ` [RFC PATCH v7 17/23] kernel/entry: Add support for core-wide protection of kernel-mode Julien Desfossez
2020-09-01 15:54 ` Thomas Gleixner
2020-09-01 16:50 ` Joel Fernandes
2020-09-01 20:02 ` Thomas Gleixner
2020-09-02 1:29 ` Joel Fernandes
2020-09-02 7:53 ` Thomas Gleixner
2020-09-02 15:12 ` Joel Fernandes
2020-09-02 16:57 ` Dario Faggioli
2020-09-03 4:34 ` Joel Fernandes
2020-09-03 11:05 ` Vineeth Pillai
2020-09-03 13:20 ` Thomas Gleixner
2020-09-03 20:30 ` Joel Fernandes
2020-09-03 13:43 ` Dario Faggioli
2020-09-03 20:25 ` Joel Fernandes
2020-08-28 19:51 ` [RFC PATCH v7 18/23] entry/idle: Enter and exit kernel protection during idle entry and exit Julien Desfossez
2020-08-28 19:51 ` [RFC PATCH v7 19/23] entry/kvm: Protect the kernel when entering from guest Julien Desfossez
2020-08-28 19:51 ` [RFC PATCH v7 20/23] sched/coresched: config option for kernel protection Julien Desfossez
2020-08-28 19:51 ` [RFC PATCH v7 21/23] sched: cgroup tagging interface for core scheduling Julien Desfossez
2020-08-28 19:51 ` [RFC PATCH v7 22/23] Documentation: Add documentation on " Julien Desfossez
2020-08-28 19:51 ` [RFC PATCH v7 23/23] sched: Debug bits Julien Desfossez
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=8b9f28f2-7f21-b7da-1056-732b6227ea25@linux.microsoft.com \
--to=viremana@linux.microsoft.com \
--cc=aaron.lwe@gmail.com \
--cc=agata.gruza@intel.com \
--cc=antonio.gomez.iglesias@intel.com \
--cc=aubrey.intel@gmail.com \
--cc=benbjiang@tencent.com \
--cc=chris.hyser@oracle.com \
--cc=christian.brauner@ubuntu.com \
--cc=derkling@google.com \
--cc=dfaggioli@suse.com \
--cc=dhaval.giani@oracle.com \
--cc=fweisbec@gmail.com \
--cc=graf@amazon.com \
--cc=jdesfossez@digitalocean.com \
--cc=joel@joelfernandes.org \
--cc=joelaf@google.com \
--cc=keescook@chromium.org \
--cc=kerrnel@google.com \
--cc=konrad.wilk@oracle.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mgorman@techsingularity.net \
--cc=mingo@kernel.org \
--cc=naravamudan@digitalocean.com \
--cc=pauld@redhat.com \
--cc=pawan.kumar.gupta@linux.intel.com \
--cc=pbonzini@redhat.com \
--cc=peterz@infradead.org \
--cc=pjt@google.com \
--cc=rostedt@goodmis.org \
--cc=tglx@linutronix.de \
--cc=tim.c.chen@linux.intel.com \
--cc=torvalds@linux-foundation.org \
--cc=valentin.schneider@arm.com \
--cc=vineeth@bitbyteword.org \
--cc=yu.c.chen@intel.com \
--cc=ziqian.lzq@antfin.com \
/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
Powered by JetHome