From 6bf0fdd1176e5f6b0143983366978399685a4964 Mon Sep 17 00:00:00 2001 From: Luke D Jones Date: Thu, 25 Mar 2021 10:24:02 +1300 Subject: [PATCH] Bugfix vfio/integrated --- CHANGELOG.md | 4 ++++ Cargo.lock | 2 +- README.md | 14 +++++++++----- asusctl/src/main.rs | 1 + daemon/Cargo.toml | 2 +- daemon/src/ctrl_gfx/error.rs | 4 ++++ daemon/src/ctrl_gfx/gfx.rs | 30 +++++++++++++++++++----------- data/asusd-ledmodes.toml | 2 +- 8 files changed, 40 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b897333..a84b0999 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +# [3.2.4] - 2021-03-24 +### Changed +- Ignore vfio-builtin error if switching to integrated + # [3.2.3] - 2021-03-24 ### Changed - Better handling of session tracking diff --git a/Cargo.lock b/Cargo.lock index 6bc6e92d..9d71ca4f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -197,7 +197,7 @@ dependencies = [ [[package]] name = "daemon" -version = "3.2.3" +version = "3.2.4" dependencies = [ "env_logger", "intel-pstate", diff --git a/README.md b/README.md index 04c29ade..9ba50571 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,10 @@ stray configs blocking nvidia modules from loading in: - `/etc/modprobe.d/` - `/usr/lib/modprope.d/` +**VFIO NOTE:** The vfio modules *must not* be compiled into the kernel, they need +to be separate modules. If you don't plan to use vfio mode then you can ignore this +otherwise you may need a custom built kernel. + ### Power management udev rule If you have installed the Nvidia driver manually you will require the @@ -89,8 +93,8 @@ If you have installed the Nvidia driver manually you will require the ### fedora and openSUSE You *may* need a file `/etc/dracut.conf.d/90-nvidia-dracut-G05.conf` installed -to stop dracut including the nvidia modules in the ramdisk. This is espeically -true if you manually installed the nvidia drivers. +to stop dracut including the nvidia modules in the ramdisk if you manually +installed the nvidia drivers. ``` # filename /etc/dracut.conf.d/90-nvidia-dracut-G05.conf @@ -122,7 +126,8 @@ If you model isn't getting the correct led modes, you can edit the file - Comet - Flash -use `cat /sys/class/dmi/id/product_name` to get details about your laptop. +use `cat /sys/class/dmi/id/product_name` to get details about your laptop. You +must restart the `asusd.service` after editing. # Keybinds @@ -152,8 +157,6 @@ Packaging and auto-builds are available [here](https://build.opensuse.org/packag Download repositories are available [here](https://download.opensuse.org/repositories/home:/luke_nukem:/asus/) -Alternatively check the releases page for f33 RPM. - --- Run `make` then `sudo make install` then reboot. @@ -208,6 +211,7 @@ can enable the user service to get basic notifications when something changes. systemctl --user enable asus-notify.service systemctl --user start asus-notify.service ``` + # OTHER ## AniMe input diff --git a/asusctl/src/main.rs b/asusctl/src/main.rs index 4f414d50..4a1ddd01 100644 --- a/asusctl/src/main.rs +++ b/asusctl/src/main.rs @@ -143,6 +143,7 @@ fn main() -> Result<(), Box> { if parsed.help { print_supported_help(&supported, &parsed); + println!("\nSee https://asus-linux.org/faq/ for additional help"); std::process::exit(1); } diff --git a/daemon/Cargo.toml b/daemon/Cargo.toml index 07f18346..b0be9293 100644 --- a/daemon/Cargo.toml +++ b/daemon/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "daemon" -version = "3.2.3" +version = "3.2.4" license = "MPL-2.0" readme = "README.md" authors = ["Luke "] diff --git a/daemon/src/ctrl_gfx/error.rs b/daemon/src/ctrl_gfx/error.rs index 9030f02f..349fb87d 100644 --- a/daemon/src/ctrl_gfx/error.rs +++ b/daemon/src/ctrl_gfx/error.rs @@ -12,6 +12,8 @@ pub enum GfxError { GsyncModeActive, VfioBuiltin, MissingModule(String), + Modprobe(String), + Command(String, std::io::Error), } impl fmt::Display for GfxError { @@ -35,6 +37,8 @@ impl fmt::Display for GfxError { "Can not switch to vfio mode if the modules are built in to kernel" ), GfxError::MissingModule(m) => write!(f, "The module {} is missing", m), + GfxError::Modprobe(detail) => write!(f, "Modprobe error: {}", detail), + GfxError::Command(func, error) => write!(f, "Command exec error: {}: {}", func, error), } } } diff --git a/daemon/src/ctrl_gfx/gfx.rs b/daemon/src/ctrl_gfx/gfx.rs index d7a978b5..9fa282b3 100644 --- a/daemon/src/ctrl_gfx/gfx.rs +++ b/daemon/src/ctrl_gfx/gfx.rs @@ -95,10 +95,8 @@ impl Reloadable for CtrlGraphics { impl CtrlGraphics { pub fn new(config: Arc>) -> std::io::Result { let bus = PciBus::new()?; - info!("GFX: Rescanning PCI bus"); bus.rescan()?; - let devs = PciDevice::all()?; let functions = |parent: &PciDevice| -> Vec { @@ -169,7 +167,6 @@ impl CtrlGraphics { config.gfx_mode = vendor; config.write(); } - // TODO: Error here } /// Associated method to get which vendor mode is set @@ -187,6 +184,7 @@ impl CtrlGraphics { Ok(buf) } + /// Some systems have a fallback service to load nouveau if nvidia fails fn toggle_fallback_service(vendor: GfxVendors) -> Result<(), RogError> { let action = if vendor == GfxVendors::Nvidia { info!("GFX: Enabling nvidia-fallback.service"); @@ -213,6 +211,7 @@ impl CtrlGraphics { Ok(()) } + /// Write the appropriate xorg config for the chosen mode fn write_xorg_conf(vendor: GfxVendors) -> Result<(), RogError> { let text = if vendor == GfxVendors::Nvidia { [PRIMARY_GPU_BEGIN, PRIMARY_GPU_NVIDIA, PRIMARY_GPU_END].concat() @@ -239,6 +238,7 @@ impl CtrlGraphics { Ok(()) } + /// Creates the full modprobe.conf required for vfio pass-through fn get_vfio_conf(devices: &[GraphicsDevice]) -> Vec { let mut vifo = MODPROBE_VFIO.to_vec(); for (d_count, dev) in devices.iter().enumerate() { @@ -303,7 +303,7 @@ impl CtrlGraphics { .map_err(|err| RogError::Command("device unbind error".into(), err)) } - fn do_driver_action(driver: &str, action: &str) -> Result<(), RogError> { + fn do_driver_action(driver: &str, action: &str) -> Result<(), GfxError> { let mut cmd = Command::new(action); cmd.arg(driver); @@ -318,7 +318,7 @@ impl CtrlGraphics { let output = cmd .output() - .map_err(|err| RogError::Command(format!("{:?}", cmd), err))?; + .map_err(|err| GfxError::Command(format!("{:?}", cmd), err))?; if !output.status.success() { if output .stderr @@ -327,7 +327,7 @@ impl CtrlGraphics { return Ok(()); } if output.stderr.ends_with("is builtin.\n".as_bytes()) { - return Err(GfxError::VfioBuiltin.into()); + return Err(GfxError::VfioBuiltin); } if output.stderr.ends_with("Permission denied\n".as_bytes()) { warn!( @@ -342,7 +342,7 @@ impl CtrlGraphics { if String::from_utf8_lossy(&output.stderr) .contains(&format!("Module {} not found", driver)) { - return Err(GfxError::MissingModule(driver.into()).into()); + return Err(GfxError::MissingModule(driver.into())); } if count >= MAX_TRIES { let msg = format!( @@ -351,7 +351,7 @@ impl CtrlGraphics { driver, String::from_utf8_lossy(&output.stderr) ); - return Err(RogError::Modprobe(msg)); + return Err(GfxError::Modprobe(msg)); } } else if output.status.success() { return Ok(()); @@ -457,7 +457,13 @@ impl CtrlGraphics { GfxVendors::Integrated => { Self::do_driver_action("nouveau", "rmmod")?; for driver in VFIO_DRIVERS.iter() { - Self::do_driver_action(driver, "rmmod")?; + Self::do_driver_action(driver, "rmmod").or_else(|err| { + if matches!(err, GfxError::VfioBuiltin) { + warn!("{}", err); + return Ok(()); + } + Err(err) + })?; } for driver in NVIDIA_DRIVERS.iter() { Self::do_driver_action(driver, "rmmod")?; @@ -468,7 +474,8 @@ impl CtrlGraphics { Ok(()) } - fn graphical_session_alive( + /// Check if the user has any graphical uiser sessions that are active or online + fn graphical_user_sessions_exist( connection: &Connection, sessions: &[SessionInfo], ) -> Result { @@ -513,7 +520,7 @@ impl CtrlGraphics { sessions = tmp; } - if !Self::graphical_session_alive(&connection, &sessions)? { + if !Self::graphical_user_sessions_exist(&connection, &sessions)? { break; } @@ -547,6 +554,7 @@ impl CtrlGraphics { Ok(format!("Graphics mode changed to {} successfully", v)) } + /// Before starting a new thread the old one *must* be cancelled fn cancel_thread(&self) { if let Ok(lock) = self.thread_kill.lock() { if let Some(tx) = lock.as_ref() { diff --git a/data/asusd-ledmodes.toml b/data/asusd-ledmodes.toml index 741250f9..23a007bd 100644 --- a/data/asusd-ledmodes.toml +++ b/data/asusd-ledmodes.toml @@ -42,7 +42,7 @@ per_key = true [[led_data]] prod_family = "ROG Strix" -board_names = ["GX531", "G512LV", "G712LV"] +board_names = ["GX531", "G512LV", "G712LV", "G712LW"] standard = ["Static", "Breathe", "Strobe", "Rainbow", "Pulse"] multizone = true per_key = false