Commit 00cdee573eafb5d475ac936fce98530be23ceb42
Committed by
Greg Kroah-Hartman
1 parent
469231ffd4
ipc/sem.c: update sem_otime for all operations
commit 0e8c665699e953fa58dc1b0b0d09e5dce7343cc7 upstream. 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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Showing 1 changed file with 29 additions and 13 deletions Side-by-side Diff
ipc/sem.c
... | ... | @@ -918,6 +918,24 @@ |
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 | 939 | * do_smart_update(sma, sops, nsops, otime, pt) - optimized update_queue |
922 | 940 | * @sma: semaphore array |
923 | 941 | * @sops: operations that were performed |
924 | 942 | |
... | ... | @@ -967,17 +985,10 @@ |
967 | 985 | } |
968 | 986 | } |
969 | 987 | } |
970 | - if (otime) { | |
971 | - if (sops == NULL) { | |
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 | - } | |
988 | + if (otime) | |
989 | + set_semotime(sma, sops); | |
978 | 990 | } |
979 | 991 | |
980 | - | |
981 | 992 | /* The following counts are associated to each semaphore: |
982 | 993 | * semncnt number of tasks waiting on semval being nonzero |
983 | 994 | * semzcnt number of tasks waiting on semval being zero |
984 | 995 | |
985 | 996 | |
... | ... | @@ -1839,12 +1850,17 @@ |
1839 | 1850 | |
1840 | 1851 | error = perform_atomic_semop(sma, sops, nsops, un, |
1841 | 1852 | task_tgid_vnr(current)); |
1842 | - if (error <= 0) { | |
1843 | - if (alter && error == 0) | |
1853 | + if (error == 0) { | |
1854 | + /* If the operation was successful, then do | |
1855 | + * the required updates. | |
1856 | + */ | |
1857 | + if (alter) | |
1844 | 1858 | do_smart_update(sma, sops, nsops, 1, &tasks); |
1845 | - | |
1846 | - goto out_unlock_free; | |
1859 | + else | |
1860 | + set_semotime(sma, sops); | |
1847 | 1861 | } |
1862 | + if (error <= 0) | |
1863 | + goto out_unlock_free; | |
1848 | 1864 | |
1849 | 1865 | /* We need to sleep on this operation, so we put the current |
1850 | 1866 | * task into the pending queue and go to sleep. |