[PATCH RFC] configurable maximum number of clients

Olivier Fourdan ofourdan at redhat.com
Thu May 28 08:56:33 PDT 2015


Make the maximum number of client user configurable, either from the command
line or from xorg.conf

This patch works by keeping the MAXCLIENTS define (of 512) as the maximum
allowed number of clients, but allowing the actual limit to be set by the
user (default to 256).

There is a limit size of 29 bits to be used to store both the client ID and
the X resources ID, so by reducing the number of clients allowed to connect to
the X server, the user can increase the number of X resources per client.

Parts of this patch are based on a similar patch from Adam Jackson
<ajax at redhat.com>

Signed-off-by: Adam Jackson <ajax at redhat.com>
Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
---
 dix/resource.c                 | 23 +++++++++++++++++++++++
 hw/xfree86/common/xf86Config.c | 16 ++++++++++++++++
 hw/xfree86/man/xorg.conf.man   |  4 ++++
 include/misc.h                 |  3 ++-
 include/opaque.h               |  1 +
 include/resource.h             | 15 ++-------------
 man/Xserver.man                |  5 +++++
 os/osinit.c                    |  3 +++
 os/utils.c                     | 14 ++++++++++++++
 9 files changed, 70 insertions(+), 14 deletions(-)

diff --git a/dix/resource.c b/dix/resource.c
index af8e162..4f8066a 100644
--- a/dix/resource.c
+++ b/dix/resource.c
@@ -600,6 +600,29 @@ CreateNewResourceClass(void)
 
 static ClientResourceRec clientTable[MAXCLIENTS];
 
+static unsigned int
+ilog2(int val)
+{
+    int bits;
+
+    if (val <= 0)
+	return 0;
+    for (bits = 0; val != 0; bits++)
+	val >>= 1;
+    return bits - 1;
+}
+
+/*****************
+ * ResourceClientBits
+ *    Returns the client bit offset in the client + resources ID field
+ *****************/
+
+unsigned int
+ResourceClientBits(void)
+{
+    return (ilog2(LimitClients));
+}
+
 /*****************
  * InitClientResources
  *    When a new client is created, call this to allocate space
diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c
index b8ec8a0..cd6d222 100644
--- a/hw/xfree86/common/xf86Config.c
+++ b/hw/xfree86/common/xf86Config.c
@@ -703,6 +703,7 @@ typedef enum {
     FLAG_DRI2,
     FLAG_USE_SIGIO,
     FLAG_AUTO_ADD_GPU,
+    FLAG_MAX_CLIENTS,
 } FlagValues;
 
 /**
@@ -762,6 +763,8 @@ static OptionInfoRec FlagOptions[] = {
      {0}, FALSE},
     {FLAG_AUTO_ADD_GPU, "AutoAddGPU", OPTV_BOOLEAN,
      {0}, FALSE},
+    {FLAG_MAX_CLIENTS, "MaxClients", OPTV_INTEGER,
+     {0}, FALSE },
     {-1, NULL, OPTV_NONE,
      {0}, FALSE},
 };
@@ -1052,6 +1055,19 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
         xf86Info.dri2From = X_CONFIG;
     }
 #endif
+
+    from = X_DEFAULT;
+    if (LimitClients != LIMITCLIENTS)
+	from = X_CMDLINE;
+    i = -1;
+    if (xf86GetOptValInteger(FlagOptions, FLAG_MAX_CLIENTS, &i)) {
+	if (i != 64 && i != 128 && i != 256 && i != 512)
+		ErrorF("MaxClients must be one of 64, 128, 256 or 512\n");
+	from = X_CONFIG;
+	LimitClients = i;
+    }
+    xf86Msg(from, "Max clients allowed: %i, resource mask: 0x%x\n",
+	    LimitClients, RESOURCE_ID_MASK);
 }
 
 Bool
diff --git a/hw/xfree86/man/xorg.conf.man b/hw/xfree86/man/xorg.conf.man
index e9b6d99..08eb7a9 100644
--- a/hw/xfree86/man/xorg.conf.man
+++ b/hw/xfree86/man/xorg.conf.man
@@ -621,6 +621,10 @@ It is only enabled for screens that have the
 .B \*qDPMS\*q
 option set (see the MONITOR section below).
 .TP 7
+.BI "Option \*qMaxClients\*q  \*q" integer \*q
+Set the maximum number of clients allowed to connect to the X server.
+Acceptable values are 64, 128, 256 or 512.
+.TP 7
 .BI "Option \*qPixmap\*q  \*q" bpp \*q
 This sets the pixmap format to use for depth 24.
 Allowed values for
diff --git a/include/misc.h b/include/misc.h
index 9b1c03a..56e138c 100644
--- a/include/misc.h
+++ b/include/misc.h
@@ -86,7 +86,8 @@ OF THIS SOFTWARE.
 #ifndef MAXGPUSCREENS
 #define MAXGPUSCREENS	16
 #endif
-#define MAXCLIENTS	256
+#define MAXCLIENTS	512
+#define LIMITCLIENTS	256     /* Must be a power of 2 and <= MAXCLIENTS */
 #define MAXEXTENSIONS   128
 #define MAXFORMATS	8
 #define MAXDEVICES	40      /* input devices */
diff --git a/include/opaque.h b/include/opaque.h
index a2c54aa..0ba0d64 100644
--- a/include/opaque.h
+++ b/include/opaque.h
@@ -36,6 +36,7 @@ from The Open Group.
 extern _X_EXPORT const char *defaultTextFont;
 extern _X_EXPORT const char *defaultCursorFont;
 extern _X_EXPORT int MaxClients;
+extern _X_EXPORT int LimitClients;
 extern _X_EXPORT volatile char isItTimeToYield;
 extern _X_EXPORT volatile char dispatchException;
 
diff --git a/include/resource.h b/include/resource.h
index 772f363..597f7b6 100644
--- a/include/resource.h
+++ b/include/resource.h
@@ -85,21 +85,10 @@ typedef uint32_t RESTYPE;
 #define RT_LASTPREDEF	((RESTYPE)9)
 #define RT_NONE		((RESTYPE)0)
 
+extern unsigned int ResourceClientBits(void);
 /* bits and fields within a resource id */
 #define RESOURCE_AND_CLIENT_COUNT   29  /* 29 bits for XIDs */
-#if MAXCLIENTS == 64
-#define RESOURCE_CLIENT_BITS	6
-#endif
-#if MAXCLIENTS == 128
-#define RESOURCE_CLIENT_BITS	7
-#endif
-#if MAXCLIENTS == 256
-#define RESOURCE_CLIENT_BITS	8
-#endif
-#if MAXCLIENTS == 512
-#define RESOURCE_CLIENT_BITS	9
-#endif
-/* client field offset */
+#define RESOURCE_CLIENT_BITS        ResourceClientBits() /* client field offset */
 #define CLIENTOFFSET	    (RESOURCE_AND_CLIENT_COUNT - RESOURCE_CLIENT_BITS)
 /* resource field */
 #define RESOURCE_ID_MASK	((1 << CLIENTOFFSET) - 1)
diff --git a/man/Xserver.man b/man/Xserver.man
index 3bf844f..aba4f31 100644
--- a/man/Xserver.man
+++ b/man/Xserver.man
@@ -320,6 +320,11 @@ sets the stack space limit of the server to the specified number of kilobytes.
 A value of zero makes the stack size as large as possible.  The default value
 of \-1 leaves the stack space limit unchanged.
 .TP 8
+.B \-maxclients
+.BR 64 | 128 | 256 | 512
+Set the maximum number of clients allowed to connect to the X server.
+Acceptable values are 64, 128, 256 or 512.
+.TP 8
 .B \-render
 .BR default | mono | gray | color
 sets the color allocation policy that will be used by the render extension.
diff --git a/os/osinit.c b/os/osinit.c
index 91e3e06..ddd3fce 100644
--- a/os/osinit.c
+++ b/os/osinit.c
@@ -86,6 +86,9 @@ int limitStackSpace = -1;
 int limitNoFile = -1;
 #endif
 
+/* The actual user defined max number of clients */
+int LimitClients = LIMITCLIENTS;
+
 static OsSigWrapperPtr OsSigWrapper = NULL;
 
 OsSigWrapperPtr
diff --git a/os/utils.c b/os/utils.c
index 7fd395b..d27605c 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -556,6 +556,7 @@ UseMsg(void)
 #ifdef LOCK_SERVER
     ErrorF("-nolock                disable the locking mechanism\n");
 #endif
+    ErrorF("-maxclients n          set maximum number of clients (power of two)\n");
     ErrorF("-nolisten string       don't listen on protocol\n");
     ErrorF("-listen string         listen on protocol\n");
     ErrorF("-noreset               don't reset after last client exists\n");
@@ -860,6 +861,19 @@ ProcessCommandLine(int argc, char *argv[])
                 nolock = TRUE;
         }
 #endif
+	else if ( strcmp( argv[i], "-maxclients") == 0)
+	{
+	    if (++i < argc) {
+		LimitClients = atoi(argv[i]);
+		if (LimitClients != 64 &&
+		    LimitClients != 128 &&
+		    LimitClients != 256 &&
+		    LimitClients != 512) {
+		    FatalError("maxclients must be one of 64, 128, 256 or 512\n");
+		}
+	    } else
+		UseMsg();
+	}
         else if (strcmp(argv[i], "-nolisten") == 0) {
             if (++i < argc) {
                 if (_XSERVTransNoListen(argv[i]))
-- 
2.4.1



More information about the xorg-devel mailing list