aboutsummaryrefslogtreecommitdiffstats
path: root/ipc/msg.c
diff options
context:
space:
mode:
authorDavidlohr Bueso <davidlohr.bueso@hp.com>2013-07-08 19:01:13 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-09 13:33:27 -0400
commit15724ecb7e9bab35fc694c666ad563adba820cc3 (patch)
treed9ae089252e84327367056a29c0cf6b16f844c2e /ipc/msg.c
parent7b4cc5d8411bd4e9d61d8714f53859740cf830c2 (diff)
ipc,msg: shorten critical region in msgctl_down
Instead of holding the ipc lock for the entire function, use the ipcctl_pre_down_nolock and only acquire the lock for specific commands: RMID and SET. Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com> Cc: Andi Kleen <andi@firstfloor.org> Cc: Rik van Riel <riel@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'ipc/msg.c')
-rw-r--r--ipc/msg.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/ipc/msg.c b/ipc/msg.c
index f62fa5eed847..de422ff71c87 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -410,11 +410,10 @@ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd,
410 down_write(&msg_ids(ns).rw_mutex); 410 down_write(&msg_ids(ns).rw_mutex);
411 rcu_read_lock(); 411 rcu_read_lock();
412 412
413 ipcp = ipcctl_pre_down(ns, &msg_ids(ns), msqid, cmd, 413 ipcp = ipcctl_pre_down_nolock(ns, &msg_ids(ns), msqid, cmd,
414 &msqid64.msg_perm, msqid64.msg_qbytes); 414 &msqid64.msg_perm, msqid64.msg_qbytes);
415 if (IS_ERR(ipcp)) { 415 if (IS_ERR(ipcp)) {
416 err = PTR_ERR(ipcp); 416 err = PTR_ERR(ipcp);
417 /* the ipc lock is not held upon failure */
418 goto out_unlock1; 417 goto out_unlock1;
419 } 418 }
420 419
@@ -422,10 +421,11 @@ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd,
422 421
423 err = security_msg_queue_msgctl(msq, cmd); 422 err = security_msg_queue_msgctl(msq, cmd);
424 if (err) 423 if (err)
425 goto out_unlock0; 424 goto out_unlock1;
426 425
427 switch (cmd) { 426 switch (cmd) {
428 case IPC_RMID: 427 case IPC_RMID:
428 ipc_lock_object(&msq->q_perm);
429 /* freeque unlocks the ipc object and rcu */ 429 /* freeque unlocks the ipc object and rcu */
430 freeque(ns, ipcp); 430 freeque(ns, ipcp);
431 goto out_up; 431 goto out_up;
@@ -433,9 +433,10 @@ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd,
433 if (msqid64.msg_qbytes > ns->msg_ctlmnb && 433 if (msqid64.msg_qbytes > ns->msg_ctlmnb &&
434 !capable(CAP_SYS_RESOURCE)) { 434 !capable(CAP_SYS_RESOURCE)) {
435 err = -EPERM; 435 err = -EPERM;
436 goto out_unlock0; 436 goto out_unlock1;
437 } 437 }
438 438
439 ipc_lock_object(&msq->q_perm);
439 err = ipc_update_perm(&msqid64.msg_perm, ipcp); 440 err = ipc_update_perm(&msqid64.msg_perm, ipcp);
440 if (err) 441 if (err)
441 goto out_unlock0; 442 goto out_unlock0;
@@ -454,6 +455,7 @@ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd,
454 break; 455 break;
455 default: 456 default:
456 err = -EINVAL; 457 err = -EINVAL;
458 goto out_unlock1;
457 } 459 }
458 460
459out_unlock0: 461out_unlock0: