From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 19B0475048; Fri, 4 Jun 2021 14:16:33 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 0CF9F1C82C; Fri, 4 Jun 2021 14:16:33 +0200 (CEST) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id 91FBF1C81E; Fri, 4 Jun 2021 14:16:28 +0200 (CEST) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 65BF045964; Fri, 4 Jun 2021 14:16:28 +0200 (CEST) Date: Fri, 4 Jun 2021 14:16:27 +0200 From: Wolfgang Bumiller To: Stefan Reiter Cc: pve-devel@lists.proxmox.com, pbs-devel@lists.proxmox.com Message-ID: <20210604121627.hrvzcoju6nape6cf@olga.proxmox.com> References: <20210602143833.4423-1-s.reiter@proxmox.com> <20210602143833.4423-9-s.reiter@proxmox.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20210602143833.4423-9-s.reiter@proxmox.com> User-Agent: NeoMutt/20180716 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.016 Adjusted score from AWL reputation of From: address KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [lib.rs] Subject: Re: [pve-devel] [pbs-devel] [PATCH proxmox-backup-qemu 8/9] add shared_cache module X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 04 Jun 2021 12:16:33 -0000 On Wed, Jun 02, 2021 at 04:38:32PM +0200, Stefan Reiter wrote: > Provides a shared AsyncLruCache of 256MB (w/ 4MB chunks) that can be > used by multiple readers at the same time. It is dropped once no more > readers exist, so the memory gets freed if all QEMU block/pbs instances > disappear. > > Signed-off-by: Stefan Reiter > --- > src/lib.rs | 7 ++++++- > src/shared_cache.rs | 36 ++++++++++++++++++++++++++++++++++++ > 2 files changed, 42 insertions(+), 1 deletion(-) > create mode 100644 src/shared_cache.rs > > diff --git a/src/lib.rs b/src/lib.rs > index 05d7b58..aa167f7 100644 > --- a/src/lib.rs > +++ b/src/lib.rs > @@ -25,6 +25,7 @@ mod restore; > use restore::*; > > mod tools; > +mod shared_cache; > > pub const PROXMOX_BACKUP_DEFAULT_CHUNK_SIZE: u64 = 1024*1024*4; > > @@ -804,7 +805,11 @@ pub extern "C" fn proxmox_restore_connect_async( > pub extern "C" fn proxmox_restore_disconnect(handle: *mut ProxmoxRestoreHandle) { > > let restore_task = handle as * mut Arc; > - unsafe { Box::from_raw(restore_task) }; //drop(restore_task) > + let restore_task = unsafe { Box::from_raw(restore_task) }; > + drop(restore_task); > + > + // after dropping, cache may be unused (if no other handles open) > + shared_cache::shared_chunk_cache_cleanup(); > } > > /// Restore an image (sync) > diff --git a/src/shared_cache.rs b/src/shared_cache.rs > new file mode 100644 > index 0000000..bebae5b > --- /dev/null > +++ b/src/shared_cache.rs > @@ -0,0 +1,36 @@ > +use once_cell::sync::OnceCell; > +use proxmox_backup::backup::ChunkCache; > +use proxmox_backup::tools::async_lru_cache::AsyncLruCache; > +use std::sync::{Arc, Mutex}; > + > +const SHARED_CACHE_CAPACITY: usize = 64; // 256 MB > +static SHARED_CACHE: OnceCell>> = OnceCell::new(); OnceCell *and* Option is a bit too much, `get_shared_chunk_chache()` can just initialize it in `get_or_init()` directly. > + > +pub fn get_shared_chunk_cache() -> ChunkCache { > + let mut guard = SHARED_CACHE > + .get_or_init(|| Mutex::new(None)) > + .lock() > + .unwrap(); > + match &*guard { > + Some(cache) => Arc::clone(cache), > + None => { > + let cache = Arc::new(AsyncLruCache::new(SHARED_CACHE_CAPACITY)); > + *guard = Some(Arc::clone(&cache)); > + cache > + } > + } > +} > + > +pub fn shared_chunk_cache_cleanup() { > + let mut guard = SHARED_CACHE > + .get_or_init(|| Mutex::new(None)) > + .lock() > + .unwrap(); > + if let Some(arc) = guard.as_ref() { > + let refcount = Arc::strong_count(arc); > + if refcount == 1 { > + // no one else is using the cache anymore, drop it > + let _drop = guard.take(); > + } > + } > +} > -- > 2.30.2