diff --git a/CHANGELOG.md b/CHANGELOG.md index c4df0bcb..e3480f94 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `NotifyEgpuEnable` - `MainsOnline` (This is AC, check if plugged in or not) - `NotifyMainsOnline` +- `nvidia-powerd.service` will now enable or disable depending on the AC power state + and on resume/boot (hybrid boot). It has been proven that this nvidia daemon can be + problematic when on battery, not allowing the dgpu to suspend within decent time and + sometimes blocking it completely. ### Changed - Use loops to ensure that mutex is gained for LED changes. - asusctl now uses tokio for async runtime. This helps simplify some code. @@ -30,7 +34,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `ChargeControlEndThreshold` - `SetChargeControlEndThreshold` - `NotifyChargeControlEndThreshold` - - `PanelOd` (form PanelOverdrive) +- DBUS: all panel overdrive methods renamed to: + - `PanelOd` (from PanelOverdrive) - `SetPanelOd` - `NotifyPanelOd` - Path `/org/asuslinux/Charge` changed to `/org/asuslinux/Power` diff --git a/daemon/src/ctrl_power.rs b/daemon/src/ctrl_power.rs index dab60300..9c7f1232 100644 --- a/daemon/src/ctrl_power.rs +++ b/daemon/src/ctrl_power.rs @@ -1,3 +1,4 @@ +use crate::systemd::{do_systemd_unit_action, SystemdUnitAction}; use crate::{config::Config, error::RogError, GetSupported}; use crate::{task_watch_item, CtrlTask}; use async_trait::async_trait; @@ -5,13 +6,15 @@ use log::{info, warn}; use rog_platform::power::AsusPower; use rog_platform::supported::ChargeSupportedFunctions; use std::sync::Arc; +use std::time::Duration; +use tokio::time::sleep; use zbus::dbus_interface; use zbus::export::futures_util::lock::Mutex; -use zbus::export::futures_util::StreamExt; use zbus::Connection; use zbus::SignalContext; const ZBUS_PATH: &str = "/org/asuslinux/Power"; +const NVIDIA_POWERD: &str = "nvidia-powerd.service"; impl GetSupported for CtrlPower { type A = ChargeSupportedFunctions; @@ -163,6 +166,16 @@ impl CtrlTask for CtrlPower { }) .ok(); } + if let Ok(value) = power1.power.get_online() { + let action = if value == 1 { + SystemdUnitAction::Restart + } else { + SystemdUnitAction::Stop + }; + if do_systemd_unit_action(action, NVIDIA_POWERD).is_ok() { + info!("CtrlPower task: did {action:?} on {NVIDIA_POWERD}"); + } + } }, move || {}, move || { @@ -176,6 +189,16 @@ impl CtrlTask for CtrlPower { }) .ok(); } + if let Ok(value) = power2.power.get_online() { + let action = if value == 1 { + SystemdUnitAction::Restart + } else { + SystemdUnitAction::Stop + }; + if do_systemd_unit_action(action, NVIDIA_POWERD).is_ok() { + info!("CtrlPower task: did {action:?} on {NVIDIA_POWERD}"); + } + } }, ) .await; @@ -184,25 +207,32 @@ impl CtrlTask for CtrlPower { .await?; let ctrl = self.clone(); - match ctrl.power.monitor_online() { - Ok(mut watch) => { - tokio::spawn(async move { - let mut buffer = [0; 32]; - watch - .event_stream(&mut buffer) - .unwrap() - .for_each(|_| async { - if let Ok(value) = ctrl.power.get_online() { - Self::notify_mains_online(&signal_ctxt, value == 1) - .await - .unwrap(); - } - }) - .await; - }); + dbg!("CtrlPower"); + tokio::spawn(async move { + let mut online = 10; + loop { + if let Ok(value) = ctrl.power.get_online() { + if online != value { + online = value; + let action = if value == 1 { + SystemdUnitAction::Restart + } else { + SystemdUnitAction::Stop + }; + if do_systemd_unit_action(action, NVIDIA_POWERD).is_ok() { + info!("CtrlPower task: did {action:?} on {NVIDIA_POWERD}"); + } + + Self::notify_mains_online(&signal_ctxt, value == 1) + .await + .unwrap(); + } + } + // The inotify doesn't pick up events when the kernel changes internal value + // so we need to watch it with a thread and sleep unfortunately + sleep(Duration::from_secs(1)).await; } - Err(e) => info!("inotify watch failed: {}", e), - } + }); Ok(()) } diff --git a/daemon/src/error.rs b/daemon/src/error.rs index 04b8556b..34166353 100644 --- a/daemon/src/error.rs +++ b/daemon/src/error.rs @@ -30,6 +30,9 @@ pub enum RogError { NoAuraNode, Anime(AnimeError), Platform(PlatformError), + SystemdUnitAction(String), + SystemdUnitWaitTimeout(String), + Command(String, std::io::Error), } impl fmt::Display for RogError { @@ -60,6 +63,17 @@ impl fmt::Display for RogError { RogError::NoAuraNode => write!(f, "No Aura keyboard node found"), RogError::Anime(deets) => write!(f, "AniMe Matrix error: {}", deets), RogError::Platform(deets) => write!(f, "Asus Platform error: {}", deets), + RogError::SystemdUnitAction(action) => { + write!(f, "systemd unit action {} failed", action) + } + RogError::SystemdUnitWaitTimeout(state) => { + write!( + f, + "Timed out waiting for systemd unit change {} state", + state + ) + } + RogError::Command(func, error) => write!(f, "Command exec error: {}: {}", func, error), } } } diff --git a/daemon/src/lib.rs b/daemon/src/lib.rs index 281e8d3c..d9ebd0b6 100644 --- a/daemon/src/lib.rs +++ b/daemon/src/lib.rs @@ -14,6 +14,8 @@ pub mod ctrl_profiles; /// Laptop matching to determine capabilities pub mod laptops; +pub mod systemd; + /// Fetch all supported functions for the laptop pub mod ctrl_supported;