aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/litmus/litmus_proc.h38
-rw-r--r--include/litmus/sched_plugin.h6
-rw-r--r--litmus/litmus.c12
-rw-r--r--litmus/litmus_proc.c171
-rw-r--r--litmus/sched_cedf.c64
-rw-r--r--litmus/sched_cfl_split.c62
-rw-r--r--litmus/sched_gsn_edf.c55
-rw-r--r--litmus/sched_pfair.c64
-rw-r--r--litmus/sched_pfp.c48
-rw-r--r--litmus/sched_plugin.c8
-rw-r--r--litmus/sched_psn_edf.c50
11 files changed, 573 insertions, 5 deletions
diff --git a/include/litmus/litmus_proc.h b/include/litmus/litmus_proc.h
index 6800e725d48c..a5db24c03ec0 100644
--- a/include/litmus/litmus_proc.h
+++ b/include/litmus/litmus_proc.h
@@ -4,6 +4,22 @@
4int __init init_litmus_proc(void); 4int __init init_litmus_proc(void);
5void exit_litmus_proc(void); 5void exit_litmus_proc(void);
6 6
7struct cd_mapping
8{
9 int id;
10 cpumask_var_t mask;
11 struct proc_dir_entry *proc_file;
12};
13
14struct domain_proc_info
15{
16 int num_cpus;
17 int num_domains;
18
19 struct cd_mapping *cpu_to_domains;
20 struct cd_mapping *domain_to_cpus;
21};
22
7/* 23/*
8 * On success, returns 0 and sets the pointer to the location of the new 24 * On success, returns 0 and sets the pointer to the location of the new
9 * proc dir entry, otherwise returns an error code and sets pde to NULL. 25 * proc dir entry, otherwise returns an error code and sets pde to NULL.
@@ -17,6 +33,28 @@ long make_plugin_proc_dir(struct sched_plugin* plugin,
17 */ 33 */
18void remove_plugin_proc_dir(struct sched_plugin* plugin); 34void remove_plugin_proc_dir(struct sched_plugin* plugin);
19 35
36/*
37 * Setup the CPU <-> sched domain mappings in proc
38 */
39long activate_domain_proc(struct domain_proc_info* map);
40
41/*
42 * Remove the CPU <-> sched domain mappings from proc
43 */
44long deactivate_domain_proc(void);
45
46/*
47 * Alloc memory for the mapping
48 * Note: Does not set up proc files. Use make_sched_domain_maps for that.
49 */
50long init_domain_proc_info(struct domain_proc_info* map,
51 int num_cpus, int num_domains);
52
53/*
54 * Free memory of the mapping
55 * Note: Does not clean up proc files. Use deactivate_domain_proc for that.
56 */
57void destroy_domain_proc_info(struct domain_proc_info* map);
20 58
21/* Copy at most size-1 bytes from ubuf into kbuf, null-terminate buf, and 59/* Copy at most size-1 bytes from ubuf into kbuf, null-terminate buf, and
22 * remove a '\n' if present. Returns the number of bytes that were read or 60 * remove a '\n' if present. Returns the number of bytes that were read or
diff --git a/include/litmus/sched_plugin.h b/include/litmus/sched_plugin.h
index 0f2fe90123db..f173dca7cd65 100644
--- a/include/litmus/sched_plugin.h
+++ b/include/litmus/sched_plugin.h
@@ -16,6 +16,8 @@
16typedef long (*activate_plugin_t) (void); 16typedef long (*activate_plugin_t) (void);
17typedef long (*deactivate_plugin_t) (void); 17typedef long (*deactivate_plugin_t) (void);
18 18
19struct domain_proc_info;
20typedef long (*get_domain_proc_info_t) (struct domain_proc_info **info);
19 21
20 22
21/********************* scheduler invocation ******************/ 23/********************* scheduler invocation ******************/
@@ -69,6 +71,9 @@ typedef long (*admit_task_t)(struct task_struct* tsk);
69 71
70typedef void (*release_at_t)(struct task_struct *t, lt_t start); 72typedef void (*release_at_t)(struct task_struct *t, lt_t start);
71 73
74/************************ misc routines ***********************/
75
76
72struct sched_plugin { 77struct sched_plugin {
73 struct list_head list; 78 struct list_head list;
74 /* basic info */ 79 /* basic info */
@@ -77,6 +82,7 @@ struct sched_plugin {
77 /* setup */ 82 /* setup */
78 activate_plugin_t activate_plugin; 83 activate_plugin_t activate_plugin;
79 deactivate_plugin_t deactivate_plugin; 84 deactivate_plugin_t deactivate_plugin;
85 get_domain_proc_info_t get_domain_proc_info;
80 86
81 /* scheduler invocation */ 87 /* scheduler invocation */
82 scheduler_tick_t tick; 88 scheduler_tick_t tick;
diff --git a/litmus/litmus.c b/litmus/litmus.c
index 76378ce34c2b..058cb956fb44 100644
--- a/litmus/litmus.c
+++ b/litmus/litmus.c
@@ -424,20 +424,30 @@ static int do_plugin_switch(void *_plugin)
424{ 424{
425 int ret; 425 int ret;
426 struct sched_plugin* plugin = _plugin; 426 struct sched_plugin* plugin = _plugin;
427 struct domain_proc_info* domain_info;
427 428
428 /* don't switch if there are active real-time tasks */ 429 /* don't switch if there are active real-time tasks */
429 if (atomic_read(&rt_task_count) == 0) { 430 if (atomic_read(&rt_task_count) == 0) {
431 deactivate_domain_proc();
430 ret = litmus->deactivate_plugin(); 432 ret = litmus->deactivate_plugin();
431 if (0 != ret) 433 if (0 != ret) {
434 /* reactivate the old proc info */
435 if(!litmus->get_domain_proc_info(&domain_info))
436 activate_domain_proc(domain_info);
432 goto out; 437 goto out;
438 }
433 ret = plugin->activate_plugin(); 439 ret = plugin->activate_plugin();
434 if (0 != ret) { 440 if (0 != ret) {
435 printk(KERN_INFO "Can't activate %s (%d).\n", 441 printk(KERN_INFO "Can't activate %s (%d).\n",
436 plugin->plugin_name, ret); 442 plugin->plugin_name, ret);
437 plugin = &linux_sched_plugin; 443 plugin = &linux_sched_plugin;
438 } 444 }
445
439 printk(KERN_INFO "Switching to LITMUS^RT plugin %s.\n", plugin->plugin_name); 446 printk(KERN_INFO "Switching to LITMUS^RT plugin %s.\n", plugin->plugin_name);
440 litmus = plugin; 447 litmus = plugin;
448
449 if(!litmus->get_domain_proc_info(&domain_info))
450 activate_domain_proc(domain_info);
441 } else 451 } else
442 ret = -EBUSY; 452 ret = -EBUSY;
443out: 453out:
diff --git a/litmus/litmus_proc.c b/litmus/litmus_proc.c
index 1ebf1277f5d3..4db3fe2a672d 100644
--- a/litmus/litmus_proc.c
+++ b/litmus/litmus_proc.c
@@ -3,6 +3,7 @@
3 */ 3 */
4 4
5#include <linux/sched.h> 5#include <linux/sched.h>
6#include <linux/slab.h>
6#include <linux/uaccess.h> 7#include <linux/uaccess.h>
7#include <linux/seq_file.h> 8#include <linux/seq_file.h>
8 9
@@ -21,7 +22,10 @@ static struct proc_dir_entry *litmus_dir = NULL,
21#ifdef CONFIG_RELEASE_MASTER 22#ifdef CONFIG_RELEASE_MASTER
22 *release_master_file = NULL, 23 *release_master_file = NULL,
23#endif 24#endif
24 *plugs_file = NULL; 25 *plugs_file = NULL,
26 *domains_dir = NULL,
27 *cpus_dir = NULL;
28
25 29
26/* in litmus/sync.c */ 30/* in litmus/sync.c */
27int count_tasks_waiting_for_release(void); 31int count_tasks_waiting_for_release(void);
@@ -218,11 +222,32 @@ int __init init_litmus_proc(void)
218 plugs_file = proc_create("loaded", 0444, plugs_dir, 222 plugs_file = proc_create("loaded", 0444, plugs_dir,
219 &litmus_loaded_proc_fops); 223 &litmus_loaded_proc_fops);
220 224
225 domains_dir = proc_mkdir("domains", litmus_dir);
226 if (!domains_dir) {
227 printk(KERN_ERR "Could not allocate domains directory "
228 "procfs entry.\n");
229 return -ENOMEM;
230 }
231
232 cpus_dir = proc_mkdir("cpus", litmus_dir);
233 if (!cpus_dir) {
234 printk(KERN_ERR "Could not allocate cpus directory "
235 "procfs entry.\n");
236 return -ENOMEM;
237 }
238
221 return 0; 239 return 0;
222} 240}
223 241
224void exit_litmus_proc(void) 242void exit_litmus_proc(void)
225{ 243{
244 if (cpus_dir || domains_dir) {
245 deactivate_domain_proc();
246 if (cpus_dir)
247 remove_proc_entry("cpus", litmus_dir);
248 if (domains_dir)
249 remove_proc_entry("domains", litmus_dir);
250 }
226 if (plugs_file) 251 if (plugs_file)
227 remove_proc_entry("loaded", plugs_dir); 252 remove_proc_entry("loaded", plugs_dir);
228 if (plugs_dir) 253 if (plugs_dir)
@@ -405,3 +430,147 @@ struct proc_dir_entry* create_cluster_file(struct proc_dir_entry* parent,
405 } 430 }
406 return cluster_file; 431 return cluster_file;
407} 432}
433
434static struct domain_proc_info* active_mapping = NULL;
435
436static int litmus_mapping_proc_show(struct seq_file *m, void *v)
437{
438 struct cd_mapping *mapping = (struct cd_mapping*) m->private;
439 char buf[256];
440
441 if(!mapping)
442 return 0;
443
444 cpumask_scnprintf(buf, sizeof(buf), mapping->mask);
445 buf[255] = '\0'; /* just in case... */
446 seq_printf(m, "%s\n", buf);
447 return 0;
448}
449
450static int litmus_mapping_proc_open(struct inode *inode, struct file *file)
451{
452 return single_open(file, litmus_mapping_proc_show, PDE_DATA(inode));
453}
454
455static const struct file_operations litmus_domain_proc_fops = {
456 .open = litmus_mapping_proc_open,
457 .read = seq_read,
458 .llseek = seq_lseek,
459 .release = single_release,
460};
461
462long activate_domain_proc(struct domain_proc_info* map)
463{
464 int i;
465 char name[8];
466
467 if (!map)
468 return -EINVAL;
469 if (cpus_dir == NULL || domains_dir == NULL)
470 return -EINVAL;
471
472 if (active_mapping)
473 deactivate_domain_proc();
474
475 active_mapping = map;
476
477 for (i = 0; i < map->num_cpus; ++i) {
478 struct cd_mapping* m = &map->cpu_to_domains[i];
479 snprintf(name, sizeof(name), "%d", m->id);
480 m->proc_file = proc_create_data(name, 0444, cpus_dir,
481 &litmus_domain_proc_fops, (void*)m);
482 }
483
484 for (i = 0; i < map->num_domains; ++i) {
485 struct cd_mapping* m = &map->domain_to_cpus[i];
486 snprintf(name, sizeof(name), "%d", m->id);
487 m->proc_file = proc_create_data(name, 0444, domains_dir,
488 &litmus_domain_proc_fops, (void*)m);
489 }
490
491 return 0;
492}
493
494long deactivate_domain_proc()
495{
496 int i;
497 char name[65];
498
499 struct domain_proc_info* map = active_mapping;
500
501 if (!map)
502 return -EINVAL;
503
504 for (i = 0; i < map->num_cpus; ++i) {
505 struct cd_mapping* m = &map->cpu_to_domains[i];
506 snprintf(name, sizeof(name), "%d", m->id);
507 remove_proc_entry(name, cpus_dir);
508 m->proc_file = NULL;
509 }
510 for (i = 0; i < map->num_domains; ++i) {
511 struct cd_mapping* m = &map->domain_to_cpus[i];
512 snprintf(name, sizeof(name), "%d", m->id);
513 remove_proc_entry(name, domains_dir);
514 m->proc_file = NULL;
515 }
516
517 active_mapping = NULL;
518
519 return 0;
520}
521
522long init_domain_proc_info(struct domain_proc_info* m,
523 int num_cpus, int num_domains)
524{
525 int i;
526 int num_alloced_cpu_masks = 0;
527 int num_alloced_domain_masks = 0;
528
529 m->cpu_to_domains =
530 kmalloc(sizeof(*(m->cpu_to_domains))*num_cpus,
531 GFP_ATOMIC);
532 if(!m->cpu_to_domains)
533 goto failure;
534
535 m->domain_to_cpus =
536 kmalloc(sizeof(*(m->domain_to_cpus))*num_domains,
537 GFP_ATOMIC);
538 if(!m->domain_to_cpus)
539 goto failure;
540
541 for(i = 0; i < num_cpus; ++i) {
542 if(!zalloc_cpumask_var(&m->cpu_to_domains[i].mask, GFP_ATOMIC))
543 goto failure;
544 ++num_alloced_cpu_masks;
545 }
546 for(i = 0; i < num_domains; ++i) {
547 if(!zalloc_cpumask_var(&m->domain_to_cpus[i].mask, GFP_ATOMIC))
548 goto failure;
549 ++num_alloced_domain_masks;
550 }
551
552 return 0;
553
554failure:
555 for(i = 0; i < num_alloced_cpu_masks; ++i)
556 free_cpumask_var(m->cpu_to_domains[i].mask);
557 for(i = 0; i < num_alloced_domain_masks; ++i)
558 free_cpumask_var(m->domain_to_cpus[i].mask);
559 if(m->cpu_to_domains)
560 kfree(m->cpu_to_domains);
561 if(m->domain_to_cpus)
562 kfree(m->domain_to_cpus);
563 return -ENOMEM;
564}
565
566void destroy_domain_proc_info(struct domain_proc_info* m)
567{
568 int i;
569 for(i = 0; i < m->num_cpus; ++i)
570 free_cpumask_var(m->cpu_to_domains[i].mask);
571 for(i = 0; i < m->num_domains; ++i)
572 free_cpumask_var(m->domain_to_cpus[i].mask);
573 kfree(m->cpu_to_domains);
574 kfree(m->domain_to_cpus);
575 memset(m, sizeof(*m), 0);
576}
diff --git a/litmus/sched_cedf.c b/litmus/sched_cedf.c
index 10ada7edadf2..33ea89e81eff 100644
--- a/litmus/sched_cedf.c
+++ b/litmus/sched_cedf.c
@@ -753,6 +753,55 @@ static void cleanup_cedf(void)
753 } 753 }
754} 754}
755 755
756static struct domain_proc_info cedf_domain_proc_info;
757static long cedf_get_domain_proc_info(struct domain_proc_info **ret)
758{
759 *ret = &cedf_domain_proc_info;
760 return 0;
761}
762
763static void cedf_setup_domain_proc(void)
764{
765 int i, cpu, domain;
766#ifdef CONFIG_RELEASE_MASTER
767 int release_master = atomic_read(&release_master_cpu);
768 /* skip over the domain with the release master if cluster size is 1 */
769 int skip_domain = (1 == cluster_size && release_master != NO_CPU) ?
770 release_master : NO_CPU;
771#else
772 int release_master = NO_CPU;
773 int skip_domain = NO_CPU;
774#endif
775 int num_rt_cpus = num_online_cpus() - (release_master != NO_CPU);
776 int num_rt_domains = num_clusters - (skip_domain != NO_CPU);
777 struct cd_mapping *map;
778
779 memset(&cedf_domain_proc_info, sizeof(cedf_domain_proc_info), 0);
780 init_domain_proc_info(&cedf_domain_proc_info, num_rt_cpus, num_rt_domains);
781 cedf_domain_proc_info.num_cpus = num_rt_cpus;
782 cedf_domain_proc_info.num_domains = num_rt_domains;
783
784 for (cpu = 0, i = 0; cpu < num_online_cpus(); ++cpu) {
785 if (cpu == release_master)
786 continue;
787 map = &cedf_domain_proc_info.cpu_to_domains[i];
788 /* pointer math to figure out the domain index */
789 domain = remote_cluster(cpu) - cedf;
790 map->id = cpu;
791 cpumask_set_cpu(domain, map->mask);
792 ++i;
793 }
794
795 for (domain = 0, i = 0; domain < num_clusters; ++domain) {
796 if (domain == skip_domain)
797 continue;
798 map = &cedf_domain_proc_info.domain_to_cpus[i];
799 map->id = i;
800 cpumask_copy(map->mask, cedf[domain].cpu_map);
801 ++i;
802 }
803}
804
756static long cedf_activate_plugin(void) 805static long cedf_activate_plugin(void)
757{ 806{
758 int i, j, cpu, ccpu, cpu_count; 807 int i, j, cpu, ccpu, cpu_count;
@@ -771,7 +820,7 @@ static long cedf_activate_plugin(void)
771 if(!zalloc_cpumask_var(&mask, GFP_ATOMIC)) 820 if(!zalloc_cpumask_var(&mask, GFP_ATOMIC))
772 return -ENOMEM; 821 return -ENOMEM;
773 822
774 if (unlikely(cluster_config == GLOBAL_CLUSTER)) { 823 if (cluster_config == GLOBAL_CLUSTER) {
775 cluster_size = num_online_cpus(); 824 cluster_size = num_online_cpus();
776 } else { 825 } else {
777 chk = get_shared_cpu_map(mask, 0, cluster_config); 826 chk = get_shared_cpu_map(mask, 0, cluster_config);
@@ -869,8 +918,17 @@ static long cedf_activate_plugin(void)
869 } 918 }
870 } 919 }
871 920
872 free_cpumask_var(mask);
873 clusters_allocated = 1; 921 clusters_allocated = 1;
922 free_cpumask_var(mask);
923
924 cedf_setup_domain_proc();
925
926 return 0;
927}
928
929static long cedf_deactivate_plugin(void)
930{
931 destroy_domain_proc_info(&cedf_domain_proc_info);
874 return 0; 932 return 0;
875} 933}
876 934
@@ -887,6 +945,8 @@ static struct sched_plugin cedf_plugin __cacheline_aligned_in_smp = {
887 .task_block = cedf_task_block, 945 .task_block = cedf_task_block,
888 .admit_task = cedf_admit_task, 946 .admit_task = cedf_admit_task,
889 .activate_plugin = cedf_activate_plugin, 947 .activate_plugin = cedf_activate_plugin,
948 .deactivate_plugin = cedf_deactivate_plugin,
949 .get_domain_proc_info = cedf_get_domain_proc_info,
890}; 950};
891 951
892static struct proc_dir_entry *cluster_file = NULL, *cedf_dir = NULL; 952static struct proc_dir_entry *cluster_file = NULL, *cedf_dir = NULL;
diff --git a/litmus/sched_cfl_split.c b/litmus/sched_cfl_split.c
index 8dc72c39dcb2..eef10f46c7e1 100644
--- a/litmus/sched_cfl_split.c
+++ b/litmus/sched_cfl_split.c
@@ -914,6 +914,55 @@ static void cleanup_cflsplit(void)
914 } 914 }
915} 915}
916 916
917static struct domain_proc_info cflsplit_domain_proc_info;
918static long cflsplit_get_domain_proc_info(struct domain_proc_info **ret)
919{
920 *ret = &cflsplit_domain_proc_info;
921 return 0;
922}
923
924static void cflsplit_setup_domain_proc(void)
925{
926 int i, cpu, domain;
927#ifdef CONFIG_RELEASE_MASTER
928 int release_master = atomic_read(&release_master_cpu);
929 /* skip over the domain with the release master if cluster size is 1 */
930 int skip_domain = (1 == cluster_size && release_master != NO_CPU) ?
931 release_master : NO_CPU;
932#else
933 int release_master = NO_CPU;
934 int skip_domain = NO_CPU;
935#endif
936 int num_rt_cpus = num_online_cpus() - (release_master != NO_CPU);
937 int num_rt_domains = num_clusters - (skip_domain != NO_CPU);
938 struct cd_mapping *map;
939
940 memset(&cflsplit_domain_proc_info, sizeof(cflsplit_domain_proc_info), 0);
941 init_domain_proc_info(&cflsplit_domain_proc_info, num_rt_cpus, num_rt_domains);
942 cflsplit_domain_proc_info.num_cpus = num_rt_cpus;
943 cflsplit_domain_proc_info.num_domains = num_rt_domains;
944
945 for (cpu = 0, i = 0; cpu < num_online_cpus(); ++cpu) {
946 if (cpu == release_master)
947 continue;
948 map = &cflsplit_domain_proc_info.cpu_to_domains[i];
949 /* pointer math to figure out the domain index */
950 domain = remote_cluster(cpu) - cflsplit;
951 map->id = cpu;
952 cpumask_set_cpu(domain, map->mask);
953 ++i;
954 }
955
956 for (domain = 0, i = 0; domain < num_clusters; ++domain) {
957 if (domain == skip_domain)
958 continue;
959 map = &cflsplit_domain_proc_info.domain_to_cpus[i];
960 map->id = i;
961 cpumask_copy(map->mask, cflsplit[domain].cpu_map);
962 ++i;
963 }
964}
965
917static long cflsplit_activate_plugin(void) 966static long cflsplit_activate_plugin(void)
918{ 967{
919 int i, j, cpu, ccpu, cpu_count; 968 int i, j, cpu, ccpu, cpu_count;
@@ -1035,8 +1084,17 @@ static long cflsplit_activate_plugin(void)
1035 } 1084 }
1036 } 1085 }
1037 1086
1038 free_cpumask_var(mask);
1039 clusters_allocated = 1; 1087 clusters_allocated = 1;
1088 free_cpumask_var(mask);
1089
1090 cflsplit_setup_domain_proc();
1091
1092 return 0;
1093}
1094
1095static long cflsplit_deactivate_plugin(void)
1096{
1097 destroy_domain_proc_info(&cflsplit_domain_proc_info);
1040 return 0; 1098 return 0;
1041} 1099}
1042 1100
@@ -1054,6 +1112,8 @@ static struct sched_plugin cflsplit_plugin __cacheline_aligned_in_smp = {
1054 .task_block = cflsplit_task_block, 1112 .task_block = cflsplit_task_block,
1055 .admit_task = cflsplit_admit_task, 1113 .admit_task = cflsplit_admit_task,
1056 .activate_plugin = cflsplit_activate_plugin, 1114 .activate_plugin = cflsplit_activate_plugin,
1115 .deactivate_plugin = cflsplit_deactivate_plugin,
1116 .get_domain_proc_info = cflsplit_get_domain_proc_info,
1057}; 1117};
1058 1118
1059static struct proc_dir_entry *cluster_file = NULL, *cflsplit_dir = NULL; 1119static struct proc_dir_entry *cluster_file = NULL, *cflsplit_dir = NULL;
diff --git a/litmus/sched_gsn_edf.c b/litmus/sched_gsn_edf.c
index 073f0f4db821..207f4b65bcbc 100644
--- a/litmus/sched_gsn_edf.c
+++ b/litmus/sched_gsn_edf.c
@@ -28,6 +28,12 @@
28#ifdef CONFIG_SCHED_CPU_AFFINITY 28#ifdef CONFIG_SCHED_CPU_AFFINITY
29#include <litmus/affinity.h> 29#include <litmus/affinity.h>
30#endif 30#endif
31/* to set up domain/cpu mappings */
32#include <litmus/litmus_proc.h>
33
34#ifdef CONFIG_SCHED_PGM
35#include <litmus/pgm.h>
36#endif
31 37
32#ifdef CONFIG_SCHED_PGM 38#ifdef CONFIG_SCHED_PGM
33#include <litmus/pgm.h> 39#include <litmus/pgm.h>
@@ -1034,6 +1040,44 @@ static long gsnedf_allocate_lock(struct litmus_lock **lock, int type,
1034 1040
1035#endif 1041#endif
1036 1042
1043static struct domain_proc_info gsnedf_domain_proc_info;
1044static long gsnedf_get_domain_proc_info(struct domain_proc_info **ret)
1045{
1046 *ret = &gsnedf_domain_proc_info;
1047 return 0;
1048}
1049
1050static void gsnedf_setup_domain_proc(void)
1051{
1052 int i, cpu;
1053 int release_master =
1054#ifdef CONFIG_RELEASE_MASTER
1055 atomic_read(&release_master_cpu);
1056#else
1057 NO_CPU;
1058#endif
1059 int num_rt_cpus = num_online_cpus() - (release_master != NO_CPU);
1060 struct cd_mapping *map;
1061
1062 memset(&gsnedf_domain_proc_info, sizeof(gsnedf_domain_proc_info), 0);
1063 init_domain_proc_info(&gsnedf_domain_proc_info, num_rt_cpus, 1);
1064 gsnedf_domain_proc_info.num_cpus = num_rt_cpus;
1065 gsnedf_domain_proc_info.num_domains = 1;
1066
1067 gsnedf_domain_proc_info.domain_to_cpus[0].id = 0;
1068 for (cpu = 0, i = 0; cpu < num_online_cpus(); ++cpu) {
1069 if (cpu == release_master)
1070 continue;
1071 map = &gsnedf_domain_proc_info.cpu_to_domains[i];
1072 map->id = cpu;
1073 cpumask_set_cpu(0, map->mask);
1074 ++i;
1075
1076 /* add cpu to the domain */
1077 cpumask_set_cpu(cpu,
1078 gsnedf_domain_proc_info.domain_to_cpus[0].mask);
1079 }
1080}
1037 1081
1038static long gsnedf_activate_plugin(void) 1082static long gsnedf_activate_plugin(void)
1039{ 1083{
@@ -1061,6 +1105,15 @@ static long gsnedf_activate_plugin(void)
1061 } 1105 }
1062#endif 1106#endif
1063 } 1107 }
1108
1109 gsnedf_setup_domain_proc();
1110
1111 return 0;
1112}
1113
1114static long gsnedf_deactivate_plugin(void)
1115{
1116 destroy_domain_proc_info(&gsnedf_domain_proc_info);
1064 return 0; 1117 return 0;
1065} 1118}
1066 1119
@@ -1077,6 +1130,8 @@ static struct sched_plugin gsn_edf_plugin __cacheline_aligned_in_smp = {
1077 .task_block = gsnedf_task_block, 1130 .task_block = gsnedf_task_block,
1078 .admit_task = gsnedf_admit_task, 1131 .admit_task = gsnedf_admit_task,
1079 .activate_plugin = gsnedf_activate_plugin, 1132 .activate_plugin = gsnedf_activate_plugin,
1133 .deactivate_plugin = gsnedf_deactivate_plugin,
1134 .get_domain_proc_info = gsnedf_get_domain_proc_info,
1080#ifdef CONFIG_LITMUS_LOCKING 1135#ifdef CONFIG_LITMUS_LOCKING
1081 .allocate_lock = gsnedf_allocate_lock, 1136 .allocate_lock = gsnedf_allocate_lock,
1082#endif 1137#endif
diff --git a/litmus/sched_pfair.c b/litmus/sched_pfair.c
index efe5e130da15..269049861362 100644
--- a/litmus/sched_pfair.c
+++ b/litmus/sched_pfair.c
@@ -940,6 +940,66 @@ static void cleanup_clusters(void)
940 } 940 }
941} 941}
942 942
943static struct domain_proc_info pfair_domain_proc_info;
944static long pfair_get_domain_proc_info(struct domain_proc_info **ret)
945{
946 *ret = &pfair_domain_proc_info;
947 return 0;
948}
949
950static void pfair_setup_domain_proc(void)
951{
952 int i, cpu, domain;
953#ifdef CONFIG_RELEASE_MASTER
954 int release_master = atomic_read(&release_master_cpu);
955 /* skip over the domain with the release master if cluster size is 1 */
956 int cluster_size = num_online_cpus() / num_pfair_clusters;
957 int skip_domain = (1 == cluster_size && release_master != NO_CPU) ?
958 release_master : NO_CPU;
959#else
960 int release_master = NO_CPU;
961 int skip_domain = NO_CPU;
962#endif
963 int num_rt_cpus = num_online_cpus() - (release_master != NO_CPU);
964 int num_rt_domains = num_pfair_clusters - (skip_domain != NO_CPU);
965 struct cd_mapping *map;
966
967 memset(&pfair_domain_proc_info, sizeof(pfair_domain_proc_info), 0);
968 init_domain_proc_info(&pfair_domain_proc_info, num_rt_cpus, num_pfair_clusters);
969 pfair_domain_proc_info.num_cpus = num_rt_cpus;
970 pfair_domain_proc_info.num_domains = num_rt_domains;
971
972 for (cpu = 0, i = 0; cpu < num_online_cpus(); ++cpu) {
973 if (cpu == release_master)
974 continue;
975 map = &pfair_domain_proc_info.cpu_to_domains[i];
976 /* pointer math to figure out the domain index */
977 domain = cpu_cluster(&per_cpu(pfair_state, cpu)) - pfair_clusters;
978 map->id = cpu;
979 cpumask_set_cpu(domain, map->mask);
980 ++i;
981 }
982
983 for (domain = 0, i = 0; domain < num_pfair_clusters; ++domain) {
984 struct pfair_cluster *cluster;
985 struct list_head *pos;
986
987 if (domain == skip_domain)
988 continue;
989
990 cluster = &pfair_clusters[domain];
991 map = &pfair_domain_proc_info.domain_to_cpus[i];
992 map->id = i;
993
994 list_for_each(pos, &cluster->topology.cpus) {
995 cpu = cpu_id(from_cluster_list(pos));
996 if (cpu != release_master)
997 cpumask_set_cpu(cpu, map->mask);
998 }
999 ++i;
1000 }
1001}
1002
943static long pfair_activate_plugin(void) 1003static long pfair_activate_plugin(void)
944{ 1004{
945 int err, i; 1005 int err, i;
@@ -994,6 +1054,8 @@ static long pfair_activate_plugin(void)
994 1054
995 if (err < 0) 1055 if (err < 0)
996 cleanup_clusters(); 1056 cleanup_clusters();
1057 else
1058 pfair_setup_domain_proc();
997 1059
998 return err; 1060 return err;
999} 1061}
@@ -1001,6 +1063,7 @@ static long pfair_activate_plugin(void)
1001static long pfair_deactivate_plugin(void) 1063static long pfair_deactivate_plugin(void)
1002{ 1064{
1003 cleanup_clusters(); 1065 cleanup_clusters();
1066 destroy_domain_proc_info(&pfair_domain_proc_info);
1004 return 0; 1067 return 0;
1005} 1068}
1006 1069
@@ -1018,6 +1081,7 @@ static struct sched_plugin pfair_plugin __cacheline_aligned_in_smp = {
1018 .complete_job = complete_job, 1081 .complete_job = complete_job,
1019 .activate_plugin = pfair_activate_plugin, 1082 .activate_plugin = pfair_activate_plugin,
1020 .deactivate_plugin = pfair_deactivate_plugin, 1083 .deactivate_plugin = pfair_deactivate_plugin,
1084 .get_domain_proc_info = pfair_get_domain_proc_info,
1021}; 1085};
1022 1086
1023 1087
diff --git a/litmus/sched_pfp.c b/litmus/sched_pfp.c
index 01ac97d7f161..3a0157851702 100644
--- a/litmus/sched_pfp.c
+++ b/litmus/sched_pfp.c
@@ -21,6 +21,8 @@
21#include <litmus/trace.h> 21#include <litmus/trace.h>
22#include <litmus/budget.h> 22#include <litmus/budget.h>
23 23
24/* to set up domain/cpu mappings */
25#include <litmus/litmus_proc.h>
24#include <linux/uaccess.h> 26#include <linux/uaccess.h>
25 27
26 28
@@ -1681,6 +1683,43 @@ static long pfp_admit_task(struct task_struct* tsk)
1681 return -EINVAL; 1683 return -EINVAL;
1682} 1684}
1683 1685
1686static struct domain_proc_info pfp_domain_proc_info;
1687static long pfp_get_domain_proc_info(struct domain_proc_info **ret)
1688{
1689 *ret = &pfp_domain_proc_info;
1690 return 0;
1691}
1692
1693static void pfp_setup_domain_proc(void)
1694{
1695 int i, cpu;
1696 int release_master =
1697#ifdef CONFIG_RELEASE_MASTER
1698 atomic_read(&release_master_cpu);
1699#else
1700 NO_CPU;
1701#endif
1702 int num_rt_cpus = num_online_cpus() - (release_master != NO_CPU);
1703 struct cd_mapping *cpu_map, *domain_map;
1704
1705 memset(&pfp_domain_proc_info, sizeof(pfp_domain_proc_info), 0);
1706 init_domain_proc_info(&pfp_domain_proc_info, num_rt_cpus, num_rt_cpus);
1707 pfp_domain_proc_info.num_cpus = num_rt_cpus;
1708 pfp_domain_proc_info.num_domains = num_rt_cpus;
1709 for (cpu = 0, i = 0; cpu < num_online_cpus(); ++cpu) {
1710 if (cpu == release_master)
1711 continue;
1712 cpu_map = &pfp_domain_proc_info.cpu_to_domains[i];
1713 domain_map = &pfp_domain_proc_info.domain_to_cpus[i];
1714
1715 cpu_map->id = cpu;
1716 domain_map->id = i; /* enumerate w/o counting the release master */
1717 cpumask_set_cpu(i, cpu_map->mask);
1718 cpumask_set_cpu(cpu, domain_map->mask);
1719 ++i;
1720 }
1721}
1722
1684static long pfp_activate_plugin(void) 1723static long pfp_activate_plugin(void)
1685{ 1724{
1686#if defined(CONFIG_RELEASE_MASTER) || defined(CONFIG_LITMUS_LOCKING) 1725#if defined(CONFIG_RELEASE_MASTER) || defined(CONFIG_LITMUS_LOCKING)
@@ -1706,9 +1745,16 @@ static long pfp_activate_plugin(void)
1706 1745
1707#endif 1746#endif
1708 1747
1748 pfp_setup_domain_proc();
1749
1709 return 0; 1750 return 0;
1710} 1751}
1711 1752
1753static long pfp_deactivate_plugin(void)
1754{
1755 destroy_domain_proc_info(&pfp_domain_proc_info);
1756 return 0;
1757}
1712 1758
1713/* Plugin object */ 1759/* Plugin object */
1714static struct sched_plugin pfp_plugin __cacheline_aligned_in_smp = { 1760static struct sched_plugin pfp_plugin __cacheline_aligned_in_smp = {
@@ -1722,6 +1768,8 @@ static struct sched_plugin pfp_plugin __cacheline_aligned_in_smp = {
1722 .task_block = pfp_task_block, 1768 .task_block = pfp_task_block,
1723 .admit_task = pfp_admit_task, 1769 .admit_task = pfp_admit_task,
1724 .activate_plugin = pfp_activate_plugin, 1770 .activate_plugin = pfp_activate_plugin,
1771 .deactivate_plugin = pfp_deactivate_plugin,
1772 .get_domain_proc_info = pfp_get_domain_proc_info,
1725#ifdef CONFIG_LITMUS_LOCKING 1773#ifdef CONFIG_LITMUS_LOCKING
1726 .allocate_lock = pfp_allocate_lock, 1774 .allocate_lock = pfp_allocate_lock,
1727 .finish_switch = pfp_finish_switch, 1775 .finish_switch = pfp_finish_switch,
diff --git a/litmus/sched_plugin.c b/litmus/sched_plugin.c
index c4747e0ef2ab..592489629105 100644
--- a/litmus/sched_plugin.c
+++ b/litmus/sched_plugin.c
@@ -111,6 +111,12 @@ static long litmus_dummy_deactivate_plugin(void)
111 return 0; 111 return 0;
112} 112}
113 113
114static long litmus_dummy_get_domain_proc_info(struct domain_proc_info **d)
115{
116 *d = NULL;
117 return 0;
118}
119
114#ifdef CONFIG_LITMUS_LOCKING 120#ifdef CONFIG_LITMUS_LOCKING
115 121
116static long litmus_dummy_allocate_lock(struct litmus_lock **lock, int type, 122static long litmus_dummy_allocate_lock(struct litmus_lock **lock, int type,
@@ -137,6 +143,7 @@ struct sched_plugin linux_sched_plugin = {
137 .finish_switch = litmus_dummy_finish_switch, 143 .finish_switch = litmus_dummy_finish_switch,
138 .activate_plugin = litmus_dummy_activate_plugin, 144 .activate_plugin = litmus_dummy_activate_plugin,
139 .deactivate_plugin = litmus_dummy_deactivate_plugin, 145 .deactivate_plugin = litmus_dummy_deactivate_plugin,
146 .get_domain_proc_info = litmus_dummy_get_domain_proc_info,
140#ifdef CONFIG_LITMUS_LOCKING 147#ifdef CONFIG_LITMUS_LOCKING
141 .allocate_lock = litmus_dummy_allocate_lock, 148 .allocate_lock = litmus_dummy_allocate_lock,
142#endif 149#endif
@@ -175,6 +182,7 @@ int register_sched_plugin(struct sched_plugin* plugin)
175 CHECK(complete_job); 182 CHECK(complete_job);
176 CHECK(activate_plugin); 183 CHECK(activate_plugin);
177 CHECK(deactivate_plugin); 184 CHECK(deactivate_plugin);
185 CHECK(get_domain_proc_info);
178#ifdef CONFIG_LITMUS_LOCKING 186#ifdef CONFIG_LITMUS_LOCKING
179 CHECK(allocate_lock); 187 CHECK(allocate_lock);
180#endif 188#endif
diff --git a/litmus/sched_psn_edf.c b/litmus/sched_psn_edf.c
index 0873dc172651..7546dcb95317 100644
--- a/litmus/sched_psn_edf.c
+++ b/litmus/sched_psn_edf.c
@@ -23,6 +23,9 @@
23#include <litmus/sched_trace.h> 23#include <litmus/sched_trace.h>
24#include <litmus/trace.h> 24#include <litmus/trace.h>
25 25
26/* to set up domain/cpu mappings */
27#include <litmus/litmus_proc.h>
28
26typedef struct { 29typedef struct {
27 rt_domain_t domain; 30 rt_domain_t domain;
28 int cpu; 31 int cpu;
@@ -599,6 +602,43 @@ static long psnedf_allocate_lock(struct litmus_lock **lock, int type,
599 602
600#endif 603#endif
601 604
605static struct domain_proc_info psnedf_domain_proc_info;
606static long psnedf_get_domain_proc_info(struct domain_proc_info **ret)
607{
608 *ret = &psnedf_domain_proc_info;
609 return 0;
610}
611
612static void psnedf_setup_domain_proc(void)
613{
614 int i, cpu;
615 int release_master =
616#ifdef CONFIG_RELEASE_MASTER
617 atomic_read(&release_master_cpu);
618#else
619 NO_CPU;
620#endif
621 int num_rt_cpus = num_online_cpus() - (release_master != NO_CPU);
622 struct cd_mapping *cpu_map, *domain_map;
623
624 memset(&psnedf_domain_proc_info, sizeof(psnedf_domain_proc_info), 0);
625 init_domain_proc_info(&psnedf_domain_proc_info, num_rt_cpus, num_rt_cpus);
626 psnedf_domain_proc_info.num_cpus = num_rt_cpus;
627 psnedf_domain_proc_info.num_domains = num_rt_cpus;
628
629 for (cpu = 0, i = 0; cpu < num_online_cpus(); ++cpu) {
630 if (cpu == release_master)
631 continue;
632 cpu_map = &psnedf_domain_proc_info.cpu_to_domains[i];
633 domain_map = &psnedf_domain_proc_info.domain_to_cpus[i];
634
635 cpu_map->id = cpu;
636 domain_map->id = i; /* enumerate w/o counting the release master */
637 cpumask_set_cpu(i, cpu_map->mask);
638 cpumask_set_cpu(cpu, domain_map->mask);
639 ++i;
640 }
641}
602 642
603static long psnedf_activate_plugin(void) 643static long psnedf_activate_plugin(void)
604{ 644{
@@ -614,6 +654,14 @@ static long psnedf_activate_plugin(void)
614 get_srp_prio = psnedf_get_srp_prio; 654 get_srp_prio = psnedf_get_srp_prio;
615#endif 655#endif
616 656
657 psnedf_setup_domain_proc();
658
659 return 0;
660}
661
662static long psnedf_deactivate_plugin(void)
663{
664 destroy_domain_proc_info(&psnedf_domain_proc_info);
617 return 0; 665 return 0;
618} 666}
619 667
@@ -642,6 +690,8 @@ static struct sched_plugin psn_edf_plugin __cacheline_aligned_in_smp = {
642 .task_block = psnedf_task_block, 690 .task_block = psnedf_task_block,
643 .admit_task = psnedf_admit_task, 691 .admit_task = psnedf_admit_task,
644 .activate_plugin = psnedf_activate_plugin, 692 .activate_plugin = psnedf_activate_plugin,
693 .deactivate_plugin = psnedf_deactivate_plugin,
694 .get_domain_proc_info = psnedf_get_domain_proc_info,
645#ifdef CONFIG_LITMUS_LOCKING 695#ifdef CONFIG_LITMUS_LOCKING
646 .allocate_lock = psnedf_allocate_lock, 696 .allocate_lock = psnedf_allocate_lock,
647#endif 697#endif