Thursday 21 April 2011

BFS 0.401

I was meant to be on holidays this week, and indeed I've been away from home somewhere warm. While BFS was supposed to be the last thing I cared about, I was fortunate enough to have other people actually find some bugfixes to BFS. First up was _sid_ who found some very small optimisations that I've committed to the new version of BFS. But even more impressively, Serge Belyshev found a long standing bug that would cause bad latencies when Hz values were low, due to the "last_ran" variable not being set. This may well have been causing a significant latency disadvantage to BFS when Hz was 100.


As you can see in this graph, worst case latencies could be 100 times better with this bug fixed. While it will affect all Hz values, it is most significant at low Hz and probably unnoticeable by the time you're on 1000Hz. Those who are on low Hz configurations, especially those on say android, will notice a dramatic speedup moving to BFS 401.

So get it here (available for 2.6.38.3, 2.6.35.12 and 2.6.32.38):
BFS PATCHES

Again, thanks VERY much to the testers and even more to those contributing bugfixes and code.

9 comments:

  1. --- linux-2.6.35.orig/kernel/sched_bfs.c 2010-08-31 16:32:43.859976211 +0200
    +++ linux-2.6.35/kernel/sched_bfs.c 2010-08-31 16:33:53.943976073 +0200
    @@ -2858,18 +2858,7 @@ EXPORT_SYMBOL_GPL(__wake_up_sync_key);
    */
    void __wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr_exclusive)
    {
    - unsigned long flags;
    - int sync = 1;
    -
    - if (unlikely(!q))
    - return;
    -
    - if (unlikely(!nr_exclusive))
    - sync = 0;
    -
    - spin_lock_irqsave(&q->lock, flags);
    - __wake_up_common(q, mode, nr_exclusive, sync, NULL);
    - spin_unlock_irqrestore(&q->lock, flags);
    + __wake_up_sync_key(q, mode, nr_exclusive, NULL);
    }
    EXPORT_SYMBOL_GPL(__wake_up_sync); /* For internal use only */

    ReplyDelete
  2. --- linux-2.6.38.3-bfs401/kernel/sched_bfs.c 2011-04-21 18:30:46.718536473 +0300
    +++ linux-2.6.38/kernel/sched_bfs.c 2011-04-21 19:59:52.817108649 +0300
    @@ -2808,16 +2808,23 @@
    if (idx >= PRIO_LIMIT)
    goto out;
    queue = grq.queue + idx;
    - list_for_each_entry(p, queue, run_list) {
    - /* Make sure cpu affinity is ok */
    - if (needs_other_cpu(p, cpu))
    - continue;
    - if (idx < MAX_RT_PRIO) {
    + if (idx < MAX_RT_PRIO) {
    + list_for_each_entry(p, queue, run_list) {
    + /* Make sure cpu affinity is ok */
    + if (needs_other_cpu(p, cpu))
    + continue;
    /* We found an rt task */
    edt = p;
    goto out_take;
    }
    -
    + if (++idx < PRIO_LIMIT)
    + goto retry;
    + goto out;
    + }
    + list_for_each_entry(p, queue, run_list) {
    + /* Make sure cpu affinity is ok */
    + if (needs_other_cpu(p, cpu))
    + continue;
    /*
    * Soft affinity happens here by not scheduling a task with
    * its sticky flag set that ran on a different CPU last when

    ReplyDelete
  3. Already testing. Everything is working well.

    ReplyDelete
  4. Are these patches to enhance 4.0.1 or are these bug fixes because there is some kind of problem with 4.0.1?

    ReplyDelete
  5. @Anonymous
    enhance, I'm using 4.0.1 and its rocks !

    ReplyDelete
  6. trivial cleanup:

    --- linux-2.6.38.orig/kernel/sched_bfs.c 2011-04-22 01:48:54.168472094 +0200
    +++ linux-2.6.38/kernel/sched_bfs.c 2011-04-22 01:50:08.866497472 +0200
    @@ -1291,8 +1291,7 @@ EXPORT_SYMBOL_GPL(kick_process);
    * prio PRIO_LIMIT so it is always preempted.
    */
    static inline int
    -can_preempt(struct task_struct *p, int prio, u64 deadline,
    - unsigned int policy)
    +can_preempt(struct task_struct *p, int prio, u64 deadline)
    {
    /* Better static priority RT task or better policy preemption */
    if (p->prio < prio)
    @@ -1387,8 +1386,7 @@ static void try_preempt(struct task_stru
    }
    }

    - if (!can_preempt(p, highest_prio, highest_prio_rq->rq_deadline,
    - highest_prio_rq->rq_policy))
    + if (!can_preempt(p, highest_prio, highest_prio_rq->rq_deadline))
    return;

    resched_task(highest_prio_rq->curr);
    @@ -1403,8 +1401,7 @@ static void try_preempt(struct task_stru
    {
    if (p->policy == SCHED_IDLEPRIO)
    return;
    - if (can_preempt(p, uprq->rq_prio, uprq->rq_deadline,
    - uprq->rq_policy))
    + if (can_preempt(p, uprq->rq_prio, uprq->rq_deadline))
    resched_task(uprq->curr);
    }
    #endif /* CONFIG_SMP */

    ReplyDelete
  7. --- linux-2.6.38.orig/kernel/sched_bfs.c 2011-04-22 02:25:47.785882786 +0200
    +++ linux-2.6.38/kernel/sched_bfs.c 2011-04-22 02:25:58.145499443 +0200
    @@ -1934,7 +1934,7 @@ unsigned long long nr_context_switches(v
    /* This is of course impossible */
    if (unlikely(ns < 0))
    ns = 1;
    - return (long long)ns;
    + return (unsigned long long)ns;
    }

    unsigned long nr_iowait(void)

    ReplyDelete
  8. Email patches please... this is getting out of hand lol. Thanks!

    ReplyDelete