Bug 1401776 - Raise fd limit to 4096 on Unix. r=glandium,mcmanus
authorJed Davis <jld@mozilla.com>
Thu, 10 May 2018 17:36:32 -0600
changeset 472457 fcfbfc7d96d90fb5bbc3f03284a460a70e7674ac
parent 472456 74dc3b5bb9aa99a041a48a9a096e05168b294bb6
child 472458 513c6708a3337a6b008118dd4083fb693775ba70
push id9374
push userjlund@mozilla.com
push dateMon, 18 Jun 2018 21:43:20 +0000
treeherdermozilla-beta@160e085dfb0b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersglandium, mcmanus
bugs1401776, 1036682, 1161166
milestone62.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1401776 - Raise fd limit to 4096 on Unix. r=glandium,mcmanus This is to accommodate non-networking fd usage (IPC transports, various databases, .xpi files, etc.), so it's separate from Necko's existing manipulation of the fd limit, which is tied into Necko's internal limits on how many sockets it will try to poll at once. Note that resource limits are inherited by child processes, so this needs to be done only in the parent. This patch also removes similar code used on Solaris and Mac OS X. The Mac case (bug 1036682) refers to fd use by graphics textures, which shouldn't be consuming fds anymore (even transiently) as of bug 1161166. MozReview-Commit-ID: 2uodrkW5sUn
gfx/thebes/gfxPlatformMac.cpp
toolkit/xre/nsAppRunner.cpp
toolkit/xre/nsSigHandlers.cpp
--- a/gfx/thebes/gfxPlatformMac.cpp
+++ b/gfx/thebes/gfxPlatformMac.cpp
@@ -76,28 +76,16 @@ DisableFontActivation()
 
 gfxPlatformMac::gfxPlatformMac()
 {
     DisableFontActivation();
     mFontAntiAliasingThreshold = ReadAntiAliasingThreshold();
 
     InitBackendPrefs(GetBackendPrefs());
 
-    // XXX: Bug 1036682 - we run out of fds on Mac when using tiled layers because
-    // with 256x256 tiles we can easily hit the soft limit of 800 when using double
-    // buffered tiles in e10s, so let's bump the soft limit to the hard limit for the OS
-    // up to a new cap of OPEN_MAX.
-    struct rlimit limits;
-    if (getrlimit(RLIMIT_NOFILE, &limits) == 0) {
-        limits.rlim_cur = std::min(rlim_t(OPEN_MAX), limits.rlim_max);
-        if (setrlimit(RLIMIT_NOFILE, &limits) != 0) {
-            NS_WARNING("Unable to bump RLIMIT_NOFILE to the maximum number on this OS");
-        }
-    }
-
     MacIOSurfaceLib::LoadLibrary();
 }
 
 gfxPlatformMac::~gfxPlatformMac()
 {
     gfxCoreTextShaper::Shutdown();
 }
 
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -148,19 +148,22 @@
 #include "mozilla/Omnijar.h"
 #include "mozilla/StartupTimeline.h"
 #include "mozilla/LateWriteChecks.h"
 
 #include <stdlib.h>
 #include <locale.h>
 
 #ifdef XP_UNIX
+#include <errno.h>
+#include <pwd.h>
+#include <string.h>
+#include <sys/resource.h>
 #include <sys/stat.h>
 #include <unistd.h>
-#include <pwd.h>
 #endif
 
 #ifdef XP_WIN
 #include <process.h>
 #include <shlobj.h>
 #include "mozilla/WinDllServices.h"
 #include "nsThreadUtils.h"
 #include <comdef.h>
@@ -3079,16 +3082,45 @@ CheckForUserMismatch()
 #else // !XP_UNIX || ANDROID
 static bool
 CheckForUserMismatch()
 {
   return false;
 }
 #endif
 
+static void
+IncreaseDescriptorLimits()
+{
+#ifdef XP_UNIX
+  // Increase the fd limit to accomodate IPC resources like shared memory.
+  static const rlim_t kFDs = 4096;
+  struct rlimit rlim;
+
+  if (getrlimit(RLIMIT_NOFILE, &rlim) != 0) {
+    Output(false, "getrlimit: %s\n", strerror(errno));
+    return;
+  }
+  // Don't decrease the limit if it's already high enough, but don't
+  // try to go over the hard limit.  (RLIM_INFINITY isn't required to
+  // be the numerically largest rlim_t, so don't assume that.)
+  if (rlim.rlim_cur != RLIM_INFINITY && rlim.rlim_cur < kFDs &&
+      rlim.rlim_cur < rlim.rlim_max) {
+    if (rlim.rlim_max != RLIM_INFINITY && rlim.rlim_max < kFDs) {
+      rlim.rlim_cur = rlim.rlim_max;
+    } else {
+      rlim.rlim_cur = kFDs;
+    }
+    if (setrlimit(RLIMIT_NOFILE, &rlim) != 0) {
+      Output(false, "setrlimit: %s\n", strerror(errno));
+    }
+  }
+#endif
+}
+
 /*
  * XRE_mainInit - Initial setup and command line parameter processing.
  * Main() will exit early if either return value != 0 or if aExitFlag is
  * true.
  */
 int
 XREMain::XRE_mainInit(bool* aExitFlag)
 {
@@ -3149,16 +3181,18 @@ XREMain::XRE_mainInit(bool* aExitFlag)
   nsresult rv;
   ArgResult ar;
 
 #ifdef DEBUG
   if (PR_GetEnv("XRE_MAIN_BREAK"))
     NS_BREAK();
 #endif
 
+  IncreaseDescriptorLimits();
+
 #ifdef USE_GLX_TEST
   // bug 639842 - it's very important to fire this process BEFORE we set up
   // error handling. indeed, this process is expected to be crashy, and we
   // don't want the user to see its crashes. That's the whole reason for
   // doing this in a separate process.
   //
   // This call will cause a fork and the fork will terminate itself separately
   // from the usual shutdown sequence
--- a/toolkit/xre/nsSigHandlers.cpp
+++ b/toolkit/xre/nsSigHandlers.cpp
@@ -282,40 +282,16 @@ void InstallSignalHandlers(const char *a
     m *= (1024*1024);
     struct rlimit r;
     r.rlim_cur = m;
     r.rlim_max = m;
     setrlimit(RLIMIT_AS, &r);
   }
 #endif
 
-#if defined(SOLARIS)
-#define NOFILES 512
-
-    // Boost Solaris file descriptors
-    {
-	struct rlimit rl;
-
-	if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
-
-	    if (rl.rlim_cur < NOFILES) {
-		rl.rlim_cur = NOFILES;
-
-		if (setrlimit(RLIMIT_NOFILE, &rl) < 0) {
-		    perror("setrlimit(RLIMIT_NOFILE)");
-		    fprintf(stderr, "Cannot exceed hard limit for open files");
-		}
-#if defined(DEBUG)
-	    	if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
-		    printf("File descriptors set to %d\n", rl.rlim_cur);
-#endif //DEBUG
-	    }
-    }
-#endif //SOLARIS
-
 #if defined(MOZ_WIDGET_GTK) && (GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 6))
   const char *assertString = PR_GetEnv("XPCOM_DEBUG_BREAK");
   if (assertString &&
       (!strcmp(assertString, "suspend") ||
        !strcmp(assertString, "stack") ||
        !strcmp(assertString, "abort") ||
        !strcmp(assertString, "trap") ||
        !strcmp(assertString, "break"))) {