add preferred jemalloc config

add muzzy/dirty configuration mallctl interface

add program argument for --gc-muzzy=false

Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
Jason Volk 2025-01-18 01:30:41 +00:00
parent 3eed408b29
commit 3dae02b886
12 changed files with 289 additions and 82 deletions

View file

@ -41,6 +41,7 @@ default = [
"gzip_compression",
"io_uring",
"jemalloc",
"jemalloc_conf",
"media_thumbnail",
"release_max_log_level",
"systemd",
@ -85,6 +86,9 @@ jemalloc_prof = [
jemalloc_stats = [
"conduwuit-core/jemalloc_stats",
]
jemalloc_conf = [
"conduwuit-core/jemalloc_conf",
]
media_thumbnail = [
"conduwuit-service/media_thumbnail",
]

View file

@ -92,6 +92,22 @@ pub(crate) struct Args {
require_equals(false),
)]
pub(crate) gc_on_park: Option<bool>,
/// Toggles muzzy decay for jemalloc arenas associated with a tokio
/// worker (when worker-affinity is enabled). Setting to false releases
/// memory to the operating system using MADV_FREE without MADV_DONTNEED.
/// Setting to false increases performance by reducing pagefaults, but
/// resident memory usage appears high until there is memory pressure. The
/// default is true unless the system has four or more cores.
#[arg(
long,
hide(true),
env = "CONDUWUIT_RUNTIME_GC_MUZZY",
action = ArgAction::Set,
num_args = 0..=1,
require_equals(false),
)]
pub(crate) gc_muzzy: Option<bool>,
}
/// Parse commandline arguments into structured data

View file

@ -9,8 +9,12 @@ use std::{
};
use conduwuit::{
result::LogErr,
utils::sys::compute::{nth_core_available, set_affinity},
is_true,
result::LogDebugErr,
utils::{
available_parallelism,
sys::compute::{nth_core_available, set_affinity},
},
Result,
};
use tokio::runtime::Builder;
@ -21,9 +25,11 @@ const WORKER_NAME: &str = "conduwuit:worker";
const WORKER_MIN: usize = 2;
const WORKER_KEEPALIVE: u64 = 36;
const MAX_BLOCKING_THREADS: usize = 1024;
const DISABLE_MUZZY_THRESHOLD: usize = 4;
static WORKER_AFFINITY: OnceLock<bool> = OnceLock::new();
static GC_ON_PARK: OnceLock<Option<bool>> = OnceLock::new();
static GC_MUZZY: OnceLock<Option<bool>> = OnceLock::new();
pub(super) fn new(args: &Args) -> Result<tokio::runtime::Runtime> {
WORKER_AFFINITY
@ -34,6 +40,10 @@ pub(super) fn new(args: &Args) -> Result<tokio::runtime::Runtime> {
.set(args.gc_on_park)
.expect("set GC_ON_PARK from program argument");
GC_MUZZY
.set(args.gc_muzzy)
.expect("set GC_MUZZY from program argument");
let mut builder = Builder::new_multi_thread();
builder
.enable_io()
@ -83,11 +93,13 @@ fn enable_histogram(builder: &mut Builder, args: &Args) {
),
)]
fn thread_start() {
if WORKER_AFFINITY
.get()
.copied()
.expect("WORKER_AFFINITY initialized by runtime::new()")
{
debug_assert_eq!(
Some(WORKER_NAME),
thread::current().name(),
"tokio worker name mismatch at thread start"
);
if WORKER_AFFINITY.get().is_some_and(is_true!()) {
set_worker_affinity();
}
}
@ -95,10 +107,6 @@ fn thread_start() {
fn set_worker_affinity() {
static CORES_OCCUPIED: AtomicUsize = AtomicUsize::new(0);
if thread::current().name() != Some(WORKER_NAME) {
return;
}
let handle = tokio::runtime::Handle::current();
let num_workers = handle.metrics().num_workers();
let i = CORES_OCCUPIED.fetch_add(1, Ordering::Relaxed);
@ -111,8 +119,33 @@ fn set_worker_affinity() {
};
set_affinity(once(id));
set_worker_mallctl(id);
}
#[cfg(feature = "jemalloc")]
fn set_worker_mallctl(id: usize) {
use conduwuit::alloc::je::{
is_affine_arena,
this_thread::{set_arena, set_muzzy_decay},
};
if is_affine_arena() {
set_arena(id).log_debug_err().ok();
}
let muzzy_option = GC_MUZZY
.get()
.expect("GC_MUZZY initialized by runtime::new()");
let muzzy_auto_disable = available_parallelism() >= DISABLE_MUZZY_THRESHOLD;
if matches!(muzzy_option, Some(false) | None if muzzy_auto_disable) {
set_muzzy_decay(-1).log_debug_err().ok();
}
}
#[cfg(not(feature = "jemalloc"))]
fn set_worker_mallctl(_: usize) {}
#[tracing::instrument(
name = "join",
level = "debug",
@ -157,7 +190,9 @@ fn thread_park() {
fn gc_on_park() {
#[cfg(feature = "jemalloc")]
conduwuit::alloc::je::this_thread::decay().log_err().ok();
conduwuit::alloc::je::this_thread::decay()
.log_debug_err()
.ok();
}
#[cfg(tokio_unstable)]