aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/sem.h1
-rw-r--r--ipc/sem.c37
2 files changed, 31 insertions, 7 deletions
diff --git a/include/linux/sem.h b/include/linux/sem.h
index 55e17f68d256..976ce3a19f1b 100644
--- a/include/linux/sem.h
+++ b/include/linux/sem.h
@@ -12,7 +12,6 @@ struct task_struct;
12struct sem_array { 12struct sem_array {
13 struct kern_ipc_perm ____cacheline_aligned_in_smp 13 struct kern_ipc_perm ____cacheline_aligned_in_smp
14 sem_perm; /* permissions .. see ipc.h */ 14 sem_perm; /* permissions .. see ipc.h */
15 time_t sem_otime; /* last semop time */
16 time_t sem_ctime; /* last change time */ 15 time_t sem_ctime; /* last change time */
17 struct sem *sem_base; /* ptr to first semaphore in array */ 16 struct sem *sem_base; /* ptr to first semaphore in array */
18 struct list_head pending_alter; /* pending operations */ 17 struct list_head pending_alter; /* pending operations */
diff --git a/ipc/sem.c b/ipc/sem.c
index 6291257ee049..51352e1bfff9 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -99,6 +99,7 @@ struct sem {
99 /* that alter the semaphore */ 99 /* that alter the semaphore */
100 struct list_head pending_const; /* pending single-sop operations */ 100 struct list_head pending_const; /* pending single-sop operations */
101 /* that do not alter the semaphore*/ 101 /* that do not alter the semaphore*/
102 time_t sem_otime; /* candidate for sem_otime */
102} ____cacheline_aligned_in_smp; 103} ____cacheline_aligned_in_smp;
103 104
104/* One queue for each sleeping process in the system. */ 105/* One queue for each sleeping process in the system. */
@@ -911,8 +912,14 @@ static void do_smart_update(struct sem_array *sma, struct sembuf *sops, int nsop
911 } 912 }
912 } 913 }
913 } 914 }
914 if (otime) 915 if (otime) {
915 sma->sem_otime = get_seconds(); 916 if (sops == NULL) {
917 sma->sem_base[0].sem_otime = get_seconds();
918 } else {
919 sma->sem_base[sops[0].sem_num].sem_otime =
920 get_seconds();
921 }
922 }
916} 923}
917 924
918 925
@@ -1058,6 +1065,21 @@ static unsigned long copy_semid_to_user(void __user *buf, struct semid64_ds *in,
1058 } 1065 }
1059} 1066}
1060 1067
1068static time_t get_semotime(struct sem_array *sma)
1069{
1070 int i;
1071 time_t res;
1072
1073 res = sma->sem_base[0].sem_otime;
1074 for (i = 1; i < sma->sem_nsems; i++) {
1075 time_t to = sma->sem_base[i].sem_otime;
1076
1077 if (to > res)
1078 res = to;
1079 }
1080 return res;
1081}
1082
1061static int semctl_nolock(struct ipc_namespace *ns, int semid, 1083static int semctl_nolock(struct ipc_namespace *ns, int semid,
1062 int cmd, int version, void __user *p) 1084 int cmd, int version, void __user *p)
1063{ 1085{
@@ -1131,9 +1153,9 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid,
1131 goto out_unlock; 1153 goto out_unlock;
1132 1154
1133 kernel_to_ipc64_perm(&sma->sem_perm, &tbuf.sem_perm); 1155 kernel_to_ipc64_perm(&sma->sem_perm, &tbuf.sem_perm);
1134 tbuf.sem_otime = sma->sem_otime; 1156 tbuf.sem_otime = get_semotime(sma);
1135 tbuf.sem_ctime = sma->sem_ctime; 1157 tbuf.sem_ctime = sma->sem_ctime;
1136 tbuf.sem_nsems = sma->sem_nsems; 1158 tbuf.sem_nsems = sma->sem_nsems;
1137 rcu_read_unlock(); 1159 rcu_read_unlock();
1138 if (copy_semid_to_user(p, &tbuf, version)) 1160 if (copy_semid_to_user(p, &tbuf, version))
1139 return -EFAULT; 1161 return -EFAULT;
@@ -2025,6 +2047,9 @@ static int sysvipc_sem_proc_show(struct seq_file *s, void *it)
2025{ 2047{
2026 struct user_namespace *user_ns = seq_user_ns(s); 2048 struct user_namespace *user_ns = seq_user_ns(s);
2027 struct sem_array *sma = it; 2049 struct sem_array *sma = it;
2050 time_t sem_otime;
2051
2052 sem_otime = get_semotime(sma);
2028 2053
2029 return seq_printf(s, 2054 return seq_printf(s,
2030 "%10d %10d %4o %10u %5u %5u %5u %5u %10lu %10lu\n", 2055 "%10d %10d %4o %10u %5u %5u %5u %5u %10lu %10lu\n",
@@ -2036,7 +2061,7 @@ static int sysvipc_sem_proc_show(struct seq_file *s, void *it)
2036 from_kgid_munged(user_ns, sma->sem_perm.gid), 2061 from_kgid_munged(user_ns, sma->sem_perm.gid),
2037 from_kuid_munged(user_ns, sma->sem_perm.cuid), 2062 from_kuid_munged(user_ns, sma->sem_perm.cuid),
2038 from_kgid_munged(user_ns, sma->sem_perm.cgid), 2063 from_kgid_munged(user_ns, sma->sem_perm.cgid),
2039 sma->sem_otime, 2064 sem_otime,
2040 sma->sem_ctime); 2065 sma->sem_ctime);
2041} 2066}
2042#endif 2067#endif