linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: [PATCH] O12.2int for interactivity
@ 2003-08-04 19:50 Charlie Baylis
  2003-08-05  2:10 ` Con Kolivas
  2003-08-05 22:49 ` Timothy Miller
  0 siblings, 2 replies; 35+ messages in thread
From: Charlie Baylis @ 2003-08-04 19:50 UTC (permalink / raw)
  To: linux-kernel; +Cc: kernel


> I tried them aggressively; irman2 and thud don't hurt here. The idle
> detection limits both of them from gaining too much sleep_avg while waiting
> around and they dont get better dynamic priority than 17. 

Sounds like you've taken the teeth out of the thud program :) The original aim
was to demonstrate what happens when a maximally interactive task suddenly
becomes a CPU hog - similar to a web browser starting to render and causing
intense X activity in the process. Stopping thud getting maximum priority is
addressing the symptom, not the cause. (That's not to say the idle detection
is a bad idea - but it's not the complete answer)

What happens if you change the line
  struct timespec st={10,50000000}; 
to
  struct timespec st={0,250000000}; 

and the line
    nanosleep(&st, 0); 
to
    for (n=0; n<40; n++) nanosleep(&st, 0); 

the idea is to do a little bit of work so that the idle detection doesn't kick
in and thud can reach the max interactive bonus. (I haven't tried your patch
yet to see if this change achieves this)

Charlie


^ permalink raw reply	[flat|nested] 35+ messages in thread
* Re: [PATCH] O12.2int for interactivity
@ 2003-08-03 21:19 Voluspa
  2003-08-04  2:34 ` Con Kolivas
  0 siblings, 1 reply; 35+ messages in thread
From: Voluspa @ 2003-08-03 21:19 UTC (permalink / raw)
  To: linux-kernel


On 2003-08-03 10:14:00 Con Kolivas wrote:

> Please note if you do test the interactivity it would be most valuable
> if you test Ingo's A3 patch first looking for improvements and
> problems compared to vanilla _first_, and then test my O12.2 patch on
> top of it. Hopefully there has been no regression and only
> improvement in going to Ingo's new infrastructure.

I can hardly spot any difference between 2.6.0-test2, A3 and A3-O12.2
while running the test as outlined in:

http://marc.theaimsgroup.com/?l=linux-kernel&m=105956126017752&w=2

I'll never do such a three hours again... All was equally well, which
probably just means that my environment is too lightweight during
"normal" operation. So I had to focus on the taxing game scenario.

XFree86 Version 4.3.99.9 compiled against my glibc 2.2.4, and the same
story with winex 3.1 running "Baldurs Gate I":

_2.6.0-test2_

Animations have cyclic hacking like --- . --- . --- . (dots are pauses).
Ambient sound hacks in concert, with an almost oscillating quality.
Mouse pointer is impossible to place since movement can mean a few
pixels or a full screen. Panning the play area is, of course, a real
pain. Playability = 0 (on a scale from 0 to 10)

_2.6.0-test2-A3_

All problems gone. Just slight bumps (very short graphic pauses) when
doing a long play area panning. Sound is not perceptibly disturbed by
any graphic bumps. Playability = 9.

_2.6.0-test2-A3-O12.2_

Regression compared to plain A3, both in sound and animations. Mouse and
panning seem less regressed. For example, a character can take four
steps, freeze for half a second, take another four steps, freeze etc.
Playablility = 8.

I did the game-test two times with each A3 and A3-O12.2 (alternating
boots) and the results were persistent. Looking at a "top" terminal
while in the game, I couldn't spot any striking differences between the
numbers. Just one oddity - and now I'm uncertain of its validity - as
can be seen on the screencaps below. In A3 wine had a PRI of 25,
wineserver had 15. In A3-O12.2 the numbers were reversed. I can redo the
test if necessary.

( the niced process is foldingathome, always running on my system)

--A3--
20:15:01 up 23 min, 4 users, load average: 2.86, 3.09, 2.46
58 processes: 53 sleeping, 4 running, 0 zombie, 1 stopped
CPU states: 53.7% user 42.1% system 4.1% nice 0.0% iowait 0.0% idle
Mem: 127032k av, 123384k used, 3648k free, 0k shrd, 732k buff
86876k active, 28660k inactive
Swap: 489940k av, 0k used, 489940k free 49436k cached

PID USER PRI NI SIZE RSS SHARE STAT %CPU %MEM TIME CPU COMMAND
209 loke 25  0 75316  46M 14284 R    56.6 37.2 10:40 0 wine
216 loke 15  0  2712  992  2388 S    34.4 0.7  5:42  0 wineserver
147 loke 34  19 33220 2388 24144 S N 4.3  1.8  2:02  0 FahCore_ca.ex
252 loke 16  0  1820  968  1664 R    1.7  0.7  0:01  0 top
172 root 16  0 27652  16M 13884 R    1.3 13.1  4:04  0 X
178 loke 15  0  5752  3428 5200 S    1.1  2.6  0:13  0 gkrellm
175 loke 15  0  8056  5936 4528 S    0.3  4.6  0:06  0 enlightenment
--

--A3-O12.2--
20:53:19 up 14 min, 4 users, load average: 3.57, 2.52, 1.27
58 processes: 52 sleeping, 5 running, 0 zombie, 1 stopped
CPU states: 60.3% user 36.5% system 3.1% nice 0.0% iowait 0.0% idle
Mem: 127032k av, 123672k used, 3360k free, 0k shrd, 640k buff
87996k active, 27860k inactive
Swap: 489940k av, 0k used, 489940k free 50664k cached

PID USER PRI NI SIZE RSS SHARE STAT %CPU %MEM TIME CPU COMMAND
193 loke 15  0 66548  37M 14284 S   60.3 30.2 2:36   0 wine
200 loke 25  0  2704  984  2388 R   31.7 0.7  1:24   0 wineserver
150 loke 39  19 37248  10M 28172 S N 3.1 8.2  8:49   0 FahCore_ca.ex
220 loke 18  0  1820  968  1664 R   1.9  0.7  0:03   0 top
175 root 15  0 27492  16M 13872 S   1.3  13.0 0:31   0 X
181 loke 16  0  5752 3428  5200 S   0.9  2.6  0:03   0 gkrellm
178 loke 16  0  8232 6084  4520 S   0.3  4.7  0:03   0 enlightenment
--

Mvh
Mats Johannesson

^ permalink raw reply	[flat|nested] 35+ messages in thread
* [PATCH] O12.2int for interactivity
@ 2003-08-03 10:14 Con Kolivas
  2003-08-03 11:25 ` Ingo Molnar
  2003-08-03 11:37 ` Felipe Alfaro Solana
  0 siblings, 2 replies; 35+ messages in thread
From: Con Kolivas @ 2003-08-03 10:14 UTC (permalink / raw)
  To: linux kernel mailing list, Ingo Molnar, Andrew Morton
  Cc: Felipe Alfaro Solana

I've continued development on the interactivity patches against Ingo's new 
infrastructure changes. 

This is a complete resync of the work so far with changes to suit the 
nanosecond timing.

Rather than just a changelog, here is a complete list of what this patch
does on top of Ingo's :

Interactivity credit determines whether a task is interactive or not and 
treats them differently during priority changing.

Some #defines are used to help conversion from ns to jiffies, and the tuning 
knobs have been altered slightly to work with these changes.

Tasks do not earn sleep_avg on their initial wakeup.

User tasks sleeping for a long period get just interactive sleep_avg to stay 
on the active queue but be unable to starve if they turn into cpu hogs.

Tasks with interactive credit elevate their sleep avg proportionately more as 
their priority bonus starts dropping off.

Tasks without interactive credit are limited to one timeslice worth of sleep 
avg as a bonus.

Accumulated sleep_avg of over MAX_SLEEP_AVG starts earning tasks interactive 
credits.

Run out of sleep_avg makes you lose interactive credits.

On their very first wakeup new forks don't get any sleep_avg bonus.

Only tasks with interactive_credits gain sleep_avg for time waiting on the 
runqueue.

New forks get the lowest value of sleep_avg compatible with the dynamic 
priority they will wake up with.

Reverted Ingo's EXPIRED_STARVING definition; it was making interactive tasks 
expire faster as cpu load increased.

Only user tasks get requeued after TIMESLICE_GRANULARITY, and only if they 
have at least MIN_TIMESLICE remaining.

Tasks with interactive credit lose proportionately less sleep_avg as their 
dynamic priority drops.

Using up a full timeslice makes you lose interactive credits.

The patch patch-A3-O12.2int is available against 2.6.0-test2-mm3 here:

http://kernel.kolivas.org/2.5

Ingo's patch-test2-A3 patch against 2.6.0-test2 is also available there, and a 
patch-test2-A3-O12.2  to go on top of that is also available.

Please note if you do test the interactivity it would be most valuable if you 
test Ingo's A3 patch first looking for improvements and problems compared to 
vanilla _first_, and then test my O12.2 patch on top of it. Hopefully there
has been no regression and only improvement in going to Ingo's new
infrastructure.

Con

patch-A3-O12.2int against 2.6.0-test2-mm3:

--- linux-2.6.0-test2-mm3/include/linux/sched.h	2003-08-03 09:51:49.000000000 +1000
+++ linux-2.6.0-test2-mm3-O12.2/include/linux/sched.h	2003-08-03 09:53:32.000000000 +1000
@@ -341,6 +341,7 @@ struct task_struct {
 	prio_array_t *array;
 
 	unsigned long sleep_avg;
+	long interactive_credit;
 	unsigned long long timestamp;
 	int activated;
 
--- linux-2.6.0-test2-mm3/kernel/sched.c	2003-08-03 09:51:49.000000000 +1000
+++ linux-2.6.0-test2-mm3-O12.2/kernel/sched.c	2003-08-03 10:19:22.000000000 +1000
@@ -58,6 +58,14 @@
 #define USER_PRIO(p)		((p)-MAX_RT_PRIO)
 #define TASK_USER_PRIO(p)	USER_PRIO((p)->static_prio)
 #define MAX_USER_PRIO		(USER_PRIO(MAX_PRIO))
+#define AVG_TIMESLICE	(MIN_TIMESLICE + ((MAX_TIMESLICE - MIN_TIMESLICE) *\
+			(MAX_PRIO-1-NICE_TO_PRIO(0))/(MAX_USER_PRIO - 1)))
+
+/*
+ * Some helpers for converting nanosecond timing to jiffy resolution
+ */
+#define NS_TO_JIFFIES(TIME)	(TIME / (1000000000 / HZ))
+#define JIFFIES_TO_NS(TIME)	(TIME * (1000000000 / HZ))
 
 /*
  * These are the 'tuning knobs' of the scheduler:
@@ -70,13 +78,15 @@
 #define MAX_TIMESLICE		(200 * HZ / 1000)
 #define TIMESLICE_GRANULARITY	(HZ/40 ?: 1)
 #define ON_RUNQUEUE_WEIGHT	30
-#define CHILD_PENALTY		95
+#define CHILD_PENALTY		90
 #define PARENT_PENALTY		100
 #define EXIT_WEIGHT		3
 #define PRIO_BONUS_RATIO	25
+#define MAX_BONUS		(MAX_USER_PRIO * PRIO_BONUS_RATIO / 100)
 #define INTERACTIVE_DELTA	2
-#define MAX_SLEEP_AVG		(1*1000000000)
-#define STARVATION_LIMIT	HZ
+#define MAX_SLEEP_AVG		(AVG_TIMESLICE * MAX_BONUS)
+#define STARVATION_LIMIT	(MAX_SLEEP_AVG)
+#define NS_MAX_SLEEP_AVG	(JIFFIES_TO_NS(MAX_SLEEP_AVG))
 #define NODE_THRESHOLD		125
 
 /*
@@ -117,6 +127,9 @@
 #define TASK_INTERACTIVE(p) \
 	((p)->prio <= (p)->static_prio - DELTA(p))
 
+#define JUST_INTERACTIVE_SLEEP(p) \
+	(MAX_SLEEP_AVG - (DELTA(p) * AVG_TIMESLICE))
+
 #define TASK_PREEMPTS_CURR(p, rq) \
 	((p)->prio < (rq)->curr->prio || \
 		((p)->prio == (rq)->curr->prio && \
@@ -326,8 +339,9 @@ static int effective_prio(task_t *p)
 	if (rt_task(p))
 		return p->prio;
 
-	bonus = MAX_USER_PRIO*PRIO_BONUS_RATIO*(p->sleep_avg/1024)/(MAX_SLEEP_AVG/1024)/100;
-	bonus -= MAX_USER_PRIO*PRIO_BONUS_RATIO/100/2;
+	bonus = MAX_USER_PRIO * PRIO_BONUS_RATIO *
+		NS_TO_JIFFIES(p->sleep_avg) / MAX_SLEEP_AVG / 100;
+	bonus -= MAX_USER_PRIO * PRIO_BONUS_RATIO / 100 / 2;
 
 	prio = p->static_prio - bonus;
 	if (prio < MAX_RT_PRIO)
@@ -351,37 +365,65 @@ static void recalc_task_prio(task_t *p, 
 	unsigned long long __sleep_time = now - p->timestamp;
 	unsigned long sleep_time;
 
-	if (__sleep_time > MAX_SLEEP_AVG)
-		sleep_time = MAX_SLEEP_AVG;
+	if (unlikely(!p->timestamp))
+		__sleep_time = 0;
+
+	if (__sleep_time > NS_MAX_SLEEP_AVG)
+		sleep_time = NS_MAX_SLEEP_AVG;
 	else
 		sleep_time = (unsigned long)__sleep_time;
 
-	if (sleep_time > 0) {
-		unsigned long long sleep_avg;
+	if (likely(sleep_time > 0)) {
 
 		/*
-		 * This code gives a bonus to interactive tasks.
-		 *
-		 * The boost works by updating the 'average sleep time'
-		 * value here, based on ->timestamp. The more time a task
-		 * spends sleeping, the higher the average gets - and the
-		 * higher the priority boost gets as well.
+		 * User tasks that sleep a long time are categorised as
+		 * idle and will get just interactive status to stay active &
+		 * prevent them suddenly becoming cpu hogs and starving
+		 * other processes.
 		 */
-		sleep_avg = p->sleep_avg + sleep_time;
+		if (p->mm && sleep_time >
+			JIFFIES_TO_NS(JUST_INTERACTIVE_SLEEP(p)))
+				p->sleep_avg =
+					JIFFIES_TO_NS(JUST_INTERACTIVE_SLEEP(p));
+		else {
+			/*
+			 * Tasks with interactive credits get boosted more
+			 * rapidly if their bonus has dropped off. Other
+			 * tasks are limited to one timeslice worth of
+			 * sleep avg.
+			 */
+			if (p->interactive_credit > 0)
+				sleep_time *= (MAX_BONUS + 1 -
+					(NS_TO_JIFFIES(p->sleep_avg) *
+					MAX_BONUS / MAX_SLEEP_AVG));
+			else if (sleep_time > JIFFIES_TO_NS(task_timeslice(p)))
+				sleep_time = JIFFIES_TO_NS(task_timeslice(p));
 
-		/*
-		 * 'Overflow' bonus ticks go to the waker as well, so the
-		 * ticks are not lost. This has the effect of further
-		 * boosting tasks that are related to maximum-interactive
-		 * tasks.
-		 */
-		if (sleep_avg > MAX_SLEEP_AVG)
-			sleep_avg = MAX_SLEEP_AVG;
-		if (p->sleep_avg != sleep_avg) {
-			p->sleep_avg = sleep_avg;
-			p->prio = effective_prio(p);
+			/*
+			 * This code gives a bonus to interactive tasks.
+			 *
+			 * The boost works by updating the 'average sleep time'
+			 * value here, based on ->timestamp. The more time a task
+			 * spends sleeping, the higher the average gets - and the
+			 * higher the priority boost gets as well.
+			 */
+			p->sleep_avg += sleep_time;
+
+			/*
+			 * 'Overflow' bonus ticks go to the waker as well, so the
+			 * ticks are not lost. This has the effect of further
+			 * boosting tasks that are related to maximum-interactive
+			 * tasks.
+			 */
+			if (p->sleep_avg > NS_MAX_SLEEP_AVG){
+				p->sleep_avg = NS_MAX_SLEEP_AVG;
+				p->interactive_credit++;
+			}
 		}
-	}
+	} else if (!p->sleep_avg)
+		p->interactive_credit--;
+
+	p->prio = effective_prio(p);
 }
 
 /*
@@ -411,6 +453,10 @@ static inline void activate_task(task_t 
 	 * but it will be weighted down:
 	 */
 		p->activated = 1;
+
+	if (unlikely(!p->timestamp))
+		p->activated = 0;
+
 	p->timestamp = now;
 
 	__activate_task(p, rq);
@@ -579,7 +625,7 @@ int wake_up_state(task_t *p, unsigned in
  */
 void wake_up_forked_process(task_t * p)
 {
-	unsigned long flags;
+	unsigned long flags, sleep_avg;
 	runqueue_t *rq = task_rq_lock(current, &flags);
 
 	p->state = TASK_RUNNING;
@@ -588,8 +634,18 @@ void wake_up_forked_process(task_t * p)
 	 * and children as well, to keep max-interactive tasks
 	 * from forking tasks that are max-interactive.
 	 */
-	current->sleep_avg = current->sleep_avg / 100 * PARENT_PENALTY;
-	p->sleep_avg = p->sleep_avg / 100 * CHILD_PENALTY;
+	sleep_avg = NS_TO_JIFFIES(current->sleep_avg) * MAX_BONUS /
+			MAX_SLEEP_AVG * PARENT_PENALTY / 100 *
+			MAX_SLEEP_AVG / MAX_BONUS;
+	current->sleep_avg = JIFFIES_TO_NS(sleep_avg);
+
+	sleep_avg = NS_TO_JIFFIES(p->sleep_avg) * MAX_BONUS / MAX_SLEEP_AVG *
+			CHILD_PENALTY / 100 * MAX_SLEEP_AVG / MAX_BONUS;
+	p->sleep_avg = JIFFIES_TO_NS(sleep_avg);
+
+	p->interactive_credit = 0;
+	p->timestamp = 0;
+
 	p->prio = effective_prio(p);
 	set_task_cpu(p, smp_processor_id());
 
@@ -630,7 +686,9 @@ void sched_exit(task_t * p)
 	 * the sleep_avg of the parent as well.
 	 */
 	if (p->sleep_avg < p->parent->sleep_avg)
-		p->parent->sleep_avg = p->parent->sleep_avg / (EXIT_WEIGHT + 1) * EXIT_WEIGHT + p->sleep_avg / (EXIT_WEIGHT + 1);
+		p->parent->sleep_avg = p->parent->sleep_avg /
+		(EXIT_WEIGHT + 1) * EXIT_WEIGHT + p->sleep_avg /
+		(EXIT_WEIGHT + 1);
 }
 
 /**
@@ -1204,7 +1262,8 @@ EXPORT_PER_CPU_SYMBOL(kstat);
  */
 #define EXPIRED_STARVING(rq) \
 		(STARVATION_LIMIT && ((rq)->expired_timestamp && \
-		(jiffies - (rq)->expired_timestamp >= STARVATION_LIMIT)))
+		(jiffies - (rq)->expired_timestamp >= \
+			STARVATION_LIMIT * ((rq)->nr_running) + 1)))
 
 /*
  * This function gets called by the timer code, with HZ frequency.
@@ -1275,6 +1334,7 @@ void scheduler_tick(int user_ticks, int 
 		p->prio = effective_prio(p);
 		p->time_slice = task_timeslice(p);
 		p->first_time_slice = 0;
+		p->interactive_credit--;
 
 		if (!rq->expired_timestamp)
 			rq->expired_timestamp = jiffies;
@@ -1296,11 +1356,12 @@ void scheduler_tick(int user_ticks, int 
 		 * level, which is in essence a round-robin of tasks with
 		 * equal priority.
 		 */
-		if (!((task_timeslice(p) - p->time_slice) % TIMESLICE_GRANULARITY) &&
-			       		(p->array == rq->active)) {
+		if (p->mm && !((task_timeslice(p) - p->time_slice) %
+			TIMESLICE_GRANULARITY) && (p->time_slice > MIN_TIMESLICE) &&
+			(p->array == rq->active)) {
+
 			dequeue_task(p, rq->active);
 			set_tsk_need_resched(p);
-			p->prio = effective_prio(p);
 			enqueue_task(p, rq->active);
 		}
 	}
@@ -1344,10 +1405,21 @@ need_resched:
 
 	release_kernel_lock(prev);
 	now = sched_clock();
-	if (likely(now - prev->timestamp < MAX_SLEEP_AVG))
+	if (likely(now - prev->timestamp < NS_MAX_SLEEP_AVG))
 		run_time = now - prev->timestamp;
 	else
-		run_time = MAX_SLEEP_AVG;
+		run_time = NS_MAX_SLEEP_AVG;
+
+	/*
+	 * Tasks with interactive credits get charged less run_time
+	 * as their sleep_avg decreases to slow them losing their
+	 * priority bonus
+	 */
+	if (prev->interactive_credit > 0)
+		run_time /= (MAX_BONUS + 1 -
+			(NS_TO_JIFFIES(prev->sleep_avg) * MAX_BONUS /
+			MAX_SLEEP_AVG));
+
 	spin_lock_irq(&rq->lock);
 
 	/*
@@ -1395,7 +1467,7 @@ pick_next_task:
 	queue = array->queue + idx;
 	next = list_entry(queue->next, task_t, run_list);
 
-	if (next->activated) {
+	if (next->activated && next->interactive_credit > 0) {
 		unsigned long long delta = now - next->timestamp;
 
 		if (next->activated == 1)


^ permalink raw reply	[flat|nested] 35+ messages in thread

end of thread, other threads:[~2003-08-17 18:00 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-08-04 19:50 [PATCH] O12.2int for interactivity Charlie Baylis
2003-08-05  2:10 ` Con Kolivas
2003-08-05 22:49 ` Timothy Miller
2003-08-06  0:12   ` charlie.baylis
2003-08-06  1:23   ` Con Kolivas
2003-08-06 22:24     ` Timothy Miller
2003-08-11  8:14   ` Rob Landley
2003-08-11 23:49     ` Timothy Miller
2003-08-12  0:17       ` William Lee Irwin III
2003-08-12 15:04         ` Timothy Miller
2003-08-12 23:32           ` William Lee Irwin III
2003-08-13 15:46             ` Timothy Miller
2003-08-14  6:09               ` William Lee Irwin III
2003-08-14  6:59                 ` Con Kolivas
2003-08-14  7:01                   ` William Lee Irwin III
2003-08-14  7:46                     ` Con Kolivas
2003-08-14 20:03                       ` Timothy Miller
2003-08-15 16:40                         ` Con Kolivas
2003-08-14 20:00                     ` Timothy Miller
2003-08-15 16:38                       ` Con Kolivas
2003-08-15 18:12                         ` Timothy Miller
2003-08-17  2:19                           ` William Lee Irwin III
2003-08-17 18:00                           ` Mike Fedyk
2003-08-14 19:57                   ` Timothy Miller
2003-08-15 16:35                     ` Con Kolivas
2003-08-15 18:17                       ` Timothy Miller
2003-08-16  2:29                         ` Con Kolivas
2003-08-14 19:54                 ` Timothy Miller
  -- strict thread matches above, loose matches on Subject: below --
2003-08-03 21:19 Voluspa
2003-08-04  2:34 ` Con Kolivas
2003-08-03 10:14 Con Kolivas
2003-08-03 11:25 ` Ingo Molnar
2003-08-03 11:36   ` Con Kolivas
2003-08-04  3:06   ` Con Kolivas
2003-08-03 11:37 ` Felipe Alfaro Solana

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).