2008-07-16 09:20:04

by Solofo.Ramangalahy

[permalink] [raw]
Subject: [PATCH -mm v2 1/3] sysv ipc: increase msgmnb default value wrt. the number of cpus

From: Solofo Ramangalahy <[email protected]>

Initialize msgmnb value to
min(MSGMNB * num_online_cpus(), MSGMNB * MSG_CPU_SCALE)
to increase the default value for larger machines.

MSG_CPU_SCALE scaling factor is defined to be 4, as 16384 x 4 = 65536
is an already used and recommended value.

The msgmni value is made dependant of msgmnb to keep the memory
dedicated to message queues within the 1/MSG_MEM_SCALE of lowmem
bound.

Unlike msgmni, the value is not scaled (down) with respect to the
number of ipc namespaces for simplicity.

To disable recomputation when user explicitely set a value,
we reuse the callback defined for msgmni.

As msgmni and msgmnb are correlated, user settings of any of the two
disable recomputation of both, for now. This is refined in a later
patch.

When a negative value is put in /proc/sys/kernel/msgmnb
automatic recomputing is re-enabled.


Signed-off-by: Solofo Ramangalahy <[email protected]>

---
include/linux/msg.h | 7 +++++++
ipc/ipc_sysctl.c | 5 +++--
ipc/msg.c | 22 ++++++++++++++++++----
ipc/util.h | 1 +
4 files changed, 29 insertions(+), 6 deletions(-)

Index: linux-2.6.26-rc8-mm1-MSGMNB3/ipc/msg.c
===================================================================
--- linux-2.6.26-rc8-mm1-MSGMNB3.orig/ipc/msg.c
+++ linux-2.6.26-rc8-mm1-MSGMNB3/ipc/msg.c
@@ -38,6 +38,7 @@
#include <linux/rwsem.h>
#include <linux/nsproxy.h>
#include <linux/ipc_namespace.h>
+#include <linux/cpumask.h>

#include <asm/current.h>
#include <asm/uaccess.h>
@@ -92,7 +93,7 @@ void recompute_msgmni(struct ipc_namespa

si_meminfo(&i);
allowed = (((i.totalram - i.totalhigh) / MSG_MEM_SCALE) * i.mem_unit)
- / MSGMNB;
+ / ns->msg_ctlmnb;
nb_ns = atomic_read(&nr_ipc_ns);
allowed /= nb_ns;

@@ -108,11 +109,24 @@ void recompute_msgmni(struct ipc_namespa

ns->msg_ctlmni = allowed;
}
+/*
+ * Scale msgmnb with the number of online cpus, up to 4x MSGMNB. For
+ * simplicity, it is not adjusted wrt. ipc namespaces. This is done
+ * indirectly by msgmni for the whole message pool. Zero-sized
+ * messages can be enqueued up to msgmnb consuming memory. If this
+ * becomes a problem, this function can be updated with a constraint
+ * on low memory like in recompute_msgmni().
+ */
+void ipc_recompute_msgmnb(struct ipc_namespace *ns)
+{
+ ns->msg_ctlmnb =
+ min(MSGMNB * num_online_cpus(), MSGMNB * MSG_CPU_SCALE);
+}

void msg_init_ns(struct ipc_namespace *ns)
{
ns->msg_ctlmax = MSGMAX;
- ns->msg_ctlmnb = MSGMNB;
+ ipc_recompute_msgmnb(ns);

recompute_msgmni(ns);

@@ -132,8 +146,8 @@ 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);
+ printk(KERN_INFO "msgmni has been set to %d, msgmnb to %d\n",
+ init_ipc_ns.msg_ctlmni, init_ipc_ns.msg_ctlmnb);

ipc_init_proc_interface("sysvipc/msg",
" key msqid perms cbytes qnum lspid lrpid uid gid cuid cgid stime rtime ctime\n",
Index: linux-2.6.26-rc8-mm1-MSGMNB3/include/linux/msg.h
===================================================================
--- linux-2.6.26-rc8-mm1-MSGMNB3.orig/include/linux/msg.h
+++ linux-2.6.26-rc8-mm1-MSGMNB3/include/linux/msg.h
@@ -58,6 +58,13 @@ struct msginfo {
* more than 16 GB : msgmni = 32K (IPCMNI)
*/
#define MSG_MEM_SCALE 32
+/*
+ * Scaling factor to compute msgmnb: ns->msg_ctlmnb is between MSGMNB
+ * and MSGMNB * MSG_CPU_SCALE. This leads to a max msgmnb value of
+ * 65536 which is an already used and recommended value.
+ * Note that zero-sized messages can be enqueued up to this max value.
+ */
+#define MSG_CPU_SCALE 4

#define MSGMNI 16 /* <= IPCMNI */ /* max # of msg queue identifiers */
#define MSGMAX 8192 /* <= INT_MAX */ /* max size of message (bytes) */
Index: linux-2.6.26-rc8-mm1-MSGMNB3/ipc/ipc_sysctl.c
===================================================================
--- linux-2.6.26-rc8-mm1-MSGMNB3.orig/ipc/ipc_sysctl.c
+++ linux-2.6.26-rc8-mm1-MSGMNB3/ipc/ipc_sysctl.c
@@ -44,6 +44,7 @@ static void ipc_auto_callback(int val)
* Re-enable automatic recomputing only if not already
* enabled.
*/
+ ipc_recompute_msgmnb(current->nsproxy->ipc_ns);
recompute_msgmni(current->nsproxy->ipc_ns);
cond_register_ipcns_notifier(current->nsproxy->ipc_ns);
}
@@ -246,8 +247,8 @@ static struct ctl_table ipc_kern_table[]
.data = &init_ipc_ns.msg_ctlmnb,
.maxlen = sizeof (init_ipc_ns.msg_ctlmnb),
.mode = 0644,
- .proc_handler = proc_ipc_dointvec,
- .strategy = sysctl_ipc_data,
+ .proc_handler = proc_ipc_callback_dointvec,
+ .strategy = sysctl_ipc_registered_data,
},
{
.ctl_name = KERN_SEM,
Index: linux-2.6.26-rc8-mm1-MSGMNB3/ipc/util.h
===================================================================
--- linux-2.6.26-rc8-mm1-MSGMNB3.orig/ipc/util.h
+++ linux-2.6.26-rc8-mm1-MSGMNB3/ipc/util.h
@@ -122,6 +122,7 @@ extern struct msg_msg *load_msg(const vo
extern int store_msg(void __user *dest, struct msg_msg *msg, int len);

extern void recompute_msgmni(struct ipc_namespace *);
+extern void ipc_recompute_msgmnb(struct ipc_namespace *);

static inline int ipc_buildid(int id, int seq)
{

--