|
@@ -4139,9 +4139,25 @@ DEFINE_PER_CPU(struct kernel_stat, kstat);
|
|
|
EXPORT_PER_CPU_SYMBOL(kstat);
|
|
|
|
|
|
/*
|
|
|
- * Return any ns on the sched_clock that have not yet been banked in
|
|
|
+ * Return any ns on the sched_clock that have not yet been accounted in
|
|
|
* @p in case that task is currently running.
|
|
|
+ *
|
|
|
+ * Called with task_rq_lock() held on @rq.
|
|
|
*/
|
|
|
+static u64 do_task_delta_exec(struct task_struct *p, struct rq *rq)
|
|
|
+{
|
|
|
+ u64 ns = 0;
|
|
|
+
|
|
|
+ if (task_current(rq, p)) {
|
|
|
+ update_rq_clock(rq);
|
|
|
+ ns = rq->clock - p->se.exec_start;
|
|
|
+ if ((s64)ns < 0)
|
|
|
+ ns = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ return ns;
|
|
|
+}
|
|
|
+
|
|
|
unsigned long long task_delta_exec(struct task_struct *p)
|
|
|
{
|
|
|
unsigned long flags;
|
|
@@ -4149,16 +4165,49 @@ unsigned long long task_delta_exec(struct task_struct *p)
|
|
|
u64 ns = 0;
|
|
|
|
|
|
rq = task_rq_lock(p, &flags);
|
|
|
+ ns = do_task_delta_exec(p, rq);
|
|
|
+ task_rq_unlock(rq, &flags);
|
|
|
|
|
|
- if (task_current(rq, p)) {
|
|
|
- u64 delta_exec;
|
|
|
+ return ns;
|
|
|
+}
|
|
|
|
|
|
- update_rq_clock(rq);
|
|
|
- delta_exec = rq->clock - p->se.exec_start;
|
|
|
- if ((s64)delta_exec > 0)
|
|
|
- ns = delta_exec;
|
|
|
- }
|
|
|
+/*
|
|
|
+ * Return accounted runtime for the task.
|
|
|
+ * In case the task is currently running, return the runtime plus current's
|
|
|
+ * pending runtime that have not been accounted yet.
|
|
|
+ */
|
|
|
+unsigned long long task_sched_runtime(struct task_struct *p)
|
|
|
+{
|
|
|
+ unsigned long flags;
|
|
|
+ struct rq *rq;
|
|
|
+ u64 ns = 0;
|
|
|
+
|
|
|
+ rq = task_rq_lock(p, &flags);
|
|
|
+ ns = p->se.sum_exec_runtime + do_task_delta_exec(p, rq);
|
|
|
+ task_rq_unlock(rq, &flags);
|
|
|
+
|
|
|
+ return ns;
|
|
|
+}
|
|
|
|
|
|
+/*
|
|
|
+ * Return sum_exec_runtime for the thread group.
|
|
|
+ * In case the task is currently running, return the sum plus current's
|
|
|
+ * pending runtime that have not been accounted yet.
|
|
|
+ *
|
|
|
+ * Note that the thread group might have other running tasks as well,
|
|
|
+ * so the return value not includes other pending runtime that other
|
|
|
+ * running tasks might have.
|
|
|
+ */
|
|
|
+unsigned long long thread_group_sched_runtime(struct task_struct *p)
|
|
|
+{
|
|
|
+ struct task_cputime totals;
|
|
|
+ unsigned long flags;
|
|
|
+ struct rq *rq;
|
|
|
+ u64 ns;
|
|
|
+
|
|
|
+ rq = task_rq_lock(p, &flags);
|
|
|
+ thread_group_cputime(p, &totals);
|
|
|
+ ns = totals.sum_exec_runtime + do_task_delta_exec(p, rq);
|
|
|
task_rq_unlock(rq, &flags);
|
|
|
|
|
|
return ns;
|