Skip to content

Commit

Permalink
ipc,msg: make msgctl_nolock lockless
Browse files Browse the repository at this point in the history
While the INFO cmd doesn't take the ipc lock, the STAT commands do
acquire it unnecessarily.  We can do the permissions and security checks
only holding the rcu lock.

This function now mimics semctl_nolock().

Signed-off-by: Davidlohr Bueso <[email protected]>
Cc: Andi Kleen <[email protected]>
Cc: Rik van Riel <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
Davidlohr Bueso authored and torvalds committed Jul 9, 2013
1 parent a5001a0 commit ac0ba20
Showing 1 changed file with 17 additions and 10 deletions.
27 changes: 17 additions & 10 deletions ipc/msg.c
Original file line number Diff line number Diff line change
Expand Up @@ -545,17 +545,25 @@ static int msgctl_nolock(struct ipc_namespace *ns, int msqid,
if (!buf)
return -EFAULT;

memset(&tbuf, 0, sizeof(tbuf));

rcu_read_lock();
if (cmd == MSG_STAT) {
msq = msg_lock(ns, msqid);
if (IS_ERR(msq))
return PTR_ERR(msq);
msq = msq_obtain_object(ns, msqid);
if (IS_ERR(msq)) {
err = PTR_ERR(msq);
goto out_unlock;
}
success_return = msq->q_perm.id;
} else {
msq = msg_lock_check(ns, msqid);
if (IS_ERR(msq))
return PTR_ERR(msq);
msq = msq_obtain_object_check(ns, msqid);
if (IS_ERR(msq)) {
err = PTR_ERR(msq);
goto out_unlock;
}
success_return = 0;
}

err = -EACCES;
if (ipcperms(ns, &msq->q_perm, S_IRUGO))
goto out_unlock;
Expand All @@ -564,8 +572,6 @@ static int msgctl_nolock(struct ipc_namespace *ns, int msqid,
if (err)
goto out_unlock;

memset(&tbuf, 0, sizeof(tbuf));

kernel_to_ipc64_perm(&msq->q_perm, &tbuf.msg_perm);
tbuf.msg_stime = msq->q_stime;
tbuf.msg_rtime = msq->q_rtime;
Expand All @@ -575,7 +581,8 @@ static int msgctl_nolock(struct ipc_namespace *ns, int msqid,
tbuf.msg_qbytes = msq->q_qbytes;
tbuf.msg_lspid = msq->q_lspid;
tbuf.msg_lrpid = msq->q_lrpid;
msg_unlock(msq);
rcu_read_unlock();

if (copy_msqid_to_user(buf, &tbuf, version))
return -EFAULT;
return success_return;
Expand All @@ -587,7 +594,7 @@ static int msgctl_nolock(struct ipc_namespace *ns, int msqid,

return err;
out_unlock:
msg_unlock(msq);
rcu_read_unlock();
return err;
}

Expand Down

0 comments on commit ac0ba20

Please sign in to comment.