aboutsummaryrefslogtreecommitdiffstats
path: root/ipc/mqueue.c
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 /ipc/mqueue.c
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>
Diffstat (limited to 'ipc/mqueue.c')
-rw-r--r--ipc/mqueue.c11
1 files changed, 9 insertions, 2 deletions
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 */