Merge branch 'fluke/vfio' into 'main'

Bugfix vfio/integrated

See merge request asus-linux/asus-nb-ctrl!41
This commit is contained in:
Luke Jones
2021-03-24 23:04:23 +00:00
8 changed files with 40 additions and 19 deletions

View File

@@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
# [3.2.4] - 2021-03-24
### Changed
- Ignore vfio-builtin error if switching to integrated
# [3.2.3] - 2021-03-24 # [3.2.3] - 2021-03-24
### Changed ### Changed
- Better handling of session tracking - Better handling of session tracking

2
Cargo.lock generated
View File

@@ -197,7 +197,7 @@ dependencies = [
[[package]] [[package]]
name = "daemon" name = "daemon"
version = "3.2.3" version = "3.2.4"
dependencies = [ dependencies = [
"env_logger", "env_logger",
"intel-pstate", "intel-pstate",

View File

@@ -81,6 +81,10 @@ stray configs blocking nvidia modules from loading in:
- `/etc/modprobe.d/` - `/etc/modprobe.d/`
- `/usr/lib/modprope.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 ### Power management udev rule
If you have installed the Nvidia driver manually you will require the 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 ### fedora and openSUSE
You *may* need a file `/etc/dracut.conf.d/90-nvidia-dracut-G05.conf` installed 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 to stop dracut including the nvidia modules in the ramdisk if you manually
true if you manually installed the nvidia drivers. installed the nvidia drivers.
``` ```
# filename /etc/dracut.conf.d/90-nvidia-dracut-G05.conf # 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 - Comet
- Flash - 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 # 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/) 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. 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 enable asus-notify.service
systemctl --user start asus-notify.service systemctl --user start asus-notify.service
``` ```
# OTHER # OTHER
## AniMe input ## AniMe input

View File

@@ -143,6 +143,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
if parsed.help { if parsed.help {
print_supported_help(&supported, &parsed); print_supported_help(&supported, &parsed);
println!("\nSee https://asus-linux.org/faq/ for additional help");
std::process::exit(1); std::process::exit(1);
} }

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "daemon" name = "daemon"
version = "3.2.3" version = "3.2.4"
license = "MPL-2.0" license = "MPL-2.0"
readme = "README.md" readme = "README.md"
authors = ["Luke <luke@ljones.dev>"] authors = ["Luke <luke@ljones.dev>"]

View File

@@ -12,6 +12,8 @@ pub enum GfxError {
GsyncModeActive, GsyncModeActive,
VfioBuiltin, VfioBuiltin,
MissingModule(String), MissingModule(String),
Modprobe(String),
Command(String, std::io::Error),
} }
impl fmt::Display for GfxError { 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" "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::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),
} }
} }
} }

View File

@@ -95,10 +95,8 @@ impl Reloadable for CtrlGraphics {
impl CtrlGraphics { impl CtrlGraphics {
pub fn new(config: Arc<Mutex<Config>>) -> std::io::Result<CtrlGraphics> { pub fn new(config: Arc<Mutex<Config>>) -> std::io::Result<CtrlGraphics> {
let bus = PciBus::new()?; let bus = PciBus::new()?;
info!("GFX: Rescanning PCI bus"); info!("GFX: Rescanning PCI bus");
bus.rescan()?; bus.rescan()?;
let devs = PciDevice::all()?; let devs = PciDevice::all()?;
let functions = |parent: &PciDevice| -> Vec<PciDevice> { let functions = |parent: &PciDevice| -> Vec<PciDevice> {
@@ -169,7 +167,6 @@ impl CtrlGraphics {
config.gfx_mode = vendor; config.gfx_mode = vendor;
config.write(); config.write();
} }
// TODO: Error here
} }
/// Associated method to get which vendor mode is set /// Associated method to get which vendor mode is set
@@ -187,6 +184,7 @@ impl CtrlGraphics {
Ok(buf) Ok(buf)
} }
/// Some systems have a fallback service to load nouveau if nvidia fails
fn toggle_fallback_service(vendor: GfxVendors) -> Result<(), RogError> { fn toggle_fallback_service(vendor: GfxVendors) -> Result<(), RogError> {
let action = if vendor == GfxVendors::Nvidia { let action = if vendor == GfxVendors::Nvidia {
info!("GFX: Enabling nvidia-fallback.service"); info!("GFX: Enabling nvidia-fallback.service");
@@ -213,6 +211,7 @@ impl CtrlGraphics {
Ok(()) Ok(())
} }
/// Write the appropriate xorg config for the chosen mode
fn write_xorg_conf(vendor: GfxVendors) -> Result<(), RogError> { fn write_xorg_conf(vendor: GfxVendors) -> Result<(), RogError> {
let text = if vendor == GfxVendors::Nvidia { let text = if vendor == GfxVendors::Nvidia {
[PRIMARY_GPU_BEGIN, PRIMARY_GPU_NVIDIA, PRIMARY_GPU_END].concat() [PRIMARY_GPU_BEGIN, PRIMARY_GPU_NVIDIA, PRIMARY_GPU_END].concat()
@@ -239,6 +238,7 @@ impl CtrlGraphics {
Ok(()) Ok(())
} }
/// Creates the full modprobe.conf required for vfio pass-through
fn get_vfio_conf(devices: &[GraphicsDevice]) -> Vec<u8> { fn get_vfio_conf(devices: &[GraphicsDevice]) -> Vec<u8> {
let mut vifo = MODPROBE_VFIO.to_vec(); let mut vifo = MODPROBE_VFIO.to_vec();
for (d_count, dev) in devices.iter().enumerate() { for (d_count, dev) in devices.iter().enumerate() {
@@ -303,7 +303,7 @@ impl CtrlGraphics {
.map_err(|err| RogError::Command("device unbind error".into(), err)) .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); let mut cmd = Command::new(action);
cmd.arg(driver); cmd.arg(driver);
@@ -318,7 +318,7 @@ impl CtrlGraphics {
let output = cmd let output = cmd
.output() .output()
.map_err(|err| RogError::Command(format!("{:?}", cmd), err))?; .map_err(|err| GfxError::Command(format!("{:?}", cmd), err))?;
if !output.status.success() { if !output.status.success() {
if output if output
.stderr .stderr
@@ -327,7 +327,7 @@ impl CtrlGraphics {
return Ok(()); return Ok(());
} }
if output.stderr.ends_with("is builtin.\n".as_bytes()) { 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()) { if output.stderr.ends_with("Permission denied\n".as_bytes()) {
warn!( warn!(
@@ -342,7 +342,7 @@ impl CtrlGraphics {
if String::from_utf8_lossy(&output.stderr) if String::from_utf8_lossy(&output.stderr)
.contains(&format!("Module {} not found", driver)) .contains(&format!("Module {} not found", driver))
{ {
return Err(GfxError::MissingModule(driver.into()).into()); return Err(GfxError::MissingModule(driver.into()));
} }
if count >= MAX_TRIES { if count >= MAX_TRIES {
let msg = format!( let msg = format!(
@@ -351,7 +351,7 @@ impl CtrlGraphics {
driver, driver,
String::from_utf8_lossy(&output.stderr) String::from_utf8_lossy(&output.stderr)
); );
return Err(RogError::Modprobe(msg)); return Err(GfxError::Modprobe(msg));
} }
} else if output.status.success() { } else if output.status.success() {
return Ok(()); return Ok(());
@@ -457,7 +457,13 @@ impl CtrlGraphics {
GfxVendors::Integrated => { GfxVendors::Integrated => {
Self::do_driver_action("nouveau", "rmmod")?; Self::do_driver_action("nouveau", "rmmod")?;
for driver in VFIO_DRIVERS.iter() { 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() { for driver in NVIDIA_DRIVERS.iter() {
Self::do_driver_action(driver, "rmmod")?; Self::do_driver_action(driver, "rmmod")?;
@@ -468,7 +474,8 @@ impl CtrlGraphics {
Ok(()) 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, connection: &Connection,
sessions: &[SessionInfo], sessions: &[SessionInfo],
) -> Result<bool, RogError> { ) -> Result<bool, RogError> {
@@ -513,7 +520,7 @@ impl CtrlGraphics {
sessions = tmp; sessions = tmp;
} }
if !Self::graphical_session_alive(&connection, &sessions)? { if !Self::graphical_user_sessions_exist(&connection, &sessions)? {
break; break;
} }
@@ -547,6 +554,7 @@ impl CtrlGraphics {
Ok(format!("Graphics mode changed to {} successfully", v)) Ok(format!("Graphics mode changed to {} successfully", v))
} }
/// Before starting a new thread the old one *must* be cancelled
fn cancel_thread(&self) { fn cancel_thread(&self) {
if let Ok(lock) = self.thread_kill.lock() { if let Ok(lock) = self.thread_kill.lock() {
if let Some(tx) = lock.as_ref() { if let Some(tx) = lock.as_ref() {

View File

@@ -42,7 +42,7 @@ per_key = true
[[led_data]] [[led_data]]
prod_family = "ROG Strix" prod_family = "ROG Strix"
board_names = ["GX531", "G512LV", "G712LV"] board_names = ["GX531", "G512LV", "G712LV", "G712LW"]
standard = ["Static", "Breathe", "Strobe", "Rainbow", "Pulse"] standard = ["Static", "Breathe", "Strobe", "Rainbow", "Pulse"]
multizone = true multizone = true
per_key = false per_key = false