From: Solofo Ramangalahy 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 --- 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 #include #include +#include #include #include @@ -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) { -- -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/