From: James Page <[email protected]> Normally when OVS runs on a server the effective system limit for locked memory is unlimited as the ovs-vswitchd runs as the root user in the root namespace of the server.
When OVS is run in a non-priviledged container a system limit will apply and its possible that this limit will be reached during normal operation. If this occurs unlock all memory and re-attempt (re)allocation of memory rather than fail and abort. If this subsequent attempt also fails abort the process as before. Signed-off-by: James Page <[email protected]> [[email protected] adapted to cover more cases] Signed-off-by: Ben Pfaff <[email protected]> --- lib/stream-ssl.c | 4 ++-- lib/util.c | 40 +++++++++++++++++++++++++++++++--------- lib/util.h | 3 ++- 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/lib/stream-ssl.c b/lib/stream-ssl.c index 078fcbc3aa4a..cd906e9e7b1d 100644 --- a/lib/stream-ssl.c +++ b/lib/stream-ssl.c @@ -1096,10 +1096,10 @@ tmp_dh_callback(SSL *ssl OVS_UNUSED, int is_export OVS_UNUSED, int keylength) for (dh = dh_table; dh < &dh_table[ARRAY_SIZE(dh_table)]; dh++) { if (dh->keylength == keylength) { - if (!dh->dh) { + while (!dh->dh) { dh->dh = dh->constructor(); if (!dh->dh) { - out_of_memory(); + munlockall_or_out_of_memory(); } } return dh->dh; diff --git a/lib/util.c b/lib/util.c index 1195c7982118..e9c5c40094bc 100644 --- a/lib/util.c +++ b/lib/util.c @@ -41,6 +41,9 @@ #ifdef _WIN32 #include <shlwapi.h> #endif +#ifdef HAVE_MLOCKALL +#include <sys/mman.h> +#endif VLOG_DEFINE_THIS_MODULE(util); @@ -103,6 +106,12 @@ set_memory_locked(void) is_memory_locked = true; } +void +set_memory_unlocked(void) +{ + is_memory_locked = false; +} + bool memory_locked(void) { @@ -110,8 +119,17 @@ memory_locked(void) } void -out_of_memory(void) -{ +munlockall_or_out_of_memory(void) +{ +#ifdef HAVE_MLOCKALL + if (errno == EAGAIN && memory_locked()) { + /* Locked memory allocation failed + * unlock and try again */ + munlockall(); + set_memory_unlocked(); + return; + } +#endif // HAVE_MLOCKALL ovs_abort(0, "virtual memory exhausted"); } @@ -120,7 +138,8 @@ xcalloc__(size_t count, size_t size) { void *p = count && size ? calloc(count, size) : malloc(1); if (p == NULL) { - out_of_memory(); + munlockall_or_out_of_memory(); + return xcalloc__(count, size); } return p; } @@ -136,7 +155,8 @@ xmalloc__(size_t size) { void *p = malloc(size ? size : 1); if (p == NULL) { - out_of_memory(); + munlockall_or_out_of_memory(); + return xmalloc__(size); } return p; } @@ -144,11 +164,12 @@ xmalloc__(size_t size) void * xrealloc__(void *p, size_t size) { - p = realloc(p, size ? size : 1); - if (p == NULL) { - out_of_memory(); + void *rp = realloc(p, size ? size : 1); + if (rp == NULL) { + munlockall_or_out_of_memory(); + return xrealloc__(p, size); } - return p; + return rp; } void * @@ -253,7 +274,8 @@ xmalloc_size_align(size_t size, size_t alignment) COVERAGE_INC(util_xalloc); error = posix_memalign(&p, alignment, size ? size : 1); if (error != 0) { - out_of_memory(); + munlockall_or_out_of_memory(); + return xmalloc_size_align(size, alignment); } return p; #else diff --git a/lib/util.h b/lib/util.h index 9c2b14fae304..a1958fcf93b4 100644 --- a/lib/util.h +++ b/lib/util.h @@ -144,8 +144,9 @@ void ctl_timeout_setup(unsigned int secs); void ovs_print_version(uint8_t min_ofp, uint8_t max_ofp); void set_memory_locked(void); +void set_memory_unlocked(void); bool memory_locked(void); -OVS_NO_RETURN void out_of_memory(void); +void munlockall_or_out_of_memory(void); /* Allocation wrappers that abort if memory is exhausted. */ void *xmalloc(size_t) MALLOC_LIKE; -- 2.29.2 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
