Skip to content

Commit

Permalink
[Pal/Linux-SGX] Pre-allocate more PAL memory on huge manifest files
Browse files Browse the repository at this point in the history
The tomlc99 library to parse TOML files uses a lot of memory during
`toml_parse()`. Sometimes apps have very large manifest files (>10MB),
and parsing these manifest files requires more than 128MB of
preallocated memory pool in Linux-SGX PAL.

Since this function is called before PAL can read
`loader.pal_internal_mem_size`, there is no way to learn the additional
memory size for PAL from the manifest. Thus we use a heuristic to
pre-allocate some PAL memory before `toml_parse()`.

Signed-off-by: Dmitrii Kuvaiskii <dmitrii.kuvaiskii@intel.com>
  • Loading branch information
dimakuv committed Sep 16, 2021
1 parent 4321ecf commit f52e492
Showing 1 changed file with 22 additions and 1 deletion.
23 changes: 22 additions & 1 deletion Pal/src/host/Linux-SGX/db_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,19 @@ noreturn void pal_linux_main(char* uptr_libpal_uri, size_t libpal_uri_len, char*
ocall_exit(1, /*is_exitgroup=*/true);
}

/* TOML parser (for whatever reason) allocates a lot of memory when parsing the manifest into an
* in-memory struct. We heuristically pre-allocate additional PAL internal memory if the
* manifest file looks large enough. Hopefully below sizes are sufficient for any manifest.
*
* FIXME: this is a quick hack, we need proper memory allocation in PAL. */
if (manifest_size > 10 * 1024 * 1024) {
log_always("Detected a huge manifest, preallocating 128MB of internal memory.");
g_pal_internal_mem_size += 128 * 1024 * 1024; /* 10MB manifest -> 64 + 128 MB PAL mem */
} else if (manifest_size > 5 * 1024 * 1024) {
log_always("Detected a huge manifest, preallocating 64MB of internal memory.");
g_pal_internal_mem_size += 64 * 1024 * 1024; /* 5MB manifest -> 64 + 64 MB PAL mem */
}

/* parse manifest */
char errbuf[256];
toml_table_t* manifest_root = toml_parse(manifest_addr, errbuf, sizeof(errbuf));
Expand All @@ -700,13 +713,21 @@ noreturn void pal_linux_main(char* uptr_libpal_uri, size_t libpal_uri_len, char*
READ_ONCE(*(size_t*)i);
}

size_t pal_internal_mem_size;
ret = toml_sizestring_in(g_pal_state.manifest_root, "loader.pal_internal_mem_size",
/*defaultval=*/0, &g_pal_internal_mem_size);
/*defaultval=*/0, &pal_internal_mem_size);
if (ret < 0) {
log_error("Cannot parse 'loader.pal_internal_mem_size'");
ocall_exit(1, true);
}

if (pal_internal_mem_size < g_pal_internal_mem_size) {
log_error("Too small `loader.pal_internal_mem_size`, need at least %luMB because the "
"manifest is large", g_pal_internal_mem_size / 1024 / 1024);
ocall_exit(1, true);
}
g_pal_internal_mem_size = pal_internal_mem_size;

if ((ret = init_file_check_policy()) < 0) {
log_error("Failed to load the file check policy: %d", ret);
ocall_exit(1, true);
Expand Down

0 comments on commit f52e492

Please sign in to comment.