All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/4] posix-timers: move global timer id management to signal_struct v2
@ 2011-08-29 23:39 Andi Kleen
  2011-08-29 23:39 ` [PATCH 2/4] posix-timers: limit the number of posix timers per process Andi Kleen
                   ` (4 more replies)
  0 siblings, 5 replies; 40+ messages in thread
From: Andi Kleen @ 2011-08-29 23:39 UTC (permalink / raw)
  To: linux-kernel; +Cc: akpm, eric.dumazet, Andi Kleen

From: Andi Kleen <ak@linux.intel.com>

Move the global posix timer ids IDR to signal_struct. This removes
a minor global scalability bottleneck and also allows to finally limit
the number of process timers in a sane way (see next patch)

I put it into signal_struct following the other posix timer per process
structures.

v2: Now with locking again (thanks Eric)
Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
 include/linux/init_task.h |    3 +++
 include/linux/sched.h     |    4 ++++
 kernel/fork.c             |    2 ++
 kernel/posix-timers.c     |   23 ++++++++++++-----------
 4 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index d14e058..564248d 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -10,6 +10,7 @@
 #include <linux/pid_namespace.h>
 #include <linux/user_namespace.h>
 #include <linux/securebits.h>
+#include <linux/idr.h>
 #include <net/net_namespace.h>
 
 #ifdef CONFIG_SMP
@@ -37,6 +38,7 @@ extern struct fs_struct init_fs;
 		.list = LIST_HEAD_INIT(sig.shared_pending.list),	\
 		.signal =  {{0}}},					\
 	.posix_timers	 = LIST_HEAD_INIT(sig.posix_timers),		\
+	.idr_lock	 = __SPIN_LOCK_UNLOCKED(idr_lock),		\
 	.cpu_timers	= INIT_CPU_TIMERS(sig.cpu_timers),		\
 	.rlim		= INIT_RLIMITS,					\
 	.cputimer	= { 						\
@@ -46,6 +48,7 @@ extern struct fs_struct init_fs;
 	},								\
 	.cred_guard_mutex =						\
 		 __MUTEX_INITIALIZER(sig.cred_guard_mutex),		\
+	.posix_timers_id = IDR_INIT(posix_timer_id),			\
 	INIT_THREADGROUP_FORK_LOCK(sig)					\
 }
 
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 4ac2c05..87fa2fc 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -62,6 +62,7 @@ struct sched_param {
 #include <linux/errno.h>
 #include <linux/nodemask.h>
 #include <linux/mm_types.h>
+#include <linux/idr.h>
 
 #include <asm/system.h>
 #include <asm/page.h>
@@ -652,6 +653,9 @@ struct signal_struct {
 	struct mutex cred_guard_mutex;	/* guard against foreign influences on
 					 * credential calculations
 					 * (notably. ptrace) */
+
+	struct idr posix_timers_id;
+	spinlock_t idr_lock;		/* Protect posix_timers_id writes */
 };
 
 /* Context switch must be unlocked if interrupts are to be enabled */
diff --git a/kernel/fork.c b/kernel/fork.c
index 8e6b6f4..1054cfd 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -943,6 +943,8 @@ static void posix_cpu_timers_init_group(struct signal_struct *sig)
 	INIT_LIST_HEAD(&sig->cpu_timers[0]);
 	INIT_LIST_HEAD(&sig->cpu_timers[1]);
 	INIT_LIST_HEAD(&sig->cpu_timers[2]);
+
+	idr_init(&sig->posix_timers_id);
 }
 
 static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c
index 4556182..4193cf7 100644
--- a/kernel/posix-timers.c
+++ b/kernel/posix-timers.c
@@ -70,8 +70,6 @@
  * Lets keep our timers in a slab cache :-)
  */
 static struct kmem_cache *posix_timers_cache;
-static struct idr posix_timers_id;
-static DEFINE_SPINLOCK(idr_lock);
 
 /*
  * we assume that the new SIGEV_THREAD_ID shares no bits with the other
@@ -282,7 +280,6 @@ static __init int init_posix_timers(void)
 	posix_timers_cache = kmem_cache_create("posix_timers_cache",
 					sizeof (struct k_itimer), 0, SLAB_PANIC,
 					NULL);
-	idr_init(&posix_timers_id);
 	return 0;
 }
 
@@ -503,10 +500,11 @@ static void k_itimer_rcu_free(struct rcu_head *head)
 static void release_posix_timer(struct k_itimer *tmr, int it_id_set)
 {
 	if (it_id_set) {
+		struct signal_struct *s = current->signal;
 		unsigned long flags;
-		spin_lock_irqsave(&idr_lock, flags);
-		idr_remove(&posix_timers_id, tmr->it_id);
-		spin_unlock_irqrestore(&idr_lock, flags);
+		spin_lock_irqsave(&s->idr_lock, flags);
+		idr_remove(&s->posix_timers_id, tmr->it_id);
+		spin_unlock_irqrestore(&s->idr_lock, flags);
 	}
 	put_pid(tmr->it_pid);
 	sigqueue_free(tmr->sigq);
@@ -541,6 +539,7 @@ SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock,
 	int error, new_timer_id;
 	sigevent_t event;
 	int it_id_set = IT_ID_NOT_SET;
+	struct signal_struct *s = current->signal;
 
 	if (!kc)
 		return -EINVAL;
@@ -553,13 +552,13 @@ SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock,
 
 	spin_lock_init(&new_timer->it_lock);
  retry:
-	if (unlikely(!idr_pre_get(&posix_timers_id, GFP_KERNEL))) {
+	if (unlikely(!idr_pre_get(&s->posix_timers_id, GFP_KERNEL))) {
 		error = -EAGAIN;
 		goto out;
 	}
-	spin_lock_irq(&idr_lock);
-	error = idr_get_new(&posix_timers_id, new_timer, &new_timer_id);
-	spin_unlock_irq(&idr_lock);
+	spin_lock_irq(&s->idr_lock);
+	error = idr_get_new(&s->posix_timers_id, new_timer, &new_timer_id);
+	spin_unlock_irq(&s->idr_lock);
 	if (error) {
 		if (error == -EAGAIN)
 			goto retry;
@@ -638,9 +637,10 @@ out:
 static struct k_itimer *__lock_timer(timer_t timer_id, unsigned long *flags)
 {
 	struct k_itimer *timr;
+	struct signal_struct *s = current->signal;
 
 	rcu_read_lock();
-	timr = idr_find(&posix_timers_id, (int)timer_id);
+	timr = idr_find(&s->posix_timers_id, (int)timer_id);
 	if (timr) {
 		spin_lock_irqsave(&timr->it_lock, *flags);
 		if (timr->it_signal == current->signal) {
@@ -945,6 +945,7 @@ void exit_itimers(struct signal_struct *sig)
 		tmr = list_entry(sig->posix_timers.next, struct k_itimer, list);
 		itimer_delete(tmr);
 	}
+	idr_destroy(&sig->posix_timers_id);
 }
 
 SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
-- 
1.7.4.4


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

end of thread, other threads:[~2011-09-22 11:20 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-29 23:39 [PATCH 1/4] posix-timers: move global timer id management to signal_struct v2 Andi Kleen
2011-08-29 23:39 ` [PATCH 2/4] posix-timers: limit the number of posix timers per process Andi Kleen
2011-08-30 21:44   ` Andrew Morton
2011-08-30 22:06     ` Andi Kleen
2011-08-30 22:22       ` Andrew Morton
2011-08-30 22:47         ` Andi Kleen
2011-08-30 23:02           ` Andrew Morton
2011-08-31  6:45             ` Jiri Slaby
2011-09-02  9:30   ` Thomas Gleixner
2011-08-29 23:39 ` [PATCH 3/4] posix-timers: Don't disable interrupts in idr_lock Andi Kleen
2011-08-29 23:39 ` [PATCH 4/4] posix-timers: turn it_signal into it_valid flag Andi Kleen
2011-09-02 10:06   ` Thomas Gleixner
2011-09-02 11:49     ` Eric Dumazet
2011-09-02 14:19       ` Thomas Gleixner
2011-09-04 16:56     ` Oleg Nesterov
2011-09-04 19:07       ` Andi Kleen
2011-09-04 20:29       ` Oleg Nesterov
2011-09-06  3:14         ` Andi Kleen
2011-09-06 14:51           ` Oleg Nesterov
2011-09-06 15:39             ` Eric Dumazet
2011-09-06 16:27               ` Oleg Nesterov
2011-09-06 18:47               ` Thomas Gleixner
2011-09-06 18:49                 ` Oleg Nesterov
2011-09-06 19:16                   ` Thomas Gleixner
2011-09-06 19:26                     ` Oleg Nesterov
2011-09-06 19:45                       ` Thomas Gleixner
2011-09-06 22:08                         ` Oleg Nesterov
2011-09-06 22:34                           ` Thomas Gleixner
2011-09-21 16:46                           ` Thomas Gleixner
2011-09-21 17:56                             ` Thomas Gleixner
2011-09-22 11:19                               ` Thomas Gleixner
2011-09-06 19:30                     ` Eric Dumazet
2011-09-06 20:10                       ` Thomas Gleixner
2011-09-06 20:27                         ` Eric Dumazet
2011-09-06 19:04                 ` Eric Dumazet
2011-08-31  8:53 ` [PATCH 1/4] posix-timers: move global timer id management to signal_struct v2 Eric Dumazet
2011-08-31 16:57   ` Andi Kleen
2011-09-02  9:19 ` Thomas Gleixner
2011-09-02 10:05   ` Eric Dumazet
2011-09-19 21:46   ` Andi Kleen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.