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

Commit 2473f3e7 authored by Frederic Weisbecker's avatar Frederic Weisbecker
Browse files

posix_cpu_timers: consolidate expired timers check



Consolidate the common code amongst per thread and per process timers list
on tick time.

List traversal, expiry check and subsequent updates can be shared in a
common helper.

Signed-off-by: default avatarFrederic Weisbecker <fweisbec@gmail.com>
Cc: Stanislaw Gruszka <sgruszka@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: KOSAKI Motohiro <kosaki.motohiro@gmail.com>
Cc: Olivier Langlois <olivier@trillion01.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
parent 1a7fa510
Loading
Loading
Loading
Loading
+33 −85
Original line number Diff line number Diff line
@@ -862,6 +862,28 @@ static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp)
	}
}

static unsigned long long
check_timers_list(struct list_head *timers,
		  struct list_head *firing,
		  unsigned long long curr)
{
	int maxfire = 20;

	while (!list_empty(timers)) {
		struct cpu_timer_list *t;

		t = list_first_entry(timers, struct cpu_timer_list, entry);

		if (!--maxfire || curr < t->expires)
			return t->expires;

		t->firing = 1;
		list_move_tail(&t->entry, firing);
	}

	return 0;
}

/*
 * Check for any per-thread CPU timers that have fired and move them off
 * the tsk->cpu_timers[N] list onto the firing list.  Here we update the
@@ -870,54 +892,20 @@ static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp)
static void check_thread_timers(struct task_struct *tsk,
				struct list_head *firing)
{
	int maxfire;
	struct list_head *timers = tsk->cpu_timers;
	struct signal_struct *const sig = tsk->signal;
	struct task_cputime *tsk_expires = &tsk->cputime_expires;
	unsigned long long expires;
	unsigned long soft;

	maxfire = 20;
	tsk->cputime_expires.prof_exp = 0;
	while (!list_empty(timers)) {
		struct cpu_timer_list *t = list_first_entry(timers,
						      struct cpu_timer_list,
						      entry);
		if (!--maxfire || prof_ticks(tsk) < t->expires) {
			tsk->cputime_expires.prof_exp = expires_to_cputime(t->expires);
			break;
		}
		t->firing = 1;
		list_move_tail(&t->entry, firing);
	}
	expires = check_timers_list(timers, firing, prof_ticks(tsk));
	tsk_expires->prof_exp = expires_to_cputime(expires);

	++timers;
	maxfire = 20;
	tsk->cputime_expires.virt_exp = 0;
	while (!list_empty(timers)) {
		struct cpu_timer_list *t = list_first_entry(timers,
						      struct cpu_timer_list,
						      entry);
		if (!--maxfire || virt_ticks(tsk) < t->expires) {
			tsk->cputime_expires.virt_exp = expires_to_cputime(t->expires);
			break;
		}
		t->firing = 1;
		list_move_tail(&t->entry, firing);
	}
	expires = check_timers_list(++timers, firing, virt_ticks(tsk));
	tsk_expires->virt_exp = expires_to_cputime(expires);

	++timers;
	maxfire = 20;
	tsk->cputime_expires.sched_exp = 0;
	while (!list_empty(timers)) {
		struct cpu_timer_list *t = list_first_entry(timers,
						      struct cpu_timer_list,
						      entry);
		if (!--maxfire || tsk->se.sum_exec_runtime < t->expires) {
			tsk->cputime_expires.sched_exp = t->expires;
			break;
		}
		t->firing = 1;
		list_move_tail(&t->entry, firing);
	}
	tsk_expires->sched_exp = check_timers_list(++timers, firing,
						   tsk->se.sum_exec_runtime);

	/*
	 * Check for the special case thread timers.
@@ -1002,7 +990,6 @@ static void check_cpu_itimer(struct task_struct *tsk, struct cpu_itimer *it,
static void check_process_timers(struct task_struct *tsk,
				 struct list_head *firing)
{
	int maxfire;
	struct signal_struct *const sig = tsk->signal;
	unsigned long long utime, ptime, virt_expires, prof_expires;
	unsigned long long sum_sched_runtime, sched_expires;
@@ -1017,49 +1004,10 @@ static void check_process_timers(struct task_struct *tsk,
	utime = cputime_to_expires(cputime.utime);
	ptime = utime + cputime_to_expires(cputime.stime);
	sum_sched_runtime = cputime.sum_exec_runtime;
	maxfire = 20;
	prof_expires = 0;
	while (!list_empty(timers)) {
		struct cpu_timer_list *tl = list_first_entry(timers,
						      struct cpu_timer_list,
						      entry);
		if (!--maxfire || ptime < tl->expires) {
			prof_expires = tl->expires;
			break;
		}
		tl->firing = 1;
		list_move_tail(&tl->entry, firing);
	}

	++timers;
	maxfire = 20;
	virt_expires = 0;
	while (!list_empty(timers)) {
		struct cpu_timer_list *tl = list_first_entry(timers,
						      struct cpu_timer_list,
						      entry);
		if (!--maxfire || utime < tl->expires) {
			virt_expires = tl->expires;
			break;
		}
		tl->firing = 1;
		list_move_tail(&tl->entry, firing);
	}

	++timers;
	maxfire = 20;
	sched_expires = 0;
	while (!list_empty(timers)) {
		struct cpu_timer_list *tl = list_first_entry(timers,
						      struct cpu_timer_list,
						      entry);
		if (!--maxfire || sum_sched_runtime < tl->expires) {
			sched_expires = tl->expires;
			break;
		}
		tl->firing = 1;
		list_move_tail(&tl->entry, firing);
	}
	prof_expires = check_timers_list(timers, firing, ptime);
	virt_expires = check_timers_list(++timers, firing, utime);
	sched_expires = check_timers_list(++timers, firing, sum_sched_runtime);

	/*
	 * Check for the special case process timers.