diff options
Diffstat (limited to 'litmus/litmus.c')
-rw-r--r-- | litmus/litmus.c | 82 |
1 files changed, 79 insertions, 3 deletions
diff --git a/litmus/litmus.c b/litmus/litmus.c index 3cf7cb9e8a9f..e43596a5104c 100644 --- a/litmus/litmus.c +++ b/litmus/litmus.c | |||
@@ -24,6 +24,8 @@ | |||
24 | /* Number of RT tasks that exist in the system */ | 24 | /* Number of RT tasks that exist in the system */ |
25 | atomic_t rt_task_count = ATOMIC_INIT(0); | 25 | atomic_t rt_task_count = ATOMIC_INIT(0); |
26 | static DEFINE_SPINLOCK(task_transition_lock); | 26 | static DEFINE_SPINLOCK(task_transition_lock); |
27 | /* synchronize plugin switching */ | ||
28 | atomic_t cannot_use_plugin = ATOMIC_INIT(0); | ||
27 | 29 | ||
28 | /* Give log messages sequential IDs. */ | 30 | /* Give log messages sequential IDs. */ |
29 | atomic_t __log_seq_no = ATOMIC_INIT(0); | 31 | atomic_t __log_seq_no = ATOMIC_INIT(0); |
@@ -369,13 +371,17 @@ void litmus_exit_task(struct task_struct* tsk) | |||
369 | } | 371 | } |
370 | } | 372 | } |
371 | 373 | ||
374 | /* IPI callback to synchronize plugin switching */ | ||
375 | static void synch_on_plugin_switch(void* info) | ||
376 | { | ||
377 | while (atomic_read(&cannot_use_plugin)) | ||
378 | cpu_relax(); | ||
379 | } | ||
380 | |||
372 | /* Switching a plugin in use is tricky. | 381 | /* Switching a plugin in use is tricky. |
373 | * We must watch out that no real-time tasks exists | 382 | * We must watch out that no real-time tasks exists |
374 | * (and that none is created in parallel) and that the plugin is not | 383 | * (and that none is created in parallel) and that the plugin is not |
375 | * currently in use on any processor (in theory). | 384 | * currently in use on any processor (in theory). |
376 | * | ||
377 | * For now, we don't enforce the second part since it is unlikely to cause | ||
378 | * any trouble by itself as long as we don't unload modules. | ||
379 | */ | 385 | */ |
380 | int switch_sched_plugin(struct sched_plugin* plugin) | 386 | int switch_sched_plugin(struct sched_plugin* plugin) |
381 | { | 387 | { |
@@ -384,6 +390,11 @@ int switch_sched_plugin(struct sched_plugin* plugin) | |||
384 | 390 | ||
385 | BUG_ON(!plugin); | 391 | BUG_ON(!plugin); |
386 | 392 | ||
393 | /* forbid other cpus to use the plugin */ | ||
394 | atomic_set(&cannot_use_plugin, 1); | ||
395 | /* send IPI to force other CPUs to synch with us */ | ||
396 | smp_call_function(synch_on_plugin_switch, NULL, 0); | ||
397 | |||
387 | /* stop task transitions */ | 398 | /* stop task transitions */ |
388 | spin_lock_irqsave(&task_transition_lock, flags); | 399 | spin_lock_irqsave(&task_transition_lock, flags); |
389 | 400 | ||
@@ -404,6 +415,7 @@ int switch_sched_plugin(struct sched_plugin* plugin) | |||
404 | ret = -EBUSY; | 415 | ret = -EBUSY; |
405 | out: | 416 | out: |
406 | spin_unlock_irqrestore(&task_transition_lock, flags); | 417 | spin_unlock_irqrestore(&task_transition_lock, flags); |
418 | atomic_set(&cannot_use_plugin, 0); | ||
407 | return ret; | 419 | return ret; |
408 | } | 420 | } |
409 | 421 | ||
@@ -554,6 +566,55 @@ static int proc_write_curr(struct file *file, | |||
554 | return len; | 566 | return len; |
555 | } | 567 | } |
556 | 568 | ||
569 | static int proc_read_cluster_size(char *page, char **start, | ||
570 | off_t off, int count, | ||
571 | int *eof, void *data) | ||
572 | { | ||
573 | int len; | ||
574 | if (cluster_cache_index == 2) | ||
575 | len = snprintf(page, PAGE_SIZE, "L2\n"); | ||
576 | else if (cluster_cache_index == 3) | ||
577 | len = snprintf(page, PAGE_SIZE, "L3\n"); | ||
578 | else /* (cluster_cache_index == 1) */ | ||
579 | len = snprintf(page, PAGE_SIZE, "L1\n"); | ||
580 | |||
581 | return len; | ||
582 | } | ||
583 | |||
584 | static int proc_write_cluster_size(struct file *file, | ||
585 | const char *buffer, | ||
586 | unsigned long count, | ||
587 | void *data) | ||
588 | { | ||
589 | int len; | ||
590 | /* L2, L3 */ | ||
591 | char cache_name[33]; | ||
592 | |||
593 | if(count > 32) | ||
594 | len = 32; | ||
595 | else | ||
596 | len = count; | ||
597 | |||
598 | if(copy_from_user(cache_name, buffer, len)) | ||
599 | return -EFAULT; | ||
600 | |||
601 | cache_name[len] = '\0'; | ||
602 | /* chomp name */ | ||
603 | if (len > 1 && cache_name[len - 1] == '\n') | ||
604 | cache_name[len - 1] = '\0'; | ||
605 | |||
606 | /* do a quick and dirty comparison to find the cluster size */ | ||
607 | if (!strcmp(cache_name, "L2")) | ||
608 | cluster_cache_index = 2; | ||
609 | else if (!strcmp(cache_name, "L3")) | ||
610 | cluster_cache_index = 3; | ||
611 | else if (!strcmp(cache_name, "L1")) | ||
612 | cluster_cache_index = 1; | ||
613 | else | ||
614 | printk(KERN_INFO "Cluster '%s' is unknown.\n", cache_name); | ||
615 | |||
616 | return len; | ||
617 | } | ||
557 | 618 | ||
558 | static int proc_read_release_master(char *page, char **start, | 619 | static int proc_read_release_master(char *page, char **start, |
559 | off_t off, int count, | 620 | off_t off, int count, |
@@ -609,6 +670,7 @@ static struct proc_dir_entry *litmus_dir = NULL, | |||
609 | *curr_file = NULL, | 670 | *curr_file = NULL, |
610 | *stat_file = NULL, | 671 | *stat_file = NULL, |
611 | *plugs_file = NULL, | 672 | *plugs_file = NULL, |
673 | *clus_cache_idx_file = NULL, | ||
612 | *release_master_file = NULL; | 674 | *release_master_file = NULL; |
613 | 675 | ||
614 | static int __init init_litmus_proc(void) | 676 | static int __init init_litmus_proc(void) |
@@ -639,6 +701,16 @@ static int __init init_litmus_proc(void) | |||
639 | release_master_file->read_proc = proc_read_release_master; | 701 | release_master_file->read_proc = proc_read_release_master; |
640 | release_master_file->write_proc = proc_write_release_master; | 702 | release_master_file->write_proc = proc_write_release_master; |
641 | 703 | ||
704 | clus_cache_idx_file = create_proc_entry("cluster_cache", | ||
705 | 0644, litmus_dir); | ||
706 | if (!clus_cache_idx_file) { | ||
707 | printk(KERN_ERR "Could not allocate cluster_cache " | ||
708 | "procfs entry.\n"); | ||
709 | return -ENOMEM; | ||
710 | } | ||
711 | clus_cache_idx_file->read_proc = proc_read_cluster_size; | ||
712 | clus_cache_idx_file->write_proc = proc_write_cluster_size; | ||
713 | |||
642 | stat_file = create_proc_read_entry("stats", 0444, litmus_dir, | 714 | stat_file = create_proc_read_entry("stats", 0444, litmus_dir, |
643 | proc_read_stats, NULL); | 715 | proc_read_stats, NULL); |
644 | 716 | ||
@@ -656,6 +728,10 @@ static void exit_litmus_proc(void) | |||
656 | remove_proc_entry("stats", litmus_dir); | 728 | remove_proc_entry("stats", litmus_dir); |
657 | if (curr_file) | 729 | if (curr_file) |
658 | remove_proc_entry("active_plugin", litmus_dir); | 730 | remove_proc_entry("active_plugin", litmus_dir); |
731 | if (clus_cache_idx_file) | ||
732 | remove_proc_entry("cluster_cache", litmus_dir); | ||
733 | if (release_master_file) | ||
734 | remove_proc_entry("release_master", litmus_dir); | ||
659 | if (litmus_dir) | 735 | if (litmus_dir) |
660 | remove_proc_entry("litmus", NULL); | 736 | remove_proc_entry("litmus", NULL); |
661 | } | 737 | } |