aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern Brandenburg <bbb@mpi-sws.org>2014-04-30 12:34:33 -0400
committerBjoern Brandenburg <bbb@mpi-sws.org>2015-09-07 16:47:32 -0400
commit2971daf071d2c0a35986f16bfed7e661e7e88f92 (patch)
treebf8c419cfbb3cc116f17ef6e24af2bcbe66f8f79
parent8e51b378224ae53244c6917964c88aa2a9d024ad (diff)
LITMUS^RT Core: add get_current_budget() system call
Allow userspace to figure out the used-up and remaining budget of a task.
-rw-r--r--include/litmus/budget.h2
-rw-r--r--include/litmus/sched_plugin.h9
-rw-r--r--litmus/budget.c52
-rw-r--r--litmus/sched_plugin.c4
4 files changed, 67 insertions, 0 deletions
diff --git a/include/litmus/budget.h b/include/litmus/budget.h
index bd2d5c964f92..60eb814fc82b 100644
--- a/include/litmus/budget.h
+++ b/include/litmus/budget.h
@@ -33,4 +33,6 @@ static inline int requeue_preempted_job(struct task_struct* t)
33 (!budget_exhausted(t) || !budget_enforced(t)); 33 (!budget_exhausted(t) || !budget_enforced(t));
34} 34}
35 35
36void litmus_current_budget(lt_t *used_so_far, lt_t *remaining);
37
36#endif 38#endif
diff --git a/include/litmus/sched_plugin.h b/include/litmus/sched_plugin.h
index 0ccccd6ae1af..f36bb3875f58 100644
--- a/include/litmus/sched_plugin.h
+++ b/include/litmus/sched_plugin.h
@@ -77,6 +77,13 @@ typedef long (*wait_for_release_at_t)(lt_t release_time);
77/* Informs the plugin when a synchronous release takes place. */ 77/* Informs the plugin when a synchronous release takes place. */
78typedef void (*synchronous_release_at_t)(lt_t time_zero); 78typedef void (*synchronous_release_at_t)(lt_t time_zero);
79 79
80/* How much budget has the current task consumed so far, and how much
81 * has it left? The default implementation ties into the per-task
82 * budget enforcement code. Plugins can override this to report
83 * reservation-specific values. */
84typedef void (*current_budget_t)(lt_t *used_so_far, lt_t *remaining);
85
86
80/************************ misc routines ***********************/ 87/************************ misc routines ***********************/
81 88
82 89
@@ -109,6 +116,8 @@ struct sched_plugin {
109 task_exit_t task_exit; 116 task_exit_t task_exit;
110 task_cleanup_t task_cleanup; 117 task_cleanup_t task_cleanup;
111 118
119 current_budget_t current_budget;
120
112#ifdef CONFIG_LITMUS_LOCKING 121#ifdef CONFIG_LITMUS_LOCKING
113 /* locking protocols */ 122 /* locking protocols */
114 allocate_lock_t allocate_lock; 123 allocate_lock_t allocate_lock;
diff --git a/litmus/budget.c b/litmus/budget.c
index 47bf78a19f87..d67f4b387862 100644
--- a/litmus/budget.c
+++ b/litmus/budget.c
@@ -1,9 +1,11 @@
1#include <linux/sched.h> 1#include <linux/sched.h>
2#include <linux/percpu.h> 2#include <linux/percpu.h>
3#include <linux/hrtimer.h> 3#include <linux/hrtimer.h>
4#include <linux/uaccess.h>
4 5
5#include <litmus/litmus.h> 6#include <litmus/litmus.h>
6#include <litmus/preempt.h> 7#include <litmus/preempt.h>
8#include <litmus/sched_plugin.h>
7 9
8#include <litmus/budget.h> 10#include <litmus/budget.h>
9 11
@@ -113,4 +115,54 @@ static int __init init_budget_enforcement(void)
113 return 0; 115 return 0;
114} 116}
115 117
118void litmus_current_budget(lt_t *used_so_far, lt_t *remaining)
119{
120 struct task_struct *t = current;
121 unsigned long flags;
122 s64 delta;
123
124 local_irq_save(flags);
125
126 delta = sched_clock_cpu(smp_processor_id()) - t->se.exec_start;
127 if (delta < 0)
128 delta = 0;
129
130 TRACE_CUR("current_budget: sc:%llu start:%llu lt_t:%llu delta:%lld exec-time:%llu rem:%llu\n",
131 sched_clock_cpu(smp_processor_id()), t->se.exec_start,
132 litmus_clock(), delta,
133 tsk_rt(t)->job_params.exec_time,
134 budget_remaining(t));
135
136 if (used_so_far)
137 *used_so_far = tsk_rt(t)->job_params.exec_time + delta;
138
139 if (remaining) {
140 *remaining = budget_remaining(t);
141 if (*remaining > delta)
142 *remaining -= delta;
143 else
144 *remaining = 0;
145 }
146
147 local_irq_restore(flags);
148}
149
150asmlinkage long sys_get_current_budget(
151 lt_t __user * _expended,
152 lt_t __user *_remaining)
153{
154 lt_t expended = 0, remaining = 0;
155
156 if (is_realtime(current))
157 litmus->current_budget(&expended, &remaining);
158
159 if (_expended && put_user(expended, _expended))
160 return -EFAULT;
161
162 if (_remaining && put_user(remaining, _remaining))
163 return -EFAULT;
164
165 return 0;
166}
167
116module_init(init_budget_enforcement); 168module_init(init_budget_enforcement);
diff --git a/litmus/sched_plugin.c b/litmus/sched_plugin.c
index edd91e9bf773..7b1eba0de75c 100644
--- a/litmus/sched_plugin.c
+++ b/litmus/sched_plugin.c
@@ -13,6 +13,7 @@
13#include <litmus/sched_plugin.h> 13#include <litmus/sched_plugin.h>
14#include <litmus/preempt.h> 14#include <litmus/preempt.h>
15#include <litmus/jobs.h> 15#include <litmus/jobs.h>
16#include <litmus/budget.h>
16 17
17/* 18/*
18 * Generic function to trigger preemption on either local or remote cpu 19 * Generic function to trigger preemption on either local or remote cpu
@@ -197,6 +198,9 @@ int register_sched_plugin(struct sched_plugin* plugin)
197 if (!plugin->wait_for_release_at) 198 if (!plugin->wait_for_release_at)
198 plugin->wait_for_release_at = default_wait_for_release_at; 199 plugin->wait_for_release_at = default_wait_for_release_at;
199 200
201 if (!plugin->current_budget)
202 plugin->current_budget = litmus_current_budget;
203
200 raw_spin_lock(&sched_plugins_lock); 204 raw_spin_lock(&sched_plugins_lock);
201 list_add(&plugin->list, &sched_plugins); 205 list_add(&plugin->list, &sched_plugins);
202 raw_spin_unlock(&sched_plugins_lock); 206 raw_spin_unlock(&sched_plugins_lock);