aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDoug Ledford <dledford@redhat.com>2012-05-31 19:26:30 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-31 20:49:30 -0400
commit5b5c4d1a1440e94994c73dddbad7be0676cd8b9a (patch)
treefe00ef0f888fbfc40b7542fd8a66cf3368d3d2c7
parent02967ea08ede0f8cc7e0526aedffdae65a099b07 (diff)
ipc/mqueue: update maximums for the mqueue subsystem
Commit b231cca4381e ("message queues: increase range limits") changed the maximum size of a message in a message queue from INT_MAX to 8192*128. Unfortunately, we had customers that relied on a size much larger than 8192*128 on their production systems. After reviewing POSIX, we found that it is silent on the maximum message size. We did find a couple other areas in which it was not silent. Fix up the mqueue maximums so that the customer's system can continue to work, and document both the POSIX and real world requirements in ipc_namespace.h so that we don't have this issue crop back up. Also, commit 9cf18e1dd74cd0 ("ipc: HARD_MSGMAX should be higher not lower on 64bit") fiddled with HARD_MSGMAX without realizing that the number was intentionally in place to limit the msg queue depth to one that was small enough to kmalloc an array of pointers (hence why we divided 128k by sizeof(long)). If we wish to meet POSIX requirements, we have no choice but to change our allocation to a vmalloc instead (at least for the large queue size case). With that, it's possible to increase our allowed maximum to the POSIX requirements (or more if we choose). [sfr@canb.auug.org.au: using vmalloc requires including vmalloc.h] Signed-off-by: Doug Ledford <dledford@redhat.com> Cc: Serge E. Hallyn <serue@us.ibm.com> Cc: Amerigo Wang <amwang@redhat.com> Cc: Joe Korty <joe.korty@ccur.com> Cc: Jiri Slaby <jslaby@suse.cz> Acked-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> Cc: Manfred Spraul <manfred@colorfullife.com> Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--include/linux/ipc_namespace.h47
-rw-r--r--ipc/mqueue.c11
2 files changed, 44 insertions, 14 deletions
diff --git a/include/linux/ipc_namespace.h b/include/linux/ipc_namespace.h
index bde094ee7b0e..6e1dd08194fd 100644
--- a/include/linux/ipc_namespace.h
+++ b/include/linux/ipc_namespace.h
@@ -90,18 +90,41 @@ static inline void shm_destroy_orphaned(struct ipc_namespace *ns) {}
90 90
91#ifdef CONFIG_POSIX_MQUEUE 91#ifdef CONFIG_POSIX_MQUEUE
92extern int mq_init_ns(struct ipc_namespace *ns); 92extern int mq_init_ns(struct ipc_namespace *ns);
93/* default values */ 93/*
94#define MIN_QUEUESMAX 1 94 * POSIX Message Queue default values:
95#define DFLT_QUEUESMAX 256 /* max number of message queues */ 95 *
96#define HARD_QUEUESMAX 1024 96 * MIN_*: Lowest value an admin can set the maximum unprivileged limit to
97#define MIN_MSGMAX 1 97 * DFLT_*MAX: Default values for the maximum unprivileged limits
98#define DFLT_MSG 10U 98 * DFLT_{MSG,MSGSIZE}: Default values used when the user doesn't supply
99#define DFLT_MSGMAX 10 /* max number of messages in each queue */ 99 * an attribute to the open call and the queue must be created
100#define HARD_MSGMAX (32768*sizeof(void *)/4) 100 * HARD_*: Highest value the maximums can be set to. These are enforced
101#define MIN_MSGSIZEMAX 128 101 * on CAP_SYS_RESOURCE apps as well making them inviolate (so make them
102#define DFLT_MSGSIZE 8192U 102 * suitably high)
103#define DFLT_MSGSIZEMAX 8192 /* max message size */ 103 *
104#define HARD_MSGSIZEMAX (8192*128) 104 * POSIX Requirements:
105 * Per app minimum openable message queues - 8. This does not map well
106 * to the fact that we limit the number of queues on a per namespace
107 * basis instead of a per app basis. So, make the default high enough
108 * that no given app should have a hard time opening 8 queues.
109 * Minimum maximum for HARD_MSGMAX - 32767. I bumped this to 65536.
110 * Minimum maximum for HARD_MSGSIZEMAX - POSIX is silent on this. However,
111 * we have run into a situation where running applications in the wild
112 * require this to be at least 5MB, and preferably 10MB, so I set the
113 * value to 16MB in hopes that this user is the worst of the bunch and
114 * the new maximum will handle anyone else. I may have to revisit this
115 * in the future.
116 */
117#define MIN_QUEUESMAX 1
118#define DFLT_QUEUESMAX 256
119#define HARD_QUEUESMAX 1024
120#define MIN_MSGMAX 1
121#define DFLT_MSG 64U
122#define DFLT_MSGMAX 1024
123#define HARD_MSGMAX 65536
124#define MIN_MSGSIZEMAX 128
125#define DFLT_MSGSIZE 8192U
126#define DFLT_MSGSIZEMAX (1024*1024)
127#define HARD_MSGSIZEMAX (16*1024*1024)
105#else 128#else
106static inline int mq_init_ns(struct ipc_namespace *ns) { return 0; } 129static inline int mq_init_ns(struct ipc_namespace *ns) { return 0; }
107#endif 130#endif
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index 6e10a55a78c5..f8eba5e46c5a 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -24,6 +24,7 @@
24#include <linux/mqueue.h> 24#include <linux/mqueue.h>
25#include <linux/msg.h> 25#include <linux/msg.h>
26#include <linux/skbuff.h> 26#include <linux/skbuff.h>
27#include <linux/vmalloc.h>
27#include <linux/netlink.h> 28#include <linux/netlink.h>
28#include <linux/syscalls.h> 29#include <linux/syscalls.h>
29#include <linux/audit.h> 30#include <linux/audit.h>
@@ -152,7 +153,10 @@ static struct inode *mqueue_get_inode(struct super_block *sb,
152 info->attr.mq_msgsize = attr->mq_msgsize; 153 info->attr.mq_msgsize = attr->mq_msgsize;
153 } 154 }
154 mq_msg_tblsz = info->attr.mq_maxmsg * sizeof(struct msg_msg *); 155 mq_msg_tblsz = info->attr.mq_maxmsg * sizeof(struct msg_msg *);
155 info->messages = kmalloc(mq_msg_tblsz, GFP_KERNEL); 156 if (mq_msg_tblsz > KMALLOC_MAX_SIZE)
157 info->messages = vmalloc(mq_msg_tblsz);
158 else
159 info->messages = kmalloc(mq_msg_tblsz, GFP_KERNEL);
156 if (!info->messages) 160 if (!info->messages)
157 goto out_inode; 161 goto out_inode;
158 162
@@ -262,7 +266,10 @@ static void mqueue_evict_inode(struct inode *inode)
262 spin_lock(&info->lock); 266 spin_lock(&info->lock);
263 for (i = 0; i < info->attr.mq_curmsgs; i++) 267 for (i = 0; i < info->attr.mq_curmsgs; i++)
264 free_msg(info->messages[i]); 268 free_msg(info->messages[i]);
265 kfree(info->messages); 269 if (info->attr.mq_maxmsg * sizeof(struct msg_msg *) > KMALLOC_MAX_SIZE)
270 vfree(info->messages);
271 else
272 kfree(info->messages);
266 spin_unlock(&info->lock); 273 spin_unlock(&info->lock);
267 274
268 /* Total amount of bytes accounted for the mqueue */ 275 /* Total amount of bytes accounted for the mqueue */