| From d12e1e50e47e0900dbbf52237b7e171f4f15ea1e Mon Sep 17 00:00:00 2001 |
| From: Manfred Spraul <manfred@colorfullife.com> |
| Date: Mon, 8 Jul 2013 16:01:25 -0700 |
| Subject: ipc/sem.c: replace shared sem_otime with per-semaphore value |
| |
| From: Manfred Spraul <manfred@colorfullife.com> |
| |
| commit d12e1e50e47e0900dbbf52237b7e171f4f15ea1e upstream. |
| |
| sem_otime contains the time of the last semaphore operation that |
| completed successfully. Every operation updates this value, thus access |
| from multiple cpus can cause thrashing. |
| |
| Therefore the patch replaces the variable with a per-semaphore variable. |
| The per-array sem_otime is only calculated when required. |
| |
| No performance improvement on a single-socket i3 - only important for |
| larger systems. |
| |
| Signed-off-by: Manfred Spraul <manfred@colorfullife.com> |
| Cc: Rik van Riel <riel@redhat.com> |
| Cc: Davidlohr Bueso <davidlohr.bueso@hp.com> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| Cc: Mike Galbraith <efault@gmx.de> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| include/linux/sem.h | 1 - |
| ipc/sem.c | 37 +++++++++++++++++++++++++++++++------ |
| 2 files changed, 31 insertions(+), 7 deletions(-) |
| |
| --- a/include/linux/sem.h |
| +++ b/include/linux/sem.h |
| @@ -12,7 +12,6 @@ struct task_struct; |
| struct sem_array { |
| struct kern_ipc_perm ____cacheline_aligned_in_smp |
| sem_perm; /* permissions .. see ipc.h */ |
| - time_t sem_otime; /* last semop time */ |
| time_t sem_ctime; /* last change time */ |
| struct sem *sem_base; /* ptr to first semaphore in array */ |
| struct list_head pending_alter; /* pending operations */ |
| --- a/ipc/sem.c |
| +++ b/ipc/sem.c |
| @@ -99,6 +99,7 @@ struct sem { |
| /* that alter the semaphore */ |
| struct list_head pending_const; /* pending single-sop operations */ |
| /* that do not alter the semaphore*/ |
| + time_t sem_otime; /* candidate for sem_otime */ |
| } ____cacheline_aligned_in_smp; |
| |
| /* One queue for each sleeping process in the system. */ |
| @@ -911,8 +912,14 @@ static void do_smart_update(struct sem_a |
| } |
| } |
| } |
| - if (otime) |
| - sma->sem_otime = get_seconds(); |
| + if (otime) { |
| + if (sops == NULL) { |
| + sma->sem_base[0].sem_otime = get_seconds(); |
| + } else { |
| + sma->sem_base[sops[0].sem_num].sem_otime = |
| + get_seconds(); |
| + } |
| + } |
| } |
| |
| |
| @@ -1058,6 +1065,21 @@ static unsigned long copy_semid_to_user( |
| } |
| } |
| |
| +static time_t get_semotime(struct sem_array *sma) |
| +{ |
| + int i; |
| + time_t res; |
| + |
| + res = sma->sem_base[0].sem_otime; |
| + for (i = 1; i < sma->sem_nsems; i++) { |
| + time_t to = sma->sem_base[i].sem_otime; |
| + |
| + if (to > res) |
| + res = to; |
| + } |
| + return res; |
| +} |
| + |
| static int semctl_nolock(struct ipc_namespace *ns, int semid, |
| int cmd, int version, void __user *p) |
| { |
| @@ -1131,9 +1153,9 @@ static int semctl_nolock(struct ipc_name |
| goto out_unlock; |
| |
| kernel_to_ipc64_perm(&sma->sem_perm, &tbuf.sem_perm); |
| - tbuf.sem_otime = sma->sem_otime; |
| - tbuf.sem_ctime = sma->sem_ctime; |
| - tbuf.sem_nsems = sma->sem_nsems; |
| + tbuf.sem_otime = get_semotime(sma); |
| + tbuf.sem_ctime = sma->sem_ctime; |
| + tbuf.sem_nsems = sma->sem_nsems; |
| rcu_read_unlock(); |
| if (copy_semid_to_user(p, &tbuf, version)) |
| return -EFAULT; |
| @@ -2025,6 +2047,9 @@ static int sysvipc_sem_proc_show(struct |
| { |
| struct user_namespace *user_ns = seq_user_ns(s); |
| struct sem_array *sma = it; |
| + time_t sem_otime; |
| + |
| + sem_otime = get_semotime(sma); |
| |
| return seq_printf(s, |
| "%10d %10d %4o %10u %5u %5u %5u %5u %10lu %10lu\n", |
| @@ -2036,7 +2061,7 @@ static int sysvipc_sem_proc_show(struct |
| from_kgid_munged(user_ns, sma->sem_perm.gid), |
| from_kuid_munged(user_ns, sma->sem_perm.cuid), |
| from_kgid_munged(user_ns, sma->sem_perm.cgid), |
| - sma->sem_otime, |
| + sem_otime, |
| sma->sem_ctime); |
| } |
| #endif |