ipc/sem.c: remove code duplication
[sfrench/cifs-2.6.git] / ipc / msg.c
index 5a8489b36e5f55dbfd57091cb7d3dd525ead982e..c5d8e3749985be98b17c7bb1183dafb41332ea36 100644 (file)
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -42,9 +42,7 @@
 #include <linux/uaccess.h>
 #include "util.h"
 
-/*
- * one msg_receiver structure for each sleeping receiver:
- */
+/* one msg_receiver structure for each sleeping receiver */
 struct msg_receiver {
        struct list_head        r_list;
        struct task_struct      *r_tsk;
@@ -53,6 +51,12 @@ struct msg_receiver {
        long                    r_msgtype;
        long                    r_maxsize;
 
+       /*
+        * Mark r_msg volatile so that the compiler
+        * does not try to get smart and optimize
+        * it. We rely on this for the lockless
+        * receive algorithm.
+        */
        struct msg_msg          *volatile r_msg;
 };
 
@@ -70,75 +74,6 @@ struct msg_sender {
 
 #define msg_ids(ns)    ((ns)->ids[IPC_MSG_IDS])
 
-static void freeque(struct ipc_namespace *, struct kern_ipc_perm *);
-static int newque(struct ipc_namespace *, struct ipc_params *);
-#ifdef CONFIG_PROC_FS
-static int sysvipc_msg_proc_show(struct seq_file *s, void *it);
-#endif
-
-/*
- * Scale msgmni with the available lowmem size: the memory dedicated to msg
- * queues should occupy at most 1/MSG_MEM_SCALE of lowmem.
- * Also take into account the number of nsproxies created so far.
- * This should be done staying within the (MSGMNI , IPCMNI/nr_ipc_ns) range.
- */
-void recompute_msgmni(struct ipc_namespace *ns)
-{
-       struct sysinfo i;
-       unsigned long allowed;
-       int nb_ns;
-
-       si_meminfo(&i);
-       allowed = (((i.totalram - i.totalhigh) / MSG_MEM_SCALE) * i.mem_unit)
-               / MSGMNB;
-       nb_ns = atomic_read(&nr_ipc_ns);
-       allowed /= nb_ns;
-
-       if (allowed < MSGMNI) {
-               ns->msg_ctlmni = MSGMNI;
-               return;
-       }
-
-       if (allowed > IPCMNI / nb_ns) {
-               ns->msg_ctlmni = IPCMNI / nb_ns;
-               return;
-       }
-
-       ns->msg_ctlmni = allowed;
-}
-
-void msg_init_ns(struct ipc_namespace *ns)
-{
-       ns->msg_ctlmax = MSGMAX;
-       ns->msg_ctlmnb = MSGMNB;
-
-       recompute_msgmni(ns);
-
-       atomic_set(&ns->msg_bytes, 0);
-       atomic_set(&ns->msg_hdrs, 0);
-       ipc_init_ids(&ns->ids[IPC_MSG_IDS]);
-}
-
-#ifdef CONFIG_IPC_NS
-void msg_exit_ns(struct ipc_namespace *ns)
-{
-       free_ipcs(ns, &msg_ids(ns), freeque);
-       idr_destroy(&ns->ids[IPC_MSG_IDS].ipcs_idr);
-}
-#endif
-
-void __init msg_init(void)
-{
-       msg_init_ns(&init_ipc_ns);
-
-       printk(KERN_INFO "msgmni has been set to %d\n",
-               init_ipc_ns.msg_ctlmni);
-
-       ipc_init_proc_interface("sysvipc/msg",
-                               "       key      msqid perms      cbytes       qnum lspid lrpid   uid   gid  cuid  cgid      stime      rtime      ctime\n",
-                               IPC_MSG_IDS, sysvipc_msg_proc_show);
-}
-
 static inline struct msg_queue *msq_obtain_object(struct ipc_namespace *ns, int id)
 {
        struct kern_ipc_perm *ipcp = ipc_obtain_object(&msg_ids(ns), id);
@@ -1054,6 +989,57 @@ SYSCALL_DEFINE5(msgrcv, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz,
        return do_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg, do_msg_fill);
 }
 
+/*
+ * Scale msgmni with the available lowmem size: the memory dedicated to msg
+ * queues should occupy at most 1/MSG_MEM_SCALE of lowmem.
+ * Also take into account the number of nsproxies created so far.
+ * This should be done staying within the (MSGMNI , IPCMNI/nr_ipc_ns) range.
+ */
+void recompute_msgmni(struct ipc_namespace *ns)
+{
+       struct sysinfo i;
+       unsigned long allowed;
+       int nb_ns;
+
+       si_meminfo(&i);
+       allowed = (((i.totalram - i.totalhigh) / MSG_MEM_SCALE) * i.mem_unit)
+               / MSGMNB;
+       nb_ns = atomic_read(&nr_ipc_ns);
+       allowed /= nb_ns;
+
+       if (allowed < MSGMNI) {
+               ns->msg_ctlmni = MSGMNI;
+               return;
+       }
+
+       if (allowed > IPCMNI / nb_ns) {
+               ns->msg_ctlmni = IPCMNI / nb_ns;
+               return;
+       }
+
+       ns->msg_ctlmni = allowed;
+}
+
+void msg_init_ns(struct ipc_namespace *ns)
+{
+       ns->msg_ctlmax = MSGMAX;
+       ns->msg_ctlmnb = MSGMNB;
+
+       recompute_msgmni(ns);
+
+       atomic_set(&ns->msg_bytes, 0);
+       atomic_set(&ns->msg_hdrs, 0);
+       ipc_init_ids(&ns->ids[IPC_MSG_IDS]);
+}
+
+#ifdef CONFIG_IPC_NS
+void msg_exit_ns(struct ipc_namespace *ns)
+{
+       free_ipcs(ns, &msg_ids(ns), freeque);
+       idr_destroy(&ns->ids[IPC_MSG_IDS].ipcs_idr);
+}
+#endif
+
 #ifdef CONFIG_PROC_FS
 static int sysvipc_msg_proc_show(struct seq_file *s, void *it)
 {
@@ -1078,3 +1064,15 @@ static int sysvipc_msg_proc_show(struct seq_file *s, void *it)
                        msq->q_ctime);
 }
 #endif
+
+void __init msg_init(void)
+{
+       msg_init_ns(&init_ipc_ns);
+
+       printk(KERN_INFO "msgmni has been set to %d\n",
+               init_ipc_ns.msg_ctlmni);
+
+       ipc_init_proc_interface("sysvipc/msg",
+                               "       key      msqid perms      cbytes       qnum lspid lrpid   uid   gid  cuid  cgid      stime      rtime      ctime\n",
+                               IPC_MSG_IDS, sysvipc_msg_proc_show);
+}