list_del(&mss->list);
}
-static void ss_wakeup(struct list_head *h, int kill)
+static void ss_wakeup(struct list_head *h,
+ struct wake_q_head *wake_q, int kill)
{
struct msg_sender *mss, *t;
list_for_each_entry_safe(mss, t, h, list) {
if (kill)
mss->list.next = NULL;
- wake_up_process(mss->tsk);
+ wake_q_add(wake_q, mss->tsk);
}
}
WAKE_Q(wake_q);
expunge_all(msq, -EIDRM, &wake_q);
- ss_wakeup(&msq->q_senders, 1);
+ ss_wakeup(&msq->q_senders, &wake_q, 1);
msg_rmid(ns, msq);
ipc_unlock_object(&msq->q_perm);
wake_up_q(&wake_q);
struct kern_ipc_perm *ipcp;
struct msqid64_ds uninitialized_var(msqid64);
struct msg_queue *msq;
- WAKE_Q(wake_q);
int err;
if (cmd == IPC_SET) {
freeque(ns, ipcp);
goto out_up;
case IPC_SET:
+ {
+ WAKE_Q(wake_q);
+
if (msqid64.msg_qbytes > ns->msg_ctlmnb &&
!capable(CAP_SYS_RESOURCE)) {
err = -EPERM;
msq->q_qbytes = msqid64.msg_qbytes;
msq->q_ctime = get_seconds();
- /* sleeping receivers might be excluded by
+ /*
+ * Sleeping receivers might be excluded by
* stricter permissions.
*/
expunge_all(msq, -EAGAIN, &wake_q);
- /* sleeping senders might be able to send
+ /*
+ * Sleeping senders might be able to send
* due to a larger queue size.
*/
- ss_wakeup(&msq->q_senders, 0);
- break;
+ ss_wakeup(&msq->q_senders, &wake_q, 0);
+ ipc_unlock_object(&msq->q_perm);
+ wake_up_q(&wake_q);
+
+ goto out_unlock1;
+ }
default:
err = -EINVAL;
goto out_unlock1;
out_unlock0:
ipc_unlock_object(&msq->q_perm);
- wake_up_q(&wake_q);
out_unlock1:
rcu_read_unlock();
out_up:
struct msg_queue *msq;
struct ipc_namespace *ns;
struct msg_msg *msg, *copy = NULL;
+ WAKE_Q(wake_q);
ns = current->nsproxy->ipc_ns;
msq->q_cbytes -= msg->m_ts;
atomic_sub(msg->m_ts, &ns->msg_bytes);
atomic_dec(&ns->msg_hdrs);
- ss_wakeup(&msq->q_senders, 0);
+ ss_wakeup(&msq->q_senders, &wake_q, 0);
goto out_unlock0;
}
out_unlock0:
ipc_unlock_object(&msq->q_perm);
+ wake_up_q(&wake_q);
out_unlock1:
rcu_read_unlock();
if (IS_ERR(msg)) {