diff options
author | Christopher Kenna <cjk@cs.unc.edu> | 2011-09-08 10:27:46 -0400 |
---|---|---|
committer | Christopher Kenna <cjk@cs.unc.edu> | 2011-09-08 10:27:46 -0400 |
commit | 9d5161afcc52b34cdde7ab9fd997dc73e988ffb7 (patch) | |
tree | 4798a2c8764e3bcb244eab604b22a27210548837 | |
parent | 87c74e28dbad17050783cb30278561f451677152 (diff) |
Better procfs error handling and plugin activation locking.
-rw-r--r-- | litmus/sched_mc_ce.c | 76 |
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; | |||
31 | static atomic_t start_time_set = ATOMIC_INIT(0); | 31 | static atomic_t start_time_set = ATOMIC_INIT(0); |
32 | static atomic64_t start_time = ATOMIC64_INIT(0); | 32 | static atomic64_t start_time = ATOMIC64_INIT(0); |
33 | static struct proc_dir_entry *mc_ce_dir = NULL, *ce_file = NULL; | 33 | static struct proc_dir_entry *mc_ce_dir = NULL, *ce_file = NULL; |
34 | static 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 | ||
450 | static 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 | |||
473 | static void tear_down_proc(void); | ||
446 | static long mc_ce_deactivate_plugin(void) | 474 | static 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 | ||
479 | static 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 | |||
502 | static int setup_proc(void); | 509 | static int setup_proc(void); |
503 | |||
504 | static int __init init_sched_mc_ce(void) | 510 | static 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 | } |
759 | out: | 767 | out: |
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" | ||
774 | static 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 | |||
764 | static int setup_proc(void) | 782 | static 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; | ||
799 | out_remove_proc: | ||
800 | tear_down_proc(); | ||
780 | out: | 801 | out: |
781 | return err; | 802 | return err; |
782 | } | 803 | } |
804 | #undef CE_FILE_PROC_NAME | ||
783 | 805 | ||
784 | module_init(init_sched_mc_ce); | 806 | module_init(init_sched_mc_ce); |