From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [45.144.208.40]) by lore.proxmox.com (Postfix) with ESMTPS id C9D301FF0C0 for ; Wed, 21 Oct 2026 11:00:26 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id 7A41521726; Wed, 21 Oct 2026 10:59:43 +0200 (CEST) From: Dominik Rusovac To: pve-devel@lists.proxmox.com Subject: [PATCH proxmox-perl-rs 06/15] fix #7993: pve-rs: resource-scheduling: add weights to pve bindings Date: Wed, 21 Oct 2026 10:59:23 +0200 Message-ID: <20261021085932.1196302-7-d.rusovac@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20261021085932.1196302-1-d.rusovac@proxmox.com> References: <20261021085932.1196302-1-d.rusovac@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1792573177420 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.105 Adjusted score from AWL reputation of From: address DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment (newer systems) RCVD_IN_DNSWL_MED -2.3 Sender listed at https://www.dnswl.org/, medium trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: BLYZEWOXGUG44D43SGLTMK4PZUMC6JEG X-Message-ID-Hash: BLYZEWOXGUG44D43SGLTMK4PZUMC6JEG X-MailFrom: d.rusovac@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Add weights for weighted load balancing. Adjust existing resource scheduling test to explicitly use same weights as before. Signed-off-by: Dominik Rusovac --- .../resource_scheduling/pve_dynamic.rs | 27 +++++++++++++++---- .../resource_scheduling/pve_static.rs | 25 +++++++++++++---- pve-rs/test/resource_scheduling.pl | 3 ++- 3 files changed, 44 insertions(+), 11 deletions(-) diff --git a/pve-rs/src/bindings/resource_scheduling/pve_dynamic.rs b/pve-rs/src/bindings/resource_scheduling/pve_dynamic.rs index 8e066e0..d6b6f9b 100644 --- a/pve-rs/src/bindings/resource_scheduling/pve_dynamic.rs +++ b/pve-rs/src/bindings/resource_scheduling/pve_dynamic.rs @@ -166,10 +166,16 @@ pub mod pve_rs_resource_scheduling_dynamic { /// /// See [`proxmox_resource_scheduling::scheduler::Scheduler::node_imbalance`]. #[export] - pub fn calculate_node_imbalance(#[try_from_ref] this: &Scheduler) -> f64 { + pub fn calculate_node_imbalance( + #[try_from_ref] this: &Scheduler, + cpu_weight: usize, + mem_weight: usize, + ) -> f64 { let usage = this.inner.lock().unwrap(); - usage.to_scheduler::().node_imbalance() + usage + .to_scheduler::() + .node_imbalance(cpu_weight as f64, mem_weight as f64) } /// Method: Scores the given migration `candidates` by the best node imbalance improvement with @@ -181,6 +187,8 @@ pub mod pve_rs_resource_scheduling_dynamic { #[try_from_ref] this: &Scheduler, candidates: Vec, limit: usize, + cpu_weight: usize, + mem_weight: usize, ) -> Result, Error> { let usage = this.inner.lock().unwrap(); @@ -188,7 +196,7 @@ pub mod pve_rs_resource_scheduling_dynamic { Ok(usage .to_scheduler::() - .score_best_balancing_migration_candidates(candidates, limit)) + .score_best_balancing_migration_candidates(candidates, limit, cpu_weight, mem_weight)) } /// Method: Scores the given migration `candidates` by the best node imbalance improvement with @@ -200,6 +208,8 @@ pub mod pve_rs_resource_scheduling_dynamic { #[try_from_ref] this: &Scheduler, candidates: Vec, limit: usize, + cpu_weight: usize, + mem_weight: usize, ) -> Result, Error> { let usage = this.inner.lock().unwrap(); @@ -207,7 +217,12 @@ pub mod pve_rs_resource_scheduling_dynamic { usage .to_scheduler::() - .score_best_balancing_migration_candidates_topsis(&candidates, limit) + .score_best_balancing_migration_candidates_topsis( + &candidates, + limit, + cpu_weight, + mem_weight, + ) } /// Method: Scores nodes to start a resource with the usage statistics `resource_stats` on. @@ -217,11 +232,13 @@ pub mod pve_rs_resource_scheduling_dynamic { pub fn score_nodes_to_start_resource( #[try_from_ref] this: &Scheduler, resource_stats: DynamicResourceStats, + cpu_weight: usize, + mem_weight: usize, ) -> Result, Error> { let usage = this.inner.lock().unwrap(); usage .to_scheduler::() - .score_nodes_to_start_resource(resource_stats) + .score_nodes_to_start_resource(resource_stats, cpu_weight, mem_weight) } } diff --git a/pve-rs/src/bindings/resource_scheduling/pve_static.rs b/pve-rs/src/bindings/resource_scheduling/pve_static.rs index d83aa38..2fa8d8c 100644 --- a/pve-rs/src/bindings/resource_scheduling/pve_static.rs +++ b/pve-rs/src/bindings/resource_scheduling/pve_static.rs @@ -162,12 +162,16 @@ pub mod pve_rs_resource_scheduling_static { /// /// See [`proxmox_resource_scheduling::scheduler::Scheduler::node_imbalance`]. #[export] - pub fn calculate_node_imbalance(#[try_from_ref] this: &Scheduler) -> f64 { + pub fn calculate_node_imbalance( + #[try_from_ref] this: &Scheduler, + cpu_weight: usize, + mem_weight: usize, + ) -> f64 { let usage = this.inner.lock().unwrap(); usage .to_scheduler::() - .node_imbalance() + .node_imbalance(cpu_weight as f64, mem_weight as f64) } /// Method: Scores the given migration `candidates` by the best node imbalance improvement with @@ -179,6 +183,8 @@ pub mod pve_rs_resource_scheduling_static { #[try_from_ref] this: &Scheduler, candidates: Vec, limit: usize, + cpu_weight: usize, + mem_weight: usize, ) -> Result, Error> { let usage = this.inner.lock().unwrap(); @@ -186,7 +192,7 @@ pub mod pve_rs_resource_scheduling_static { Ok(usage .to_scheduler::() - .score_best_balancing_migration_candidates(candidates, limit)) + .score_best_balancing_migration_candidates(candidates, limit, cpu_weight, mem_weight)) } /// Method: Scores the given migration `candidates` by the best node imbalance improvement with @@ -198,6 +204,8 @@ pub mod pve_rs_resource_scheduling_static { #[try_from_ref] this: &Scheduler, candidates: Vec, limit: usize, + cpu_weight: usize, + mem_weight: usize, ) -> Result, Error> { let usage = this.inner.lock().unwrap(); @@ -205,7 +213,12 @@ pub mod pve_rs_resource_scheduling_static { usage .to_scheduler::() - .score_best_balancing_migration_candidates_topsis(&candidates, limit) + .score_best_balancing_migration_candidates_topsis( + &candidates, + limit, + cpu_weight, + mem_weight, + ) } /// Method: Scores nodes to start a service with the usage statistics `service_stats` on. @@ -215,11 +228,13 @@ pub mod pve_rs_resource_scheduling_static { pub fn score_nodes_to_start_service( #[try_from_ref] this: &Scheduler, service_stats: StaticResourceStats, + cpu_weight: usize, + mem_weight: usize, ) -> Result, Error> { let usage = this.inner.lock().unwrap(); usage .to_scheduler::() - .score_nodes_to_start_resource(service_stats) + .score_nodes_to_start_resource(service_stats, cpu_weight, mem_weight) } } diff --git a/pve-rs/test/resource_scheduling.pl b/pve-rs/test/resource_scheduling.pl index 3775242..31f2622 100755 --- a/pve-rs/test/resource_scheduling.pl +++ b/pve-rs/test/resource_scheduling.pl @@ -11,7 +11,8 @@ use PVE::RS::ResourceScheduling::Dynamic; my sub score_nodes { my ($static, $service) = @_; - my $score_list = $static->score_nodes_to_start_service($service); + # uses original empirically determined weights + my $score_list = $static->score_nodes_to_start_service($service, 1.0, 5.0); # imitate HA manager my $scores = { map { $_->[0] => -$_->[1] } $score_list->@* }; -- 2.47.3