[RFC][PATCH 2.5.70] dynamically tuning msgtql

From: Dhruv Anand (dhruv.anand@wipro.com)
Date: Fri Jun 06 2003 - 09:00:10 EST


Hi,
Please find below the patch (RFC) that makes msgtql dynamically tunable
through /proc interface.

1) IPC_NOWAIT flag not handled.
Handling this will cause overheads (additional queue, wake-ups etc).
Please comment.

Or Handling IPC_NOWAIT may require:
a) An additional global queue for processes when message to be
queued is > msgtql && IPC_NOWAIT flag is not set.
Please comment.

Thanks,
Dhruv

diff -Nur linux-2.5.70/include/linux/msg.h linux-2.5.70msg/include/linux/msg.h
--- linux-2.5.70/include/linux/msg.h Tue May 27 06:30:40 2003
+++ linux-2.5.70msg/include/linux/msg.h Fri Jun 6 14:31:26 2003
@@ -49,13 +49,13 @@
         unsigned short msgseg;
 };
 
-#define MSGMNI 16 /* <= IPCMNI */ /* max # of msg queue identifiers */
-#define MSGMAX 8192 /* <= INT_MAX */ /* max size of message (bytes) */
-#define MSGMNB 16384 /* <= INT_MAX */ /* default max size of a message queue */
+#define MSGMNI 16 /* <= IPCMNI */ /* max # of msg queue identifiers */
+#define MSGMAX 8192 /* <= INT_MAX */ /* max size of message (bytes) */
+#define MSGMNB 16384 /* <= INT_MAX */ /* default max size of a message queue */
+#define MSGTQL 0x7fffffff /* <= INT_MAX */ /* number of system message */
 
 /* unused */
 #define MSGPOOL (MSGMNI*MSGMNB/1024) /* size in kilobytes of message pool */
-#define MSGTQL MSGMNB /* number of system message headers */
 #define MSGMAP MSGMNB /* number of entries in message map */
 #define MSGSSZ 16 /* message segment size */
 #define __MSGSEG ((MSGPOOL*1024)/ MSGSSZ) /* max no. of segments */
diff -Nur linux-2.5.70/include/linux/sysctl.h linux-2.5.70msg/include/linux/sysctl.h
--- linux-2.5.70/include/linux/sysctl.h Tue May 27 06:30:40 2003
+++ linux-2.5.70msg/include/linux/sysctl.h Fri Jun 6 14:00:54 2003
@@ -130,6 +130,7 @@
         KERN_PIDMAX=55, /* int: PID # limit */
           KERN_CORE_PATTERN=56, /* string: pattern for core-file names */
         KERN_PANIC_ON_OOPS=57, /* int: whether we will panic on an oops */
+ KERN_MSGTQL=57, /* int: Maximum number of messages system wide */
 };
 

diff -Nur linux-2.5.70/ipc/msg.c linux-2.5.70msg/ipc/msg.c
--- linux-2.5.70/ipc/msg.c Tue May 27 06:30:20 2003
+++ linux-2.5.70msg/ipc/msg.c Fri Jun 6 18:43:42 2003
@@ -32,6 +32,9 @@
 int msg_ctlmax = MSGMAX;
 int msg_ctlmnb = MSGMNB;
 int msg_ctlmni = MSGMNI;
+int msg_ctltql = MSGTQL;
+static int msg_count = 0; /* counter for MSGTQL */
+static spinlock_t msg_count_lock; /* spinlock for MSGTQL */
 
 /* one msg_receiver structure for each sleeping receiver */
 struct msg_receiver {
@@ -137,6 +140,9 @@
 
         seg = msg->next;
         kfree(msg);
+ spin_lock(&msg_count_lock);
+ msg_count--;
+ spin_unlock(&msg_count_lock);
         while(seg != NULL) {
                 struct msg_msgseg* tmp = seg->next;
                 kfree(seg);
@@ -154,48 +160,59 @@
         alen = len;
         if(alen > DATALEN_MSG)
                 alen = DATALEN_MSG;
-
- msg = (struct msg_msg *) kmalloc (sizeof(*msg) + alen, GFP_KERNEL);
- if(msg==NULL)
- return ERR_PTR(-ENOMEM);
-
- msg->next = NULL;
- msg->security = NULL;
-
- if (copy_from_user(msg+1, src, alen)) {
- err = -EFAULT;
- goto out_err;
- }
-
- len -= alen;
- src = ((char*)src)+alen;
- pseg = &msg->next;
- while(len > 0) {
- struct msg_msgseg* seg;
- alen = len;
- if(alen > DATALEN_SEG)
- alen = DATALEN_SEG;
- seg = (struct msg_msgseg *) kmalloc (sizeof(*seg) + alen, GFP_KERNEL);
- if(seg==NULL) {
- err=-ENOMEM;
- goto out_err;
+
+ spin_lock(&msg_count_lock);
+ if(msg_count < msg_ctltql){
+ msg = (struct msg_msg *) kmalloc (sizeof(*msg) + alen, GFP_KERNEL);
+ if(msg==NULL) {
+ spin_unlock(msg_count_lock);
+ return ERR_PTR(-ENOMEM);
                 }
- *pseg = seg;
- seg->next = NULL;
- if(copy_from_user (seg+1, src, alen)) {
+ msg_count++;
+ spin_unlock(msg_count_lock);
+ msg->next = NULL;
+ msg->security = NULL;
+
+ if (copy_from_user(msg+1, src, alen)) {
                         err = -EFAULT;
                         goto out_err;
                 }
- pseg = &seg->next;
+
                 len -= alen;
                 src = ((char*)src)+alen;
- }
+ pseg = &msg->next;
+ while(len > 0) {
+ struct msg_msgseg* seg;
+ alen = len;
+ if(alen > DATALEN_SEG)
+ alen = DATALEN_SEG;
+ seg = (struct msg_msgseg *) kmalloc (sizeof(*seg) + alen, GFP_KERNEL);
+ if(seg==NULL) {
+ err=-ENOMEM;
+ goto out_err;
+ }
+ *pseg = seg;
+ seg->next = NULL;
+ if(copy_from_user (seg+1, src, alen)) {
+ err = -EFAULT;
+ goto out_err;
+ }
+ pseg = &seg->next;
+ len -= alen;
+ src = ((char*)src)+alen;
+ }
         
- err = security_msg_msg_alloc(msg);
- if (err)
- goto out_err;
+ err = security_msg_msg_alloc(msg);
+ if (err)
+ goto out_err;
 
- return msg;
+ return msg;
+ }
+ else {
+ spin_unlock(&msg_count_lock);
+ err= -EAGAIN;
+ return ERR_PTR(err);
+ }
 
 out_err:
         free_msg(msg);
diff -Nur linux-2.5.70/kernel/sysctl.c linux-2.5.70msg/kernel/sysctl.c
--- linux-2.5.70/kernel/sysctl.c Tue May 27 06:30:23 2003
+++ linux-2.5.70msg/kernel/sysctl.c Fri Jun 6 14:35:06 2003
@@ -61,6 +61,9 @@
 /* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */
 static int maxolduid = 65535;
 static int minolduid;
+static int zero = 0;
+static int one = 1;
+static int one_hundred = 100;
 
 #ifdef CONFIG_KMOD
 extern char modprobe_path[];
@@ -78,6 +81,7 @@
 extern int msg_ctlmax;
 extern int msg_ctlmnb;
 extern int msg_ctlmni;
+extern int msg_ctltql;
 extern int sem_ctls[];
 #endif
 
@@ -235,6 +239,8 @@
          0644, NULL, &proc_dointvec},
         {KERN_MSGMNB, "msgmnb", &msg_ctlmnb, sizeof (int),
          0644, NULL, &proc_dointvec},
+ {KERN_MSGTQL, "msgtql", &msg_ctltql, sizeof (int),
+ 0644, NULL, &proc_dointvec_minmax, NULL, NULL, &zero, NULL},
         {KERN_SEM, "sem", &sem_ctls, 4*sizeof (int),
          0644, NULL, &proc_dointvec},
 #endif
@@ -270,9 +276,6 @@
 
 /* Constants for minimum and maximum testing in vm_table.
    We use these as one-element integer vectors. */
-static int zero = 0;
-static int one = 1;
-static int one_hundred = 100;
 

 static ctl_table vm_table[] = {

-
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/



This archive was generated by hypermail 2b29 : Sat Jun 07 2003 - 22:00:30 EST