From f82b8e13acc675b5e799b8eebd79350747372d1e Mon Sep 17 00:00:00 2001 From: Doug Ledford Date: Thu, 31 May 2012 16:26:30 -0700 Subject: [PATCH] --- yaml --- r: 309759 b: refs/heads/master c: 5b5c4d1a1440e94994c73dddbad7be0676cd8b9a h: refs/heads/master i: 309757: bc99c5efaf031dd6d82383ff316ce979e4bf1f15 309755: fbda22b6679d5ac2a70fb4fcd4a397bb31542776 309751: ab126ea63866d331437cb87c3e0026b587e7a1a6 309743: 70e36d3c9fc89ff49c8602408809be2527d7b3cb 309727: e4f18fb21ad1aa2adc9c960aa72bb3a1b57fa022 309695: 9291771c28294bf03bdf239257c68882cf7429ec 309631: 2b728b35f429d107d788d7524fc271881264ded5 309503: 566e2eba9853189b4998abaa521dabd9269ed872 309247: 16667435e6776b6345b835d81b816f40854d960e v: v3 --- [refs] | 2 +- trunk/include/linux/ipc_namespace.h | 47 +++++++++++++++++++++-------- trunk/ipc/mqueue.c | 11 +++++-- 3 files changed, 45 insertions(+), 15 deletions(-) diff --git a/[refs] b/[refs] index 9e3a272eb139..7a74c3aa1690 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 02967ea08ede0f8cc7e0526aedffdae65a099b07 +refs/heads/master: 5b5c4d1a1440e94994c73dddbad7be0676cd8b9a diff --git a/trunk/include/linux/ipc_namespace.h b/trunk/include/linux/ipc_namespace.h index bde094ee7b0e..6e1dd08194fd 100644 --- a/trunk/include/linux/ipc_namespace.h +++ b/trunk/include/linux/ipc_namespace.h @@ -90,18 +90,41 @@ static inline void shm_destroy_orphaned(struct ipc_namespace *ns) {} #ifdef CONFIG_POSIX_MQUEUE extern int mq_init_ns(struct ipc_namespace *ns); -/* default values */ -#define MIN_QUEUESMAX 1 -#define DFLT_QUEUESMAX 256 /* max number of message queues */ -#define HARD_QUEUESMAX 1024 -#define MIN_MSGMAX 1 -#define DFLT_MSG 10U -#define DFLT_MSGMAX 10 /* max number of messages in each queue */ -#define HARD_MSGMAX (32768*sizeof(void *)/4) -#define MIN_MSGSIZEMAX 128 -#define DFLT_MSGSIZE 8192U -#define DFLT_MSGSIZEMAX 8192 /* max message size */ -#define HARD_MSGSIZEMAX (8192*128) +/* + * POSIX Message Queue default values: + * + * MIN_*: Lowest value an admin can set the maximum unprivileged limit to + * DFLT_*MAX: Default values for the maximum unprivileged limits + * DFLT_{MSG,MSGSIZE}: Default values used when the user doesn't supply + * an attribute to the open call and the queue must be created + * HARD_*: Highest value the maximums can be set to. These are enforced + * on CAP_SYS_RESOURCE apps as well making them inviolate (so make them + * suitably high) + * + * POSIX Requirements: + * Per app minimum openable message queues - 8. This does not map well + * to the fact that we limit the number of queues on a per namespace + * basis instead of a per app basis. So, make the default high enough + * that no given app should have a hard time opening 8 queues. + * Minimum maximum for HARD_MSGMAX - 32767. I bumped this to 65536. + * Minimum maximum for HARD_MSGSIZEMAX - POSIX is silent on this. However, + * we have run into a situation where running applications in the wild + * require this to be at least 5MB, and preferably 10MB, so I set the + * value to 16MB in hopes that this user is the worst of the bunch and + * the new maximum will handle anyone else. I may have to revisit this + * in the future. + */ +#define MIN_QUEUESMAX 1 +#define DFLT_QUEUESMAX 256 +#define HARD_QUEUESMAX 1024 +#define MIN_MSGMAX 1 +#define DFLT_MSG 64U +#define DFLT_MSGMAX 1024 +#define HARD_MSGMAX 65536 +#define MIN_MSGSIZEMAX 128 +#define DFLT_MSGSIZE 8192U +#define DFLT_MSGSIZEMAX (1024*1024) +#define HARD_MSGSIZEMAX (16*1024*1024) #else static inline int mq_init_ns(struct ipc_namespace *ns) { return 0; } #endif diff --git a/trunk/ipc/mqueue.c b/trunk/ipc/mqueue.c index 6e10a55a78c5..f8eba5e46c5a 100644 --- a/trunk/ipc/mqueue.c +++ b/trunk/ipc/mqueue.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -152,7 +153,10 @@ static struct inode *mqueue_get_inode(struct super_block *sb, info->attr.mq_msgsize = attr->mq_msgsize; } mq_msg_tblsz = info->attr.mq_maxmsg * sizeof(struct msg_msg *); - info->messages = kmalloc(mq_msg_tblsz, GFP_KERNEL); + if (mq_msg_tblsz > KMALLOC_MAX_SIZE) + info->messages = vmalloc(mq_msg_tblsz); + else + info->messages = kmalloc(mq_msg_tblsz, GFP_KERNEL); if (!info->messages) goto out_inode; @@ -262,7 +266,10 @@ static void mqueue_evict_inode(struct inode *inode) spin_lock(&info->lock); for (i = 0; i < info->attr.mq_curmsgs; i++) free_msg(info->messages[i]); - kfree(info->messages); + if (info->attr.mq_maxmsg * sizeof(struct msg_msg *) > KMALLOC_MAX_SIZE) + vfree(info->messages); + else + kfree(info->messages); spin_unlock(&info->lock); /* Total amount of bytes accounted for the mqueue */