aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/msg.h14
-rw-r--r--ipc/msg.c37
2 files changed, 48 insertions, 3 deletions
diff --git a/include/linux/msg.h b/include/linux/msg.h
index 10a3d5a1abff..6f3b8e79a991 100644
--- a/include/linux/msg.h
+++ b/include/linux/msg.h
@@ -49,16 +49,26 @@ struct msginfo {
49 unsigned short msgseg; 49 unsigned short msgseg;
50}; 50};
51 51
52/*
53 * Scaling factor to compute msgmni:
54 * the memory dedicated to msg queues (msgmni * msgmnb) should occupy
55 * at most 1/MSG_MEM_SCALE of the lowmem (see the formula in ipc/msg.c):
56 * up to 8MB : msgmni = 16 (MSGMNI)
57 * 4 GB : msgmni = 8K
58 * more than 16 GB : msgmni = 32K (IPCMNI)
59 */
60#define MSG_MEM_SCALE 32
61
52#define MSGMNI 16 /* <= IPCMNI */ /* max # of msg queue identifiers */ 62#define MSGMNI 16 /* <= IPCMNI */ /* max # of msg queue identifiers */
53#define MSGMAX 8192 /* <= INT_MAX */ /* max size of message (bytes) */ 63#define MSGMAX 8192 /* <= INT_MAX */ /* max size of message (bytes) */
54#define MSGMNB 16384 /* <= INT_MAX */ /* default max size of a message queue */ 64#define MSGMNB 16384 /* <= INT_MAX */ /* default max size of a message queue */
55 65
56/* unused */ 66/* unused */
57#define MSGPOOL (MSGMNI*MSGMNB/1024) /* size in kilobytes of message pool */ 67#define MSGPOOL (MSGMNI * MSGMNB) /* size in bytes of message pool */
58#define MSGTQL MSGMNB /* number of system message headers */ 68#define MSGTQL MSGMNB /* number of system message headers */
59#define MSGMAP MSGMNB /* number of entries in message map */ 69#define MSGMAP MSGMNB /* number of entries in message map */
60#define MSGSSZ 16 /* message segment size */ 70#define MSGSSZ 16 /* message segment size */
61#define __MSGSEG ((MSGPOOL*1024)/ MSGSSZ) /* max no. of segments */ 71#define __MSGSEG (MSGPOOL / MSGSSZ) /* max no. of segments */
62#define MSGSEG (__MSGSEG <= 0xffff ? __MSGSEG : 0xffff) 72#define MSGSEG (__MSGSEG <= 0xffff ? __MSGSEG : 0xffff)
63 73
64#ifdef __KERNEL__ 74#ifdef __KERNEL__
diff --git a/ipc/msg.c b/ipc/msg.c
index 805ee08ec8bb..9e7211122e27 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -27,6 +27,7 @@
27#include <linux/msg.h> 27#include <linux/msg.h>
28#include <linux/spinlock.h> 28#include <linux/spinlock.h>
29#include <linux/init.h> 29#include <linux/init.h>
30#include <linux/mm.h>
30#include <linux/proc_fs.h> 31#include <linux/proc_fs.h>
31#include <linux/list.h> 32#include <linux/list.h>
32#include <linux/security.h> 33#include <linux/security.h>
@@ -77,11 +78,45 @@ static int newque(struct ipc_namespace *, struct ipc_params *);
77static int sysvipc_msg_proc_show(struct seq_file *s, void *it); 78static int sysvipc_msg_proc_show(struct seq_file *s, void *it);
78#endif 79#endif
79 80
81/*
82 * Scale msgmni with the available lowmem size: the memory dedicated to msg
83 * queues should occupy at most 1/MSG_MEM_SCALE of lowmem.
84 * This should be done staying within the (MSGMNI , IPCMNI) range.
85 */
86static void recompute_msgmni(struct ipc_namespace *ns)
87{
88 struct sysinfo i;
89 unsigned long allowed;
90
91 si_meminfo(&i);
92 allowed = (((i.totalram - i.totalhigh) / MSG_MEM_SCALE) * i.mem_unit)
93 / MSGMNB;
94
95 if (allowed < MSGMNI) {
96 ns->msg_ctlmni = MSGMNI;
97 goto out_callback;
98 }
99
100 if (allowed > IPCMNI) {
101 ns->msg_ctlmni = IPCMNI;
102 goto out_callback;
103 }
104
105 ns->msg_ctlmni = allowed;
106
107out_callback:
108
109 printk(KERN_INFO "msgmni has been set to %d for ipc namespace %p\n",
110 ns->msg_ctlmni, ns);
111}
112
80void msg_init_ns(struct ipc_namespace *ns) 113void msg_init_ns(struct ipc_namespace *ns)
81{ 114{
82 ns->msg_ctlmax = MSGMAX; 115 ns->msg_ctlmax = MSGMAX;
83 ns->msg_ctlmnb = MSGMNB; 116 ns->msg_ctlmnb = MSGMNB;
84 ns->msg_ctlmni = MSGMNI; 117
118 recompute_msgmni(ns);
119
85 atomic_set(&ns->msg_bytes, 0); 120 atomic_set(&ns->msg_bytes, 0);
86 atomic_set(&ns->msg_hdrs, 0); 121 atomic_set(&ns->msg_hdrs, 0);
87 ipc_init_ids(&ns->ids[IPC_MSG_IDS]); 122 ipc_init_ids(&ns->ids[IPC_MSG_IDS]);