2003-07-26 16:48:46

by Con Kolivas

[permalink] [raw]
Subject: [PATCH] O9int for interactivity

Here is the evolution of the orthogonal interactivity patches. These patches
will not benefit from the extra resolution of nanosecond timing in Ingo's
patch G3 so I'm not going to try and merge the two fully. Also it avoids
the extra overhead in that timing.

O8+ should be resistant to irman2 and should cope ok with reniced X if
that's your flavour.

Changes:
Tweaking of the numbers to improve startup time of applications,
hopefully without sacrificing interactivity elsewhere.

Newly forked processes dont get any interactivity bonus on their first
activation.

Tasks are requeued according to Ingo's TIMESLICE_GRANULARITY rules, with some
adjustments. Tasks do not change priority during requeuing and must have at
least MIN_TIMESLICE left to requeue.

Patch applies on top of 2.6.0-test1-mm2 + O8int. A patch against vanilla
2.6.0-test1 is also available on my website.

Con

Patch available here:
http://kernel.kolivas.org/2.5

and here:

--- linux-2.6.0-test1-mm2/kernel/sched.c 2003-07-24 10:31:41.000000000 +1000
+++ linux-2.6.0-test1ck2/kernel/sched.c 2003-07-27 01:39:07.000000000 +1000
@@ -68,7 +68,8 @@
*/
#define MIN_TIMESLICE ( 10 * HZ / 1000)
#define MAX_TIMESLICE (200 * HZ / 1000)
-#define CHILD_PENALTY 60
+#define TIMESLICE_GRANULARITY (HZ / 20 ?: 1)
+#define CHILD_PENALTY 90
#define PARENT_PENALTY 100
#define EXIT_WEIGHT 3
#define PRIO_BONUS_RATIO 25
@@ -348,28 +349,32 @@ static inline void __activate_task(task_
*/
static inline void activate_task(task_t *p, runqueue_t *rq)
{
- long sleep_time = jiffies - p->last_run - 1;
-
- if (sleep_time > 0) {
- /*
- * User tasks that sleep a long time are categorised as idle and
- * will get just under interactive status to prevent them suddenly
- * becoming cpu hogs and starving other processes.
- */
- if (p->mm && sleep_time > HZ)
- p->sleep_avg = MAX_SLEEP_AVG * (MAX_BONUS - INTERACTIVE_DELTA - 2) /
MAX_BONUS;
- else {
+ if (likely(p->last_run)){
+ long sleep_time = jiffies - p->last_run - 1;

+ if (sleep_time > 0) {
/*
- * Processes that sleep get pushed to one higher priority
- * each time they sleep greater than one tick. -ck
+ * User tasks that sleep a long time are categorised as idle and
+ * will get just under interactive status to prevent them suddenly
+ * becoming cpu hogs and starving other processes.
*/
- p->sleep_avg = (p->sleep_avg * MAX_BONUS / MAX_SLEEP_AVG + 1) *
MAX_SLEEP_AVG / MAX_BONUS;
+ if (p->mm && sleep_time > HZ)
+ p->sleep_avg = MAX_SLEEP_AVG * (MAX_BONUS - 1) / MAX_BONUS - 1;
+ else {
+
+ /*
+ * Processes that sleep get pushed to one higher priority
+ * each time they sleep greater than one tick. -ck
+ */
+ p->sleep_avg = (p->sleep_avg * MAX_BONUS / MAX_SLEEP_AVG + 1) *
MAX_SLEEP_AVG / MAX_BONUS;

- if (p->sleep_avg > MAX_SLEEP_AVG)
- p->sleep_avg = MAX_SLEEP_AVG;
+ if (p->sleep_avg > MAX_SLEEP_AVG)
+ p->sleep_avg = MAX_SLEEP_AVG;
+ }
}
- }
+ } else
+ p->last_run = jiffies;
+
p->prio = effective_prio(p);
__activate_task(p, rq);
}
@@ -549,6 +554,7 @@ void wake_up_forked_process(task_t * p)
current->sleep_avg = current->sleep_avg * PARENT_PENALTY / 100;
p->sleep_avg = p->sleep_avg * CHILD_PENALTY / 100;
p->prio = effective_prio(p);
+ p->last_run = 0;
set_task_cpu(p, smp_processor_id());

if (unlikely(!current->array))
@@ -1242,16 +1248,15 @@ void scheduler_tick(int user_ticks, int
enqueue_task(p, rq->expired);
} else
enqueue_task(p, rq->active);
- } else if (p->mm && !((task_timeslice(p) - p->time_slice) %
- (MIN_TIMESLICE * (MAX_BONUS + 1 - p->sleep_avg * MAX_BONUS /
MAX_SLEEP_AVG)))){
+ } else if (!((task_timeslice(p) - p->time_slice) % TIMESLICE_GRANULARITY) &&
+ (p->time_slice > MIN_TIMESLICE)){
/*
* Running user tasks get requeued with their remaining timeslice
- * after a period proportional to how cpu intensive they are to
- * minimise the duration one interactive task can starve another
+ * after TIMESLICE_GRANULARITY provided they have at least
+ * MIN_TIMESLICE to go.
*/
dequeue_task(p, rq->active);
set_tsk_need_resched(p);
- p->prio = effective_prio(p);
enqueue_task(p, rq->active);
}
out_unlock:


2003-07-26 18:02:29

by Felipe Alfaro Solana

[permalink] [raw]
Subject: Re: [PATCH] O9int for interactivity

On Sat, 2003-07-26 at 19:06, Con Kolivas wrote:

> Patch applies on top of 2.6.0-test1-mm2 + O8int. A patch against vanilla
> 2.6.0-test1 is also available on my website.

patch-test1-O9 contains some differences with respect to patch-O9 for
the -mm kernels. In the patch-test1-O9, MAX_SLEEP_AVG and
STARVATION_LIMIT are both set to (10*HZ), while in patch-O9-mm2 they are
set to (HZ).

Is this intentional?

2003-07-26 18:17:53

by Wiktor Wodecki

[permalink] [raw]
Subject: Re: [PATCH] O9int for interactivity

On Sat, Jul 26, 2003 at 08:17:38PM +0200, Felipe Alfaro Solana wrote:
> On Sat, 2003-07-26 at 19:06, Con Kolivas wrote:
>
> > Patch applies on top of 2.6.0-test1-mm2 + O8int. A patch against vanilla
> > 2.6.0-test1 is also available on my website.
>
> patch-test1-O9 contains some differences with respect to patch-O9 for
> the -mm kernels. In the patch-test1-O9, MAX_SLEEP_AVG and
> STARVATION_LIMIT are both set to (10*HZ), while in patch-O9-mm2 they are
> set to (HZ).
>
> Is this intentional?

probably yes, since vanilla runs on HZ=1000 and -mm on HZ=100

--
Regards,

Wiktor Wodecki


Attachments:
(No filename) (593.00 B)
(No filename) (189.00 B)
Download all attachments

2003-07-26 18:24:37

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH] O9int for interactivity

Wiktor Wodecki <[email protected]> wrote:
>
> since vanilla runs on HZ=1000 and -mm on HZ=100

No, -mm has been back at 1000 for a couple of weeks now.

But people do need to test with HZ=100 - only eight architectures are using
HZ=1000 at present.

2003-07-26 21:02:36

by Guillaume Chazarain

[permalink] [raw]
Subject: Re: [PATCH] O9int for interactivity

Hi Con,

Strange your activate() function in O9. Isn't it?
It doesn't care that much about sleep_time.

So here is a very simple trouble maker.



#include <time.h>
#include <unistd.h>

int main(void)
{
int i;

fork();
fork();

for (;;) {
clock_t c = clock();

usleep(1);
usleep(1);
while (clock() <= c);
}

return 0;
}






2003-07-26 23:49:05

by Con Kolivas

[permalink] [raw]
Subject: Re: [PATCH] O9int for interactivity

On Sun, 27 Jul 2003 04:17, Felipe Alfaro Solana wrote:
> On Sat, 2003-07-26 at 19:06, Con Kolivas wrote:
> > Patch applies on top of 2.6.0-test1-mm2 + O8int. A patch against vanilla
> > 2.6.0-test1 is also available on my website.
>
> patch-test1-O9 contains some differences with respect to patch-O9 for
> the -mm kernels. In the patch-test1-O9, MAX_SLEEP_AVG and
> STARVATION_LIMIT are both set to (10*HZ), while in patch-O9-mm2 they are
> set to (HZ).
>
> Is this intentional?

No, my bad. Will post a fix on my site soon.

Con

2003-07-27 01:37:57

by Con Kolivas

[permalink] [raw]
Subject: Re: [PATCH] O9int for interactivity

On Sun, 27 Jul 2003 07:20, Guillaume Chazarain wrote:
> Hi Con,
>
> Strange your activate() function in O9. Isn't it?
> It doesn't care that much about sleep_time.
>
> So here is a very simple trouble maker.

Yes I know it's a way to make something fairly cpu intensive remain
interactive. However since it sleeps long enough (2ms at 1000Hz is just
enough), it doesn't bring the machine to a standstill, and is easily
killable. I doubt it is worth working around this, but I'm open to your
comments about variations on this theme that might be a problem.

Con

2003-07-27 14:42:05

by Guillaume Chazarain

[permalink] [raw]
Subject: Re: [PATCH] O9int for interactivity

27/07/03 03:57:19, Con Kolivas <[email protected]> wrote:

>On Sun, 27 Jul 2003 07:20, Guillaume Chazarain wrote:
>> Hi Con,
>>
>> Strange your activate() function in O9. Isn't it?
>> It doesn't care that much about sleep_time.
>>
>> So here is a very simple trouble maker.
>
>Yes I know it's a way to make something fairly cpu intensive remain
>interactive. However since it sleeps long enough (2ms at 1000Hz is just
>enough), it doesn't bring the machine to a standstill, and is easily
>killable. I doubt it is worth working around this, but I'm open to your
>comments about variations on this theme that might be a problem.

The previous code was a mistake. (Calling clock() before sleeping is quite dumb...)
Here is another one. If you put the right value in MHZ, (maybe more, maybe less, I dunno),
I bet you won't get out without power cycling your box...


#include <unistd.h>

#define MHZ 450 /* Your CPU Mhz */
#define COUNT (MHZ * 1000)

#define PRIO_LEVELS 10

int main(void)
{
int i;

fork();
fork();

/* Climb all priority levels. */
for (i = 0; i < PRIO_LEVELS; i++)
usleep(1);

for (;;) {
usleep(1); /* get one point. */
for (i = 0; i < COUNT; i++); /* lose one point. */
}

return 0;
}



Guillaume




2003-07-27 14:49:48

by Con Kolivas

[permalink] [raw]
Subject: Re: [PATCH] O9int for interactivity

On Mon, 28 Jul 2003 01:00, Guillaume Chazarain wrote:
> 27/07/03 03:57:19, Con Kolivas <[email protected]> wrote:
> >On Sun, 27 Jul 2003 07:20, Guillaume Chazarain wrote:
> >> Hi Con,
> >>
> >> Strange your activate() function in O9. Isn't it?
> >> It doesn't care that much about sleep_time.
> >>
> >> So here is a very simple trouble maker.
> >
> >Yes I know it's a way to make something fairly cpu intensive remain
> >interactive. However since it sleeps long enough (2ms at 1000Hz is just
> >enough), it doesn't bring the machine to a standstill, and is easily
> >killable. I doubt it is worth working around this, but I'm open to your
> >comments about variations on this theme that might be a problem.
>
> The previous code was a mistake. (Calling clock() before sleeping is quite
> dumb...) Here is another one. If you put the right value in MHZ, (maybe
> more, maybe less, I dunno), I bet you won't get out without power cycling
> your box...

Well I tried it. Luckily it was on an O10 int patched kernel which has some
extra safeguards and it made the machine jerky but usable and easy to kill
the troublemaker. Check for O10int which I'm posting soon, and see if what
I've done is adequate.

Con