Commit 15724ecb7e9bab35fc694c666ad563adba820cc3
Committed by
Linus Torvalds
1 parent
7b4cc5d841
Exists in
smarc-imx_3.14.28_1.0.0_ga
and in
1 other branch
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>
Showing 1 changed file with 7 additions and 5 deletions Side-by-side Diff
ipc/msg.c
... | ... | @@ -410,11 +410,10 @@ |
410 | 410 | down_write(&msg_ids(ns).rw_mutex); |
411 | 411 | rcu_read_lock(); |
412 | 412 | |
413 | - ipcp = ipcctl_pre_down(ns, &msg_ids(ns), msqid, cmd, | |
414 | - &msqid64.msg_perm, msqid64.msg_qbytes); | |
413 | + ipcp = ipcctl_pre_down_nolock(ns, &msg_ids(ns), msqid, cmd, | |
414 | + &msqid64.msg_perm, msqid64.msg_qbytes); | |
415 | 415 | if (IS_ERR(ipcp)) { |
416 | 416 | err = PTR_ERR(ipcp); |
417 | - /* the ipc lock is not held upon failure */ | |
418 | 417 | goto out_unlock1; |
419 | 418 | } |
420 | 419 | |
421 | 420 | |
... | ... | @@ -422,10 +421,11 @@ |
422 | 421 | |
423 | 422 | err = security_msg_queue_msgctl(msq, cmd); |
424 | 423 | if (err) |
425 | - goto out_unlock0; | |
424 | + goto out_unlock1; | |
426 | 425 | |
427 | 426 | switch (cmd) { |
428 | 427 | case IPC_RMID: |
428 | + ipc_lock_object(&msq->q_perm); | |
429 | 429 | /* freeque unlocks the ipc object and rcu */ |
430 | 430 | freeque(ns, ipcp); |
431 | 431 | goto out_up; |
432 | 432 | |
... | ... | @@ -433,9 +433,10 @@ |
433 | 433 | if (msqid64.msg_qbytes > ns->msg_ctlmnb && |
434 | 434 | !capable(CAP_SYS_RESOURCE)) { |
435 | 435 | err = -EPERM; |
436 | - goto out_unlock0; | |
436 | + goto out_unlock1; | |
437 | 437 | } |
438 | 438 | |
439 | + ipc_lock_object(&msq->q_perm); | |
439 | 440 | err = ipc_update_perm(&msqid64.msg_perm, ipcp); |
440 | 441 | if (err) |
441 | 442 | goto out_unlock0; |
... | ... | @@ -454,6 +455,7 @@ |
454 | 455 | break; |
455 | 456 | default: |
456 | 457 | err = -EINVAL; |
458 | + goto out_unlock1; | |
457 | 459 | } |
458 | 460 | |
459 | 461 | out_unlock0: |