diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-04-13 23:30:50 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-04-13 23:30:50 -0400 |
commit | 3a20b086526106a315b52a44339d8d2900eef6c6 (patch) | |
tree | 6f75327b466c895da777ce62ccdac3d40b6031c2 | |
parent | 32b0d2e92d12a13051fc985bcc7f5ae7ee98a339 (diff) |
Add /proc/litmus/cluster_cache
- read L2, L3 clustering from proc file (default L2)
- check for "feasible cluster size"
-rw-r--r-- | arch/x86/include/asm/processor.h | 2 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/intel_cacheinfo.c | 12 | ||||
-rw-r--r-- | include/litmus/sched_plugin.h | 3 | ||||
-rw-r--r-- | litmus/litmus.c | 61 | ||||
-rw-r--r-- | litmus/sched_cedf.c | 15 | ||||
-rw-r--r-- | litmus/sched_plugin.c | 8 |
6 files changed, 93 insertions, 8 deletions
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 4e60b624d121..e75daac64962 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h | |||
@@ -172,7 +172,7 @@ extern void print_cpu_info(struct cpuinfo_x86 *); | |||
172 | extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c); | 172 | extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c); |
173 | extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c); | 173 | extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c); |
174 | extern unsigned short num_cache_leaves; | 174 | extern unsigned short num_cache_leaves; |
175 | extern void get_shared_cpu_map(cpumask_var_t mask, | 175 | extern int get_shared_cpu_map(cpumask_var_t mask, |
176 | unsigned int cpu, int index); | 176 | unsigned int cpu, int index); |
177 | 177 | ||
178 | extern void detect_extended_topology(struct cpuinfo_x86 *c); | 178 | extern void detect_extended_topology(struct cpuinfo_x86 *c); |
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c index ffdc69c05e4c..ea348f24c23b 100644 --- a/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c | |||
@@ -516,13 +516,21 @@ static DEFINE_PER_CPU(struct _cpuid4_info *, cpuid4_info); | |||
516 | #define CPUID4_INFO_IDX(x, y) (&((per_cpu(cpuid4_info, x))[y])) | 516 | #define CPUID4_INFO_IDX(x, y) (&((per_cpu(cpuid4_info, x))[y])) |
517 | 517 | ||
518 | /* returns CPUs that share the index cache with cpu */ | 518 | /* returns CPUs that share the index cache with cpu */ |
519 | void get_shared_cpu_map(cpumask_var_t mask, unsigned int cpu, int index) | 519 | int get_shared_cpu_map(cpumask_var_t mask, unsigned int cpu, int index) |
520 | { | 520 | { |
521 | int ret = 0; | ||
521 | struct _cpuid4_info *this_leaf; | 522 | struct _cpuid4_info *this_leaf; |
522 | 523 | ||
524 | printk(KERN_INFO "idx = %d, max = %d\n", index, num_cache_leaves); | ||
525 | if (index >= num_cache_leaves) { | ||
526 | index = num_cache_leaves - 1; | ||
527 | ret = index; | ||
528 | } | ||
529 | |||
523 | this_leaf = CPUID4_INFO_IDX(cpu,index); | 530 | this_leaf = CPUID4_INFO_IDX(cpu,index); |
524 | cpumask_copy(mask, to_cpumask(this_leaf->shared_cpu_map)); | 531 | cpumask_copy(mask, to_cpumask(this_leaf->shared_cpu_map)); |
525 | return; | 532 | |
533 | return ret; | ||
526 | } | 534 | } |
527 | 535 | ||
528 | #ifdef CONFIG_SMP | 536 | #ifdef CONFIG_SMP |
diff --git a/include/litmus/sched_plugin.h b/include/litmus/sched_plugin.h index 2d856d587041..9c1c9f28ba79 100644 --- a/include/litmus/sched_plugin.h +++ b/include/litmus/sched_plugin.h | |||
@@ -133,6 +133,9 @@ struct sched_plugin { | |||
133 | 133 | ||
134 | extern struct sched_plugin *litmus; | 134 | extern struct sched_plugin *litmus; |
135 | 135 | ||
136 | /* cluster size: cache_index = 2 L2, cache_index = 3 L3 */ | ||
137 | extern int cluster_cache_index; | ||
138 | |||
136 | int register_sched_plugin(struct sched_plugin* plugin); | 139 | int register_sched_plugin(struct sched_plugin* plugin); |
137 | struct sched_plugin* find_sched_plugin(const char* name); | 140 | struct sched_plugin* find_sched_plugin(const char* name); |
138 | int print_sched_plugins(char* buf, int max); | 141 | int print_sched_plugins(char* buf, int max); |
diff --git a/litmus/litmus.c b/litmus/litmus.c index 3cf7cb9e8a9f..c815c5ac492c 100644 --- a/litmus/litmus.c +++ b/litmus/litmus.c | |||
@@ -554,6 +554,52 @@ static int proc_write_curr(struct file *file, | |||
554 | return len; | 554 | return len; |
555 | } | 555 | } |
556 | 556 | ||
557 | static int proc_read_cluster_size(char *page, char **start, | ||
558 | off_t off, int count, | ||
559 | int *eof, void *data) | ||
560 | { | ||
561 | int len; | ||
562 | if (cluster_cache_index == 2) | ||
563 | len = snprintf(page, PAGE_SIZE, "L2\n"); | ||
564 | else | ||
565 | /* (cluster_cache_index == 3) */ | ||
566 | len = snprintf(page, PAGE_SIZE, "L3\n"); | ||
567 | |||
568 | return len; | ||
569 | } | ||
570 | |||
571 | static int proc_write_cluster_size(struct file *file, | ||
572 | const char *buffer, | ||
573 | unsigned long count, | ||
574 | void *data) | ||
575 | { | ||
576 | int len; | ||
577 | /* L2, L3 */ | ||
578 | char cache_name[5]; | ||
579 | |||
580 | if(count > 5) | ||
581 | len = 4; | ||
582 | else | ||
583 | len = count; | ||
584 | |||
585 | if(copy_from_user(cache_name, buffer, len)) | ||
586 | return -EFAULT; | ||
587 | |||
588 | cache_name[len] = '\0'; | ||
589 | /* chomp name */ | ||
590 | if (len > 1 && cache_name[len - 1] == '\n') | ||
591 | cache_name[len - 1] = '\0'; | ||
592 | |||
593 | /* do a quick and dirty comparison to find the cluster size */ | ||
594 | if (!strcmp(cache_name, "L2")) | ||
595 | cluster_cache_index = 2; | ||
596 | else if (!strcmp(cache_name, "L3")) | ||
597 | cluster_cache_index = 3; | ||
598 | else | ||
599 | printk(KERN_INFO "Cluster '%s' is unknown.\n", cache_name); | ||
600 | |||
601 | return len; | ||
602 | } | ||
557 | 603 | ||
558 | static int proc_read_release_master(char *page, char **start, | 604 | static int proc_read_release_master(char *page, char **start, |
559 | off_t off, int count, | 605 | off_t off, int count, |
@@ -609,6 +655,7 @@ static struct proc_dir_entry *litmus_dir = NULL, | |||
609 | *curr_file = NULL, | 655 | *curr_file = NULL, |
610 | *stat_file = NULL, | 656 | *stat_file = NULL, |
611 | *plugs_file = NULL, | 657 | *plugs_file = NULL, |
658 | *clus_cache_idx_file = NULL, | ||
612 | *release_master_file = NULL; | 659 | *release_master_file = NULL; |
613 | 660 | ||
614 | static int __init init_litmus_proc(void) | 661 | static int __init init_litmus_proc(void) |
@@ -639,6 +686,16 @@ static int __init init_litmus_proc(void) | |||
639 | release_master_file->read_proc = proc_read_release_master; | 686 | release_master_file->read_proc = proc_read_release_master; |
640 | release_master_file->write_proc = proc_write_release_master; | 687 | release_master_file->write_proc = proc_write_release_master; |
641 | 688 | ||
689 | clus_cache_idx_file = create_proc_entry("cluster_cache", | ||
690 | 0644, litmus_dir); | ||
691 | if (!clus_cache_idx_file) { | ||
692 | printk(KERN_ERR "Could not allocate cluster_cache " | ||
693 | "procfs entry.\n"); | ||
694 | return -ENOMEM; | ||
695 | } | ||
696 | clus_cache_idx_file->read_proc = proc_read_cluster_size; | ||
697 | clus_cache_idx_file->write_proc = proc_write_cluster_size; | ||
698 | |||
642 | stat_file = create_proc_read_entry("stats", 0444, litmus_dir, | 699 | stat_file = create_proc_read_entry("stats", 0444, litmus_dir, |
643 | proc_read_stats, NULL); | 700 | proc_read_stats, NULL); |
644 | 701 | ||
@@ -656,6 +713,10 @@ static void exit_litmus_proc(void) | |||
656 | remove_proc_entry("stats", litmus_dir); | 713 | remove_proc_entry("stats", litmus_dir); |
657 | if (curr_file) | 714 | if (curr_file) |
658 | remove_proc_entry("active_plugin", litmus_dir); | 715 | remove_proc_entry("active_plugin", litmus_dir); |
716 | if (clus_cache_idx_file) | ||
717 | remove_proc_entry("cluster_cache", litmus_dir); | ||
718 | if (release_master_file) | ||
719 | remove_proc_entry("release_master", litmus_dir); | ||
659 | if (litmus_dir) | 720 | if (litmus_dir) |
660 | remove_proc_entry("litmus", NULL); | 721 | remove_proc_entry("litmus", NULL); |
661 | } | 722 | } |
diff --git a/litmus/sched_cedf.c b/litmus/sched_cedf.c index 4f3b1ebe906c..e11c4c4eb27e 100644 --- a/litmus/sched_cedf.c +++ b/litmus/sched_cedf.c | |||
@@ -766,11 +766,12 @@ static long cedf_activate_plugin(void) | |||
766 | 766 | ||
767 | cpumask_var_t mask; | 767 | cpumask_var_t mask; |
768 | char buf[255]; | 768 | char buf[255]; |
769 | int wrt; | 769 | int chk = 0; |
770 | 770 | ||
771 | bheap_init(&cedf_cpu_heap); | 771 | bheap_init(&cedf_cpu_heap); |
772 | cedf.release_master = atomic_read(&release_master_cpu); | 772 | cedf.release_master = atomic_read(&release_master_cpu); |
773 | 773 | ||
774 | printk(KERN_INFO "Cluster cache index = %d\n", cluster_cache_index); | ||
774 | for_each_online_cpu(cpu) { | 775 | for_each_online_cpu(cpu) { |
775 | entry = &per_cpu(cedf_cpu_entries, cpu); | 776 | entry = &per_cpu(cedf_cpu_entries, cpu); |
776 | bheap_node_init(&entry->hn, entry); | 777 | bheap_node_init(&entry->hn, entry); |
@@ -784,11 +785,15 @@ static long cedf_activate_plugin(void) | |||
784 | TRACE("C-EDF: CPU %d is release master.\n", cpu); | 785 | TRACE("C-EDF: CPU %d is release master.\n", cpu); |
785 | } | 786 | } |
786 | 787 | ||
787 | get_shared_cpu_map(mask, cpu, 2); | 788 | chk = get_shared_cpu_map(mask, cpu, cluster_cache_index); |
788 | wrt = cpulist_scnprintf(buf, 254, mask); | ||
789 | buf[wrt] = '\0'; | ||
790 | printk(KERN_INFO "CPU = %d, shared_L2 cpus = %s\n", cpu, buf); | ||
791 | 789 | ||
790 | if (chk) | ||
791 | printk(KERN_INFO "C-EDF: Cannot cluster with %d, \ | ||
792 | using %d instead", cluster_cache_index, chk); | ||
793 | |||
794 | chk = cpulist_scnprintf(buf, 254, mask); | ||
795 | buf[chk] = '\0'; | ||
796 | printk(KERN_INFO "CPU = %d, shared cpus = %s\n", cpu, buf); | ||
792 | } | 797 | } |
793 | return 0; | 798 | return 0; |
794 | } | 799 | } |
diff --git a/litmus/sched_plugin.c b/litmus/sched_plugin.c index bc7c0e93fb18..3767b30e610a 100644 --- a/litmus/sched_plugin.c +++ b/litmus/sched_plugin.c | |||
@@ -171,6 +171,14 @@ struct sched_plugin linux_sched_plugin = { | |||
171 | }; | 171 | }; |
172 | 172 | ||
173 | /* | 173 | /* |
174 | * The cluster size is needed in C-EDF: it makes sense only to cluster | ||
175 | * around L2 or L3, so if cluster_cache_index = 2 (default) we cluster | ||
176 | * all the CPUs that shares a L2 cache, while cluster_cache_index = 3 | ||
177 | * we cluster all CPs that shares a L3 cache | ||
178 | */ | ||
179 | int cluster_cache_index = 2; | ||
180 | |||
181 | /* | ||
174 | * The reference to current plugin that is used to schedule tasks within | 182 | * The reference to current plugin that is used to schedule tasks within |
175 | * the system. It stores references to actual function implementations | 183 | * the system. It stores references to actual function implementations |
176 | * Should be initialized by calling "init_***_plugin()" | 184 | * Should be initialized by calling "init_***_plugin()" |