Lines Matching refs:sma
145 #define sem_checkid(sma, semid) ipc_checkid(&sma->sem_perm, semid) argument
206 static void unmerge_queues(struct sem_array *sma) in unmerge_queues() argument
211 if (sma->complex_count) in unmerge_queues()
218 list_for_each_entry_safe(q, tq, &sma->pending_alter, list) { in unmerge_queues()
220 curr = &sma->sem_base[q->sops[0].sem_num]; in unmerge_queues()
224 INIT_LIST_HEAD(&sma->pending_alter); in unmerge_queues()
236 static void merge_queues(struct sem_array *sma) in merge_queues() argument
239 for (i = 0; i < sma->sem_nsems; i++) { in merge_queues()
240 struct sem *sem = sma->sem_base + i; in merge_queues()
242 list_splice_init(&sem->pending_alter, &sma->pending_alter); in merge_queues()
249 struct sem_array *sma = ipc_rcu_to_struct(p); in sem_rcu_free() local
251 security_sem_free(sma); in sem_rcu_free()
272 static void sem_wait_array(struct sem_array *sma) in sem_wait_array() argument
277 if (sma->complex_count) { in sem_wait_array()
284 for (i = 0; i < sma->sem_nsems; i++) { in sem_wait_array()
285 sem = sma->sem_base + i; in sem_wait_array()
298 static inline int sem_lock(struct sem_array *sma, struct sembuf *sops, in sem_lock() argument
305 ipc_lock_object(&sma->sem_perm); in sem_lock()
310 sem_wait_array(sma); in sem_lock()
329 sem = sma->sem_base + sops->sem_num; in sem_lock()
331 if (sma->complex_count == 0) { in sem_lock()
339 if (!spin_is_locked(&sma->sem_perm.lock)) { in sem_lock()
353 if (sma->complex_count == 0) { in sem_lock()
362 ipc_lock_object(&sma->sem_perm); in sem_lock()
364 if (sma->complex_count == 0) { in sem_lock()
370 ipc_unlock_object(&sma->sem_perm); in sem_lock()
376 sem_wait_array(sma); in sem_lock()
381 static inline void sem_unlock(struct sem_array *sma, int locknum) in sem_unlock() argument
384 unmerge_queues(sma); in sem_unlock()
385 ipc_unlock_object(&sma->sem_perm); in sem_unlock()
387 struct sem *sem = sma->sem_base + locknum; in sem_unlock()
402 struct sem_array *sma; in sem_obtain_lock() local
408 sma = container_of(ipcp, struct sem_array, sem_perm); in sem_obtain_lock()
409 *locknum = sem_lock(sma, sops, nsops); in sem_obtain_lock()
417 sem_unlock(sma, *locknum); in sem_obtain_lock()
442 static inline void sem_lock_and_putref(struct sem_array *sma) in sem_lock_and_putref() argument
444 sem_lock(sma, NULL, -1); in sem_lock_and_putref()
445 ipc_rcu_putref(sma, ipc_rcu_free); in sem_lock_and_putref()
498 struct sem_array *sma; in newary() local
510 size = sizeof(*sma) + nsems * sizeof(struct sem); in newary()
511 sma = ipc_rcu_alloc(size); in newary()
512 if (!sma) in newary()
515 memset(sma, 0, size); in newary()
517 sma->sem_perm.mode = (semflg & S_IRWXUGO); in newary()
518 sma->sem_perm.key = key; in newary()
520 sma->sem_perm.security = NULL; in newary()
521 retval = security_sem_alloc(sma); in newary()
523 ipc_rcu_putref(sma, ipc_rcu_free); in newary()
527 sma->sem_base = (struct sem *) &sma[1]; in newary()
530 INIT_LIST_HEAD(&sma->sem_base[i].pending_alter); in newary()
531 INIT_LIST_HEAD(&sma->sem_base[i].pending_const); in newary()
532 spin_lock_init(&sma->sem_base[i].lock); in newary()
535 sma->complex_count = 0; in newary()
536 INIT_LIST_HEAD(&sma->pending_alter); in newary()
537 INIT_LIST_HEAD(&sma->pending_const); in newary()
538 INIT_LIST_HEAD(&sma->list_id); in newary()
539 sma->sem_nsems = nsems; in newary()
540 sma->sem_ctime = get_seconds(); in newary()
542 id = ipc_addid(&sem_ids(ns), &sma->sem_perm, ns->sc_semmni); in newary()
544 ipc_rcu_putref(sma, sem_rcu_free); in newary()
549 sem_unlock(sma, -1); in newary()
552 return sma->sem_perm.id; in newary()
561 struct sem_array *sma; in sem_security() local
563 sma = container_of(ipcp, struct sem_array, sem_perm); in sem_security()
564 return security_sem_associate(sma, semflg); in sem_security()
573 struct sem_array *sma; in sem_more_checks() local
575 sma = container_of(ipcp, struct sem_array, sem_perm); in sem_more_checks()
576 if (params->u.nsems > sma->sem_nsems) in sem_more_checks()
613 static int perform_atomic_semop(struct sem_array *sma, struct sem_queue *q) in perform_atomic_semop() argument
626 curr = sma->sem_base + sop->sem_num; in perform_atomic_semop()
653 sma->sem_base[sop->sem_num].sempid = pid; in perform_atomic_semop()
675 sma->sem_base[sop->sem_num].semval -= sem_op; in perform_atomic_semop()
731 static void unlink_queue(struct sem_array *sma, struct sem_queue *q) in unlink_queue() argument
735 sma->complex_count--; in unlink_queue()
748 static int check_restart(struct sem_array *sma, struct sem_queue *q) in check_restart() argument
751 if (!list_empty(&sma->pending_alter)) in check_restart()
786 static int wake_const_ops(struct sem_array *sma, int semnum, in wake_const_ops() argument
795 pending_list = &sma->pending_const; in wake_const_ops()
797 pending_list = &sma->sem_base[semnum].pending_const; in wake_const_ops()
806 error = perform_atomic_semop(sma, q); in wake_const_ops()
811 unlink_queue(sma, q); in wake_const_ops()
832 static int do_smart_wakeup_zero(struct sem_array *sma, struct sembuf *sops, in do_smart_wakeup_zero() argument
844 if (sma->sem_base[num].semval == 0) { in do_smart_wakeup_zero()
846 semop_completed |= wake_const_ops(sma, num, pt); in do_smart_wakeup_zero()
854 for (i = 0; i < sma->sem_nsems; i++) { in do_smart_wakeup_zero()
855 if (sma->sem_base[i].semval == 0) { in do_smart_wakeup_zero()
857 semop_completed |= wake_const_ops(sma, i, pt); in do_smart_wakeup_zero()
866 semop_completed |= wake_const_ops(sma, -1, pt); in do_smart_wakeup_zero()
888 static int update_queue(struct sem_array *sma, int semnum, struct list_head *pt) in update_queue() argument
896 pending_list = &sma->pending_alter; in update_queue()
898 pending_list = &sma->sem_base[semnum].pending_alter; in update_queue()
915 if (semnum != -1 && sma->sem_base[semnum].semval == 0) in update_queue()
918 error = perform_atomic_semop(sma, q); in update_queue()
924 unlink_queue(sma, q); in update_queue()
930 do_smart_wakeup_zero(sma, q->sops, q->nsops, pt); in update_queue()
931 restart = check_restart(sma, q); in update_queue()
949 static void set_semotime(struct sem_array *sma, struct sembuf *sops) in set_semotime() argument
952 sma->sem_base[0].sem_otime = get_seconds(); in set_semotime()
954 sma->sem_base[sops[0].sem_num].sem_otime = in set_semotime()
973 static void do_smart_update(struct sem_array *sma, struct sembuf *sops, int nsops, in do_smart_update() argument
978 otime |= do_smart_wakeup_zero(sma, sops, nsops, pt); in do_smart_update()
980 if (!list_empty(&sma->pending_alter)) { in do_smart_update()
982 otime |= update_queue(sma, -1, pt); in do_smart_update()
989 for (i = 0; i < sma->sem_nsems; i++) in do_smart_update()
990 otime |= update_queue(sma, i, pt); in do_smart_update()
1003 otime |= update_queue(sma, in do_smart_update()
1010 set_semotime(sma, sops); in do_smart_update()
1016 static int check_qop(struct sem_array *sma, int semnum, struct sem_queue *q, in check_qop() argument
1050 static int count_semcnt(struct sem_array *sma, ushort semnum, in count_semcnt() argument
1060 l = &sma->sem_base[semnum].pending_const; in count_semcnt()
1062 l = &sma->sem_base[semnum].pending_alter; in count_semcnt()
1072 list_for_each_entry(q, &sma->pending_alter, list) { in count_semcnt()
1073 semcnt += check_qop(sma, semnum, q, count_zero); in count_semcnt()
1076 list_for_each_entry(q, &sma->pending_const, list) { in count_semcnt()
1077 semcnt += check_qop(sma, semnum, q, count_zero); in count_semcnt()
1091 struct sem_array *sma = container_of(ipcp, struct sem_array, sem_perm); in freeary() local
1096 ipc_assert_locked_object(&sma->sem_perm); in freeary()
1097 list_for_each_entry_safe(un, tu, &sma->list_id, list_id) { in freeary()
1108 list_for_each_entry_safe(q, tq, &sma->pending_const, list) { in freeary()
1109 unlink_queue(sma, q); in freeary()
1113 list_for_each_entry_safe(q, tq, &sma->pending_alter, list) { in freeary()
1114 unlink_queue(sma, q); in freeary()
1117 for (i = 0; i < sma->sem_nsems; i++) { in freeary()
1118 struct sem *sem = sma->sem_base + i; in freeary()
1120 unlink_queue(sma, q); in freeary()
1124 unlink_queue(sma, q); in freeary()
1130 sem_rmid(ns, sma); in freeary()
1131 sem_unlock(sma, -1); in freeary()
1135 ns->used_sems -= sma->sem_nsems; in freeary()
1136 ipc_rcu_putref(sma, sem_rcu_free); in freeary()
1163 static time_t get_semotime(struct sem_array *sma) in get_semotime() argument
1168 res = sma->sem_base[0].sem_otime; in get_semotime()
1169 for (i = 1; i < sma->sem_nsems; i++) { in get_semotime()
1170 time_t to = sma->sem_base[i].sem_otime; in get_semotime()
1182 struct sem_array *sma; in semctl_nolock() local
1228 sma = sem_obtain_object(ns, semid); in semctl_nolock()
1229 if (IS_ERR(sma)) { in semctl_nolock()
1230 err = PTR_ERR(sma); in semctl_nolock()
1233 id = sma->sem_perm.id; in semctl_nolock()
1235 sma = sem_obtain_object_check(ns, semid); in semctl_nolock()
1236 if (IS_ERR(sma)) { in semctl_nolock()
1237 err = PTR_ERR(sma); in semctl_nolock()
1243 if (ipcperms(ns, &sma->sem_perm, S_IRUGO)) in semctl_nolock()
1246 err = security_sem_semctl(sma, cmd); in semctl_nolock()
1250 kernel_to_ipc64_perm(&sma->sem_perm, &tbuf.sem_perm); in semctl_nolock()
1251 tbuf.sem_otime = get_semotime(sma); in semctl_nolock()
1252 tbuf.sem_ctime = sma->sem_ctime; in semctl_nolock()
1253 tbuf.sem_nsems = sma->sem_nsems; in semctl_nolock()
1271 struct sem_array *sma; in semctl_setval() local
1290 sma = sem_obtain_object_check(ns, semid); in semctl_setval()
1291 if (IS_ERR(sma)) { in semctl_setval()
1293 return PTR_ERR(sma); in semctl_setval()
1296 if (semnum < 0 || semnum >= sma->sem_nsems) { in semctl_setval()
1302 if (ipcperms(ns, &sma->sem_perm, S_IWUGO)) { in semctl_setval()
1307 err = security_sem_semctl(sma, SETVAL); in semctl_setval()
1313 sem_lock(sma, NULL, -1); in semctl_setval()
1315 if (!ipc_valid_object(&sma->sem_perm)) { in semctl_setval()
1316 sem_unlock(sma, -1); in semctl_setval()
1321 curr = &sma->sem_base[semnum]; in semctl_setval()
1323 ipc_assert_locked_object(&sma->sem_perm); in semctl_setval()
1324 list_for_each_entry(un, &sma->list_id, list_id) in semctl_setval()
1329 sma->sem_ctime = get_seconds(); in semctl_setval()
1331 do_smart_update(sma, NULL, 0, 0, &tasks); in semctl_setval()
1332 sem_unlock(sma, -1); in semctl_setval()
1341 struct sem_array *sma; in semctl_main() local
1351 sma = sem_obtain_object_check(ns, semid); in semctl_main()
1352 if (IS_ERR(sma)) { in semctl_main()
1354 return PTR_ERR(sma); in semctl_main()
1357 nsems = sma->sem_nsems; in semctl_main()
1360 if (ipcperms(ns, &sma->sem_perm, cmd == SETALL ? S_IWUGO : S_IRUGO)) in semctl_main()
1363 err = security_sem_semctl(sma, cmd); in semctl_main()
1374 sem_lock(sma, NULL, -1); in semctl_main()
1375 if (!ipc_valid_object(&sma->sem_perm)) { in semctl_main()
1380 if (!ipc_rcu_getref(sma)) { in semctl_main()
1384 sem_unlock(sma, -1); in semctl_main()
1388 ipc_rcu_putref(sma, ipc_rcu_free); in semctl_main()
1393 sem_lock_and_putref(sma); in semctl_main()
1394 if (!ipc_valid_object(&sma->sem_perm)) { in semctl_main()
1399 for (i = 0; i < sma->sem_nsems; i++) in semctl_main()
1400 sem_io[i] = sma->sem_base[i].semval; in semctl_main()
1401 sem_unlock(sma, -1); in semctl_main()
1413 if (!ipc_rcu_getref(sma)) { in semctl_main()
1422 ipc_rcu_putref(sma, ipc_rcu_free); in semctl_main()
1428 ipc_rcu_putref(sma, ipc_rcu_free); in semctl_main()
1435 ipc_rcu_putref(sma, ipc_rcu_free); in semctl_main()
1441 sem_lock_and_putref(sma); in semctl_main()
1442 if (!ipc_valid_object(&sma->sem_perm)) { in semctl_main()
1448 sma->sem_base[i].semval = sem_io[i]; in semctl_main()
1450 ipc_assert_locked_object(&sma->sem_perm); in semctl_main()
1451 list_for_each_entry(un, &sma->list_id, list_id) { in semctl_main()
1455 sma->sem_ctime = get_seconds(); in semctl_main()
1457 do_smart_update(sma, NULL, 0, 0, &tasks); in semctl_main()
1467 sem_lock(sma, NULL, -1); in semctl_main()
1468 if (!ipc_valid_object(&sma->sem_perm)) { in semctl_main()
1472 curr = &sma->sem_base[semnum]; in semctl_main()
1482 err = count_semcnt(sma, semnum, 0); in semctl_main()
1485 err = count_semcnt(sma, semnum, 1); in semctl_main()
1490 sem_unlock(sma, -1); in semctl_main()
1534 struct sem_array *sma; in semctl_down() local
1554 sma = container_of(ipcp, struct sem_array, sem_perm); in semctl_down()
1556 err = security_sem_semctl(sma, cmd); in semctl_down()
1562 sem_lock(sma, NULL, -1); in semctl_down()
1567 sem_lock(sma, NULL, -1); in semctl_down()
1571 sma->sem_ctime = get_seconds(); in semctl_down()
1579 sem_unlock(sma, -1); in semctl_down()
1690 struct sem_array *sma; in find_alloc_undo() local
1708 sma = sem_obtain_object_check(ns, semid); in find_alloc_undo()
1709 if (IS_ERR(sma)) { in find_alloc_undo()
1711 return ERR_CAST(sma); in find_alloc_undo()
1714 nsems = sma->sem_nsems; in find_alloc_undo()
1715 if (!ipc_rcu_getref(sma)) { in find_alloc_undo()
1725 ipc_rcu_putref(sma, ipc_rcu_free); in find_alloc_undo()
1731 sem_lock_and_putref(sma); in find_alloc_undo()
1732 if (!ipc_valid_object(&sma->sem_perm)) { in find_alloc_undo()
1733 sem_unlock(sma, -1); in find_alloc_undo()
1755 ipc_assert_locked_object(&sma->sem_perm); in find_alloc_undo()
1756 list_add(&new->list_id, &sma->list_id); in find_alloc_undo()
1761 sem_unlock(sma, -1); in find_alloc_undo()
1796 struct sem_array *sma; in SYSCALL_DEFINE4() local
1858 sma = sem_obtain_object_check(ns, semid); in SYSCALL_DEFINE4()
1859 if (IS_ERR(sma)) { in SYSCALL_DEFINE4()
1861 error = PTR_ERR(sma); in SYSCALL_DEFINE4()
1866 if (max >= sma->sem_nsems) in SYSCALL_DEFINE4()
1870 if (ipcperms(ns, &sma->sem_perm, alter ? S_IWUGO : S_IRUGO)) in SYSCALL_DEFINE4()
1873 error = security_sem_semop(sma, sops, nsops, alter); in SYSCALL_DEFINE4()
1878 locknum = sem_lock(sma, sops, nsops); in SYSCALL_DEFINE4()
1887 if (!ipc_valid_object(&sma->sem_perm)) in SYSCALL_DEFINE4()
1905 error = perform_atomic_semop(sma, &queue); in SYSCALL_DEFINE4()
1911 do_smart_update(sma, sops, nsops, 1, &tasks); in SYSCALL_DEFINE4()
1913 set_semotime(sma, sops); in SYSCALL_DEFINE4()
1924 curr = &sma->sem_base[sops->sem_num]; in SYSCALL_DEFINE4()
1927 if (sma->complex_count) { in SYSCALL_DEFINE4()
1929 &sma->pending_alter); in SYSCALL_DEFINE4()
1939 if (!sma->complex_count) in SYSCALL_DEFINE4()
1940 merge_queues(sma); in SYSCALL_DEFINE4()
1943 list_add_tail(&queue.list, &sma->pending_alter); in SYSCALL_DEFINE4()
1945 list_add_tail(&queue.list, &sma->pending_const); in SYSCALL_DEFINE4()
1947 sma->complex_count++; in SYSCALL_DEFINE4()
1955 sem_unlock(sma, locknum); in SYSCALL_DEFINE4()
1979 sma = sem_obtain_lock(ns, semid, sops, nsops, &locknum); in SYSCALL_DEFINE4()
1989 if (IS_ERR(sma)) { in SYSCALL_DEFINE4()
2014 unlink_queue(sma, &queue); in SYSCALL_DEFINE4()
2017 sem_unlock(sma, locknum); in SYSCALL_DEFINE4()
2079 struct sem_array *sma; in exit_sem() local
2108 sma = sem_obtain_object_check(tsk->nsproxy->ipc_ns, semid); in exit_sem()
2110 if (IS_ERR(sma)) { in exit_sem()
2115 sem_lock(sma, NULL, -1); in exit_sem()
2117 if (!ipc_valid_object(&sma->sem_perm)) { in exit_sem()
2118 sem_unlock(sma, -1); in exit_sem()
2127 sem_unlock(sma, -1); in exit_sem()
2133 ipc_assert_locked_object(&sma->sem_perm); in exit_sem()
2141 for (i = 0; i < sma->sem_nsems; i++) { in exit_sem()
2142 struct sem *semaphore = &sma->sem_base[i]; in exit_sem()
2167 do_smart_update(sma, NULL, 0, 1, &tasks); in exit_sem()
2168 sem_unlock(sma, -1); in exit_sem()
2181 struct sem_array *sma = it; in sysvipc_sem_proc_show() local
2190 sem_wait_array(sma); in sysvipc_sem_proc_show()
2192 sem_otime = get_semotime(sma); in sysvipc_sem_proc_show()
2196 sma->sem_perm.key, in sysvipc_sem_proc_show()
2197 sma->sem_perm.id, in sysvipc_sem_proc_show()
2198 sma->sem_perm.mode, in sysvipc_sem_proc_show()
2199 sma->sem_nsems, in sysvipc_sem_proc_show()
2200 from_kuid_munged(user_ns, sma->sem_perm.uid), in sysvipc_sem_proc_show()
2201 from_kgid_munged(user_ns, sma->sem_perm.gid), in sysvipc_sem_proc_show()
2202 from_kuid_munged(user_ns, sma->sem_perm.cuid), in sysvipc_sem_proc_show()
2203 from_kgid_munged(user_ns, sma->sem_perm.cgid), in sysvipc_sem_proc_show()
2205 sma->sem_ctime); in sysvipc_sem_proc_show()