aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPratyush Patel <pratyushpatel.1995@gmail.com>2016-02-09 04:58:11 -0500
committerPratyush Patel <pratyushpatel.1995@gmail.com>2016-02-09 04:58:11 -0500
commitd2bdf416c9c9f5d204bc218a7a36a55605aef89c (patch)
treec91470be6dc919660aa415ab300f5a4614ed4190
parentce90c1d314b15359d0595918c7dfa0ec1f5b9bb6 (diff)
Revamped hrtimer_start_on() support
This patch modifies the previous implementation of hrtimer_start_on() by now using smp_call_function_single_async() to arm hrtimers on remote CPU's.
-rw-r--r--include/litmus/litmus.h23
-rw-r--r--litmus/Kconfig2
-rw-r--r--litmus/litmus.c57
-rw-r--r--litmus/rt_domain.c3
4 files changed, 81 insertions, 4 deletions
diff --git a/include/litmus/litmus.h b/include/litmus/litmus.h
index a6eb534ee0fa..c3a52aea60fb 100644
--- a/include/litmus/litmus.h
+++ b/include/litmus/litmus.h
@@ -319,4 +319,27 @@ static inline int has_control_page(struct task_struct* t)
319 319
320#endif 320#endif
321 321
322#ifdef CONFIG_SMP
323
324/*
325 * struct hrtimer_start_on_info - timer info on remote cpu
326 * @timer: timer to be triggered on remote cpu
327 * @time: time event
328 * @mode: timer mode
329 * @csd: smp_call_function parameter to call hrtimer_pull on remote cpu
330 */
331struct hrtimer_start_on_info {
332 struct hrtimer *timer;
333 ktime_t time;
334 enum hrtimer_mode mode;
335 struct call_single_data csd;
336};
337
338void hrtimer_pull(void *csd_info);
339extern void hrtimer_start_on(int cpu, struct hrtimer_start_on_info *info,
340 struct hrtimer *timer, ktime_t time,
341 const enum hrtimer_mode mode);
342
343#endif
344
322#endif 345#endif
diff --git a/litmus/Kconfig b/litmus/Kconfig
index babb43deffb5..b0ea45d82532 100644
--- a/litmus/Kconfig
+++ b/litmus/Kconfig
@@ -27,7 +27,7 @@ config PLUGIN_PFAIR
27 27
28config RELEASE_MASTER 28config RELEASE_MASTER
29 bool "Release-master Support" 29 bool "Release-master Support"
30 depends on ARCH_HAS_SEND_PULL_TIMERS && SMP 30 depends on SMP
31 default n 31 default n
32 help 32 help
33 Allow one processor to act as a dedicated interrupt processor 33 Allow one processor to act as a dedicated interrupt processor
diff --git a/litmus/litmus.c b/litmus/litmus.c
index 885d75493118..c03de2dcea0c 100644
--- a/litmus/litmus.c
+++ b/litmus/litmus.c
@@ -648,6 +648,63 @@ static struct notifier_block shutdown_notifier = {
648 .notifier_call = litmus_shutdown_nb, 648 .notifier_call = litmus_shutdown_nb,
649}; 649};
650 650
651/**
652 * Triggering hrtimers on specific cpus as required by arm_release_timer(_on)
653 */
654#ifdef CONFIG_SMP
655
656/**
657 * hrtimer_pull - smp_call_function_single_async callback on remote cpu
658 */
659void hrtimer_pull(void *csd_info)
660{
661 struct hrtimer_start_on_info *info = csd_info;
662 TRACE("pulled timer 0x%x\n", info->timer);
663 hrtimer_start_range_ns(info->timer, info->time, 0, info->mode);
664}
665
666/**
667 * hrtimer_start_on - trigger timer arming on remote cpu
668 * @cpu: remote cpu
669 * @info: save timer information for enqueuing on remote cpu
670 * @timer: timer to be pulled
671 * @time: expire time
672 * @mode: timer mode
673 */
674void hrtimer_start_on(int cpu, struct hrtimer_start_on_info *info,
675 struct hrtimer *timer, ktime_t time,
676 const enum hrtimer_mode mode)
677{
678 info->timer = timer;
679 info->time = time;
680 info->mode = mode;
681
682 /* initialize call_single_data struct */
683 info->csd.func = &hrtimer_pull;
684 info->csd.info = info;
685 info->csd.flags = 0;
686
687 /* initiate pull */
688 preempt_disable();
689 if (cpu == smp_processor_id()) {
690 /* start timer locally; we may get called
691 * with rq->lock held, do not wake up anything
692 */
693 TRACE("hrtimer_start_on: starting on local CPU\n");
694 __hrtimer_start_range_ns(info->timer, info->time,
695 0, info->mode, 0);
696 } else {
697 /* call hrtimer_pull() on remote cpu
698 * to start remote timer asynchronously
699 */
700 TRACE("hrtimer_start_on: pulling to remote CPU\n");
701 smp_call_function_single_async(cpu, &info->csd);
702 }
703 preempt_enable();
704}
705
706#endif /* CONFIG_SMP */
707
651static int __init _init_litmus(void) 708static int __init _init_litmus(void)
652{ 709{
653 /* Common initializers, 710 /* Common initializers,
diff --git a/litmus/rt_domain.c b/litmus/rt_domain.c
index e5dec0bbbba9..c7638d0bd0d5 100644
--- a/litmus/rt_domain.c
+++ b/litmus/rt_domain.c
@@ -169,9 +169,6 @@ static void reinit_release_heap(struct task_struct* t)
169 169
170 /* initialize */ 170 /* initialize */
171 bheap_init(&rh->heap); 171 bheap_init(&rh->heap);
172#ifdef CONFIG_RELEASE_MASTER
173 atomic_set(&rh->info.state, HRTIMER_START_ON_INACTIVE);
174#endif
175} 172}
176/* arm_release_timer() - start local release timer or trigger 173/* arm_release_timer() - start local release timer or trigger
177 * remote timer (pull timer) 174 * remote timer (pull timer)