aboutsummaryrefslogtreecommitdiffstats
path: root/ipc
diff options
context:
space:
mode:
Diffstat (limited to 'ipc')
-rw-r--r--ipc/sem.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/ipc/sem.c b/ipc/sem.c
index 4734e9c2a98a..4b4139f6ad5c 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -264,7 +264,6 @@ static inline void sem_unlock(struct sem_array *sma, int locknum)
264 struct sem *sem = sma->sem_base + locknum; 264 struct sem *sem = sma->sem_base + locknum;
265 spin_unlock(&sem->lock); 265 spin_unlock(&sem->lock);
266 } 266 }
267 rcu_read_unlock();
268} 267}
269 268
270/* 269/*
@@ -332,6 +331,7 @@ static inline void sem_putref(struct sem_array *sma)
332{ 331{
333 sem_lock_and_putref(sma); 332 sem_lock_and_putref(sma);
334 sem_unlock(sma, -1); 333 sem_unlock(sma, -1);
334 rcu_read_unlock();
335} 335}
336 336
337static inline void sem_rmid(struct ipc_namespace *ns, struct sem_array *s) 337static inline void sem_rmid(struct ipc_namespace *ns, struct sem_array *s)
@@ -435,6 +435,7 @@ static int newary(struct ipc_namespace *ns, struct ipc_params *params)
435 sma->sem_nsems = nsems; 435 sma->sem_nsems = nsems;
436 sma->sem_ctime = get_seconds(); 436 sma->sem_ctime = get_seconds();
437 sem_unlock(sma, -1); 437 sem_unlock(sma, -1);
438 rcu_read_unlock();
438 439
439 return sma->sem_perm.id; 440 return sma->sem_perm.id;
440} 441}
@@ -874,6 +875,7 @@ static void freeary(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp)
874 /* Remove the semaphore set from the IDR */ 875 /* Remove the semaphore set from the IDR */
875 sem_rmid(ns, sma); 876 sem_rmid(ns, sma);
876 sem_unlock(sma, -1); 877 sem_unlock(sma, -1);
878 rcu_read_unlock();
877 879
878 wake_up_sem_queue_do(&tasks); 880 wake_up_sem_queue_do(&tasks);
879 ns->used_sems -= sma->sem_nsems; 881 ns->used_sems -= sma->sem_nsems;
@@ -1055,6 +1057,7 @@ static int semctl_setval(struct ipc_namespace *ns, int semid, int semnum,
1055 /* maybe some queued-up processes were waiting for this */ 1057 /* maybe some queued-up processes were waiting for this */
1056 do_smart_update(sma, NULL, 0, 0, &tasks); 1058 do_smart_update(sma, NULL, 0, 0, &tasks);
1057 sem_unlock(sma, -1); 1059 sem_unlock(sma, -1);
1060 rcu_read_unlock();
1058 wake_up_sem_queue_do(&tasks); 1061 wake_up_sem_queue_do(&tasks);
1059 return 0; 1062 return 0;
1060} 1063}
@@ -1104,10 +1107,12 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
1104 if(nsems > SEMMSL_FAST) { 1107 if(nsems > SEMMSL_FAST) {
1105 if (!ipc_rcu_getref(sma)) { 1108 if (!ipc_rcu_getref(sma)) {
1106 sem_unlock(sma, -1); 1109 sem_unlock(sma, -1);
1110 rcu_read_unlock();
1107 err = -EIDRM; 1111 err = -EIDRM;
1108 goto out_free; 1112 goto out_free;
1109 } 1113 }
1110 sem_unlock(sma, -1); 1114 sem_unlock(sma, -1);
1115 rcu_read_unlock();
1111 sem_io = ipc_alloc(sizeof(ushort)*nsems); 1116 sem_io = ipc_alloc(sizeof(ushort)*nsems);
1112 if(sem_io == NULL) { 1117 if(sem_io == NULL) {
1113 sem_putref(sma); 1118 sem_putref(sma);
@@ -1117,6 +1122,7 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
1117 sem_lock_and_putref(sma); 1122 sem_lock_and_putref(sma);
1118 if (sma->sem_perm.deleted) { 1123 if (sma->sem_perm.deleted) {
1119 sem_unlock(sma, -1); 1124 sem_unlock(sma, -1);
1125 rcu_read_unlock();
1120 err = -EIDRM; 1126 err = -EIDRM;
1121 goto out_free; 1127 goto out_free;
1122 } 1128 }
@@ -1124,6 +1130,7 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
1124 for (i = 0; i < sma->sem_nsems; i++) 1130 for (i = 0; i < sma->sem_nsems; i++)
1125 sem_io[i] = sma->sem_base[i].semval; 1131 sem_io[i] = sma->sem_base[i].semval;
1126 sem_unlock(sma, -1); 1132 sem_unlock(sma, -1);
1133 rcu_read_unlock();
1127 err = 0; 1134 err = 0;
1128 if(copy_to_user(array, sem_io, nsems*sizeof(ushort))) 1135 if(copy_to_user(array, sem_io, nsems*sizeof(ushort)))
1129 err = -EFAULT; 1136 err = -EFAULT;
@@ -1164,6 +1171,7 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
1164 sem_lock_and_putref(sma); 1171 sem_lock_and_putref(sma);
1165 if (sma->sem_perm.deleted) { 1172 if (sma->sem_perm.deleted) {
1166 sem_unlock(sma, -1); 1173 sem_unlock(sma, -1);
1174 rcu_read_unlock();
1167 err = -EIDRM; 1175 err = -EIDRM;
1168 goto out_free; 1176 goto out_free;
1169 } 1177 }
@@ -1210,6 +1218,7 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
1210 1218
1211out_unlock: 1219out_unlock:
1212 sem_unlock(sma, -1); 1220 sem_unlock(sma, -1);
1221 rcu_read_unlock();
1213out_wakeup: 1222out_wakeup:
1214 wake_up_sem_queue_do(&tasks); 1223 wake_up_sem_queue_do(&tasks);
1215out_free: 1224out_free:
@@ -1295,6 +1304,7 @@ static int semctl_down(struct ipc_namespace *ns, int semid,
1295 1304
1296out_unlock: 1305out_unlock:
1297 sem_unlock(sma, -1); 1306 sem_unlock(sma, -1);
1307 rcu_read_unlock();
1298out_up: 1308out_up:
1299 up_write(&sem_ids(ns).rw_mutex); 1309 up_write(&sem_ids(ns).rw_mutex);
1300 return err; 1310 return err;
@@ -1443,9 +1453,11 @@ static struct sem_undo *find_alloc_undo(struct ipc_namespace *ns, int semid)
1443 } 1453 }
1444 1454
1445 /* step 3: Acquire the lock on semaphore array */ 1455 /* step 3: Acquire the lock on semaphore array */
1456 /* This also does the rcu_read_lock() */
1446 sem_lock_and_putref(sma); 1457 sem_lock_and_putref(sma);
1447 if (sma->sem_perm.deleted) { 1458 if (sma->sem_perm.deleted) {
1448 sem_unlock(sma, -1); 1459 sem_unlock(sma, -1);
1460 rcu_read_unlock();
1449 kfree(new); 1461 kfree(new);
1450 un = ERR_PTR(-EIDRM); 1462 un = ERR_PTR(-EIDRM);
1451 goto out; 1463 goto out;
@@ -1472,7 +1484,6 @@ static struct sem_undo *find_alloc_undo(struct ipc_namespace *ns, int semid)
1472 1484
1473success: 1485success:
1474 spin_unlock(&ulp->lock); 1486 spin_unlock(&ulp->lock);
1475 rcu_read_lock();
1476 sem_unlock(sma, -1); 1487 sem_unlock(sma, -1);
1477out: 1488out:
1478 return un; 1489 return un;
@@ -1648,6 +1659,7 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
1648sleep_again: 1659sleep_again:
1649 current->state = TASK_INTERRUPTIBLE; 1660 current->state = TASK_INTERRUPTIBLE;
1650 sem_unlock(sma, locknum); 1661 sem_unlock(sma, locknum);
1662 rcu_read_unlock();
1651 1663
1652 if (timeout) 1664 if (timeout)
1653 jiffies_left = schedule_timeout(jiffies_left); 1665 jiffies_left = schedule_timeout(jiffies_left);
@@ -1709,6 +1721,7 @@ sleep_again:
1709 1721
1710out_unlock_free: 1722out_unlock_free:
1711 sem_unlock(sma, locknum); 1723 sem_unlock(sma, locknum);
1724 rcu_read_unlock();
1712out_wakeup: 1725out_wakeup:
1713 wake_up_sem_queue_do(&tasks); 1726 wake_up_sem_queue_do(&tasks);
1714out_free: 1727out_free:
@@ -1801,6 +1814,7 @@ void exit_sem(struct task_struct *tsk)
1801 * exactly the same semid. Nothing to do. 1814 * exactly the same semid. Nothing to do.
1802 */ 1815 */
1803 sem_unlock(sma, -1); 1816 sem_unlock(sma, -1);
1817 rcu_read_unlock();
1804 continue; 1818 continue;
1805 } 1819 }
1806 1820
@@ -1841,6 +1855,7 @@ void exit_sem(struct task_struct *tsk)
1841 INIT_LIST_HEAD(&tasks); 1855 INIT_LIST_HEAD(&tasks);
1842 do_smart_update(sma, NULL, 0, 1, &tasks); 1856 do_smart_update(sma, NULL, 0, 1, &tasks);
1843 sem_unlock(sma, -1); 1857 sem_unlock(sma, -1);
1858 rcu_read_unlock();
1844 wake_up_sem_queue_do(&tasks); 1859 wake_up_sem_queue_do(&tasks);
1845 1860
1846 kfree_rcu(un, rcu); 1861 kfree_rcu(un, rcu);