Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 76175
b: refs/heads/master
c: 78f2c7d
h: refs/heads/master
i:
  76173: 79acecd
  76171: ccfd170
  76167: 546f437
  76159: 8c18aee
v: v3
  • Loading branch information
Peter Zijlstra authored and Ingo Molnar committed Jan 25, 2008
1 parent 074d333 commit 8f91bce
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: fa717060f1ab7eb6570f2fb49136f838fc9195a9
refs/heads/master: 78f2c7db6068fd6ef75b8c120f04a388848eacb5
5 changes: 3 additions & 2 deletions trunk/include/asm-generic/resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@
#define RLIMIT_NICE 13 /* max nice prio allowed to raise to
0-39 for nice level 19 .. -20 */
#define RLIMIT_RTPRIO 14 /* maximum realtime priority */

#define RLIM_NLIMITS 15
#define RLIMIT_RTTIME 15 /* timeout for RT tasks in us */
#define RLIM_NLIMITS 16

/*
* SuS says limits have to be unsigned.
Expand Down Expand Up @@ -86,6 +86,7 @@
[RLIMIT_MSGQUEUE] = { MQ_BYTES_MAX, MQ_BYTES_MAX }, \
[RLIMIT_NICE] = { 0, 0 }, \
[RLIMIT_RTPRIO] = { 0, 0 }, \
[RLIMIT_RTTIME] = { RLIM_INFINITY, RLIM_INFINITY }, \
}

#endif /* __KERNEL__ */
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -932,6 +932,7 @@ struct sched_entity {
struct sched_rt_entity {
struct list_head run_list;
unsigned int time_slice;
unsigned long timeout;
};

struct task_struct {
Expand Down
29 changes: 29 additions & 0 deletions trunk/kernel/posix-cpu-timers.c
Original file line number Diff line number Diff line change
Expand Up @@ -967,6 +967,7 @@ static void check_thread_timers(struct task_struct *tsk,
{
int maxfire;
struct list_head *timers = tsk->cpu_timers;
struct signal_struct *const sig = tsk->signal;

maxfire = 20;
tsk->it_prof_expires = cputime_zero;
Expand Down Expand Up @@ -1011,6 +1012,34 @@ static void check_thread_timers(struct task_struct *tsk,
t->firing = 1;
list_move_tail(&t->entry, firing);
}

/*
* Check for the special case thread timers.
*/
if (sig->rlim[RLIMIT_RTTIME].rlim_cur != RLIM_INFINITY) {
unsigned long hard = sig->rlim[RLIMIT_RTTIME].rlim_max;
unsigned long *soft = &sig->rlim[RLIMIT_RTTIME].rlim_cur;

if (tsk->rt.timeout > DIV_ROUND_UP(hard, USEC_PER_SEC/HZ)) {
/*
* At the hard limit, we just die.
* No need to calculate anything else now.
*/
__group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
return;
}
if (tsk->rt.timeout > DIV_ROUND_UP(*soft, USEC_PER_SEC/HZ)) {
/*
* At the soft limit, send a SIGXCPU every second.
*/
if (sig->rlim[RLIMIT_RTTIME].rlim_cur
< sig->rlim[RLIMIT_RTTIME].rlim_max) {
sig->rlim[RLIMIT_RTTIME].rlim_cur +=
USEC_PER_SEC;
}
__group_send_sig_info(SIGXCPU, SEND_SIG_PRIV, tsk);
}
}
}

/*
Expand Down
30 changes: 30 additions & 0 deletions trunk/kernel/sched_rt.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ static void enqueue_task_rt(struct rq *rq, struct task_struct *p, int wakeup)
inc_cpu_load(rq, p->se.load.weight);

inc_rt_tasks(p, rq);

if (wakeup)
p->rt.timeout = 0;
}

/*
Expand Down Expand Up @@ -834,11 +837,38 @@ static void prio_changed_rt(struct rq *rq, struct task_struct *p,
}
}

static void watchdog(struct rq *rq, struct task_struct *p)
{
unsigned long soft, hard;

if (!p->signal)
return;

soft = p->signal->rlim[RLIMIT_RTTIME].rlim_cur;
hard = p->signal->rlim[RLIMIT_RTTIME].rlim_max;

if (soft != RLIM_INFINITY) {
unsigned long next;

p->rt.timeout++;
next = DIV_ROUND_UP(min(soft, hard), USEC_PER_SEC/HZ);
if (next > p->rt.timeout) {
u64 next_time = p->se.sum_exec_runtime;

next_time += next * (NSEC_PER_SEC/HZ);
if (p->it_sched_expires > next_time)
p->it_sched_expires = next_time;
} else
p->it_sched_expires = p->se.sum_exec_runtime;
}
}

static void task_tick_rt(struct rq *rq, struct task_struct *p)
{
update_curr_rt(rq);

watchdog(rq, p);

/*
* RR tasks need a special form of timeslice management.
* FIFO tasks have no timeslices.
Expand Down

0 comments on commit 8f91bce

Please sign in to comment.