def _check_bbswitch_module(config): if config["optimus"]["switching"] == "bbswitch" and not checks.is_module_available("bbswitch"): print("WARNING : bbswitch is enabled in the configuration file but the bbswitch module does" " not seem to be available for the current kernel. Power switching will not work.\n" "You can install bbswitch for the default kernel with \"sudo pacman -S bbswitch\" or" " for all kernels with \"sudo pacman -S bbswitch-dkms\".\n")
def _load_acpi_call(): if not checks.is_module_available("acpi_call"): raise KernelSetupError("Module acpi_call not available for current kernel.") print("Loading acpi_call module") try: exec_bash("modprobe acpi_call") except BashError as e: raise KernelSetupError("Cannot load acpi_call : %s" % str(e))
def _load_bbswitch(): if not checks.is_module_available("bbswitch"): raise KernelSetupError("Module bbswitch not available for current kernel.") print("Loading bbswitch module") try: exec_bash("modprobe bbswitch") except BashError as e: raise KernelSetupError("Cannot load bbswitch : %s" % str(e))
def _check_nvidia_module(switch_mode): if switch_mode == "nvidia" and not checks.is_module_available("nvidia"): print("WARNING : the nvidia module does not seem to be available for the current kernel." " It is likely the Nvidia driver was not properly installed. GPU switching will probably fail,\n" " continue anyway ? (y/N)") confirmation = _ask_confirmation() if not confirmation: sys.exit(0)
def _set_base_state(config): _unload_nvidia_modules() _unload_nouveau() switching_mode = config["optimus"]["switching"] try: if switching_mode == "bbswitch": _load_bbswitch() elif switching_mode == "acpi_call": _load_acpi_call() except KernelSetupError as e: print( "ERROR : error loading modules for %s. Continuing anyways. Error is : %s" % (switching_mode, str(e))) if not checks.is_module_available(switching_mode): print( "%s is not available for the current kernel. Is the corresponding package installed ?" ) if checks.is_module_loaded("bbswitch"): _try_set_bbswitch_state("ON") if checks.is_module_loaded("acpi_call"): try: last_acpi_call_state = var.read_last_acpi_call_state() should_send_acpi_call = (last_acpi_call_state == "OFF") except var.VarError: should_send_acpi_call = False if should_send_acpi_call: _try_set_acpi_call_state("ON") if not pci.is_nvidia_visible(): print("Nvidia card not visible in PCI bus, rescanning") _try_rescan_pci() _try_pci_reset(config) if switching_mode == "bbswitch": _load_bbswitch() else: _unload_bbswitch() if switching_mode == "none": _try_custom_set_power_state("ON") _try_set_pci_power_state("on")
def _get_available_modules(): MODULES = [ "nouveau", "bbswitch", "acpi_call", "nvidia", "nvidia_drm", "nvidia_modeset" ] return [module for module in MODULES if checks.is_module_available(module)]
def switch_to_nvidia(config): print("Switching to Nvidia") if config["optimus"]["switching"] == "bbswitch": if not checks.is_module_available("bbswitch"): print( "Module bbswitch not available for current kernel. Skipping bbswitch power switching." ) else: # bbswitch module print("Loading bbswitch module") try: exec_bash("modprobe bbswitch") except BashError as e: raise SwitchError("Cannot load bbswitch : %s" % str(e)) # bbswitch switching print("Ordering ON via bbswitch") exec_bash("echo ON | tee /proc/acpi/bbswitch") if not checks.is_gpu_powered(): raise SwitchError("bbswitch refuses to turn ON the GPU") else: print("bbswitch reports that the GPU is ON") # Unloading nouveau print("Unloading nouveau module") try: exec_bash("modprobe -r nouveau") except BashError as e: raise SwitchError("Cannot unload nouveau : %s" % str(e)) # Nvidia modules print("Loading Nvidia modules") pat_value = {"yes": 1, "no": 0}[config["nvidia"]["PAT"]] if not checks.is_pat_available(): print( "Warning : Page Attribute Tables are not available on your system.\n" "Disabling the PAT option for Nvidia.") pat_value = 0 try: exec_bash("modprobe nvidia NVreg_UsePageAttributeTable=%d" % pat_value) if config["nvidia"]["modeset"] == "yes": exec_bash("modprobe nvidia_drm modeset=1") else: exec_bash("modprobe nvidia_drm modeset=0") except BashError as e: raise SwitchError("Cannot load Nvidia modules : %s" % str(e)) # PCI power management if config["optimus"]["pci_power_control"] == "yes": if config["optimus"]["switching"] == "bbswitch": print("bbswitch is enabled, pci_power_control option ignored.") else: try: pci.set_power_management(False) except pci.PCIError as e: print("WARNING : Cannot set PCI power management : %s" % str(e)) # Xorg configuration print("Configuring Xorg...") configure_xorg(config, mode="nvidia") # Login managers configuration print("Configuring login managers..") configure_login_managers(config, mode="nvidia")
def switch_to_intel(config): print("Switching to Intel") # Nvidia modules print("Unloading Nvidia modules") try: exec_bash("modprobe -r nvidia_drm nvidia_modeset nvidia_uvm nvidia") except BashError as e: raise SwitchError("Cannot unload Nvidia modules : %s" % str(e)) if config["optimus"]["switching"] == "bbswitch": if not checks.is_module_available("bbswitch"): print( "Module bbswitch not available for current kernel. Skipping bbswitch power switching." ) else: # Load bbswitch print("Loading bbswitch module") try: exec_bash("modprobe bbswitch") except BashError as e: raise SwitchError("Cannot load bbswitch : %s" % str(e)) # bbswitch switching print("Ordering OFF via bbswitch") exec_bash("echo OFF | tee /proc/acpi/bbswitch") if checks.is_gpu_powered(): raise SwitchError("bbswitch refuses to turn OFF the GPU") else: print("bbswitch reports that the GPU is OFF") elif config["optimus"]["switching"] == "nouveau": modeset_value = {"yes": 1, "no": 0}[config["intel"]["modeset"]] # Loading nouveau print("Loading nouveau module") try: exec_bash("modprobe nouveau modeset=%d" % modeset_value) except BashError as e: raise SwitchError("Cannot load nouveau : %s" % str(e)) else: print("Power switching backend is disabled.") # PCI power management if config["optimus"]["pci_power_control"] == "yes": if config["optimus"]["switching"] == "bbswitch": print("bbswitch is enabled, pci_power_control option ignored.") else: try: pci.set_power_management(True) except pci.PCIError as e: print("WARNING : Cannot set PCI power management : %s" % str(e)) # Xorg configuration print("Configuring Xorg...") configure_xorg(config, mode="intel") # Login managers configuration print("Configuring login managers..") configure_login_managers(config, mode="intel")
def main(): # Arguments parsing parser = argparse.ArgumentParser( description="Client program for the Optimus Manager tool.\n" "https://github.com/Askannz/optimus-manager") parser.add_argument('-v', '--version', action='store_true', help='Print version and exit.') parser.add_argument('--print-mode', action='store_true', help="Print the current mode.") parser.add_argument( '--switch', metavar='MODE', action='store', help="Set the GPU mode to MODE and restart the display manager. " "Possible modes : intel, nvidia, auto (checks the current mode and switch to the other). " "WARNING : All your applications will close ! Be sure to save your work." ) parser.add_argument( '--set-startup', metavar='STARTUP_MODE', action='store', help="Set the startup mode to STARTUP_MODE. Possible modes : " "intel, nvidia, nvidia_once (starts with Nvidia and reverts to Intel for the next boot)" ) parser.add_argument('--print-startup', action='store_true', help="Print the current startup mode.") parser.add_argument( '--no-confirm', action='store_true', help="Do not ask for confirmation before switching GPUs.") parser.add_argument( '--cleanup', action='store_true', help= "Remove auto-generated configuration files left over by the daemon.") args = parser.parse_args() # Config loading if not args.version: try: config = load_config() except ConfigError as e: print("Error loading config file : %s" % str(e)) sys.exit(1) # # Arguments switch if args.version: print("Optimus Manager (Client) version %s" % envs.VERSION) sys.exit(0) elif args.print_mode: try: mode = checks.read_gpu_mode() except checks.CheckError as e: print("Error reading mode : %s" % str(e)) sys.exit(1) print("Current mode : %s" % mode) elif args.print_startup: try: startup_mode = var.read_startup_mode() except var.VarError as e: print("Error reading startup mode : %s" % str(e)) sys.exit(1) print("Current startup mode : %s" % startup_mode) elif args.switch: if args.switch not in ["auto", "intel", "nvidia"]: print("Invalid mode : %s" % args.switch) sys.exit(1) if not checks.is_daemon_active(): print( "The optimus-manager service is not running. Please enable and start it with :\n\n" "sudo systemctl enable optimus-manager\n" "sudo systemctl start optimus-manager\n") sys.exit(1) if args.switch == "auto": try: gpu_mode = checks.read_gpu_mode() except checks.CheckError as e: print("Error reading mode: %s" % str(e)) sys.exit(1) if gpu_mode == "nvidia": switch_mode = "intel" else: switch_mode = "nvidia" print("Switching to : %s" % switch_mode) else: switch_mode = args.switch # Printing warnings if something is wrong if config["optimus"][ "switching"] == "bbswitch" and not checks.is_module_available( "bbswitch"): print( "WARNING : bbswitch is enabled in the configuration file but the bbswitch module does" " not seem to be available for the current kernel. Power switching will not work.\n" "You can install bbswitch for the default kernel with \"sudo pacman -S bbswitch\" or" " for all kernels with \"sudo pacman -S bbswitch-dkms\".\n") if switch_mode == "nvidia" and not checks.is_module_available( "nvidia"): print( "WARNING : the nvidia module does not seem to be available for the current kernel." " It is likely the Nvidia driver was not properly installed. GPU switching will probably fail," " continue anyway ? (y/N)") ans = input("> ").lower() if ans == "y": pass elif ans == "n" or ans == "N": print("Aborting.") sys.exit(0) else: print("Invalid choice. Aborting") sys.exit(0) if args.no_confirm: send_command(switch_mode) else: print( "You are about to switch GPUs. This will restart the display manager and all your applications WILL CLOSE.\n" "(you can pass the --no-confirm option to disable this warning)\n" "Continue ? (y/N)") ans = input("> ").lower() if ans == "y": send_command(switch_mode) elif ans == "n" or ans == "N": print("Aborting.") sys.exit(0) else: print("Invalid choice. Aborting") sys.exit(0) elif args.set_startup: if args.set_startup not in ["intel", "nvidia", "nvidia_once"]: print("Invalid startup mode : %s" % args.set_startup) sys.exit(1) send_command("startup_" + args.set_startup) elif args.cleanup: if os.geteuid() != 0: print("You need to execute the command as root for this action.") sys.exit(1) clean_autogenerated() var.remove_startup_mode_var() var.remove_requested_mode_var() else: print("Invalid arguments.")
def _setup_intel_mode(config): # Resetting the Nvidia card to its base state _set_base_state(config) # Handling power switching according to the switching backend if config["optimus"]["switching"] == "nouveau": try: _load_nouveau(config) except KernelSetupError as e: print("ERROR : cannot load nouveau. Moving on. Error is : %s" % str(e)) elif config["optimus"]["switching"] == "bbswitch": if not checks.is_module_available("bbswitch"): print( "ERROR : module bbswitch is not available for the current kernel." " Is bbswitch or bbswitch-dkms installed ? Moving on...") else: try: _load_bbswitch() except KernelSetupError as e: print( "ERROR : cannot load bbswitch. Moving on. Error is : %s" % str(e)) else: if config["optimus"]["pci_remove"] == "yes": pci.remove_nvidia() _set_bbswitch_state("OFF") elif config["optimus"]["switching"] == "acpi_call": if not checks.is_module_available("acpi_call"): print( "ERROR : module acpi_call is not available for the current kernel." " Is acpi_call or acpi_call-dkms installed ? Moving on...") else: try: _load_acpi_call() except KernelSetupError as e: print( "ERROR : cannot load acpi_call. Moving on. Error is : %s" % str(e)) else: if config["optimus"]["pci_remove"] == "yes": pci.remove_nvidia() _set_acpi_call_state("OFF") elif config["optimus"]["switching"] == "none": pass # Handling PCI power control if config["optimus"]["pci_power_control"] == "yes": if config["optimus"]["switching"] == "bbswitch": print("bbswitch is enabled, pci_power_control option ignored.") elif config["optimus"]["switching"] == "acpi_call": print("acpi_call is enabled, pci_power_control option ignored.") else: pci.set_power_state("auto")