Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

luaL_newstate() fails when limited amount of memory is available #2158

Closed
simonemainardi opened this issue Nov 19, 2018 · 3 comments
Closed
Labels

Comments

@simonemainardi
Copy link
Contributor

Lua fails to create luaL_newstate() when a limited amount of memory is available in the system. As other memory allocations (malloc/calloc/new) don't fail, the failure could be dependent from the lua implementation of luaL_newstate().

To reproduce systematically:

  • change ntopng code to increase the num of buckets in the hosts and flows hash tables by a factor 8
  • create a dummy network interface dummy0
  • start ./ntopng -i dummy0 --capture-direction=1 -n 3 --dont-change-user --disable-login 1 -X 4000000 -x 4000000 -g 1 -m "0.0.0.0/0"
  • send traffic on the dummy interface with pfsend -i stack:dummy0 -b 800000 -r 1
@simonemainardi simonemainardi changed the title luaL_newstate() fails when limited amount of memory is available luaL_newstate() fails when limited amount of memory is available Nov 19, 2018
@simonemainardi
Copy link
Contributor Author

This is the mmap that seems to fail

static void *mmap_map32(size_t size)
  {
  #if LJ_ALLOC_MMAP_PROBE
    static int fallback = 0;
    if (fallback)
  =>  return mmap_probe(size);
  #endif
    {
      int olderr = errno;
      void *ptr = mmap((void *)LJ_ALLOC_MMAP32_START, size, MMAP_PROT, MAP_32BIT|MMAP_FLAGS, -1, 0);
      errno = olderr;
      /* This only allows 1GB on Linux. So fallback to probing to get 2GB. */
  #if LJ_ALLOC_MMAP_PROBE
      if (ptr == MFAIL) {
        fallback = 1;
        return mmap_probe(size);
      }
  #endif
      return ptr;

MAP_32BIT (since Linux 2.4.20, 2.6)
              Put the mapping into the first 2 Gigabytes of the process
              address space.  This flag is supported only on x86-64, for
              64-bit programs.  It was added to allow thread stacks to be
              allocated somewhere in the first 2 GB of memory, so as to
              improve context-switch performance on some early 64-bit
              processors.  Modern x86-64 processors no longer have this
              performance problem, so use of this flag is not required on
              those systems.  The MAP_32BIT flag is ignored when MAP_FIXED
              is set.

@simonemainardi
Copy link
Contributor Author

Issue is due to LuaJIT that only mmaps in the first 2GB of address space. That is, it looks for contiguous chunks of memory in the first 2GB.

if ((addr >> LJ_ALLOC_MBITS) == 0 && addr >= LJ_ALLOC_MMAP_PROBE_LOWER) {

This is not enough as, on large installations, the first 2GB could be easily be already used by ntopng (e.g., to keep the hash tables).

To allow LuaJIT to use more memory, it should be compiled with LUAJIT_ENABLE_GC64 but this causes ntopng to crash immediately. As of today, it seems that LUAJIT_ENABLE_GC64 isn't fully supported: LuaJIT/LuaJIT#25

Hence, we are considering to drop LuaJIT in favour of normal Lua. Indeed, the benefits of JIT in ntopng are limited as new interpreters are spawned continuously.

@simonemainardi
Copy link
Contributor Author

fixed as part of 64d969f

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant