diff options
-rw-r--r-- | include/linux/sem.h | 1 | ||||
-rw-r--r-- | ipc/sem.c | 37 |
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; | |||
12 | struct sem_array { | 12 | struct 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 */ |
@@ -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 | ||
1068 | static 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 | |||
1061 | static int semctl_nolock(struct ipc_namespace *ns, int semid, | 1083 | static 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 |