Merge tag 'iommu-updates-v3.13' of git://git.kernel.org/pub/scm/linux/kernel/git...
[cascardo/linux.git] / ipc / util.c
index fdb8ae7..3ae17a4 100644 (file)
  *            Pavel Emelianov <xemul@openvz.org>
  *
  * General sysv ipc locking scheme:
- *  when doing ipc id lookups, take the ids->rwsem
- *      rcu_read_lock()
- *          obtain the ipc object (kern_ipc_perm)
- *          perform security, capabilities, auditing and permission checks, etc.
- *          acquire the ipc lock (kern_ipc_perm.lock) throught ipc_lock_object()
- *             perform data updates (ie: SET, RMID, LOCK/UNLOCK commands)
+ *     rcu_read_lock()
+ *          obtain the ipc object (kern_ipc_perm) by looking up the id in an idr
+ *         tree.
+ *         - perform initial checks (capabilities, auditing and permission,
+ *           etc).
+ *         - perform read-only operations, such as STAT, INFO commands.
+ *           acquire the ipc lock (kern_ipc_perm.lock) through
+ *           ipc_lock_object()
+ *             - perform data updates, such as SET, RMID commands and
+ *               mechanism-specific operations (semop/semtimedop,
+ *               msgsnd/msgrcv, shmat/shmdt).
+ *         drop the ipc lock, through ipc_unlock_object().
+ *     rcu_read_unlock()
+ *
+ *  The ids->rwsem must be taken when:
+ *     - creating, removing and iterating the existing entries in ipc
+ *       identifier sets.
+ *     - iterating through files under /proc/sysvipc/
+ *
+ *  Note that sems have a special fast path that avoids kern_ipc_perm.lock -
+ *  see sem_lock().
  */
 
 #include <linux/mm.h>
@@ -75,10 +90,8 @@ static int ipc_memory_callback(struct notifier_block *self,
                 * In order not to keep the lock on the hotplug memory chain
                 * for too long, queue a work item that will, when waken up,
                 * activate the ipcns notification chain.
-                * No need to keep several ipc work items on the queue.
                 */
-               if (!work_pending(&ipc_memory_wq))
-                       schedule_work(&ipc_memory_wq);
+               schedule_work(&ipc_memory_wq);
                break;
        case MEM_GOING_ONLINE:
        case MEM_GOING_OFFLINE: