diff --git a/pbs-tools/src/lib.rs b/pbs-tools/src/lib.rs index 053b3c0c..939ba7e6 100644 --- a/pbs-tools/src/lib.rs +++ b/pbs-tools/src/lib.rs @@ -8,3 +8,22 @@ pub mod sha; pub mod ticket; pub mod async_lru_cache; + +/// Set MMAP_THRESHOLD to a fixed value (128 KiB) +/// +/// This avoids the "dynamic" mmap-treshold logic from glibc's malloc, which seems misguided and +/// effectively avoids using mmap for all allocations smaller than 32 MiB. Which, in combination +/// with the allocation pattern from our/tokio's complex async machinery, resulted in very large +/// RSS sizes due to defragmentation and long-living (smaller) allocation on top of the heap +/// avoiding that the (big) now free'd allocations below couldn't get given back to the OS. This is +/// not an issue with mmap'd memeory chunks, those can be given back at any time. +/// +/// Lowering effective MMAP treshold to 128 KiB allows freeing up memory to the OS better and with +/// lower latency, which reduces the peak *and* average RSS size by an order of magnitude when +/// running backup jobs. We measured a reduction by a factor of 10-20 in experiments and see much +/// less erratic behavior in the overall's runtime RSS size. +pub fn setup_libc_malloc_opts() { + unsafe { + libc::mallopt(libc::M_MMAP_THRESHOLD, 4096*32); + } +} diff --git a/proxmox-backup-client/src/main.rs b/proxmox-backup-client/src/main.rs index 50682637..406f2d18 100644 --- a/proxmox-backup-client/src/main.rs +++ b/proxmox-backup-client/src/main.rs @@ -1464,6 +1464,7 @@ impl ReadAt for BufferedDynamicReadAt { } fn main() { + pbs_tools::setup_libc_malloc_opts(); let backup_cmd_def = CliCommand::new(&API_METHOD_CREATE_BACKUP) .arg_param(&["backupspec"]) diff --git a/proxmox-restore-daemon/src/main.rs b/proxmox-restore-daemon/src/main.rs index c2be942b..47790a7d 100644 --- a/proxmox-restore-daemon/src/main.rs +++ b/proxmox-restore-daemon/src/main.rs @@ -38,6 +38,8 @@ lazy_static! { /// This is expected to be run by 'proxmox-file-restore' within a mini-VM fn main() -> Result<(), Error> { + pbs_tools::setup_libc_malloc_opts(); + if !Path::new(VM_DETECT_FILE).exists() { bail!( "This binary is not supposed to be run manually, use 'proxmox-file-restore' instead." diff --git a/src/bin/proxmox-backup-api.rs b/src/bin/proxmox-backup-api.rs index e6fc5f23..ee037a3b 100644 --- a/src/bin/proxmox-backup-api.rs +++ b/src/bin/proxmox-backup-api.rs @@ -19,6 +19,8 @@ use proxmox_backup::auth_helpers::*; use proxmox_backup::config; fn main() { + pbs_tools::setup_libc_malloc_opts(); + proxmox_backup::tools::setup_safe_path_env(); if let Err(err) = proxmox_async::runtime::main(run()) { diff --git a/src/bin/proxmox-backup-proxy.rs b/src/bin/proxmox-backup-proxy.rs index 523966cf..30b730ef 100644 --- a/src/bin/proxmox-backup-proxy.rs +++ b/src/bin/proxmox-backup-proxy.rs @@ -73,6 +73,8 @@ use proxmox_backup::server::do_verification_job; use proxmox_backup::server::do_prune_job; fn main() -> Result<(), Error> { + pbs_tools::setup_libc_malloc_opts(); + proxmox_backup::tools::setup_safe_path_env(); let backup_uid = pbs_config::backup_user()?.uid;