summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/sched.c17
-rw-r--r--kernel/timer.c12
2 files changed, 18 insertions, 11 deletions
diff --git a/kernel/sched.c b/kernel/sched.c
index a433a34f6470..07caec2ae996 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -137,6 +137,7 @@ struct runqueue {
spinlock_t lock;
spinlock_t frozen;
unsigned long nr_running, nr_switches, expired_timestamp;
+ signed long nr_uninterruptible;
task_t *curr, *idle;
prio_array_t *active, *expired, arrays[2];
int prev_nr_running[NR_CPUS];
@@ -244,6 +245,8 @@ static inline void activate_task(task_t *p, runqueue_t *rq)
static inline void deactivate_task(struct task_struct *p, runqueue_t *rq)
{
rq->nr_running--;
+ if (p->state == TASK_UNINTERRUPTIBLE)
+ rq->nr_uninterruptible++;
dequeue_task(p, p->array);
p->array = NULL;
}
@@ -323,11 +326,15 @@ static int try_to_wake_up(task_t * p)
{
unsigned long flags;
int success = 0;
+ long old_state;
runqueue_t *rq;
rq = task_rq_lock(p, &flags);
+ old_state = p->state;
p->state = TASK_RUNNING;
if (!p->array) {
+ if (old_state == TASK_UNINTERRUPTIBLE)
+ rq->nr_uninterruptible--;
activate_task(p, rq);
if (p->prio < rq->curr->prio)
resched_task(rq->curr);
@@ -433,6 +440,16 @@ unsigned long nr_running(void)
return sum;
}
+unsigned long nr_uninterruptible(void)
+{
+ unsigned long i, sum = 0;
+
+ for (i = 0; i < smp_num_cpus; i++)
+ sum += cpu_rq(cpu_logical_map(i))->nr_uninterruptible;
+
+ return sum;
+}
+
unsigned long nr_context_switches(void)
{
unsigned long i, sum = 0;
diff --git a/kernel/timer.c b/kernel/timer.c
index 6fc0466711cc..5175ebf0bf32 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -597,17 +597,7 @@ void update_process_times(int user_tick)
*/
static unsigned long count_active_tasks(void)
{
- struct task_struct *p;
- unsigned long nr = 0;
-
- read_lock(&tasklist_lock);
- for_each_task(p) {
- if ((p->state == TASK_RUNNING ||
- (p->state & TASK_UNINTERRUPTIBLE)))
- nr += FIXED_1;
- }
- read_unlock(&tasklist_lock);
- return nr;
+ return (nr_running() + nr_uninterruptible()) * FIXED_1;
}
/*