summaryrefslogtreecommitdiff
path: root/kernel/posix-cpu-timers.c
diff options
context:
space:
mode:
authorScott Wood <scottwood@freescale.com>2014-05-14 18:19:12 (GMT)
committerScott Wood <scottwood@freescale.com>2014-05-14 18:37:18 (GMT)
commit86ba38e6f5f2fbfe9b49e153ea89593b26482019 (patch)
treef99d2906b0eafca507f37289e68052fc105cc2dc /kernel/posix-cpu-timers.c
parent07c8b57b111585a617b2b456497fc9b33c00743c (diff)
downloadlinux-fsl-qoriq-86ba38e6f5f2fbfe9b49e153ea89593b26482019.tar.xz
Reset to 3.12.19
Diffstat (limited to 'kernel/posix-cpu-timers.c')
-rw-r--r--kernel/posix-cpu-timers.c198
1 files changed, 6 insertions, 192 deletions
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
index 4bf82f8..c7f31aa 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -3,7 +3,6 @@
*/
#include <linux/sched.h>
-#include <linux/sched/rt.h>
#include <linux/posix-timers.h>
#include <linux/errno.h>
#include <linux/math64.h>
@@ -664,7 +663,7 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int flags,
/*
* Disarm any old timer after extracting its expiry time.
*/
- BUG_ON_NONRT(!irqs_disabled());
+ BUG_ON(!irqs_disabled());
ret = 0;
old_incr = timer->it.cpu.incr;
@@ -1111,7 +1110,7 @@ void posix_cpu_timer_schedule(struct k_itimer *timer)
/*
* Now re-arm for the new expiry time.
*/
- BUG_ON_NONRT(!irqs_disabled());
+ BUG_ON(!irqs_disabled());
arm_timer(timer);
spin_unlock(&p->sighand->siglock);
@@ -1178,11 +1177,10 @@ static inline int fastpath_timer_check(struct task_struct *tsk)
sig = tsk->signal;
if (sig->cputimer.running) {
struct task_cputime group_sample;
- unsigned long flags;
- raw_spin_lock_irqsave(&sig->cputimer.lock, flags);
+ raw_spin_lock(&sig->cputimer.lock);
group_sample = sig->cputimer.cputime;
- raw_spin_unlock_irqrestore(&sig->cputimer.lock, flags);
+ raw_spin_unlock(&sig->cputimer.lock);
if (task_cputime_expired(&group_sample, &sig->cputime_expires))
return 1;
@@ -1196,13 +1194,13 @@ static inline int fastpath_timer_check(struct task_struct *tsk)
* already updated our counts. We need to check if any timers fire now.
* Interrupts are disabled.
*/
-static void __run_posix_cpu_timers(struct task_struct *tsk)
+void run_posix_cpu_timers(struct task_struct *tsk)
{
LIST_HEAD(firing);
struct k_itimer *timer, *next;
unsigned long flags;
- BUG_ON_NONRT(!irqs_disabled());
+ BUG_ON(!irqs_disabled());
/*
* The fast path checks that there are no expired thread or thread
@@ -1267,190 +1265,6 @@ static void __run_posix_cpu_timers(struct task_struct *tsk)
posix_cpu_timer_kick_nohz();
}
-#ifdef CONFIG_PREEMPT_RT_BASE
-#include <linux/kthread.h>
-#include <linux/cpu.h>
-DEFINE_PER_CPU(struct task_struct *, posix_timer_task);
-DEFINE_PER_CPU(struct task_struct *, posix_timer_tasklist);
-
-static int posix_cpu_timers_thread(void *data)
-{
- int cpu = (long)data;
-
- BUG_ON(per_cpu(posix_timer_task,cpu) != current);
-
- while (!kthread_should_stop()) {
- struct task_struct *tsk = NULL;
- struct task_struct *next = NULL;
-
- if (cpu_is_offline(cpu))
- goto wait_to_die;
-
- /* grab task list */
- raw_local_irq_disable();
- tsk = per_cpu(posix_timer_tasklist, cpu);
- per_cpu(posix_timer_tasklist, cpu) = NULL;
- raw_local_irq_enable();
-
- /* its possible the list is empty, just return */
- if (!tsk) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule();
- __set_current_state(TASK_RUNNING);
- continue;
- }
-
- /* Process task list */
- while (1) {
- /* save next */
- next = tsk->posix_timer_list;
-
- /* run the task timers, clear its ptr and
- * unreference it
- */
- __run_posix_cpu_timers(tsk);
- tsk->posix_timer_list = NULL;
- put_task_struct(tsk);
-
- /* check if this is the last on the list */
- if (next == tsk)
- break;
- tsk = next;
- }
- }
- return 0;
-
-wait_to_die:
- /* Wait for kthread_stop */
- set_current_state(TASK_INTERRUPTIBLE);
- while (!kthread_should_stop()) {
- schedule();
- set_current_state(TASK_INTERRUPTIBLE);
- }
- __set_current_state(TASK_RUNNING);
- return 0;
-}
-
-static inline int __fastpath_timer_check(struct task_struct *tsk)
-{
- /* tsk == current, ensure it is safe to use ->signal/sighand */
- if (unlikely(tsk->exit_state))
- return 0;
-
- if (!task_cputime_zero(&tsk->cputime_expires))
- return 1;
-
- if (!task_cputime_zero(&tsk->signal->cputime_expires))
- return 1;
-
- return 0;
-}
-
-void run_posix_cpu_timers(struct task_struct *tsk)
-{
- unsigned long cpu = smp_processor_id();
- struct task_struct *tasklist;
-
- BUG_ON(!irqs_disabled());
- if(!per_cpu(posix_timer_task, cpu))
- return;
- /* get per-cpu references */
- tasklist = per_cpu(posix_timer_tasklist, cpu);
-
- /* check to see if we're already queued */
- if (!tsk->posix_timer_list && __fastpath_timer_check(tsk)) {
- get_task_struct(tsk);
- if (tasklist) {
- tsk->posix_timer_list = tasklist;
- } else {
- /*
- * The list is terminated by a self-pointing
- * task_struct
- */
- tsk->posix_timer_list = tsk;
- }
- per_cpu(posix_timer_tasklist, cpu) = tsk;
-
- wake_up_process(per_cpu(posix_timer_task, cpu));
- }
-}
-
-/*
- * posix_cpu_thread_call - callback that gets triggered when a CPU is added.
- * Here we can start up the necessary migration thread for the new CPU.
- */
-static int posix_cpu_thread_call(struct notifier_block *nfb,
- unsigned long action, void *hcpu)
-{
- int cpu = (long)hcpu;
- struct task_struct *p;
- struct sched_param param;
-
- switch (action) {
- case CPU_UP_PREPARE:
- p = kthread_create(posix_cpu_timers_thread, hcpu,
- "posixcputmr/%d",cpu);
- if (IS_ERR(p))
- return NOTIFY_BAD;
- p->flags |= PF_NOFREEZE;
- kthread_bind(p, cpu);
- /* Must be high prio to avoid getting starved */
- param.sched_priority = MAX_RT_PRIO-1;
- sched_setscheduler(p, SCHED_FIFO, &param);
- per_cpu(posix_timer_task,cpu) = p;
- break;
- case CPU_ONLINE:
- /* Strictly unneccessary, as first user will wake it. */
- wake_up_process(per_cpu(posix_timer_task,cpu));
- break;
-#ifdef CONFIG_HOTPLUG_CPU
- case CPU_UP_CANCELED:
- /* Unbind it from offline cpu so it can run. Fall thru. */
- kthread_bind(per_cpu(posix_timer_task, cpu),
- cpumask_any(cpu_online_mask));
- kthread_stop(per_cpu(posix_timer_task,cpu));
- per_cpu(posix_timer_task,cpu) = NULL;
- break;
- case CPU_DEAD:
- kthread_stop(per_cpu(posix_timer_task,cpu));
- per_cpu(posix_timer_task,cpu) = NULL;
- break;
-#endif
- }
- return NOTIFY_OK;
-}
-
-/* Register at highest priority so that task migration (migrate_all_tasks)
- * happens before everything else.
- */
-static struct notifier_block posix_cpu_thread_notifier = {
- .notifier_call = posix_cpu_thread_call,
- .priority = 10
-};
-
-static int __init posix_cpu_thread_init(void)
-{
- void *hcpu = (void *)(long)smp_processor_id();
- /* Start one for boot CPU. */
- unsigned long cpu;
-
- /* init the per-cpu posix_timer_tasklets */
- for_each_possible_cpu(cpu)
- per_cpu(posix_timer_tasklist, cpu) = NULL;
-
- posix_cpu_thread_call(&posix_cpu_thread_notifier, CPU_UP_PREPARE, hcpu);
- posix_cpu_thread_call(&posix_cpu_thread_notifier, CPU_ONLINE, hcpu);
- register_cpu_notifier(&posix_cpu_thread_notifier);
- return 0;
-}
-early_initcall(posix_cpu_thread_init);
-#else /* CONFIG_PREEMPT_RT_BASE */
-void run_posix_cpu_timers(struct task_struct *tsk)
-{
- __run_posix_cpu_timers(tsk);
-}
-#endif /* CONFIG_PREEMPT_RT_BASE */
-
/*
* Set one of the process-wide special case CPU timers or RLIMIT_CPU.
* The tsk->sighand->siglock must be held by the caller.