diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2014-02-05 00:31:08 -0500 |
---|---|---|
committer | Bjoern Brandenburg <bbb@mpi-sws.org> | 2014-02-24 14:01:11 -0500 |
commit | 1f323b00f95c4704cdeea7918853f1e9e8d26c2e (patch) | |
tree | 76a6856b2465ba7d114009f231c0dae9c9e5ef2c /include | |
parent | 871eef081ff9db7289a6947d0160cd984232c34c (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]
Diffstat (limited to 'include')
-rw-r--r-- | include/litmus.h | 35 | ||||
-rw-r--r-- | include/migration.h | 53 |
2 files changed, 43 insertions, 45 deletions
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 | */ |
53 | void init_rt_task_param(struct rt_task* param); | 53 | void 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 | */ |
60 | int set_rt_task_param(pid_t pid, struct rt_task* param); | 61 | int 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 | */ |
78 | int partition_to_cpu(int partition); | 82 | int 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 | */ |
85 | int cluster_to_first_cpu(int cluster, int cluster_size); | 92 | int 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 | */ |
97 | int sporadic_global(lt_t e_ns, lt_t p_ns); | 105 | int 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 | */ |
105 | int sporadic_partitioned(lt_t e_ns, lt_t p_ns, int partition); | 114 | int 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 | */ |
114 | int sporadic_clustered(lt_t e_ns, lt_t p_ns, int cluster, int cluster_size); | 123 | int 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 | 259 | * @param arg Pointer to arguments to pass to the pointer in rt_prog |
251 | * @param cluster Cluster to schedule this task on. For partitioned scheduling, | 260 | * @param cluster Cluster to schedule this task on. For partitioned scheduling, |
252 | * set to the desired partition. For global scheduling, set to 0 | 261 | * set to the desired partition. For global scheduling, set to 0 |
253 | * @param cluster_size Size of the cluster. For partitioned scheduling, set to | ||
254 | * 1, for global scheduling set to 0. | ||
255 | * @param wcet Worst-Case execution time for this task | 262 | * @param wcet Worst-Case execution time for this task |
256 | * @param period Period at which this task should be launched | 263 | * @param period Period at which this task should be launched |
257 | * @param prio Priority for this task | 264 | * @param prio Priority for this task |
258 | */ | 265 | */ |
259 | int create_rt_task(rt_fn_t rt_prog, void *arg, int cluster, int cluster_size, | 266 | int create_rt_task(rt_fn_t rt_prog, void *arg, int cluster, |
260 | lt_t wcet, lt_t period, unsigned int prio); | 267 | lt_t wcet, lt_t period, unsigned int prio); |
261 | /** | 268 | /** |
262 | * Create a real-time task | 269 | * Create a real-time task |
263 | * @param rt_prog Function pointer to real-time task body | 270 | * @param rt_prog Function pointer to real-time task body |
264 | * @param arg Pointer to arguments to pass to the pointer in rt_prog | 271 | * @param arg Pointer to arguments to pass to the pointer in rt_prog |
265 | * @param cluster Cluster to schedule this task on. For partitioned scheduling, | 272 | * @param cluster Cluster to schedule this task on. For partitioned scheduling, |
266 | * set to the desired partition. For global scheduling, set to 0 | 273 | * set to the desired partition. For global scheduling, set to 0 |
267 | * @param cluster_size Size of the cluster. For partitioned scheduling, set to | ||
268 | * 1, for global scheduling set to 0. | ||
269 | * @param wcet Worst-Case execution time for this task | 274 | * @param wcet Worst-Case execution time for this task |
270 | * @param period Period at which this task should be launched | 275 | * @param period Period at which this task should be launched |
271 | * @param prio Priority for this task | 276 | * @param prio Priority for this task |
272 | * @param cls Task class (???) | 277 | * @param cls Task class (unused) |
273 | */ | 278 | */ |
274 | int __create_rt_task(rt_fn_t rt_prog, void *arg, int cluster, int cluster_size, | 279 | int __create_rt_task(rt_fn_t rt_prog, void *arg, int cluster, |
275 | lt_t wcet, lt_t period, unsigned int prio, task_class_t cls); | 280 | lt_t wcet, lt_t period, unsigned int prio, task_class_t cls); |
276 | 281 | ||
277 | /* per-task modes */ | 282 | /* per-task modes */ |
278 | enum rt_task_mode_t { | 283 | enum rt_task_mode_t { |
diff --git a/include/migration.h b/include/migration.h index 32d933b..f60dfe9 100644 --- a/include/migration.h +++ b/include/migration.h | |||
@@ -19,62 +19,55 @@ pid_t gettid(); | |||
19 | * @return 0 if successful | 19 | * @return 0 if successful |
20 | */ | 20 | */ |
21 | int be_migrate_thread_to_cpu(pid_t tid, int target_cpu); | 21 | int be_migrate_thread_to_cpu(pid_t tid, int target_cpu); |
22 | /** | 22 | |
23 | * Migrate and assign a task to a given partition | ||
24 | * @param tid Process ID for migrated task, 0 for current task | ||
25 | * @param partition Partition ID to migrate the task to | ||
26 | * @pre tid is not yet in real-time mode (it's a best effort task) | ||
27 | * @return 0 if successful | ||
28 | */ | ||
29 | int be_migrate_thread_to_partition(pid_t tid, int partition); | ||
30 | /** | 23 | /** |
31 | * Migrate current task to a given cluster | 24 | * Migrate current task to a given cluster |
32 | * @param tid Process ID for migrated task, 0 for current task | 25 | * @param tid Process ID for migrated task, 0 for current task |
33 | * @param cluster Cluster ID to migrate the task to | 26 | * @param domain Cluster ID to migrate the task to |
34 | * @param cluster_sz Size of the cluster to migrate to | ||
35 | * @pre tid is not yet in real-time mode (it's a best effort task) | 27 | * @pre tid is not yet in real-time mode (it's a best effort task) |
36 | * @return 0 if successful | 28 | * @return 0 if successful |
37 | * | ||
38 | * If using release master, set cluster_sz to size of largest cluster. tid | ||
39 | * will not be scheduled on release master | ||
40 | */ | ||
41 | int be_migrate_thread_to_cluster(pid_t tid, int cluster, int cluster_sz); | ||
42 | |||
43 | /** | ||
44 | * @private | ||
45 | * set ignore_rm == 1 to include release master in tid's cpu affinity | ||
46 | */ | 29 | */ |
47 | int __be_migrate_thread_to_cluster(pid_t tid, int cluster, int cluster_sz, int ignore_rm); | 30 | int be_migrate_thread_to_cluster(pid_t tid, int domain); |
48 | 31 | ||
49 | /** | 32 | /** |
50 | * Migrate current task to a given CPU | 33 | * Migrate current task to a given CPU |
51 | * @param target_cpu ID for CPU to migrate to | 34 | * @param target_cpu ID for CPU to migrate to |
52 | * @pre tid is not yet in real-time mode (it's a best effort task) | 35 | * @pre The current task is not yet in real-time mode (it's a best-effort task) |
53 | * @return 0 if successful | 36 | * @return 0 if successful |
54 | */ | 37 | */ |
55 | int be_migrate_to_cpu(int target_cpu); | 38 | int be_migrate_to_cpu(int target_cpu); |
56 | /** | 39 | |
57 | * Migrate current task to a given partition | ||
58 | * @param partition Partition ID to migrate the task to | ||
59 | * @pre tid is not yet in real-time mode (it's a best effort task) | ||
60 | * @return 0 if successful | ||
61 | */ | ||
62 | int be_migrate_to_partition(int partition); | ||
63 | /** | 40 | /** |
64 | * Migrate current task to a given cluster | 41 | * Migrate current task to a given cluster |
65 | * @param cluster Cluster ID to migrate the task to | 42 | * @param cluster Cluster ID to migrate the task to |
66 | * @param cluster_sz Size of the cluster to migrate to | 43 | * @param cluster_sz Size of the cluster to migrate to (unused) |
67 | * @pre tid is not yet in real-time mode (it's a best effort task) | 44 | * @pre The current task is not yet in real-time mode (it's a best-effort task) |
68 | * @return 0 if successful | 45 | * @return 0 if successful |
46 | * | ||
47 | * \deprecated{Use be_migrate_to_domain() instead in new code.} | ||
69 | */ | 48 | */ |
70 | int be_migrate_to_cluster(int cluster, int cluster_sz); | 49 | int be_migrate_to_cluster(int cluster, int cluster_sz); |
71 | 50 | ||
72 | /** | 51 | /** |
52 | * Migrate current task to a given scheduling domain (i.e., cluster or | ||
53 | * partition). | ||
54 | * @param domain The cluster/partition to migrate to. | ||
55 | * @pre The current task is not yet in real-time mode (it's a best-effort task). | ||
56 | * @return 0 if successful | ||
57 | */ | ||
58 | int be_migrate_to_domain(int domain); | ||
59 | |||
60 | /** | ||
73 | * Return the number of CPUs currently online | 61 | * Return the number of CPUs currently online |
74 | * @return The number of online CPUs | 62 | * @return The number of online CPUs |
75 | */ | 63 | */ |
76 | int num_online_cpus(); | 64 | int num_online_cpus(); |
65 | |||
77 | /** | 66 | /** |
78 | * @todo Document! | 67 | * @todo Document! |
79 | */ | 68 | */ |
80 | int release_master(); | 69 | int release_master(); |
70 | int domain_to_cpus(int domain, unsigned long long int* mask); | ||
71 | int cpu_to_domains(int cpu, unsigned long long int* mask); | ||
72 | |||
73 | int domain_to_first_cpu(int domain); | ||