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. |
