diff options
author | Manfred Spraul <manfred@colorfullife.com> | 2013-09-30 16:45:25 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-30 17:31:03 -0400 |
commit | 0e8c665699e953fa58dc1b0b0d09e5dce7343cc7 (patch) | |
tree | 43f6f73159d7be2fbd7930315a053e27c4c8d189 /ipc | |
parent | fb31ba30fb10fe0ee11739f51669d581b4a1412c (diff) |
ipc/sem.c: update sem_otime for all operations
In commit 0a2b9d4c7967 ("ipc/sem.c: move wake_up_process out of the
spinlock section"), the update of semaphore's sem_otime(last semop time)
was moved to one central position (do_smart_update).
But since do_smart_update() is only called for operations that modify
the array, this means that wait-for-zero semops do not update sem_otime
anymore.
The fix is simple:
Non-alter operations must update sem_otime.
[akpm@linux-foundation.org: coding-style fixes]
Signed-off-by: Manfred Spraul <manfred@colorfullife.com>
Reported-by: Jia He <jiakernel@gmail.com>
Tested-by: Jia He <jiakernel@gmail.com>
Cc: Davidlohr Bueso <davidlohr.bueso@hp.com>
Cc: Mike Galbraith <efault@gmx.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'ipc')
-rw-r--r-- | ipc/sem.c | 42 |
1 files changed, 29 insertions, 13 deletions
@@ -918,6 +918,24 @@ again: | |||
918 | } | 918 | } |
919 | 919 | ||
920 | /** | 920 | /** |
921 | * set_semotime(sma, sops) - set sem_otime | ||
922 | * @sma: semaphore array | ||
923 | * @sops: operations that modified the array, may be NULL | ||
924 | * | ||
925 | * sem_otime is replicated to avoid cache line trashing. | ||
926 | * This function sets one instance to the current time. | ||
927 | */ | ||
928 | static void set_semotime(struct sem_array *sma, struct sembuf *sops) | ||
929 | { | ||
930 | if (sops == NULL) { | ||
931 | sma->sem_base[0].sem_otime = get_seconds(); | ||
932 | } else { | ||
933 | sma->sem_base[sops[0].sem_num].sem_otime = | ||
934 | get_seconds(); | ||
935 | } | ||
936 | } | ||
937 | |||
938 | /** | ||
921 | * do_smart_update(sma, sops, nsops, otime, pt) - optimized update_queue | 939 | * do_smart_update(sma, sops, nsops, otime, pt) - optimized update_queue |
922 | * @sma: semaphore array | 940 | * @sma: semaphore array |
923 | * @sops: operations that were performed | 941 | * @sops: operations that were performed |
@@ -967,17 +985,10 @@ static void do_smart_update(struct sem_array *sma, struct sembuf *sops, int nsop | |||
967 | } | 985 | } |
968 | } | 986 | } |
969 | } | 987 | } |
970 | if (otime) { | 988 | if (otime) |
971 | if (sops == NULL) { | 989 | set_semotime(sma, sops); |
972 | sma->sem_base[0].sem_otime = get_seconds(); | ||
973 | } else { | ||
974 | sma->sem_base[sops[0].sem_num].sem_otime = | ||
975 | get_seconds(); | ||
976 | } | ||
977 | } | ||
978 | } | 990 | } |
979 | 991 | ||
980 | |||
981 | /* The following counts are associated to each semaphore: | 992 | /* The following counts are associated to each semaphore: |
982 | * semncnt number of tasks waiting on semval being nonzero | 993 | * semncnt number of tasks waiting on semval being nonzero |
983 | * semzcnt number of tasks waiting on semval being zero | 994 | * semzcnt number of tasks waiting on semval being zero |
@@ -1839,12 +1850,17 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops, | |||
1839 | 1850 | ||
1840 | error = perform_atomic_semop(sma, sops, nsops, un, | 1851 | error = perform_atomic_semop(sma, sops, nsops, un, |
1841 | task_tgid_vnr(current)); | 1852 | task_tgid_vnr(current)); |
1842 | if (error <= 0) { | 1853 | if (error == 0) { |
1843 | if (alter && error == 0) | 1854 | /* If the operation was successful, then do |
1855 | * the required updates. | ||
1856 | */ | ||
1857 | if (alter) | ||
1844 | do_smart_update(sma, sops, nsops, 1, &tasks); | 1858 | do_smart_update(sma, sops, nsops, 1, &tasks); |
1845 | 1859 | else | |
1846 | goto out_unlock_free; | 1860 | set_semotime(sma, sops); |
1847 | } | 1861 | } |
1862 | if (error <= 0) | ||
1863 | goto out_unlock_free; | ||
1848 | 1864 | ||
1849 | /* We need to sleep on this operation, so we put the current | 1865 | /* We need to sleep on this operation, so we put the current |
1850 | * task into the pending queue and go to sleep. | 1866 | * task into the pending queue and go to sleep. |