Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5eb9aa64 authored by Stanislaw Gruszka's avatar Stanislaw Gruszka Committed by Thomas Gleixner
Browse files

cpu-timers: Cleanup arm_timer()



Signed-off-by: default avatarStanislaw Gruszka <sgruszka@redhat.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
Cc: Balbir Singh <balbir@in.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent f55db609
Loading
Loading
Loading
Loading
+35 −69
Original line number Diff line number Diff line
@@ -547,98 +547,64 @@ static inline int expires_gt(cputime_t expires, cputime_t new_exp)
	       cputime_gt(expires, new_exp);
}

static inline int expires_le(cputime_t expires, cputime_t new_exp)
{
	return !cputime_eq(expires, cputime_zero) &&
	       cputime_le(expires, new_exp);
}
/*
 * Insert the timer on the appropriate list before any timers that
 * expire later.  This must be called with the tasklist_lock held
 * for reading, and interrupts disabled.
 */
static void arm_timer(struct k_itimer *timer, union cpu_time_count now)
static void arm_timer(struct k_itimer *timer)
{
	struct task_struct *p = timer->it.cpu.task;
	struct list_head *head, *listpos;
	struct task_cputime *cputime_expires;
	struct cpu_timer_list *const nt = &timer->it.cpu;
	struct cpu_timer_list *next;

	head = (CPUCLOCK_PERTHREAD(timer->it_clock) ?
		p->cpu_timers : p->signal->cpu_timers);
	if (CPUCLOCK_PERTHREAD(timer->it_clock)) {
		head = p->cpu_timers;
		cputime_expires = &p->cputime_expires;
	} else {
		head = p->signal->cpu_timers;
		cputime_expires = &p->signal->cputime_expires;
	}
	head += CPUCLOCK_WHICH(timer->it_clock);

	BUG_ON(!irqs_disabled());
	spin_lock(&p->sighand->siglock);

	listpos = head;
	if (CPUCLOCK_WHICH(timer->it_clock) == CPUCLOCK_SCHED) {
		list_for_each_entry(next, head, entry) {
			if (next->expires.sched > nt->expires.sched)
				break;
			listpos = &next->entry;
		}
	} else {
	list_for_each_entry(next, head, entry) {
			if (cputime_gt(next->expires.cpu, nt->expires.cpu))
		if (cpu_time_before(timer->it_clock, nt->expires, next->expires))
			break;
		listpos = &next->entry;
	}
	}
	list_add(&nt->entry, listpos);

	if (listpos == head) {
		union cpu_time_count *exp = &nt->expires;

		/*
		 * We are the new earliest-expiring timer.
		 * If we are a thread timer, there can always
		 * be a process timer telling us to stop earlier.
		 * We are the new earliest-expiring POSIX 1.b timer, hence
		 * need to update expiration cache. Take into account that
		 * for process timers we share expiration cache with itimers
		 * and RLIMIT_CPU and for thread timers with RLIMIT_RTTIME.
		 */

		if (CPUCLOCK_PERTHREAD(timer->it_clock)) {
			union cpu_time_count *exp = &nt->expires;

		switch (CPUCLOCK_WHICH(timer->it_clock)) {
			default:
				BUG();
		case CPUCLOCK_PROF:
				if (expires_gt(p->cputime_expires.prof_exp,
					       exp->cpu))
					p->cputime_expires.prof_exp = exp->cpu;
			if (expires_gt(cputime_expires->prof_exp, exp->cpu))
				cputime_expires->prof_exp = exp->cpu;
			break;
		case CPUCLOCK_VIRT:
				if (expires_gt(p->cputime_expires.virt_exp,
					       exp->cpu))
					p->cputime_expires.virt_exp = exp->cpu;
			if (expires_gt(cputime_expires->virt_exp, exp->cpu))
				cputime_expires->virt_exp = exp->cpu;
			break;
		case CPUCLOCK_SCHED:
				if (p->cputime_expires.sched_exp == 0 ||
				    p->cputime_expires.sched_exp > exp->sched)
					p->cputime_expires.sched_exp =
								exp->sched;
			if (cputime_expires->sched_exp == 0 ||
			    cputime_expires->sched_exp > exp->sched)
				cputime_expires->sched_exp = exp->sched;
			break;
		}
		} else {
			struct signal_struct *const sig = p->signal;
			union cpu_time_count *exp = &timer->it.cpu.expires;

			/*
			 * For a process timer, set the cached expiration time.
			 */
			switch (CPUCLOCK_WHICH(timer->it_clock)) {
			default:
				BUG();
			case CPUCLOCK_VIRT:
				if (expires_gt(sig->cputime_expires.virt_exp, exp->cpu))
					sig->cputime_expires.virt_exp = exp->cpu;
			case CPUCLOCK_PROF:
				if (expires_gt(sig->cputime_expires.prof_exp, exp->cpu))
					sig->cputime_expires.prof_exp = exp->cpu;
				break;
			case CPUCLOCK_SCHED:
				sig->cputime_expires.sched_exp = exp->sched;
				break;
			}
		}
	}

	spin_unlock(&p->sighand->siglock);
@@ -819,7 +785,7 @@ int posix_cpu_timer_set(struct k_itimer *timer, int flags,
	if (new_expires.sched != 0 &&
	    (timer->it_sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_NONE &&
	    cpu_time_before(timer->it_clock, val, new_expires)) {
		arm_timer(timer, val);
		arm_timer(timer);
	}

	read_unlock(&tasklist_lock);
@@ -1283,7 +1249,7 @@ void posix_cpu_timer_schedule(struct k_itimer *timer)
	/*
	 * Now re-arm for the new expiry time.
	 */
	arm_timer(timer, now);
	arm_timer(timer);

out_unlock:
	read_unlock(&tasklist_lock);