Process time measurement too optimistic

Pavel Machek (pavel@bug.ucw.cz)
Wed, 8 Jul 1998 15:28:11 +0200


Hi!

Linux currently charges processes for time at end of timeslice. That
means that if process wakes because of timer and finishes its
processing before end of jiffie, no time is charged to him.

It is possible to exploit this: I have code which eats ~50% of system
time, still, no time is charged to him. (This is partly dangerous
because scheduling strategy depends on same times.)

Unfortunately, some real-life applications behave in really similar
way. (For example anything what uses qt.) This patch moves charging
from end of timeslice to beggining. That means that qt-like
applications show up as eating CPU time.

Pavel

--- clean/kernel/sched.c Thu Jun 25 17:38:15 1998
+++ linux/kernel/sched.c Wed Jul 8 14:32:44 1998
@@ -82,6 +82,7 @@
long time_adjust_step = 0;

int need_resched = 0;
+int need_update_times = 0;
unsigned long event = 0;

extern int do_setitimer(int, struct itimerval *, struct itimerval *);
@@ -102,5 +103,7 @@

struct kernel_stat kstat = { 0 };

+static void update_process_times(struct task_struct *p, unsigned long ticks, unsigned long system);
+
void scheduling_functions_start_here(void) { }

@@ -495,6 +495,10 @@
next->processor = this_cpu;
#endif

+
+ if (need_update_times)
+ update_process_times( next, 1, 1 );
+
if (prev != next) {
struct timer_list timer;

@@ -767,10 +775,7 @@
struct timer_struct timer_table[32];

/*
- * Hmm.. Changed this, as the GNU make sources (load.c) seems to
- * imply that avenrun[] is the standard name for this kind of thing.
- * Nothing else seems to be standardized: the fractional size etc
- * all seem to differ on different machines.
+ * This is famous 'load average'.
*/
unsigned long avenrun[3] = { 0,0,0 };

@@ -1046,14 +1051,15 @@
do_it_prof(p, ticks);
}

-static void update_process_times(unsigned long ticks, unsigned long system)
+static void update_process_times(struct task_struct *p, unsigned long ticks, unsigned long system)
{
/*
* SMP does this on a per-CPU basis elsewhere
*/
#ifndef __SMP__
- struct task_struct * p = current;
unsigned long user = ticks - system;
+ need_update_times = 0;
+
if (p->pid) {
p->counter -= ticks;
if (p->counter < 0) {
@@ -1091,8 +1097,11 @@
calc_load(ticks);
update_wall_time(ticks);
restore_flags(flags);
-
- update_process_times(ticks, system);
+
+ if (current->pid || (!need_resched))
+ update_process_times(current, ticks, system);
+ else
+ need_update_times = 1;

} else
restore_flags(flags);
@@ -1100,8 +1109,8 @@

static void timer_bh(void)
{
- update_times();
run_old_timers();
run_timer_list();
+ update_times();
}

-- 
I'm really pavel@atrey.karlin.mff.cuni.cz. 	   Pavel
Look at http://atrey.karlin.mff.cuni.cz/~pavel/ ;-).

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu