diff options
Diffstat (limited to 'kernel/posix-cpu-timers.c')
| -rw-r--r-- | kernel/posix-cpu-timers.c | 395 | 
1 files changed, 140 insertions, 255 deletions
| diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c index 42670e9b44e..c7f31aa272f 100644 --- a/kernel/posix-cpu-timers.c +++ b/kernel/posix-cpu-timers.c @@ -51,59 +51,28 @@ static int check_clock(const clockid_t which_clock)  	return error;  } -static inline union cpu_time_count +static inline unsigned long long  timespec_to_sample(const clockid_t which_clock, const struct timespec *tp)  { -	union cpu_time_count ret; -	ret.sched = 0;		/* high half always zero when .cpu used */ +	unsigned long long ret; + +	ret = 0;		/* high half always zero when .cpu used */  	if (CPUCLOCK_WHICH(which_clock) == CPUCLOCK_SCHED) { -		ret.sched = (unsigned long long)tp->tv_sec * NSEC_PER_SEC + tp->tv_nsec; +		ret = (unsigned long long)tp->tv_sec * NSEC_PER_SEC + tp->tv_nsec;  	} else { -		ret.cpu = timespec_to_cputime(tp); +		ret = cputime_to_expires(timespec_to_cputime(tp));  	}  	return ret;  }  static void sample_to_timespec(const clockid_t which_clock, -			       union cpu_time_count cpu, +			       unsigned long long expires,  			       struct timespec *tp)  {  	if (CPUCLOCK_WHICH(which_clock) == CPUCLOCK_SCHED) -		*tp = ns_to_timespec(cpu.sched); +		*tp = ns_to_timespec(expires);  	else -		cputime_to_timespec(cpu.cpu, tp); -} - -static inline int cpu_time_before(const clockid_t which_clock, -				  union cpu_time_count now, -				  union cpu_time_count then) -{ -	if (CPUCLOCK_WHICH(which_clock) == CPUCLOCK_SCHED) { -		return now.sched < then.sched; -	}  else { -		return now.cpu < then.cpu; -	} -} -static inline void cpu_time_add(const clockid_t which_clock, -				union cpu_time_count *acc, -			        union cpu_time_count val) -{ -	if (CPUCLOCK_WHICH(which_clock) == CPUCLOCK_SCHED) { -		acc->sched += val.sched; -	}  else { -		acc->cpu += val.cpu; -	} -} -static inline union cpu_time_count cpu_time_sub(const clockid_t which_clock, -						union cpu_time_count a, -						union cpu_time_count b) -{ -	if (CPUCLOCK_WHICH(which_clock) == CPUCLOCK_SCHED) { -		a.sched -= b.sched; -	}  else { -		a.cpu -= b.cpu; -	} -	return a; +		cputime_to_timespec((__force cputime_t)expires, tp);  }  /* @@ -111,47 +80,31 @@ static inline union cpu_time_count cpu_time_sub(const clockid_t which_clock,   * given the current clock sample.   */  static void bump_cpu_timer(struct k_itimer *timer, -				  union cpu_time_count now) +			   unsigned long long now)  {  	int i; +	unsigned long long delta, incr; -	if (timer->it.cpu.incr.sched == 0) +	if (timer->it.cpu.incr == 0)  		return; -	if (CPUCLOCK_WHICH(timer->it_clock) == CPUCLOCK_SCHED) { -		unsigned long long delta, incr; +	if (now < timer->it.cpu.expires) +		return; -		if (now.sched < timer->it.cpu.expires.sched) -			return; -		incr = timer->it.cpu.incr.sched; -		delta = now.sched + incr - timer->it.cpu.expires.sched; -		/* Don't use (incr*2 < delta), incr*2 might overflow. */ -		for (i = 0; incr < delta - incr; i++) -			incr = incr << 1; -		for (; i >= 0; incr >>= 1, i--) { -			if (delta < incr) -				continue; -			timer->it.cpu.expires.sched += incr; -			timer->it_overrun += 1 << i; -			delta -= incr; -		} -	} else { -		cputime_t delta, incr; +	incr = timer->it.cpu.incr; +	delta = now + incr - timer->it.cpu.expires; -		if (now.cpu < timer->it.cpu.expires.cpu) -			return; -		incr = timer->it.cpu.incr.cpu; -		delta = now.cpu + incr - timer->it.cpu.expires.cpu; -		/* Don't use (incr*2 < delta), incr*2 might overflow. */ -		for (i = 0; incr < delta - incr; i++) -			     incr += incr; -		for (; i >= 0; incr = incr >> 1, i--) { -			if (delta < incr) -				continue; -			timer->it.cpu.expires.cpu += incr; -			timer->it_overrun += 1 << i; -			delta -= incr; -		} +	/* Don't use (incr*2 < delta), incr*2 might overflow. */ +	for (i = 0; incr < delta - incr; i++) +		incr = incr << 1; + +	for (; i >= 0; incr >>= 1, i--) { +		if (delta < incr) +			continue; + +		timer->it.cpu.expires += incr; +		timer->it_overrun += 1 << i; +		delta -= incr;  	}  } @@ -170,21 +123,21 @@ static inline int task_cputime_zero(const struct task_cputime *cputime)  	return 0;  } -static inline cputime_t prof_ticks(struct task_struct *p) +static inline unsigned long long prof_ticks(struct task_struct *p)  {  	cputime_t utime, stime;  	task_cputime(p, &utime, &stime); -	return utime + stime; +	return cputime_to_expires(utime + stime);  } -static inline cputime_t virt_ticks(struct task_struct *p) +static inline unsigned long long virt_ticks(struct task_struct *p)  {  	cputime_t utime;  	task_cputime(p, &utime, NULL); -	return utime; +	return cputime_to_expires(utime);  }  static int @@ -225,19 +178,19 @@ posix_cpu_clock_set(const clockid_t which_clock, const struct timespec *tp)   * Sample a per-thread clock for the given task.   */  static int cpu_clock_sample(const clockid_t which_clock, struct task_struct *p, -			    union cpu_time_count *cpu) +			    unsigned long long *sample)  {  	switch (CPUCLOCK_WHICH(which_clock)) {  	default:  		return -EINVAL;  	case CPUCLOCK_PROF: -		cpu->cpu = prof_ticks(p); +		*sample = prof_ticks(p);  		break;  	case CPUCLOCK_VIRT: -		cpu->cpu = virt_ticks(p); +		*sample = virt_ticks(p);  		break;  	case CPUCLOCK_SCHED: -		cpu->sched = task_sched_runtime(p); +		*sample = task_sched_runtime(p);  		break;  	}  	return 0; @@ -284,7 +237,7 @@ void thread_group_cputimer(struct task_struct *tsk, struct task_cputime *times)   */  static int cpu_clock_sample_group(const clockid_t which_clock,  				  struct task_struct *p, -				  union cpu_time_count *cpu) +				  unsigned long long *sample)  {  	struct task_cputime cputime; @@ -293,15 +246,15 @@ static int cpu_clock_sample_group(const clockid_t which_clock,  		return -EINVAL;  	case CPUCLOCK_PROF:  		thread_group_cputime(p, &cputime); -		cpu->cpu = cputime.utime + cputime.stime; +		*sample = cputime_to_expires(cputime.utime + cputime.stime);  		break;  	case CPUCLOCK_VIRT:  		thread_group_cputime(p, &cputime); -		cpu->cpu = cputime.utime; +		*sample = cputime_to_expires(cputime.utime);  		break;  	case CPUCLOCK_SCHED:  		thread_group_cputime(p, &cputime); -		cpu->sched = cputime.sum_exec_runtime; +		*sample = cputime.sum_exec_runtime;  		break;  	}  	return 0; @@ -312,7 +265,7 @@ static int posix_cpu_clock_get(const clockid_t which_clock, struct timespec *tp)  {  	const pid_t pid = CPUCLOCK_PID(which_clock);  	int error = -EINVAL; -	union cpu_time_count rtn; +	unsigned long long rtn;  	if (pid == 0) {  		/* @@ -446,6 +399,15 @@ static int posix_cpu_timer_del(struct k_itimer *timer)  	return ret;  } +static void cleanup_timers_list(struct list_head *head, +				unsigned long long curr) +{ +	struct cpu_timer_list *timer, *next; + +	list_for_each_entry_safe(timer, next, head, entry) +		list_del_init(&timer->entry); +} +  /*   * Clean out CPU timers still ticking when a thread exited.  The task   * pointer is cleared, and the expiry time is replaced with the residual @@ -456,37 +418,12 @@ static void cleanup_timers(struct list_head *head,  			   cputime_t utime, cputime_t stime,  			   unsigned long long sum_exec_runtime)  { -	struct cpu_timer_list *timer, *next; -	cputime_t ptime = utime + stime; - -	list_for_each_entry_safe(timer, next, head, entry) { -		list_del_init(&timer->entry); -		if (timer->expires.cpu < ptime) { -			timer->expires.cpu = 0; -		} else { -			timer->expires.cpu -= ptime; -		} -	} -	++head; -	list_for_each_entry_safe(timer, next, head, entry) { -		list_del_init(&timer->entry); -		if (timer->expires.cpu < utime) { -			timer->expires.cpu = 0; -		} else { -			timer->expires.cpu -= utime; -		} -	} +	cputime_t ptime = utime + stime; -	++head; -	list_for_each_entry_safe(timer, next, head, entry) { -		list_del_init(&timer->entry); -		if (timer->expires.sched < sum_exec_runtime) { -			timer->expires.sched = 0; -		} else { -			timer->expires.sched -= sum_exec_runtime; -		} -	} +	cleanup_timers_list(head, cputime_to_expires(ptime)); +	cleanup_timers_list(++head, cputime_to_expires(utime)); +	cleanup_timers_list(++head, sum_exec_runtime);  }  /* @@ -516,17 +453,21 @@ void posix_cpu_timers_exit_group(struct task_struct *tsk)  		       tsk->se.sum_exec_runtime + sig->sum_sched_runtime);  } -static void clear_dead_task(struct k_itimer *timer, union cpu_time_count now) +static void clear_dead_task(struct k_itimer *itimer, unsigned long long now)  { +	struct cpu_timer_list *timer = &itimer->it.cpu; +  	/*  	 * That's all for this thread or process.  	 * We leave our residual in expires to be reported.  	 */ -	put_task_struct(timer->it.cpu.task); -	timer->it.cpu.task = NULL; -	timer->it.cpu.expires = cpu_time_sub(timer->it_clock, -					     timer->it.cpu.expires, -					     now); +	put_task_struct(timer->task); +	timer->task = NULL; +	if (timer->expires < now) { +		timer->expires = 0; +	} else { +		timer->expires -= now; +	}  }  static inline int expires_gt(cputime_t expires, cputime_t new_exp) @@ -558,14 +499,14 @@ static void arm_timer(struct k_itimer *timer)  	listpos = head;  	list_for_each_entry(next, head, entry) { -		if (cpu_time_before(timer->it_clock, nt->expires, next->expires)) +		if (nt->expires < next->expires)  			break;  		listpos = &next->entry;  	}  	list_add(&nt->entry, listpos);  	if (listpos == head) { -		union cpu_time_count *exp = &nt->expires; +		unsigned long long exp = nt->expires;  		/*  		 * We are the new earliest-expiring POSIX 1.b timer, hence @@ -576,17 +517,17 @@ static void arm_timer(struct k_itimer *timer)  		switch (CPUCLOCK_WHICH(timer->it_clock)) {  		case CPUCLOCK_PROF: -			if (expires_gt(cputime_expires->prof_exp, exp->cpu)) -				cputime_expires->prof_exp = exp->cpu; +			if (expires_gt(cputime_expires->prof_exp, expires_to_cputime(exp))) +				cputime_expires->prof_exp = expires_to_cputime(exp);  			break;  		case CPUCLOCK_VIRT: -			if (expires_gt(cputime_expires->virt_exp, exp->cpu)) -				cputime_expires->virt_exp = exp->cpu; +			if (expires_gt(cputime_expires->virt_exp, expires_to_cputime(exp))) +				cputime_expires->virt_exp = expires_to_cputime(exp);  			break;  		case CPUCLOCK_SCHED:  			if (cputime_expires->sched_exp == 0 || -			    cputime_expires->sched_exp > exp->sched) -				cputime_expires->sched_exp = exp->sched; +			    cputime_expires->sched_exp > exp) +				cputime_expires->sched_exp = exp;  			break;  		}  	} @@ -601,20 +542,20 @@ static void cpu_timer_fire(struct k_itimer *timer)  		/*  		 * User don't want any signal.  		 */ -		timer->it.cpu.expires.sched = 0; +		timer->it.cpu.expires = 0;  	} else if (unlikely(timer->sigq == NULL)) {  		/*  		 * This a special case for clock_nanosleep,  		 * not a normal timer from sys_timer_create.  		 */  		wake_up_process(timer->it_process); -		timer->it.cpu.expires.sched = 0; -	} else if (timer->it.cpu.incr.sched == 0) { +		timer->it.cpu.expires = 0; +	} else if (timer->it.cpu.incr == 0) {  		/*  		 * One-shot timer.  Clear it as soon as it's fired.  		 */  		posix_timer_event(timer, 0); -		timer->it.cpu.expires.sched = 0; +		timer->it.cpu.expires = 0;  	} else if (posix_timer_event(timer, ++timer->it_requeue_pending)) {  		/*  		 * The signal did not get queued because the signal @@ -632,7 +573,7 @@ static void cpu_timer_fire(struct k_itimer *timer)   */  static int cpu_timer_sample_group(const clockid_t which_clock,  				  struct task_struct *p, -				  union cpu_time_count *cpu) +				  unsigned long long *sample)  {  	struct task_cputime cputime; @@ -641,13 +582,13 @@ static int cpu_timer_sample_group(const clockid_t which_clock,  	default:  		return -EINVAL;  	case CPUCLOCK_PROF: -		cpu->cpu = cputime.utime + cputime.stime; +		*sample = cputime_to_expires(cputime.utime + cputime.stime);  		break;  	case CPUCLOCK_VIRT: -		cpu->cpu = cputime.utime; +		*sample = cputime_to_expires(cputime.utime);  		break;  	case CPUCLOCK_SCHED: -		cpu->sched = cputime.sum_exec_runtime + task_delta_exec(p); +		*sample = cputime.sum_exec_runtime + task_delta_exec(p);  		break;  	}  	return 0; @@ -694,7 +635,7 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int flags,  			       struct itimerspec *new, struct itimerspec *old)  {  	struct task_struct *p = timer->it.cpu.task; -	union cpu_time_count old_expires, new_expires, old_incr, val; +	unsigned long long old_expires, new_expires, old_incr, val;  	int ret;  	if (unlikely(p == NULL)) { @@ -749,7 +690,7 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int flags,  	}  	if (old) { -		if (old_expires.sched == 0) { +		if (old_expires == 0) {  			old->it_value.tv_sec = 0;  			old->it_value.tv_nsec = 0;  		} else { @@ -764,11 +705,8 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int flags,  			 * new setting.  			 */  			bump_cpu_timer(timer, val); -			if (cpu_time_before(timer->it_clock, val, -					    timer->it.cpu.expires)) { -				old_expires = cpu_time_sub( -					timer->it_clock, -					timer->it.cpu.expires, val); +			if (val < timer->it.cpu.expires) { +				old_expires = timer->it.cpu.expires - val;  				sample_to_timespec(timer->it_clock,  						   old_expires,  						   &old->it_value); @@ -791,8 +729,8 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int flags,  		goto out;  	} -	if (new_expires.sched != 0 && !(flags & TIMER_ABSTIME)) { -		cpu_time_add(timer->it_clock, &new_expires, val); +	if (new_expires != 0 && !(flags & TIMER_ABSTIME)) { +		new_expires += val;  	}  	/* @@ -801,8 +739,7 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int flags,  	 * arm the timer (we'll just fake it for timer_gettime).  	 */  	timer->it.cpu.expires = new_expires; -	if (new_expires.sched != 0 && -	    cpu_time_before(timer->it_clock, val, new_expires)) { +	if (new_expires != 0 && val < new_expires) {  		arm_timer(timer);  	} @@ -826,8 +763,7 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int flags,  	timer->it_overrun_last = 0;  	timer->it_overrun = -1; -	if (new_expires.sched != 0 && -	    !cpu_time_before(timer->it_clock, val, new_expires)) { +	if (new_expires != 0 && !(val < new_expires)) {  		/*  		 * The designated time already passed, so we notify  		 * immediately, even if the thread never runs to @@ -849,7 +785,7 @@ static int posix_cpu_timer_set(struct k_itimer *timer, int flags,  static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp)  { -	union cpu_time_count now; +	unsigned long long now;  	struct task_struct *p = timer->it.cpu.task;  	int clear_dead; @@ -859,7 +795,7 @@ static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp)  	sample_to_timespec(timer->it_clock,  			   timer->it.cpu.incr, &itp->it_interval); -	if (timer->it.cpu.expires.sched == 0) {	/* Timer not armed at all.  */ +	if (timer->it.cpu.expires == 0) {	/* Timer not armed at all.  */  		itp->it_value.tv_sec = itp->it_value.tv_nsec = 0;  		return;  	} @@ -891,7 +827,7 @@ static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp)  			 */  			put_task_struct(p);  			timer->it.cpu.task = NULL; -			timer->it.cpu.expires.sched = 0; +			timer->it.cpu.expires = 0;  			read_unlock(&tasklist_lock);  			goto dead;  		} else { @@ -912,10 +848,9 @@ static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp)  		goto dead;  	} -	if (cpu_time_before(timer->it_clock, now, timer->it.cpu.expires)) { +	if (now < timer->it.cpu.expires) {  		sample_to_timespec(timer->it_clock, -				   cpu_time_sub(timer->it_clock, -						timer->it.cpu.expires, now), +				   timer->it.cpu.expires - now,  				   &itp->it_value);  	} else {  		/* @@ -927,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 @@ -935,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.cpu) { -			tsk->cputime_expires.prof_exp = t->expires.cpu; -			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.cpu) { -			tsk->cputime_expires.virt_exp = t->expires.cpu; -			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.sched) { -			tsk->cputime_expires.sched_exp = t->expires.sched; -			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. @@ -1030,7 +953,8 @@ static void stop_process_timers(struct signal_struct *sig)  static u32 onecputick;  static void check_cpu_itimer(struct task_struct *tsk, struct cpu_itimer *it, -			     cputime_t *expires, cputime_t cur_time, int signo) +			     unsigned long long *expires, +			     unsigned long long cur_time, int signo)  {  	if (!it->expires)  		return; @@ -1066,9 +990,8 @@ 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; -	cputime_t utime, ptime, virt_expires, prof_expires; +	unsigned long long utime, ptime, virt_expires, prof_expires;  	unsigned long long sum_sched_runtime, sched_expires;  	struct list_head *timers = sig->cpu_timers;  	struct task_cputime cputime; @@ -1078,52 +1001,13 @@ static void check_process_timers(struct task_struct *tsk,  	 * Collect the current process totals.  	 */  	thread_group_cputimer(tsk, &cputime); -	utime = cputime.utime; -	ptime = utime + cputime.stime; +	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.cpu) { -			prof_expires = tl->expires.cpu; -			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.cpu) { -			virt_expires = tl->expires.cpu; -			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) { -			sched_expires = tl->expires.sched; -			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. @@ -1162,8 +1046,8 @@ static void check_process_timers(struct task_struct *tsk,  		}  	} -	sig->cputime_expires.prof_exp = prof_expires; -	sig->cputime_expires.virt_exp = virt_expires; +	sig->cputime_expires.prof_exp = expires_to_cputime(prof_expires); +	sig->cputime_expires.virt_exp = expires_to_cputime(virt_expires);  	sig->cputime_expires.sched_exp = sched_expires;  	if (task_cputime_zero(&sig->cputime_expires))  		stop_process_timers(sig); @@ -1176,7 +1060,7 @@ static void check_process_timers(struct task_struct *tsk,  void posix_cpu_timer_schedule(struct k_itimer *timer)  {  	struct task_struct *p = timer->it.cpu.task; -	union cpu_time_count now; +	unsigned long long now;  	if (unlikely(p == NULL))  		/* @@ -1205,7 +1089,7 @@ void posix_cpu_timer_schedule(struct k_itimer *timer)  			 */  			put_task_struct(p);  			timer->it.cpu.task = p = NULL; -			timer->it.cpu.expires.sched = 0; +			timer->it.cpu.expires = 0;  			goto out_unlock;  		} else if (unlikely(p->exit_state) && thread_group_empty(p)) {  			/* @@ -1213,6 +1097,7 @@ void posix_cpu_timer_schedule(struct k_itimer *timer)  			 * not yet reaped.  Take this opportunity to  			 * drop our task ref.  			 */ +			cpu_timer_sample_group(timer->it_clock, p, &now);  			clear_dead_task(timer, now);  			goto out_unlock;  		} @@ -1387,7 +1272,7 @@ void run_posix_cpu_timers(struct task_struct *tsk)  void set_process_cpu_timer(struct task_struct *tsk, unsigned int clock_idx,  			   cputime_t *newval, cputime_t *oldval)  { -	union cpu_time_count now; +	unsigned long long now;  	BUG_ON(clock_idx == CPUCLOCK_SCHED);  	cpu_timer_sample_group(clock_idx, tsk, &now); @@ -1399,17 +1284,17 @@ void set_process_cpu_timer(struct task_struct *tsk, unsigned int clock_idx,  		 * it to be absolute.  		 */  		if (*oldval) { -			if (*oldval <= now.cpu) { +			if (*oldval <= now) {  				/* Just about to fire. */  				*oldval = cputime_one_jiffy;  			} else { -				*oldval -= now.cpu; +				*oldval -= now;  			}  		}  		if (!*newval)  			goto out; -		*newval += now.cpu; +		*newval += now;  	}  	/* @@ -1459,7 +1344,7 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags,  		}  		while (!signal_pending(current)) { -			if (timer.it.cpu.expires.sched == 0) { +			if (timer.it.cpu.expires == 0) {  				/*  				 * Our timer fired and was reset, below  				 * deletion can not fail. | 
