public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: ethan.kernel@gmail.com
To: mingo@kernel.org, tglx@linutronix.de
Cc: linux-kernel@vger.kernel.org, johlstei@codeaurora.org,
	yinghai@kernel.org, joe.jin@oracle.com,
	"ethan.zhao" <ethan.kernel@gmail.com>
Subject: [PATCH V3]hrtimer: Fix a performance regression by disable reprogramming in remove_hrtimer
Date: Sat, 27 Jul 2013 16:04:07 -0400	[thread overview]
Message-ID: <1374955447-5051-1-git-send-email-ethan.kernel@gmail.com> (raw)

commit 968320b hrtimer: Fix extra wakeups from __remove_hrtimer() introduced a significant scheduler
 performance regression, following is the test:

a. Test environment:
SUN FIRE X4170 M2 SERVER
CPU model name: Intel(R) Xeon(R) CPU X5675  @ 3.07GHz
2 socket X 6 core X 2 thread

b. To eliminate the disturbing of variable frequency technology of Intel CPU. We disabled the C-States, P-States
T-States etc SpeedStep, Turboboost, power management in BIOS configuration.

c. Test case:
1.test tool (Any better tools ?)

int main (void)
{
        unsigned long long t0, t1;
        int pipe_1[2], pipe_2[2];
        int m = 0, i;

        pipe(pipe_1);
        pipe(pipe_2);

        if (!fork()) {
                for (i = 0; i < LOOPS; i++) {
                        read(pipe_1[0], &m, sizeof(int));
                        write(pipe_2[1], &m, sizeof(int));
                }
        } else {
                for (i = 0; i < LOOPS; i++) {
                        write(pipe_1[1], &m, sizeof(int));
                        read(pipe_2[0], &m, sizeof(int));
                }
        }

        return 0;
}
from  http://people.redhat.com/mingo/cfs-scheduler/tools/pipe-test-1m.c

2.after boot the test kernel a few minutes, execute
$time ./pipe-test-1m
collect data output by time like:
real    0m9.326s
user    0m0.352s
sys     0m5.640s
3.after the test case finished a few seconds, redo the same one.

d. Test result data
Test kernel without patch 968320b hrtimer: Fix extra wakeups from __remove_hrtimer() /
Or applied this patch to disable reprogramming in remove_hrtimer()
---------------------------------------------------------------------------------------------------------
|      |    1     |     2    |   3      |    4     |    5     | 6    |    7     |    8     |   AVG        |
---------------------------------------------------------------------------------------------------------
| real | 0m5.328s | 0m5.372s | 0m5.307s | 0m5.307s | 0m5.330s | 0m5.315s | 0m5.318s | 0m5.317s | 5.32425s |
---------------------------------------------------------------------------------------------------------
| user | 0m0.106s | 0m0.098s | 0m0.108s | 0m0.120s | 0m0.113s | 0m0.121s | 0m0.125s | 0m0.103s | 0.11175s |
---------------------------------------------------------------------------------------------------------
| sys  | 0m2.287s | 0m2.334s | 0m2.269s | 0m2.269s | 0m2.298s | 0m2.274s | 0m2.263s | 0m2.292s | 2.28575s |
---------------------------------------------------------------------------------------------------------

With patch 968320b hrtimer: Fix extra wakeups from __remove_hrtimer()
Redo the test more than 10 times, select 8 of them, collect the data into following tables.
---------------------------------------------------------------------------------------------------------
|      |    1     |     2    |   3      |    4     |    5     | 6    |    7     |    8     |   AVG       |
---------------------------------------------------------------------------------------------------------
| real | 0m7.132s | 0m6.741s | 0m6.996s | 0m9.269s | 0m6.742s | 0m6.977s | 0m6.802s | 0m6.957s | 7.202s   |
---------------------------------------------------------------------------------------------------------
| user | 0m0.033s | 0m0.031s | 0m0.048s | 0m0.436s | 0m0.022s | 0m0.005s | 0m0.014s | 0m0.014s | 0.075375s|
---------------------------------------------------------------------------------------------------------
| sys  | 0m3.119s | 0m2.940s | 0m3.185s | 0m4.023s | 0m3.053s | 0m3.152s | 0m3.054s | 0m3.124s | 3.20625s |
---------------------------------------------------------------------------------------------------------

e. Conclusion
We found the performance has 1.87775S(average value) down introduced by commit
968320b hrtimer: Fix extra wakeups from __remove_hrtimer().
That is more than -35% !

Disable reprogramming in remove_hrtimer() to fix this performance regression:
function remove_hrtimer() with reprogramming the clock device is called in following two cases:

1.      In function hrtimer_try_to_cancel()
  Whatever you reprogram the clock device or not, the timer function wouldn't be called anymore. So set reprogram
        to 0 doesn't change the result of hrtimer_try_to_cancel()

         hrtimer_try_to_cancel()
         --- > remove_hrtimer()
             ---- > __remove_hrtimer(timer, base, state, reprogram);

2.      In function  __hrtimer_start_range_ns(),
  After remove_hrtimer() was called, the rest of code in this function will check the new timer added into queue is
        the leftmost or not, if needed, will reprogram the clock device.

   __hrtimer_start_range_ns()
  {
        ... ...
        ret = remove_hrtimer(timer, base);
        ... ...
        leftmost = enqueue_hrtimer(timer, new_base);
        if (leftmost && new_base->cpu_base == &__get_cpu_var(hrtimer_bases)
                && hrtimer_enqueue_reprogram(timer, new_base)) {
        ... ..
        }

Will we lose the chance to reprogram the clock device after remove_hrtimer() ?
I think No, Because we didn't reprogram the clock device in remove_hrtimer(), if the timer removed is just the next one
will expire, we still could get reprogrammed in hrtimer_interrupt().

So reprogramming in remove_hrtimer() is not necessary-----If I am wrong, just point out.

Why
 commit 968320b hrtimer: Fix extra wakeups from __remove_hrtimer()
Introduced performance regression?
The reprogramming is expensive ?  not cheap so far.
We lost one chance to wakeup?
Yes, commit 968320b actually will delay the next expiry time to the timer next to the one removed. and it looks rational.
If the extra wakeup is not harmful, We really need it to keep the performance and get the chance to wakeup in time.


Reported-by: lijun.huang@oracle.com <lijun.huang@oracle.com>
Signed-off-by: ethan.zhao <ethan.kernel@gmail.com>
---
 kernel/hrtimer.c |   13 +------------
 1 files changed, 1 insertions(+), 12 deletions(-)

diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index 383319b..3c9e828 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -942,26 +942,15 @@ remove_hrtimer(struct hrtimer *timer, struct hrtimer_clock_base *base)
 {
 	if (hrtimer_is_queued(timer)) {
 		unsigned long state;
-		int reprogram;
 
-		/*
-		 * Remove the timer and force reprogramming when high
-		 * resolution mode is active and the timer is on the current
-		 * CPU. If we remove a timer on another CPU, reprogramming is
-		 * skipped. The interrupt event on this CPU is fired and
-		 * reprogramming happens in the interrupt handler. This is a
-		 * rare case and less expensive than a smp call.
-		 */
-		debug_deactivate(timer);
 		timer_stats_hrtimer_clear_start_info(timer);
-		reprogram = base->cpu_base == &__get_cpu_var(hrtimer_bases);
 		/*
 		 * We must preserve the CALLBACK state flag here,
 		 * otherwise we could move the timer base in
 		 * switch_hrtimer_base.
 		 */
 		state = timer->state & HRTIMER_STATE_CALLBACK;
-		__remove_hrtimer(timer, base, state, reprogram);
+		__remove_hrtimer(timer, base, state, 0);
 		return 1;
 	}
 	return 0;
-- 
1.7.1


             reply	other threads:[~2013-07-28  2:06 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-07-27 20:04 ethan.kernel [this message]
2013-07-29 10:18 ` [PATCH V3]hrtimer: Fix a performance regression by disable reprogramming in remove_hrtimer Thomas Gleixner
2013-07-29 11:57   ` Peter Zijlstra
2013-08-08  7:32     ` ethan.zhao
2013-09-05  6:36       ` Mike Galbraith
     [not found]         ` <20130905111428.GB23362@gmail.com>
     [not found]           ` <1378386697.6567.9.camel@marge.simpson.net>
     [not found]             ` <20130905133750.GA26637@gmail.com>
     [not found]               ` <1378445942.5434.31.camel@marge.simpson.net>
     [not found]                 ` <20130909122325.GX31370@twins.programming.kicks-ass.net>
     [not found]                   ` <1378730538.5586.30.camel@marge.simpson.net>
2013-09-09 13:30                     ` Peter Zijlstra
2013-09-09 13:46                       ` Peter Zijlstra
2013-09-11  8:56                         ` Peter Zijlstra
2013-09-11 10:25                           ` Mike Galbraith
2013-10-04 12:06                             ` Ethan Zhao
2013-10-07  4:41                               ` Mike Galbraith
2013-10-07  4:57                                 ` Ethan Zhao
2013-12-12 14:14                                   ` Ethan Zhao
2013-12-12 14:42                                     ` Mike Galbraith
     [not found]   ` <CABawtvP4oLuvHOS3prbbgPShXVziV_wTo7i6KCqJ9KkoVdz0ag@mail.gmail.com>
2013-07-30  9:35     ` Peter Zijlstra
2013-07-30 11:44       ` Ethan Zhao
2013-07-30 11:59         ` Peter Zijlstra
2013-08-03  6:55           ` ethan
2013-08-03  7:37           ` ethan
2013-08-06  7:29       ` Mike Galbraith
2013-08-06  7:46         ` Mike Galbraith
2013-08-08  4:31           ` ethan.zhao
2013-08-08  5:29             ` Mike Galbraith
2013-08-08  5:51               ` Mike Galbraith
2013-08-08  9:04             ` ethan.zhao
2013-08-08  9:05               ` ethan.zhao
2013-08-08 12:14               ` Mike Galbraith
2013-08-07  8:25         ` Mike Galbraith
2013-08-08  4:05           ` Mike Galbraith
2013-08-08 15:02         ` ethan.zhao
2013-08-09  6:52           ` Mike Galbraith

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1374955447-5051-1-git-send-email-ethan.kernel@gmail.com \
    --to=ethan.kernel@gmail.com \
    --cc=joe.jin@oracle.com \
    --cc=johlstei@codeaurora.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=tglx@linutronix.de \
    --cc=yinghai@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox