diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2014-01-02 11:09:30 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2014-01-02 11:11:55 -0500 |
commit | 508f55e91e2bab12630df20ededa922c147b706b (patch) | |
tree | d2a0442d48496c7f8cc946004a3bb24836bc170f | |
parent | d6e5eee7b7863d179e95962f0144c3daeba35a44 (diff) |
Hack: Remap CPUs IDs to match Ludwig's cache topo.
This temporary patch remaps CPU IDs to match Ludwig's
cache topology. Thus, "virtual" CPUs 0 and 1, which share
an L2 cache, are remapped to CPUs 0 and 4.
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | bin/rtspin.c | 3 | ||||
-rw-r--r-- | bin/test_cluster.c | 22 | ||||
-rw-r--r-- | include/migration.h | 2 | ||||
-rw-r--r-- | src/migration.c | 42 |
5 files changed, 62 insertions, 12 deletions
@@ -73,7 +73,7 @@ AR := ${CROSS_COMPILE}${AR} | |||
73 | 73 | ||
74 | all = lib ${rt-apps} | 74 | all = lib ${rt-apps} |
75 | rt-apps = cycles base_task rt_launch rtspin release_ts measure_syscall \ | 75 | rt-apps = cycles base_task rt_launch rtspin release_ts measure_syscall \ |
76 | base_mt_task uncache runtests | 76 | base_mt_task uncache runtests test_cluster |
77 | 77 | ||
78 | .PHONY: all lib clean dump-config TAGS tags cscope help | 78 | .PHONY: all lib clean dump-config TAGS tags cscope help |
79 | 79 | ||
@@ -222,6 +222,9 @@ obj-rt_launch = rt_launch.o common.o | |||
222 | obj-rtspin = rtspin.o common.o | 222 | obj-rtspin = rtspin.o common.o |
223 | lib-rtspin = -lrt | 223 | lib-rtspin = -lrt |
224 | 224 | ||
225 | obj-test_cluster = test_cluster.o common.o | ||
226 | lib-test_cluster = -lrt | ||
227 | |||
225 | obj-uncache = uncache.o | 228 | obj-uncache = uncache.o |
226 | lib-uncache = -lrt | 229 | lib-uncache = -lrt |
227 | 230 | ||
diff --git a/bin/rtspin.c b/bin/rtspin.c index 224a201..3f80448 100644 --- a/bin/rtspin.c +++ b/bin/rtspin.c | |||
@@ -343,8 +343,9 @@ int main(int argc, char** argv) | |||
343 | param.cls = class; | 343 | param.cls = class; |
344 | param.budget_policy = (want_enforcement) ? | 344 | param.budget_policy = (want_enforcement) ? |
345 | PRECISE_ENFORCEMENT : NO_ENFORCEMENT; | 345 | PRECISE_ENFORCEMENT : NO_ENFORCEMENT; |
346 | if (migrate) | 346 | if (migrate) { |
347 | param.cpu = cluster_to_first_cpu(cluster, cluster_size); | 347 | param.cpu = cluster_to_first_cpu(cluster, cluster_size); |
348 | } | ||
348 | ret = set_rt_task_param(gettid(), ¶m); | 349 | ret = set_rt_task_param(gettid(), ¶m); |
349 | if (ret < 0) | 350 | if (ret < 0) |
350 | bail_out("could not setup rt task params"); | 351 | bail_out("could not setup rt task params"); |
diff --git a/bin/test_cluster.c b/bin/test_cluster.c new file mode 100644 index 0000000..3bcdc9f --- /dev/null +++ b/bin/test_cluster.c | |||
@@ -0,0 +1,22 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <assert.h> | ||
3 | #include "litmus.h" | ||
4 | |||
5 | int main(void) | ||
6 | { | ||
7 | int i; | ||
8 | int cluster_sizes[] = {1, 2, 6, 24}; | ||
9 | for(i = 0; i < sizeof(cluster_sizes)/sizeof(cluster_sizes[0]); ++i) | ||
10 | { | ||
11 | int size = cluster_sizes[i]; | ||
12 | int num_clusters = 24/size; | ||
13 | int c; | ||
14 | printf("Cluster Size: %d\n", size); | ||
15 | for(c = 0; c < num_clusters; ++c) | ||
16 | { | ||
17 | printf("\tcluster %d -> 1st pcpu %d\n", c, cluster_to_first_cpu(c, size)); | ||
18 | } | ||
19 | } | ||
20 | |||
21 | return 0; | ||
22 | } | ||
diff --git a/include/migration.h b/include/migration.h index 2413e7c..1f80376 100644 --- a/include/migration.h +++ b/include/migration.h | |||
@@ -16,7 +16,7 @@ int be_migrate_thread_to_cluster(pid_t tid, int cluster, int cluster_sz); | |||
16 | /* set ignore_rm == 1 to include release master in tid's cpu affinity */ | 16 | /* set ignore_rm == 1 to include release master in tid's cpu affinity */ |
17 | int __be_migrate_thread_to_cluster(pid_t tid, int cluster, int cluster_sz, int ignore_rm); | 17 | int __be_migrate_thread_to_cluster(pid_t tid, int cluster, int cluster_sz, int ignore_rm); |
18 | 18 | ||
19 | int be_migrate_to_cpu(int target_cpu); | 19 | int be_migrate_to_cpu(int target_pcpu); |
20 | int be_migrate_to_partition(int partition); | 20 | int be_migrate_to_partition(int partition); |
21 | int be_migrate_to_cluster(int cluster, int cluster_sz); | 21 | int be_migrate_to_cluster(int cluster, int cluster_sz); |
22 | 22 | ||
diff --git a/src/migration.c b/src/migration.c index 5de81d5..930d594 100644 --- a/src/migration.c +++ b/src/migration.c | |||
@@ -2,6 +2,7 @@ | |||
2 | #include <stdlib.h> | 2 | #include <stdlib.h> |
3 | #include <string.h> | 3 | #include <string.h> |
4 | #include <sched.h> /* for cpu sets */ | 4 | #include <sched.h> /* for cpu sets */ |
5 | #include <assert.h> | ||
5 | #include <unistd.h> | 6 | #include <unistd.h> |
6 | 7 | ||
7 | #include "migration.h" | 8 | #include "migration.h" |
@@ -27,6 +28,28 @@ int num_online_cpus() | |||
27 | return sysconf(_SC_NPROCESSORS_ONLN); | 28 | return sysconf(_SC_NPROCESSORS_ONLN); |
28 | } | 29 | } |
29 | 30 | ||
31 | int ludwig_vcpu_to_pcpu(int vcpu) { | ||
32 | static const int LUDWIG_VCPU_TO_PCPU[] = { | ||
33 | 0, 4, 8, 12, 16, 20, | ||
34 | 1, 5, 9, 13, 17, 21, | ||
35 | 2, 6, 10, 14, 18, 22, | ||
36 | 3, 7, 11, 15, 19, 23 | ||
37 | }; | ||
38 | assert(vcpu < 24 && vcpu >= 0); | ||
39 | return LUDWIG_VCPU_TO_PCPU[vcpu]; | ||
40 | } | ||
41 | |||
42 | int ludwig_pcpu_to_vcpu(int pcpu) { | ||
43 | static const int LUDWIG_PCPU_TO_VCPU[] = { | ||
44 | 0, 6, 12, 18, 1, 7, | ||
45 | 13, 19, 2, 8, 14, 20, | ||
46 | 3, 9, 15, 21, 4, 10, | ||
47 | 16, 22, 5, 11, 17, 23 | ||
48 | }; | ||
49 | assert(pcpu < 24 && pcpu >= 0); | ||
50 | return LUDWIG_PCPU_TO_VCPU[pcpu]; | ||
51 | } | ||
52 | |||
30 | int partition_to_cpu(int partition) | 53 | int partition_to_cpu(int partition) |
31 | { | 54 | { |
32 | int cpu = partition; | 55 | int cpu = partition; |
@@ -34,7 +57,7 @@ int partition_to_cpu(int partition) | |||
34 | if (master != -1 && master <= cpu) { | 57 | if (master != -1 && master <= cpu) { |
35 | ++cpu; /* skip over the release master */ | 58 | ++cpu; /* skip over the release master */ |
36 | } | 59 | } |
37 | return cpu; | 60 | return ludwig_vcpu_to_pcpu(cpu); |
38 | } | 61 | } |
39 | 62 | ||
40 | int cluster_to_first_cpu(int cluster, int cluster_sz) | 63 | int cluster_to_first_cpu(int cluster, int cluster_sz) |
@@ -51,10 +74,10 @@ int cluster_to_first_cpu(int cluster, int cluster_sz) | |||
51 | if (master == first_cpu) | 74 | if (master == first_cpu) |
52 | ++first_cpu; | 75 | ++first_cpu; |
53 | 76 | ||
54 | return first_cpu; | 77 | return ludwig_vcpu_to_pcpu(first_cpu); |
55 | } | 78 | } |
56 | 79 | ||
57 | int be_migrate_thread_to_cpu(pid_t tid, int target_cpu) | 80 | int be_migrate_thread_to_cpu(pid_t tid, int target_pcpu) |
58 | { | 81 | { |
59 | cpu_set_t *cpu_set; | 82 | cpu_set_t *cpu_set; |
60 | size_t sz; | 83 | size_t sz; |
@@ -63,20 +86,20 @@ int be_migrate_thread_to_cpu(pid_t tid, int target_cpu) | |||
63 | 86 | ||
64 | /* TODO: Error check to make sure that tid is not a real-time task. */ | 87 | /* TODO: Error check to make sure that tid is not a real-time task. */ |
65 | 88 | ||
66 | if (target_cpu < 0) | 89 | if (target_pcpu < 0) |
67 | return -1; | 90 | return -1; |
68 | 91 | ||
69 | num_cpus = num_online_cpus(); | 92 | num_cpus = num_online_cpus(); |
70 | if (num_cpus == -1) | 93 | if (num_cpus == -1) |
71 | return -1; | 94 | return -1; |
72 | 95 | ||
73 | if (target_cpu >= num_cpus) | 96 | if (target_pcpu >= num_cpus) |
74 | return -1; | 97 | return -1; |
75 | 98 | ||
76 | cpu_set = CPU_ALLOC(num_cpus); | 99 | cpu_set = CPU_ALLOC(num_cpus); |
77 | sz = CPU_ALLOC_SIZE(num_cpus); | 100 | sz = CPU_ALLOC_SIZE(num_cpus); |
78 | CPU_ZERO_S(sz, cpu_set); | 101 | CPU_ZERO_S(sz, cpu_set); |
79 | CPU_SET_S(target_cpu, sz, cpu_set); | 102 | CPU_SET_S(target_pcpu, sz, cpu_set); |
80 | 103 | ||
81 | /* apply to caller */ | 104 | /* apply to caller */ |
82 | if (tid == 0) | 105 | if (tid == 0) |
@@ -125,7 +148,8 @@ int __be_migrate_thread_to_cluster(pid_t tid, int cluster, int cluster_sz, | |||
125 | 148 | ||
126 | for (i = first_cpu; i <= last_cpu; ++i) { | 149 | for (i = first_cpu; i <= last_cpu; ++i) { |
127 | if (i != master) { | 150 | if (i != master) { |
128 | CPU_SET_S(i, sz, cpu_set); | 151 | int pcpu = ludwig_vcpu_to_pcpu(i); |
152 | CPU_SET_S(pcpu, sz, cpu_set); | ||
129 | } | 153 | } |
130 | } | 154 | } |
131 | 155 | ||
@@ -146,9 +170,9 @@ int be_migrate_thread_to_partition(pid_t tid, int partition) | |||
146 | } | 170 | } |
147 | 171 | ||
148 | 172 | ||
149 | int be_migrate_to_cpu(int target_cpu) | 173 | int be_migrate_to_cpu(int target_pcpu) |
150 | { | 174 | { |
151 | return be_migrate_thread_to_cpu(0, target_cpu); | 175 | return be_migrate_thread_to_cpu(0, target_pcpu); |
152 | } | 176 | } |
153 | 177 | ||
154 | int be_migrate_to_cluster(int cluster, int cluster_sz) | 178 | int be_migrate_to_cluster(int cluster, int cluster_sz) |