aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristopher Kenna <cjk@cs.unc.edu>2011-09-08 10:27:46 -0400
committerChristopher Kenna <cjk@cs.unc.edu>2011-09-08 10:27:46 -0400
commit9d5161afcc52b34cdde7ab9fd997dc73e988ffb7 (patch)
tree4798a2c8764e3bcb244eab604b22a27210548837
parent87c74e28dbad17050783cb30278561f451677152 (diff)
Better procfs error handling and plugin activation locking.
-rw-r--r--litmus/sched_mc_ce.c76
1 files changed, 49 insertions, 27 deletions
diff --git a/litmus/sched_mc_ce.c b/litmus/sched_mc_ce.c
index 8ed960c8729c..1fdca7a7d3aa 100644
--- a/litmus/sched_mc_ce.c
+++ b/litmus/sched_mc_ce.c
@@ -31,6 +31,7 @@ static struct sched_plugin mc_ce_plugin __cacheline_aligned_in_smp;
31static atomic_t start_time_set = ATOMIC_INIT(0); 31static atomic_t start_time_set = ATOMIC_INIT(0);
32static atomic64_t start_time = ATOMIC64_INIT(0); 32static atomic64_t start_time = ATOMIC64_INIT(0);
33static struct proc_dir_entry *mc_ce_dir = NULL, *ce_file = NULL; 33static struct proc_dir_entry *mc_ce_dir = NULL, *ce_file = NULL;
34static DEFINE_RAW_SPINLOCK(activate_lock);
34 35
35/* 36/*
36 * Cache the budget along with the struct PID for a task so that we don't need 37 * Cache the budget along with the struct PID for a task so that we don't need
@@ -430,6 +431,8 @@ static long mc_ce_activate_plugin(void)
430 domain_t *dom; 431 domain_t *dom;
431 int cpu; 432 int cpu;
432 433
434 raw_spin_lock(&activate_lock);
435
433 for_each_online_cpu(cpu) { 436 for_each_online_cpu(cpu) {
434 dom = &per_cpu(mc_ce_doms, cpu); 437 dom = &per_cpu(mc_ce_doms, cpu);
435 ce_data = dom->data; 438 ce_data = dom->data;
@@ -440,9 +443,34 @@ static long mc_ce_activate_plugin(void)
440 atomic_set(&start_time_set, 0); 443 atomic_set(&start_time_set, 0);
441 atomic64_set(&start_time, litmus_clock()); 444 atomic64_set(&start_time, litmus_clock());
442 arm_all_timers(); 445 arm_all_timers();
446 raw_spin_unlock(&activate_lock);
443 return 0; 447 return 0;
444} 448}
445 449
450static void clear_pid_entries(void)
451{
452 int cpu, entry;
453 domain_t *dom;
454 struct ce_dom_data *ce_data;
455
456 for_each_online_cpu(cpu) {
457 dom = &per_cpu(mc_ce_doms, cpu);
458 ce_data = dom->data;
459 ce_data->num_pid_entries = 0;
460 ce_data->cycle_time = 0;
461 for (entry = 0; entry < CONFIG_PLUGIN_MC_LEVEL_A_MAX_TASKS;
462 ++entry) {
463 if (NULL != ce_data->pid_entries[entry].pid) {
464 put_pid(ce_data->pid_entries[entry].pid);
465 ce_data->pid_entries[entry].pid = NULL;
466 }
467 ce_data->pid_entries[entry].exec_cost = 0;
468 ce_data->pid_entries[entry].acc_time = 0;
469 }
470 }
471}
472
473static void tear_down_proc(void);
446static long mc_ce_deactivate_plugin(void) 474static long mc_ce_deactivate_plugin(void)
447{ 475{
448 domain_t *dom; 476 domain_t *dom;
@@ -456,6 +484,8 @@ static long mc_ce_deactivate_plugin(void)
456 atomic_set(&ce_data->timer_info.state, 484 atomic_set(&ce_data->timer_info.state,
457 HRTIMER_START_ON_INACTIVE); 485 HRTIMER_START_ON_INACTIVE);
458 } 486 }
487 clear_pid_entries();
488 tear_down_proc();
459 return 0; 489 return 0;
460} 490}
461 491
@@ -476,31 +506,7 @@ static struct sched_plugin mc_ce_plugin __cacheline_aligned_in_smp = {
476 .deactivate_plugin = mc_ce_deactivate_plugin, 506 .deactivate_plugin = mc_ce_deactivate_plugin,
477}; 507};
478 508
479static void clear_pid_entries(void)
480{
481 int cpu, entry;
482 domain_t *dom;
483 struct ce_dom_data *ce_data;
484
485 for_each_online_cpu(cpu) {
486 dom = &per_cpu(mc_ce_doms, cpu);
487 ce_data = dom->data;
488 ce_data->num_pid_entries = 0;
489 ce_data->cycle_time = 0;
490 for (entry = 0; entry < CONFIG_PLUGIN_MC_LEVEL_A_MAX_TASKS;
491 ++entry) {
492 if (NULL != ce_data->pid_entries[entry].pid) {
493 put_pid(ce_data->pid_entries[entry].pid);
494 ce_data->pid_entries[entry].pid = NULL;
495 }
496 ce_data->pid_entries[entry].exec_cost = 0;
497 ce_data->pid_entries[entry].acc_time = 0;
498 }
499 }
500}
501
502static int setup_proc(void); 509static int setup_proc(void);
503
504static int __init init_sched_mc_ce(void) 510static int __init init_sched_mc_ce(void)
505{ 511{
506 struct ce_dom_data *ce_data; 512 struct ce_dom_data *ce_data;
@@ -510,7 +516,7 @@ static int __init init_sched_mc_ce(void)
510 clear_pid_entries(); 516 clear_pid_entries();
511 for_each_online_cpu(cpu) { 517 for_each_online_cpu(cpu) {
512 dom = &per_cpu(mc_ce_doms, cpu); 518 dom = &per_cpu(mc_ce_doms, cpu);
513 pd_domain_init(dom, NULL, NULL, NULL, NULL); 519 pd_domain_init(dom, NULL, NULL, NULL, NULL, NULL);
514 dom->data = &per_cpu(_mc_ce_dom_data, cpu); 520 dom->data = &per_cpu(_mc_ce_dom_data, cpu);
515 ce_data = dom->data; 521 ce_data = dom->data;
516 hrtimer_init(&ce_data->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); 522 hrtimer_init(&ce_data->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
@@ -711,6 +717,8 @@ static int proc_write_ce_file(struct file *file, const char __user *buffer,
711 int cpu, task, cnt = 0, chars_read, converted, err; 717 int cpu, task, cnt = 0, chars_read, converted, err;
712 lt_t budget; 718 lt_t budget;
713 719
720 raw_spin_lock(&activate_lock);
721
714 if (is_active_plugin()) { 722 if (is_active_plugin()) {
715 printk(KERN_INFO "litmus: can't edit MC-CE proc when plugin " 723 printk(KERN_INFO "litmus: can't edit MC-CE proc when plugin "
716 "active\n"); 724 "active\n");
@@ -757,10 +765,20 @@ static int proc_write_ce_file(struct file *file, const char __user *buffer,
757 } 765 }
758 } 766 }
759out: 767out:
768 raw_spin_unlock(&activate_lock);
760 return cnt; 769 return cnt;
761} 770}
762#undef PROCFS_MAX_SIZE 771#undef PROCFS_MAX_SIZE
763 772
773#define CE_FILE_PROC_NAME "ce_file"
774static void tear_down_proc(void)
775{
776 if (ce_file)
777 remove_proc_entry(CE_FILE_PROC_NAME, mc_ce_dir);
778 if (mc_ce_dir)
779 remove_plugin_proc_dir(&mc_ce_plugin);
780}
781
764static int setup_proc(void) 782static int setup_proc(void)
765{ 783{
766 int err; 784 int err;
@@ -769,16 +787,20 @@ static int setup_proc(void)
769 printk(KERN_ERR "could not create MC-CE procfs dir.\n"); 787 printk(KERN_ERR "could not create MC-CE procfs dir.\n");
770 goto out; 788 goto out;
771 } 789 }
772 ce_file = create_proc_entry("ce_file", 0644, mc_ce_dir); 790 ce_file = create_proc_entry(CE_FILE_PROC_NAME, 0644, mc_ce_dir);
773 if (!ce_file) { 791 if (!ce_file) {
774 printk(KERN_ERR "could not create MC-CE procfs file.\n"); 792 printk(KERN_ERR "could not create MC-CE procfs file.\n");
775 err = -EIO; 793 err = -EIO;
776 goto out; 794 goto out_remove_proc;
777 } 795 }
778 ce_file->read_proc = proc_read_ce_file; 796 ce_file->read_proc = proc_read_ce_file;
779 ce_file->write_proc = proc_write_ce_file; 797 ce_file->write_proc = proc_write_ce_file;
798 goto out;
799out_remove_proc:
800 tear_down_proc();
780out: 801out:
781 return err; 802 return err;
782} 803}
804#undef CE_FILE_PROC_NAME
783 805
784module_init(init_sched_mc_ce); 806module_init(init_sched_mc_ce);