mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-06 15:17:01 +02:00
MEDIUM: shctx: Naming shared memory context
From Linux 5.17, anonymous regions can be name via prctl/PR_SET_VMA so caches can be identified when looking at HAProxy process memory mapping. The most possible error is lack of kernel support, as a result we ignore it, if the naming fails the mapping of memory context ought to still occur.
This commit is contained in:
parent
3ef60012ae
commit
98d22f212a
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
int shctx_init(struct shared_context **orig_shctx,
|
int shctx_init(struct shared_context **orig_shctx,
|
||||||
int maxblocks, int blocksize, unsigned int maxobjsz,
|
int maxblocks, int blocksize, unsigned int maxobjsz,
|
||||||
int extra);
|
int extra, __maybe_unused const char *name);
|
||||||
struct shared_block *shctx_row_reserve_hot(struct shared_context *shctx,
|
struct shared_block *shctx_row_reserve_hot(struct shared_context *shctx,
|
||||||
struct shared_block *last, int data_len);
|
struct shared_block *last, int data_len);
|
||||||
void shctx_row_detach(struct shared_context *shctx, struct shared_block *first);
|
void shctx_row_detach(struct shared_context *shctx, struct shared_block *first);
|
||||||
|
@ -2471,7 +2471,7 @@ int post_check_cache()
|
|||||||
list_for_each_entry_safe(cache_config, back, &caches_config, list) {
|
list_for_each_entry_safe(cache_config, back, &caches_config, list) {
|
||||||
|
|
||||||
ret_shctx = shctx_init(&shctx, cache_config->maxblocks, CACHE_BLOCKSIZE,
|
ret_shctx = shctx_init(&shctx, cache_config->maxblocks, CACHE_BLOCKSIZE,
|
||||||
cache_config->maxobjsz, sizeof(struct cache));
|
cache_config->maxobjsz, sizeof(struct cache), cache_config->id);
|
||||||
|
|
||||||
if (ret_shctx <= 0) {
|
if (ret_shctx <= 0) {
|
||||||
if (ret_shctx == SHCTX_E_INIT_LOCK)
|
if (ret_shctx == SHCTX_E_INIT_LOCK)
|
||||||
|
34
src/shctx.c
34
src/shctx.c
@ -16,6 +16,9 @@
|
|||||||
#include <import/ebmbtree.h>
|
#include <import/ebmbtree.h>
|
||||||
#include <haproxy/list.h>
|
#include <haproxy/list.h>
|
||||||
#include <haproxy/shctx.h>
|
#include <haproxy/shctx.h>
|
||||||
|
#if defined(USE_PRCTL)
|
||||||
|
#include <sys/prctl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reserve a new row if <first> is null, put it in the hotlist, set the refcount to 1
|
* Reserve a new row if <first> is null, put it in the hotlist, set the refcount to 1
|
||||||
@ -269,13 +272,14 @@ int shctx_row_data_get(struct shared_context *shctx, struct shared_block *first,
|
|||||||
* and 0 if cache is already allocated.
|
* and 0 if cache is already allocated.
|
||||||
*/
|
*/
|
||||||
int shctx_init(struct shared_context **orig_shctx, int maxblocks, int blocksize,
|
int shctx_init(struct shared_context **orig_shctx, int maxblocks, int blocksize,
|
||||||
unsigned int maxobjsz, int extra)
|
unsigned int maxobjsz, int extra, const char *name)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct shared_context *shctx;
|
struct shared_context *shctx;
|
||||||
int ret;
|
int ret;
|
||||||
void *cur;
|
void *cur;
|
||||||
int maptype = MAP_SHARED;
|
int maptype = MAP_SHARED;
|
||||||
|
size_t totalsize = sizeof(struct shared_context) + extra + (maxblocks * (sizeof(struct shared_block) + blocksize));
|
||||||
|
|
||||||
if (maxblocks <= 0)
|
if (maxblocks <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
@ -284,14 +288,38 @@ int shctx_init(struct shared_context **orig_shctx, int maxblocks, int blocksize,
|
|||||||
blocksize = (blocksize + sizeof(void *) - 1) & -sizeof(void *);
|
blocksize = (blocksize + sizeof(void *) - 1) & -sizeof(void *);
|
||||||
extra = (extra + sizeof(void *) - 1) & -sizeof(void *);
|
extra = (extra + sizeof(void *) - 1) & -sizeof(void *);
|
||||||
|
|
||||||
shctx = (struct shared_context *)mmap(NULL, sizeof(struct shared_context) + extra + (maxblocks * (sizeof(struct shared_block) + blocksize)),
|
shctx = (struct shared_context *)mmap(NULL, totalsize, PROT_READ | PROT_WRITE, maptype | MAP_ANON, -1, 0);
|
||||||
PROT_READ | PROT_WRITE, maptype | MAP_ANON, -1, 0);
|
|
||||||
if (!shctx || shctx == MAP_FAILED) {
|
if (!shctx || shctx == MAP_FAILED) {
|
||||||
shctx = NULL;
|
shctx = NULL;
|
||||||
ret = SHCTX_E_ALLOC_CACHE;
|
ret = SHCTX_E_ALLOC_CACHE;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(USE_PRCTL) && defined(PR_SET_VMA)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* From Linux 5.17 (and if the `CONFIG_ANON_VMA_NAME` kernel config is set)`,
|
||||||
|
* anonymous regions can be named.
|
||||||
|
* We intentionally ignore errors as it should not jeopardize the memory context
|
||||||
|
* mapping whatsoever (e.g. older kernels).
|
||||||
|
*
|
||||||
|
* The naming can take up to 79 characters, accepting valid ASCII values
|
||||||
|
* except [, ], \, $ and '.
|
||||||
|
* As a result, when looking for /proc/<pid>/maps, we can see the anonymous range
|
||||||
|
* as follow :
|
||||||
|
* `7364c4fff000-736508000000 rw-s 00000000 00:01 3540 [anon_shmem:HAProxy globalCache]`
|
||||||
|
*/
|
||||||
|
int rn;
|
||||||
|
char fullname[80];
|
||||||
|
|
||||||
|
rn = snprintf(fullname, sizeof(fullname), "HAProxy %s", name);
|
||||||
|
if (rn >= 0) {
|
||||||
|
(void)prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, (uintptr_t)shctx,
|
||||||
|
totalsize, (uintptr_t)fullname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
shctx->nbav = 0;
|
shctx->nbav = 0;
|
||||||
|
|
||||||
LIST_INIT(&shctx->avail);
|
LIST_INIT(&shctx->avail);
|
||||||
|
@ -5351,7 +5351,7 @@ int ssl_sock_prepare_bind_conf(struct bind_conf *bind_conf)
|
|||||||
if (!ssl_shctx && global.tune.sslcachesize) {
|
if (!ssl_shctx && global.tune.sslcachesize) {
|
||||||
alloc_ctx = shctx_init(&ssl_shctx, global.tune.sslcachesize,
|
alloc_ctx = shctx_init(&ssl_shctx, global.tune.sslcachesize,
|
||||||
sizeof(struct sh_ssl_sess_hdr) + SHSESS_BLOCK_MIN_SIZE, -1,
|
sizeof(struct sh_ssl_sess_hdr) + SHSESS_BLOCK_MIN_SIZE, -1,
|
||||||
sizeof(*sh_ssl_sess_tree));
|
sizeof(*sh_ssl_sess_tree), "ssl cache");
|
||||||
if (alloc_ctx <= 0) {
|
if (alloc_ctx <= 0) {
|
||||||
if (alloc_ctx == SHCTX_E_INIT_LOCK)
|
if (alloc_ctx == SHCTX_E_INIT_LOCK)
|
||||||
ha_alert("Unable to initialize the lock for the shared SSL session cache. You can retry using the global statement 'tune.ssl.force-private-cache' but it could increase CPU usage due to renegotiations if nbproc > 1.\n");
|
ha_alert("Unable to initialize the lock for the shared SSL session cache. You can retry using the global statement 'tune.ssl.force-private-cache' but it could increase CPU usage due to renegotiations if nbproc > 1.\n");
|
||||||
|
Loading…
Reference in New Issue
Block a user