aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2014-02-05 00:31:08 -0500
committerBjoern Brandenburg <bbb@mpi-sws.org>2014-02-24 14:01:11 -0500
commit1f323b00f95c4704cdeea7918853f1e9e8d26c2e (patch)
tree76a6856b2465ba7d114009f231c0dae9c9e5ef2c
parent871eef081ff9db7289a6947d0160cd984232c34c (diff)
Use /proc/litmus/domains to set up affinity masks
This patch replaces the algorithm used to compute CPU affinity masks. The old algorithm was fragile and would break on systems with multiple levels of shared caches. (As found on some older Intel chips, and as one would probably find on a system with hyper-threading enabled.) The bug stems from fact that Linux enumerates consecutive CPUs in a way that distributes them across the physical system, thereby reducing contention resources (e.g., cache). Cluster size no longer needs to be provided now that cluster/CPU mappings are explicit in /proc/litmus/domains/. This keeps the following migration functions, but marks them as deprecated: - be_migrate_to_cluster() - cluster_to_first_cpu() - partition_to_cpu() Although the deprecated interfaces are supported, the implementations for these functions call the new be_migrate_to_domain() and domain_to_first_cpu() functions. [bbb: resolved several merge conflicts]
-rw-r--r--bin/rt_launch.c10
-rw-r--r--bin/rtspin.c10
-rw-r--r--include/litmus.h35
-rw-r--r--include/migration.h53
-rw-r--r--src/litmus.c10
-rw-r--r--src/migration.c113
-rw-r--r--src/task.c8
7 files changed, 119 insertions, 120 deletions
diff --git a/bin/rt_launch.c b/bin/rt_launch.c
index 93f10d5..5e29893 100644
--- a/bin/rt_launch.c
+++ b/bin/rt_launch.c
@@ -42,7 +42,7 @@ void usage(char *error) {
42} 42}
43 43
44 44
45#define OPTSTR "p:z:c:vwq:" 45#define OPTSTR "p:c:vwq:"
46 46
47int main(int argc, char** argv) 47int main(int argc, char** argv)
48{ 48{
@@ -51,7 +51,6 @@ int main(int argc, char** argv)
51 lt_t period; 51 lt_t period;
52 int migrate = 0; 52 int migrate = 0;
53 int cluster = 0; 53 int cluster = 0;
54 int cluster_size = 1;
55 int opt; 54 int opt;
56 int verbose = 0; 55 int verbose = 0;
57 int wait = 0; 56 int wait = 0;
@@ -71,9 +70,6 @@ int main(int argc, char** argv)
71 cluster = atoi(optarg); 70 cluster = atoi(optarg);
72 migrate = 1; 71 migrate = 1;
73 break; 72 break;
74 case 'z':
75 cluster_size = atoi(optarg);
76 break;
77 case 'q': 73 case 'q':
78 priority = atoi(optarg); 74 priority = atoi(optarg);
79 if (!litmus_is_valid_fixed_prio(priority)) 75 if (!litmus_is_valid_fixed_prio(priority))
@@ -114,11 +110,11 @@ int main(int argc, char** argv)
114 info.argv = argv + optind + 2; 110 info.argv = argv + optind + 2;
115 info.wait = wait; 111 info.wait = wait;
116 if (migrate) { 112 if (migrate) {
117 ret = be_migrate_to_cluster(cluster, cluster_size); 113 ret = be_migrate_to_domain(cluster);
118 if (ret < 0) 114 if (ret < 0)
119 bail_out("could not migrate to target partition or cluster"); 115 bail_out("could not migrate to target partition or cluster");
120 } 116 }
121 ret = __create_rt_task(launch, &info, cluster, cluster_size, wcet, period, 117 ret = __create_rt_task(launch, &info, cluster, wcet, period,
122 priority, class); 118 priority, class);
123 119
124 120
diff --git a/bin/rtspin.c b/bin/rtspin.c
index 167741d..b4156cc 100644
--- a/bin/rtspin.c
+++ b/bin/rtspin.c
@@ -184,7 +184,7 @@ static int job(double exec_time, double program_end, int lock_od, double cs_leng
184 } 184 }
185} 185}
186 186
187#define OPTSTR "p:z:c:wlveo:f:s:q:X:L:Q:" 187#define OPTSTR "p:c:wlveo:f:s:q:X:L:Q:"
188int main(int argc, char** argv) 188int main(int argc, char** argv)
189{ 189{
190 int ret; 190 int ret;
@@ -194,7 +194,6 @@ int main(int argc, char** argv)
194 unsigned int priority = LITMUS_LOWEST_PRIORITY; 194 unsigned int priority = LITMUS_LOWEST_PRIORITY;
195 int migrate = 0; 195 int migrate = 0;
196 int cluster = 0; 196 int cluster = 0;
197 int cluster_size = 1;
198 int opt; 197 int opt;
199 int wait = 0; 198 int wait = 0;
200 int test_loop = 0; 199 int test_loop = 0;
@@ -226,9 +225,6 @@ int main(int argc, char** argv)
226 cluster = atoi(optarg); 225 cluster = atoi(optarg);
227 migrate = 1; 226 migrate = 1;
228 break; 227 break;
229 case 'z':
230 cluster_size = atoi(optarg);
231 break;
232 case 'q': 228 case 'q':
233 priority = atoi(optarg); 229 priority = atoi(optarg);
234 if (!litmus_is_valid_fixed_prio(priority)) 230 if (!litmus_is_valid_fixed_prio(priority))
@@ -326,7 +322,7 @@ int main(int argc, char** argv)
326 duration += period_ms * 0.001 * (num_jobs - 1); 322 duration += period_ms * 0.001 * (num_jobs - 1);
327 323
328 if (migrate) { 324 if (migrate) {
329 ret = be_migrate_to_cluster(cluster, cluster_size); 325 ret = be_migrate_to_domain(cluster);
330 if (ret < 0) 326 if (ret < 0)
331 bail_out("could not migrate to target partition or cluster."); 327 bail_out("could not migrate to target partition or cluster.");
332 } 328 }
@@ -339,7 +335,7 @@ int main(int argc, char** argv)
339 param.budget_policy = (want_enforcement) ? 335 param.budget_policy = (want_enforcement) ?
340 PRECISE_ENFORCEMENT : NO_ENFORCEMENT; 336 PRECISE_ENFORCEMENT : NO_ENFORCEMENT;
341 if (migrate) 337 if (migrate)
342 param.cpu = cluster_to_first_cpu(cluster, cluster_size); 338 param.cpu = domain_to_first_cpu(cluster);
343 ret = set_rt_task_param(gettid(), &param); 339 ret = set_rt_task_param(gettid(), &param);
344 if (ret < 0) 340 if (ret < 0)
345 bail_out("could not setup rt task params"); 341 bail_out("could not setup rt task params");
diff --git a/include/litmus.h b/include/litmus.h
index 5a79b7d..5a5461f 100644
--- a/include/litmus.h
+++ b/include/litmus.h
@@ -51,6 +51,7 @@ extern "C" {
51 * @param param Pointer to the struct to initialise 51 * @param param Pointer to the struct to initialise
52 */ 52 */
53void init_rt_task_param(struct rt_task* param); 53void init_rt_task_param(struct rt_task* param);
54
54/** 55/**
55 * Set real-time task parameters for given process 56 * Set real-time task parameters for given process
56 * @param pid PID of process 57 * @param pid PID of process
@@ -58,6 +59,7 @@ void init_rt_task_param(struct rt_task* param);
58 * @return 0 on success 59 * @return 0 on success
59 */ 60 */
60int set_rt_task_param(pid_t pid, struct rt_task* param); 61int set_rt_task_param(pid_t pid, struct rt_task* param);
62
61/** 63/**
62 * Get real-time task parameters for given process 64 * Get real-time task parameters for given process
63 * @param pid PID of process 65 * @param pid PID of process
@@ -74,20 +76,26 @@ int get_rt_task_param(pid_t pid, struct rt_task* param);
74 * Release-master-aware functions for getting the first 76 * Release-master-aware functions for getting the first
75 * CPU in a particular cluster or partition. Use these 77 * CPU in a particular cluster or partition. Use these
76 * to set rt_task::cpu for cluster/partitioned scheduling. 78 * to set rt_task::cpu for cluster/partitioned scheduling.
79 *
80 * \deprecated{Use domain_to_first_cpu() in new code.}
77 */ 81 */
78int partition_to_cpu(int partition); 82int partition_to_cpu(int partition);
83
79/** 84/**
80 * For given cluster, return the identifier for the first associated CPU 85 * For given cluster, return the identifier for the first associated CPU
81 * @param cluster Identifier of the cluster 86 * @param cluster Identifier of the cluster
82 * @param cluster_size Size for this cluster 87 * @param cluster_size Size for this cluster
83 * @return Identifier for the first associated CPU 88 * @return Identifier for the first associated CPU
89 *
90 * \deprecated{Use domain_to_first_cpu() in new code.}
84 */ 91 */
85int cluster_to_first_cpu(int cluster, int cluster_size); 92int cluster_to_first_cpu(int cluster, int cluster_size);
86 93
87/* Convenience functions for setting up real-time tasks. 94
88 * Default behaviors set by init_rt_task_params() used. 95/* The following three functions are convenience functions for setting up
89 * Also sets affinity masks for clustered/partitions 96 * real-time tasks. Default behaviors set by init_rt_task_params() are used.
90 * functions. Time units in nanoseconds. */ 97 * Also sets affinity masks for clustered/partitions functions. Time units in
98 * nanoseconds. */
91/** 99/**
92 * Set up a sporadic task with global scheduling 100 * Set up a sporadic task with global scheduling
93 * @param e_ns Execution time in nanoseconds 101 * @param e_ns Execution time in nanoseconds
@@ -95,6 +103,7 @@ int cluster_to_first_cpu(int cluster, int cluster_size);
95 * @return 0 on success 103 * @return 0 on success
96 */ 104 */
97int sporadic_global(lt_t e_ns, lt_t p_ns); 105int sporadic_global(lt_t e_ns, lt_t p_ns);
106
98/** 107/**
99 * Set up a sporadic task with partitioned scheduling 108 * Set up a sporadic task with partitioned scheduling
100 * @param e_ns Execution time in nanoseconds 109 * @param e_ns Execution time in nanoseconds
@@ -103,15 +112,15 @@ int sporadic_global(lt_t e_ns, lt_t p_ns);
103 * @return 0 on success 112 * @return 0 on success
104 */ 113 */
105int sporadic_partitioned(lt_t e_ns, lt_t p_ns, int partition); 114int sporadic_partitioned(lt_t e_ns, lt_t p_ns, int partition);
115
106/** 116/**
107 * Set up a sporadic task with clustered scheduling 117 * Set up a sporadic task with clustered scheduling
108 * @param e_ns Execution time in nanoseconds 118 * @param e_ns Execution time in nanoseconds
109 * @param p_ns Period in nanoseconds 119 * @param p_ns Period in nanoseconds
110 * @param cluster Cluster to add this task to 120 * @param cluster Cluster to add this task to
111 * @param cluster_size Size of the cluster
112 * @return 0 on success 121 * @return 0 on success
113 */ 122 */
114int sporadic_clustered(lt_t e_ns, lt_t p_ns, int cluster, int cluster_size); 123int sporadic_clustered(lt_t e_ns, lt_t p_ns, int cluster);
115 124
116/* simple time unit conversion macros */ 125/* simple time unit conversion macros */
117/** Convert seconds to nanoseconds 126/** Convert seconds to nanoseconds
@@ -250,29 +259,25 @@ typedef int (*rt_fn_t)(void*);
250 * @param arg Pointer to arguments to pass to the pointer in rt_prog