|
@@ -27,6 +27,7 @@
|
|
|
#include <linux/msg.h>
|
|
|
#include <linux/spinlock.h>
|
|
|
#include <linux/init.h>
|
|
|
+#include <linux/mm.h>
|
|
|
#include <linux/proc_fs.h>
|
|
|
#include <linux/list.h>
|
|
|
#include <linux/security.h>
|
|
@@ -77,11 +78,45 @@ static int newque(struct ipc_namespace *, struct ipc_params *);
|
|
|
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.
|
|
|
+ * This should be done staying within the (MSGMNI , IPCMNI) range.
|
|
|
+ */
|
|
|
+static void recompute_msgmni(struct ipc_namespace *ns)
|
|
|
+{
|
|
|
+ struct sysinfo i;
|
|
|
+ unsigned long allowed;
|
|
|
+
|
|
|
+ si_meminfo(&i);
|
|
|
+ allowed = (((i.totalram - i.totalhigh) / MSG_MEM_SCALE) * i.mem_unit)
|
|
|
+ / MSGMNB;
|
|
|
+
|
|
|
+ if (allowed < MSGMNI) {
|
|
|
+ ns->msg_ctlmni = MSGMNI;
|
|
|
+ goto out_callback;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (allowed > IPCMNI) {
|
|
|
+ ns->msg_ctlmni = IPCMNI;
|
|
|
+ goto out_callback;
|
|
|
+ }
|
|
|
+
|
|
|
+ ns->msg_ctlmni = allowed;
|
|
|
+
|
|
|
+out_callback:
|
|
|
+
|
|
|
+ printk(KERN_INFO "msgmni has been set to %d for ipc namespace %p\n",
|
|
|
+ ns->msg_ctlmni, ns);
|
|
|
+}
|
|
|
+
|
|
|
void msg_init_ns(struct ipc_namespace *ns)
|
|
|
{
|
|
|
ns->msg_ctlmax = MSGMAX;
|
|
|
ns->msg_ctlmnb = MSGMNB;
|
|
|
- ns->msg_ctlmni = MSGMNI;
|
|
|
+
|
|
|
+ recompute_msgmni(ns);
|
|
|
+
|
|
|
atomic_set(&ns->msg_bytes, 0);
|
|
|
atomic_set(&ns->msg_hdrs, 0);
|
|
|
ipc_init_ids(&ns->ids[IPC_MSG_IDS]);
|