[PATCH 2/2] Split cpudl_set() into cpudl_set() and cpudl_clear(). These 2 exercise independent code paths and need different arguments.

From: Tommaso Cucinotta
Date: Fri May 13 2016 - 05:47:36 EST


---
kernel/sched/cpudeadline.c | 69 +++++++++++++++++++++++++++++-----------------
kernel/sched/cpudeadline.h | 3 +-
kernel/sched/deadline.c | 10 +++----
3 files changed, 51 insertions(+), 31 deletions(-)

diff --git a/kernel/sched/cpudeadline.c b/kernel/sched/cpudeadline.c
index 245d929..82e7c66 100644
--- a/kernel/sched/cpudeadline.c
+++ b/kernel/sched/cpudeadline.c
@@ -156,16 +156,15 @@ out:
}

/*
- * cpudl_set - update the cpudl max-heap
+ * cpudl_clear - remove a cpu from the cpudl max-heap
* @cp: the cpudl max-heap context
* @cpu: the target cpu
- * @dl: the new earliest deadline for this cpu
*
* Notes: assumes cpu_rq(cpu)->lock is locked
*
* Returns: (void)
*/
-void cpudl_set(struct cpudl *cp, int cpu, u64 dl, int is_valid)
+void cpudl_clear(struct cpudl *cp, int cpu)
{
int old_idx, new_cpu;
unsigned long flags;
@@ -173,17 +172,16 @@ void cpudl_set(struct cpudl *cp, int cpu, u64 dl, int is_valid)
WARN_ON(!cpu_present(cpu));

raw_spin_lock_irqsave(&cp->lock, flags);
+
old_idx = cp->elements[cpu].idx;
- if (!is_valid) {
+ if (old_idx == IDX_INVALID) {
+ /*
+ * Nothing to remove if old_idx was invalid.
+ * This could happen if a rq_offline_dl is
+ * called for a CPU without -dl tasks running.
+ */
+ } else {
/* remove item */
- if (old_idx == IDX_INVALID) {
- /*
- * Nothing to remove if old_idx was invalid.
- * This could happen if a rq_offline_dl is
- * called for a CPU without -dl tasks running.
- */
- goto out;
- }
cp->size--;
cp->elements[cpu].idx = IDX_INVALID;
if (old_idx != cp->size) {
@@ -193,23 +191,44 @@ void cpudl_set(struct cpudl *cp, int cpu, u64 dl, int is_valid)
cp->elements[new_cpu].idx = old_idx;
cpudl_heapify(cp, old_idx);
}
-
cpumask_set_cpu(cpu, cp->free_cpus);
+ }
+
+ raw_spin_unlock_irqrestore(&cp->lock, flags);
+}
+
+/*
+ * cpudl_set - update the cpudl max-heap
+ * @cp: the cpudl max-heap context
+ * @cpu: the target cpu
+ * @dl: the new earliest deadline for this cpu
+ *
+ * Notes: assumes cpu_rq(cpu)->lock is locked
+ *
+ * Returns: (void)
+ */
+void cpudl_set(struct cpudl *cp, int cpu, u64 dl)
+{
+ int old_idx;
+ unsigned long flags;
+
+ WARN_ON(!cpu_present(cpu));
+
+ raw_spin_lock_irqsave(&cp->lock, flags);
+
+ old_idx = cp->elements[cpu].idx;
+ if (old_idx == IDX_INVALID) {
+ int sz1 = cp->size++;
+ cp->elements[sz1].dl = dl;
+ cp->elements[sz1].cpu = cpu;
+ cp->elements[cpu].idx = sz1;
+ cpudl_heapify_up(cp, sz1);
+
+ cpumask_clear_cpu(cpu, cp->free_cpus);
} else {
- if (old_idx == IDX_INVALID) {
- int sz1 = cp->size++;
- cp->elements[sz1].dl = dl;
- cp->elements[sz1].cpu = cpu;
- cp->elements[cpu].idx = sz1;
- cpudl_heapify_up(cp, sz1);
-
- cpumask_clear_cpu(cpu, cp->free_cpus);
- } else {
- cpudl_change_key(cp, old_idx, dl);
- }
+ cpudl_change_key(cp, old_idx, dl);
}

-out:
raw_spin_unlock_irqrestore(&cp->lock, flags);
}

diff --git a/kernel/sched/cpudeadline.h b/kernel/sched/cpudeadline.h
index fcbdf83..f7da8c5 100644
--- a/kernel/sched/cpudeadline.h
+++ b/kernel/sched/cpudeadline.h
@@ -23,7 +23,8 @@ struct cpudl {
#ifdef CONFIG_SMP
int cpudl_find(struct cpudl *cp, struct task_struct *p,
struct cpumask *later_mask);
-void cpudl_set(struct cpudl *cp, int cpu, u64 dl, int is_valid);
+void cpudl_set(struct cpudl *cp, int cpu, u64 dl);
+void cpudl_clear(struct cpudl *cp, int cpu);
int cpudl_init(struct cpudl *cp);
void cpudl_set_freecpu(struct cpudl *cp, int cpu);
void cpudl_clear_freecpu(struct cpudl *cp, int cpu);
diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
index 686ec8a..e3ffc2f 100644
--- a/kernel/sched/deadline.c
+++ b/kernel/sched/deadline.c
@@ -795,7 +795,7 @@ static void inc_dl_deadline(struct dl_rq *dl_rq, u64 deadline)
if (dl_rq->earliest_dl.curr == 0 ||
dl_time_before(deadline, dl_rq->earliest_dl.curr)) {
dl_rq->earliest_dl.curr = deadline;
- cpudl_set(&rq->rd->cpudl, rq->cpu, deadline, 1);
+ cpudl_set(&rq->rd->cpudl, rq->cpu, deadline);
}
}

@@ -810,14 +810,14 @@ static void dec_dl_deadline(struct dl_rq *dl_rq, u64 deadline)
if (!dl_rq->dl_nr_running) {
dl_rq->earliest_dl.curr = 0;
dl_rq->earliest_dl.next = 0;
- cpudl_set(&rq->rd->cpudl, rq->cpu, 0, 0);
+ cpudl_clear(&rq->rd->cpudl, rq->cpu);
} else {
struct rb_node *leftmost = dl_rq->rb_leftmost;
struct sched_dl_entity *entry;

entry = rb_entry(leftmost, struct sched_dl_entity, rb_node);
dl_rq->earliest_dl.curr = entry->deadline;
- cpudl_set(&rq->rd->cpudl, rq->cpu, entry->deadline, 1);
+ cpudl_set(&rq->rd->cpudl, rq->cpu, entry->deadline);
}
}

@@ -1667,7 +1667,7 @@ static void rq_online_dl(struct rq *rq)

cpudl_set_freecpu(&rq->rd->cpudl, rq->cpu);
if (rq->dl.dl_nr_running > 0)
- cpudl_set(&rq->rd->cpudl, rq->cpu, rq->dl.earliest_dl.curr, 1);
+ cpudl_set(&rq->rd->cpudl, rq->cpu, rq->dl.earliest_dl.curr);
}

/* Assumes rq->lock is held */
@@ -1676,7 +1676,7 @@ static void rq_offline_dl(struct rq *rq)
if (rq->dl.overloaded)
dl_clear_overload(rq);

- cpudl_set(&rq->rd->cpudl, rq->cpu, 0, 0);
+ cpudl_clear(&rq->rd->cpudl, rq->cpu);
cpudl_clear_freecpu(&rq->rd->cpudl, rq->cpu);
}

--
2.7.4


--------------020507050703000801070504
Content-Type: application/pdf;
name="cpudl.pdf"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename="cpudl.pdf"

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
Cx4oXwqsnpoWy242O7NhWV0PRyfAshv1lH7KEUJvv/3MJdP16eEAK9tOeFZu1DHFwip3vWrq
KPfO26a2fNBCTjb9dd2rJgVPQWE/eW30jauu528/fhlf3/3y+gm9alIhTMZqkJV0h5Fhdw/w
6E9cI/ny68xyjeSZn3XWA47DA3qtEDT+umoRV1EsRR7gWbw4yrlxAJPEc7Yy+ZOMEnuzc/4I
enaW+4LzKTfg1cSynUM6lQzjZxIBhlmFWK3CuMawY/26IIshMsigG6LmLl/LHFuViYIsBscg
U7uPvovc82vfDlv6BF+w9c1yM06tP/rGc++vjQG2vAi6YoslspdE2HwP5fIt9f+oZYeCp1s0
xKIlcM0gpUMTvKkNaFbhvH3JhIEfQsWWrWA4rHV1i6Q+oCIbpivSQRTM/M1xmCDp5svtv2Y3
9q6W8oPl9yTVwDVIY6T7O/cCG8sOyfS2YtECK+F+sK1oEllagmxWoZLU/NReOs8gy3VTzcfl
uonLx8t1ky9INHi9/qH9WQl7MfwHUfNR7QplbmRzdHJlYW0KZW5kb2JqCjQgMCBvYmoKICAg
MjE2NQplbmRvYmoKMiAwIG9iago8PAogICAvRXh0R1N0YXRlIDw8CiAgICAgIC9hMCA8PCAv
Q0EgMSAvY2EgMSA+PgogICA+PgogICAvRm9udCA8PAogICAgICAvZi0wLTAgNSAwIFIKICAg
Pj4KPj4KZW5kb2JqCjYgMCBvYmoKPDwgL1R5cGUgL1BhZ2UKICAgL1BhcmVudCAxIDAgUgog
ICAvTWVkaWFCb3ggWyAwIDAgMzYwIDIxNiBdCiAgIC9Db250ZW50cyAzIDAgUgogICAvR3Jv
dXAgPDwKICAgICAgL1R5cGUgL0dyb3VwCiAgICAgIC9TIC9UcmFuc3BhcmVuY3kKICAgICAg
L0kgdHJ1ZQogICAgICAvQ1MgL0RldmljZVJHQgogICA+PgogICAvUmVzb3VyY2VzIDIgMCBS
Cj4+CmVuZG9iago3IDAgb2JqCjw8IC9MZW5ndGggOCAwIFIKICAgL0ZpbHRlciAvRmxhdGVE
ZWNvZGUKICAgL0xlbmd0aDEgODU0OAo+PgpzdHJlYW0KeJzlWXtcVVX23/uss+/7ce4LuNzL
fQAXxBcIoqKWN1PzNYWK5iMNBcmxTIwsFQ3FBB84iAKmmV4LnFJzGHIMxBxL8hHa1KjNONpY
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
ed5APQyNQGf/rckDW86D+e6DqCVJ8zwOoi72ieMQ+ch8JGZNkTSKWRFLZklcMBfEJXNJfGA+
EGtmHVmxRpFGsVeRt2QuiSvmilhxBkUZFGdQlEEPieMQ9Zynojya82vKryvmihiZkZj30bRP
xZqKNCVzmfRcE001kXwWSWeR7JXklfyvOFDBb5Wl0tMduffUXEOI7UwXKfWROjg6vN81P3ty
pecX1RKuQwplbmRzdHJlYW0KZW5kb2JqCjEwIDAgb2JqCiAgIDM0OQplbmRvYmoKMTEgMCBv
YmoKPDwgL1R5cGUgL0ZvbnREZXNjcmlwdG9yCiAgIC9Gb250TmFtZSAvS1FFV0FQK0RlamFW
dVNhbnMKICAgL0ZvbnRGYW1pbHkgKERlamFWdSBTYW5zKQogICAvRmxhZ3MgMzIKICAgL0Zv
bnRCQm94IFsgLTEwMjAgLTQ2MiAxNzkzIDEyMzIgXQogICAvSXRhbGljQW5nbGUgMAogICAv
QXNjZW50IDkyOAogICAvRGVzY2VudCAtMjM1CiAgIC9DYXBIZWlnaHQgMTIzMgogICAvU3Rl
bVYgODAKICAgL1N0ZW1IIDgwCiAgIC9Gb250RmlsZTIgNyAwIFIKPj4KZW5kb2JqCjUgMCBv
YmoKPDwgL1R5cGUgL0ZvbnQKICAgL1N1YnR5cGUgL1RydWVUeXBlCiAgIC9CYXNlRm9udCAv
S1FFV0FQK0RlamFWdVNhbnMKICAgL0ZpcnN0Q2hhciAzMgogICAvTGFzdENoYXIgMTE5CiAg
IC9Gb250RGVzY3JpcHRvciAxMSAwIFIKICAgL0VuY29kaW5nIC9XaW5BbnNpRW5jb2RpbmcK
ICAgL1dpZHRocyBbIDMxNyAwIDAgMCAwIDk1MCAwIDAgMzkwIDM5MCAwIDAgMCAwIDAgMCA2
MzYgNjM2IDYzNiA2MzYgNjM2IDYzNiA2MzYgMCA2MzYgNjM2IDAgMCAwIDAgMCAwIDAgMCAw
IDY5OCAwIDAgMCA3NzQgMCAwIDAgMCAwIDAgMCAwIDYwMyAwIDAgNjM0IDYxMCA3MzEgMCAw
IDAgMCAwIDAgMCAwIDAgMCAwIDYxMiAwIDAgMCA2MTUgMCA2MzQgMCAyNzcgMCAwIDAgMCA2
MzMgNjExIDAgMCA0MTEgNTIwIDAgMCAwIDgxNyBdCiAgICAvVG9Vbmljb2RlIDkgMCBSCj4+
CmVuZG9iagoxIDAgb2JqCjw8IC9UeXBlIC9QYWdlcwogICAvS2lkcyBbIDYgMCBSIF0KICAg
L0NvdW50IDEKPj4KZW5kb2JqCjEyIDAgb2JqCjw8IC9DcmVhdG9yIChjYWlybyAxLjE0LjYg
KGh0dHA6Ly9jYWlyb2dyYXBoaWNzLm9yZykpCiAgIC9Qcm9kdWNlciAoY2Fpcm8gMS4xNC42
IChodHRwOi8vY2Fpcm9ncmFwaGljcy5vcmcpKQo+PgplbmRvYmoKMTMgMCBvYmoKPDwgL1R5
cGUgL0NhdGFsb2cKICAgL1BhZ2VzIDEgMCBSCj4+CmVuZG9iagp4cmVmCjAgMTQKMDAwMDAw
MDAwMCA2NTUzNSBmIAowMDAwMDEwMTA2IDAwMDAwIG4gCjAwMDAwMDIyODAgMDAwMDAgbiAK
MDAwMDAwMDAxNSAwMDAwMCBuIAowMDAwMDAyMjU3IDAwMDAwIG4gCjAwMDAwMDk2NjEgMDAw
MDAgbiAKMDAwMDAwMjM4OSAwMDAwMCBuIAowMDAwMDAyNjAzIDAwMDAwIG4gCjAwMDAwMDg5
MTcgMDAwMDAgbiAKMDAwMDAwODk0MCAwMDAwMCBuIAowMDAwMDA5MzY3IDAwMDAwIG4gCjAw
MDAwMDkzOTAgMDAwMDAgbiAKMDAwMDAxMDE3MSAwMDAwMCBuIAowMDAwMDEwMjk5IDAwMDAw
IG4gCnRyYWlsZXIKPDwgL1NpemUgMTQKICAgL1Jvb3QgMTMgMCBSCiAgIC9JbmZvIDEyIDAg
Ugo+PgpzdGFydHhyZWYKMTAzNTIKJSVFT0YK
--------------020507050703000801070504--