aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-04-13 23:30:50 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-04-13 23:30:50 -0400
commit3a20b086526106a315b52a44339d8d2900eef6c6 (patch)
tree6f75327b466c895da777ce62ccdac3d40b6031c2
parent32b0d2e92d12a13051fc985bcc7f5ae7ee98a339 (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.h2
-rw-r--r--arch/x86/kernel/cpu/intel_cacheinfo.c12
-rw-r--r--include/litmus/sched_plugin.h3
-rw-r--r--litmus/litmus.c61
-rw-r--r--litmus/sched_cedf.c15
-rw-r--r--litmus/sched_plugin.c8
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 *);
172extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c); 172extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c);
173extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c); 173extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
174extern unsigned short num_cache_leaves; 174extern unsigned short num_cache_leaves;
175extern void get_shared_cpu_map(cpumask_var_t mask, 175extern int get_shared_cpu_map(cpumask_var_t mask,
176 unsigned int cpu, int index); 176 unsigned int cpu, int index);
177 177
178extern void detect_extended_topology(struct cpuinfo_x86 *c); 178extern 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 */
519void get_shared_cpu_map(cpumask_var_t mask, unsigned int cpu, int index) 519int 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
134extern struct sched_plugin *litmus; 134extern struct sched_plugin *litmus;
135 135
136/* cluster size: cache_index = 2 L2, cache_index = 3 L3 */
137extern int cluster_cache_index;
138
136int register_sched_plugin(struct sched_plugin* plugin); 139int register_sched_plugin(struct sched_plugin* plugin);
137struct sched_plugin* find_sched_plugin(const char* name); 140struct sched_plugin* find_sched_plugin(const char* name);
138int print_sched_plugins(char* buf, int max); 141int 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
557static 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
571static 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
558static int proc_read_release_master(char *page, char **start, 604static 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
614static int __init init_litmus_proc(void) 661static 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 */
179int 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()"