public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: tip-bot for Jason Low <tipbot@zytor.com>
To: linux-tip-commits@vger.kernel.org
Cc: fweisbec@gmail.com, oleg@redhat.com, tglx@linutronix.de,
	dave@stgolabs.net, mingo@kernel.org,
	linux-kernel@vger.kernel.org, paulmck@linux.vnet.ibm.com,
	jason.low2@hp.com, hpa@zytor.com, peterz@infradead.org,
	linux@horizon.com, rostedt@goodmis.org
Subject: [tip:timers/core] posix_cpu_timer: Reduce unnecessary sighand lock contention
Date: Thu, 15 Oct 2015 02:28:41 -0700	[thread overview]
Message-ID: <tip-c8d75aa47dd585c9538a8205e9bb9847e12cfb84@git.kernel.org> (raw)
In-Reply-To: <1444849677-29330-5-git-send-email-jason.low2@hp.com>

Commit-ID:  c8d75aa47dd585c9538a8205e9bb9847e12cfb84
Gitweb:     http://git.kernel.org/tip/c8d75aa47dd585c9538a8205e9bb9847e12cfb84
Author:     Jason Low <jason.low2@hp.com>
AuthorDate: Wed, 14 Oct 2015 12:07:56 -0700
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Thu, 15 Oct 2015 11:23:41 +0200

posix_cpu_timer: Reduce unnecessary sighand lock contention

It was found while running a database workload on large systems that
significant time was spent trying to acquire the sighand lock.

The issue was that whenever an itimer expired, many threads ended up
simultaneously trying to send the signal. Most of the time, nothing
happened after acquiring the sighand lock because another thread
had just already sent the signal and updated the "next expire" time.
The fastpath_timer_check() didn't help much since the "next expire"
time was updated after the threads exit fastpath_timer_check().

This patch addresses this by having the thread_group_cputimer structure
maintain a boolean to signify when a thread in the group is already
checking for process wide timers, and adds extra logic in the fastpath
to check the boolean.

Signed-off-by: Jason Low <jason.low2@hp.com>
Reviewed-by: Oleg Nesterov <oleg@redhat.com>
Reviewed-by: George Spelvin <linux@horizon.com>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Davidlohr Bueso <dave@stgolabs.net>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: hideaki.kimura@hpe.com
Cc: terry.rudd@hpe.com
Cc: scott.norton@hpe.com
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1444849677-29330-5-git-send-email-jason.low2@hp.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 include/linux/init_task.h      |  1 +
 include/linux/sched.h          |  3 +++
 kernel/time/posix-cpu-timers.c | 26 ++++++++++++++++++++++++--
 3 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index c43b80f..810a34f 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -60,6 +60,7 @@ extern struct fs_struct init_fs;
 	.cputimer	= { 						\
 		.cputime_atomic	= INIT_CPUTIME_ATOMIC,			\
 		.running	= false,				\
+		.checking_timer = false,				\
 	},								\
 	INIT_PREV_CPUTIME(sig)						\
 	.cred_guard_mutex =						\
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 6c8504a..f87559d 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -619,6 +619,8 @@ struct task_cputime_atomic {
  * @cputime_atomic:	atomic thread group interval timers.
  * @running:		true when there are timers running and
  *			@cputime_atomic receives updates.
+ * @checking_timer:	true when a thread in the group is in the
+ *			process of checking for thread group timers.
  *
  * This structure contains the version of task_cputime, above, that is
  * used for thread group CPU timer calculations.
@@ -626,6 +628,7 @@ struct task_cputime_atomic {
 struct thread_group_cputimer {
 	struct task_cputime_atomic cputime_atomic;
 	bool running;
+	bool checking_timer;
 };
 
 #include <linux/rwsem.h>
diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c
index 2d58153..f5e86d2 100644
--- a/kernel/time/posix-cpu-timers.c
+++ b/kernel/time/posix-cpu-timers.c
@@ -975,6 +975,12 @@ static void check_process_timers(struct task_struct *tsk,
 	if (!READ_ONCE(tsk->signal->cputimer.running))
 		return;
 
+        /*
+	 * Signify that a thread is checking for process timers.
+	 * Write access to this field is protected by the sighand lock.
+	 */
+	sig->cputimer.checking_timer = true;
+
 	/*
 	 * Collect the current process totals.
 	 */
@@ -1029,6 +1035,8 @@ static void check_process_timers(struct task_struct *tsk,
 	sig->cputime_expires.sched_exp = sched_expires;
 	if (task_cputime_zero(&sig->cputime_expires))
 		stop_process_timers(sig);
+
+	sig->cputimer.checking_timer = false;
 }
 
 /*
@@ -1142,8 +1150,22 @@ static inline int fastpath_timer_check(struct task_struct *tsk)
 	}
 
 	sig = tsk->signal;
-	/* Check if cputimer is running. This is accessed without locking. */
-	if (READ_ONCE(sig->cputimer.running)) {
+	/*
+	 * Check if thread group timers expired when the cputimer is
+	 * running and no other thread in the group is already checking
+	 * for thread group cputimers. These fields are read without the
+	 * sighand lock. However, this is fine because this is meant to
+	 * be a fastpath heuristic to determine whether we should try to
+	 * acquire the sighand lock to check/handle timers.
+	 *
+	 * In the worst case scenario, if 'running' or 'checking_timer' gets
+	 * set but the current thread doesn't see the change yet, we'll wait
+	 * until the next thread in the group gets a scheduler interrupt to
+	 * handle the timer. This isn't an issue in practice because these
+	 * types of delays with signals actually getting sent are expected.
+	 */
+	if (READ_ONCE(sig->cputimer.running) &&
+	    !READ_ONCE(sig->cputimer.checking_timer)) {
 		struct task_cputime group_sample;
 
 		sample_cputime_atomic(&group_sample, &sig->cputimer.cputime_atomic);

  reply	other threads:[~2015-10-15  9:29 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-10-14 19:07 [PATCH v2 0/4] timer: Improve itimers scalability Jason Low
2015-10-14 19:07 ` [PATCH v2 1/4] timer: Optimize fastpath_timer_check() Jason Low
2015-10-15  9:27   ` [tip:timers/core] posix_cpu_timer: Optimize fastpath_timer_check( ) tip-bot for Jason Low
2015-10-14 19:07 ` [PATCH v2 2/4] timer: Check thread timers only when there are active thread timers Jason Low
2015-10-15  9:28   ` [tip:timers/core] posix_cpu_timer: " tip-bot for Jason Low
2015-10-14 19:07 ` [PATCH v2 3/4] timer: Convert cputimer->running to bool Jason Low
2015-10-15  9:28   ` [tip:timers/core] posix_cpu_timer: Convert cputimer-> running " tip-bot for Jason Low
2015-10-14 19:07 ` [PATCH v2 4/4] timer: Reduce unnecessary sighand lock contention Jason Low
2015-10-15  9:28   ` tip-bot for Jason Low [this message]
2015-10-14 21:18 ` [PATCH v2 0/4] timer: Improve itimers scalability George Spelvin
2015-10-15 12:30   ` Frederic Weisbecker
2015-10-15 19:00   ` Jason Low
2015-10-15  8:47 ` Ingo Molnar
2015-10-15 19:01   ` Jason Low
2015-10-16  7:12     ` Ingo Molnar
2015-10-16 17:34       ` Jason Low
2015-10-16 17:46         ` Hideaki Kimura

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=tip-c8d75aa47dd585c9538a8205e9bb9847e12cfb84@git.kernel.org \
    --to=tipbot@zytor.com \
    --cc=dave@stgolabs.net \
    --cc=fweisbec@gmail.com \
    --cc=hpa@zytor.com \
    --cc=jason.low2@hp.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tip-commits@vger.kernel.org \
    --cc=linux@horizon.com \
    --cc=mingo@kernel.org \
    --cc=oleg@redhat.com \
    --cc=paulmck@linux.vnet.ibm.com \
    --cc=peterz@infradead.org \
    --cc=rostedt@goodmis.org \
    --cc=tglx@linutronix.de \
    /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