at 25.11-pre 33 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7let 8 nvidiaEnabled = lib.elem "nvidia" config.services.xserver.videoDrivers; 9 nvidia_x11 = if nvidiaEnabled || cfg.datacenter.enable then cfg.package else null; 10 11 cfg = config.hardware.nvidia; 12 13 useOpenModules = cfg.open == true; 14 15 pCfg = cfg.prime; 16 syncCfg = pCfg.sync; 17 offloadCfg = pCfg.offload; 18 reverseSyncCfg = pCfg.reverseSync; 19 primeEnabled = syncCfg.enable || reverseSyncCfg.enable || offloadCfg.enable; 20 busIDType = lib.types.strMatching "([[:print:]]+:[0-9]{1,3}(@[0-9]{1,10})?:[0-9]{1,2}:[0-9])?"; 21 ibtSupport = useOpenModules || (nvidia_x11.ibtSupport or false); 22 settingsFormat = pkgs.formats.keyValue { }; 23in 24{ 25 options = { 26 hardware.nvidia = { 27 enabled = lib.mkOption { 28 readOnly = true; 29 type = lib.types.bool; 30 default = nvidia_x11 != null; 31 defaultText = lib.literalMD "`true` if NVIDIA support is enabled"; 32 description = "True if NVIDIA support is enabled"; 33 }; 34 datacenter.enable = lib.mkEnableOption '' 35 Data Center drivers for NVIDIA cards on a NVLink topology 36 ''; 37 datacenter.settings = lib.mkOption { 38 type = settingsFormat.type; 39 default = { 40 LOG_LEVEL = 4; 41 LOG_FILE_NAME = "/var/log/fabricmanager.log"; 42 LOG_APPEND_TO_LOG = 1; 43 LOG_FILE_MAX_SIZE = 1024; 44 LOG_USE_SYSLOG = 0; 45 DAEMONIZE = 1; 46 BIND_INTERFACE_IP = "127.0.0.1"; 47 STARTING_TCP_PORT = 16000; 48 FABRIC_MODE = 0; 49 FABRIC_MODE_RESTART = 0; 50 STATE_FILE_NAME = "/var/tmp/fabricmanager.state"; 51 FM_CMD_BIND_INTERFACE = "127.0.0.1"; 52 FM_CMD_PORT_NUMBER = 6666; 53 FM_STAY_RESIDENT_ON_FAILURES = 0; 54 ACCESS_LINK_FAILURE_MODE = 0; 55 TRUNK_LINK_FAILURE_MODE = 0; 56 NVSWITCH_FAILURE_MODE = 0; 57 ABORT_CUDA_JOBS_ON_FM_EXIT = 1; 58 }; 59 defaultText = lib.literalExpression '' 60 { 61 LOG_LEVEL=4; 62 LOG_FILE_NAME="/var/log/fabricmanager.log"; 63 LOG_APPEND_TO_LOG=1; 64 LOG_FILE_MAX_SIZE=1024; 65 LOG_USE_SYSLOG=0; 66 DAEMONIZE=1; 67 BIND_INTERFACE_IP="127.0.0.1"; 68 STARTING_TCP_PORT=16000; 69 FABRIC_MODE=0; 70 FABRIC_MODE_RESTART=0; 71 STATE_FILE_NAME="/var/tmp/fabricmanager.state"; 72 FM_CMD_BIND_INTERFACE="127.0.0.1"; 73 FM_CMD_PORT_NUMBER=6666; 74 FM_STAY_RESIDENT_ON_FAILURES=0; 75 ACCESS_LINK_FAILURE_MODE=0; 76 TRUNK_LINK_FAILURE_MODE=0; 77 NVSWITCH_FAILURE_MODE=0; 78 ABORT_CUDA_JOBS_ON_FM_EXIT=1; 79 } 80 ''; 81 description = '' 82 Additional configuration options for fabricmanager. 83 ''; 84 }; 85 86 powerManagement.enable = lib.mkEnableOption '' 87 experimental power management through systemd. For more information, see 88 the NVIDIA docs, on Chapter 21. Configuring Power Management Support 89 ''; 90 91 powerManagement.finegrained = lib.mkEnableOption '' 92 experimental power management of PRIME offload. For more information, see 93 the NVIDIA docs, on Chapter 22. PCI-Express Runtime D3 (RTD3) Power Management 94 ''; 95 96 dynamicBoost.enable = lib.mkEnableOption '' 97 dynamic Boost balances power between the CPU and the GPU for improved 98 performance on supported laptops using the nvidia-powerd daemon. For more 99 information, see the NVIDIA docs, on Chapter 23. Dynamic Boost on Linux 100 ''; 101 102 modesetting.enable = 103 lib.mkEnableOption '' 104 kernel modesetting when using the NVIDIA proprietary driver. 105 106 Enabling this fixes screen tearing when using Optimus via PRIME (see 107 {option}`hardware.nvidia.prime.sync.enable`. This is not enabled 108 by default because it is not officially supported by NVIDIA and would not 109 work with SLI. 110 111 Enabling this and using version 545 or newer of the proprietary NVIDIA 112 driver causes it to provide its own framebuffer device, which can cause 113 Wayland compositors to work when they otherwise wouldn't. 114 '' 115 // { 116 default = lib.versionAtLeast cfg.package.version "535"; 117 defaultText = lib.literalExpression "lib.versionAtLeast cfg.package.version \"535\""; 118 }; 119 120 prime.nvidiaBusId = lib.mkOption { 121 type = busIDType; 122 default = ""; 123 example = "PCI:1@0:0:0"; 124 description = '' 125 Bus ID of the NVIDIA GPU. You can find it using lspci; for example if lspci 126 shows the NVIDIA GPU at "0001:02:03.4", set this option to "PCI:2@1:3:4". 127 128 lspci might omit the PCI domain (0001 in above example) if it is zero. 129 In which case, use "@0" instead. 130 131 Please be aware that this option takes decimal address while lspci reports 132 hexadecimal address. So for device at domain "10000", use "@65536". 133 ''; 134 }; 135 136 prime.intelBusId = lib.mkOption { 137 type = busIDType; 138 default = ""; 139 example = "PCI:0@0:2:0"; 140 description = '' 141 Bus ID of the Intel GPU. You can find it using lspci; for example if lspci 142 shows the Intel GPU at "0001:02:03.4", set this option to "PCI:2@1:3:4". 143 144 lspci might omit the PCI domain (0001 in above example) if it is zero. 145 In which case, use "@0" instead. 146 147 Please be aware that this option takes decimal address while lspci reports 148 hexadecimal address. So for device at domain "10000", use "@65536". 149 ''; 150 }; 151 152 prime.amdgpuBusId = lib.mkOption { 153 type = busIDType; 154 default = ""; 155 example = "PCI:4@0:0:0"; 156 description = '' 157 Bus ID of the AMD APU. You can find it using lspci; for example if lspci 158 shows the AMD APU at "0001:02:03.4", set this option to "PCI:2@1:3:4". 159 160 lspci might omit the PCI domain (0001 in above example) if it is zero. 161 In which case, use "@0" instead. 162 163 Please be aware that this option takes decimal address while lspci reports 164 hexadecimal address. So for device at domain "10000", use "@65536". 165 ''; 166 }; 167 168 prime.sync.enable = lib.mkEnableOption '' 169 NVIDIA Optimus support using the NVIDIA proprietary driver via PRIME. 170 If enabled, the NVIDIA GPU will be always on and used for all rendering, 171 while enabling output to displays attached only to the integrated Intel/AMD 172 GPU without a multiplexer. 173 174 Note that this option only has any effect if the "nvidia" driver is specified 175 in {option}`services.xserver.videoDrivers`, and it should preferably 176 be the only driver there. 177 178 If this is enabled, then the bus IDs of the NVIDIA and Intel/AMD GPUs have to 179 be specified ({option}`hardware.nvidia.prime.nvidiaBusId` and 180 {option}`hardware.nvidia.prime.intelBusId` or 181 {option}`hardware.nvidia.prime.amdgpuBusId`). 182 183 If you enable this, you may want to also enable kernel modesetting for the 184 NVIDIA driver ({option}`hardware.nvidia.modesetting.enable`) in order 185 to prevent tearing. 186 187 Note that this configuration will only be successful when a display manager 188 for which the {option}`services.xserver.displayManager.setupCommands` 189 option is supported is used 190 ''; 191 192 prime.allowExternalGpu = lib.mkEnableOption '' 193 configuring X to allow external NVIDIA GPUs when using Prime [Reverse] sync optimus 194 ''; 195 196 prime.offload.enable = lib.mkEnableOption '' 197 render offload support using the NVIDIA proprietary driver via PRIME. 198 199 If this is enabled, then the bus IDs of the NVIDIA and Intel/AMD GPUs have to 200 be specified ({option}`hardware.nvidia.prime.nvidiaBusId` and 201 {option}`hardware.nvidia.prime.intelBusId` or 202 {option}`hardware.nvidia.prime.amdgpuBusId`) 203 ''; 204 205 prime.offload.enableOffloadCmd = lib.mkEnableOption '' 206 adding a `nvidia-offload` convenience script to {option}`environment.systemPackages` 207 for offloading programs to an nvidia device. To work, should have also enabled 208 {option}`hardware.nvidia.prime.offload.enable` or {option}`hardware.nvidia.prime.reverseSync.enable`. 209 210 Example usage `nvidia-offload sauerbraten_client` 211 ''; 212 213 prime.reverseSync.enable = lib.mkEnableOption '' 214 NVIDIA Optimus support using the NVIDIA proprietary driver via reverse 215 PRIME. If enabled, the Intel/AMD GPU will be used for all rendering, while 216 enabling output to displays attached only to the NVIDIA GPU without a 217 multiplexer. 218 219 Warning: This feature is relatively new, depending on your system this might 220 work poorly. AMD support, especially so. 221 See: https://forums.developer.nvidia.com/t/the-all-new-outputsink-feature-aka-reverse-prime/129828 222 223 Note that this option only has any effect if the "nvidia" driver is specified 224 in {option}`services.xserver.videoDrivers`, and it should preferably 225 be the only driver there. 226 227 If this is enabled, then the bus IDs of the NVIDIA and Intel/AMD GPUs have to 228 be specified ({option}`hardware.nvidia.prime.nvidiaBusId` and 229 {option}`hardware.nvidia.prime.intelBusId` or 230 {option}`hardware.nvidia.prime.amdgpuBusId`). 231 232 If you enable this, you may want to also enable kernel modesetting for the 233 NVIDIA driver ({option}`hardware.nvidia.modesetting.enable`) in order 234 to prevent tearing. 235 236 Note that this configuration will only be successful when a display manager 237 for which the {option}`services.xserver.displayManager.setupCommands` 238 option is supported is used 239 ''; 240 241 prime.reverseSync.setupCommands.enable = 242 (lib.mkEnableOption '' 243 configure the display manager to be able to use the outputs 244 attached to the NVIDIA GPU. 245 Disable in order to configure the NVIDIA GPU outputs manually using xrandr. 246 Note that this configuration will only be successful when a display manager 247 for which the {option}`services.xserver.displayManager.setupCommands` 248 option is supported is used 249 '') 250 // { 251 default = true; 252 }; 253 254 nvidiaSettings = 255 (lib.mkEnableOption '' 256 nvidia-settings, NVIDIA's GUI configuration tool 257 '') 258 // { 259 default = true; 260 }; 261 262 nvidiaPersistenced = lib.mkEnableOption '' 263 nvidia-persistenced a update for NVIDIA GPU headless mode, i.e. 264 It ensures all GPUs stay awake even during headless mode 265 ''; 266 267 forceFullCompositionPipeline = lib.mkEnableOption '' 268 forcefully the full composition pipeline. 269 This sometimes fixes screen tearing issues. 270 This has been reported to reduce the performance of some OpenGL applications and may produce issues in WebGL. 271 It also drastically increases the time the driver needs to clock down after load 272 ''; 273 274 package = lib.mkOption { 275 default = 276 config.boot.kernelPackages.nvidiaPackages."${if cfg.datacenter.enable then "dc" else "stable"}"; 277 defaultText = lib.literalExpression '' 278 config.boot.kernelPackages.nvidiaPackages."\$\{if cfg.datacenter.enable then "dc" else "stable"}" 279 ''; 280 example = "config.boot.kernelPackages.nvidiaPackages.legacy_470"; 281 description = '' 282 The NVIDIA driver package to use. 283 ''; 284 }; 285 286 open = lib.mkOption { 287 example = true; 288 description = "Whether to enable the open source NVIDIA kernel module."; 289 type = lib.types.nullOr lib.types.bool; 290 default = if lib.versionOlder nvidia_x11.version "560" then false else null; 291 defaultText = lib.literalExpression '' 292 if lib.versionOlder config.hardware.nvidia.package.version "560" then false else null 293 ''; 294 }; 295 296 gsp.enable = 297 lib.mkEnableOption '' 298 the GPU System Processor (GSP) on the video card 299 '' 300 // { 301 default = useOpenModules || lib.versionAtLeast nvidia_x11.version "555"; 302 defaultText = lib.literalExpression '' 303 config.hardware.nvidia.open == true || lib.versionAtLeast config.hardware.nvidia.package.version "555" 304 ''; 305 }; 306 307 videoAcceleration = 308 (lib.mkEnableOption '' 309 Whether video acceleration (VA-API) should be enabled. 310 '') 311 // { 312 default = true; 313 }; 314 }; 315 }; 316 317 config = 318 let 319 igpuDriver = if pCfg.intelBusId != "" then "modesetting" else "amdgpu"; 320 igpuBusId = if pCfg.intelBusId != "" then pCfg.intelBusId else pCfg.amdgpuBusId; 321 in 322 lib.mkIf cfg.enabled ( 323 lib.mkMerge [ 324 # Common 325 ({ 326 assertions = [ 327 { 328 assertion = !(nvidiaEnabled && cfg.datacenter.enable); 329 message = "You cannot configure both X11 and Data Center drivers at the same time."; 330 } 331 { 332 assertion = cfg.open != null || cfg.datacenter.enable; 333 message = '' 334 You must configure `hardware.nvidia.open` on NVIDIA driver versions >= 560. 335 It is suggested to use the open source kernel modules on Turing or later GPUs (RTX series, GTX 16xx), and the closed source modules otherwise. 336 ''; 337 } 338 ]; 339 boot = { 340 blacklistedKernelModules = [ 341 "nouveau" 342 "nvidiafb" 343 ]; 344 345 # Don't add `nvidia-uvm` to `kernelModules`, because we want 346 # `nvidia-uvm` be loaded only after the GPU device is available, i.e. after `udev` rules 347 # for `nvidia` kernel module are applied. 348 # This matters on Azure GPU instances: https://github.com/NixOS/nixpkgs/pull/267335 349 # 350 # Instead, we use `softdep` to lazily load `nvidia-uvm` kernel module 351 # after `nvidia` kernel module is loaded and `udev` rules are applied. 352 extraModprobeConfig = '' 353 softdep nvidia post: nvidia-uvm 354 ''; 355 356 # Exception is the open-source kernel module failing to load nvidia-uvm using softdep 357 # for unknown reasons. 358 # It affects CUDA: https://github.com/NixOS/nixpkgs/issues/334180 359 # Previously nvidia-uvm was explicitly loaded only when xserver was enabled: 360 # https://github.com/NixOS/nixpkgs/pull/334340/commits/4548c392862115359e50860bcf658cfa8715bde9 361 # We are now loading the module eagerly for all users of the open driver (including headless). 362 kernelModules = lib.optionals useOpenModules [ "nvidia_uvm" ]; 363 }; 364 systemd.tmpfiles.rules = lib.mkIf config.virtualisation.docker.enableNvidia [ 365 "L+ /run/nvidia-docker/bin - - - - ${nvidia_x11.bin}/origBin" 366 ]; 367 services.udev.extraRules = '' 368 # Create /dev/nvidia-uvm when the nvidia-uvm module is loaded. 369 KERNEL=="nvidia", RUN+="${pkgs.runtimeShell} -c 'mknod -m 666 /dev/nvidiactl c 195 255'" 370 KERNEL=="nvidia", RUN+="${pkgs.runtimeShell} -c 'for i in $$(cat /proc/driver/nvidia/gpus/*/information | grep Minor | cut -d \ -f 4); do mknod -m 666 /dev/nvidia$${i} c 195 $${i}; done'" 371 KERNEL=="nvidia_modeset", RUN+="${pkgs.runtimeShell} -c 'mknod -m 666 /dev/nvidia-modeset c 195 254'" 372 KERNEL=="nvidia_uvm", RUN+="${pkgs.runtimeShell} -c 'mknod -m 666 /dev/nvidia-uvm c $$(grep nvidia-uvm /proc/devices | cut -d \ -f 1) 0'" 373 KERNEL=="nvidia_uvm", RUN+="${pkgs.runtimeShell} -c 'mknod -m 666 /dev/nvidia-uvm-tools c $$(grep nvidia-uvm /proc/devices | cut -d \ -f 1) 1'" 374 ''; 375 hardware.graphics = { 376 extraPackages = [ nvidia_x11.out ]; 377 extraPackages32 = [ nvidia_x11.lib32 ]; 378 }; 379 environment.systemPackages = [ nvidia_x11.bin ]; 380 }) 381 382 # X11 383 (lib.mkIf nvidiaEnabled { 384 assertions = [ 385 { 386 assertion = primeEnabled -> pCfg.intelBusId == "" || pCfg.amdgpuBusId == ""; 387 message = "You cannot configure both an Intel iGPU and an AMD APU. Pick the one corresponding to your processor."; 388 } 389 390 { 391 assertion = offloadCfg.enableOffloadCmd -> offloadCfg.enable || reverseSyncCfg.enable; 392 message = "Offload command requires offloading or reverse prime sync to be enabled."; 393 } 394 395 { 396 assertion = 397 primeEnabled -> pCfg.nvidiaBusId != "" && (pCfg.intelBusId != "" || pCfg.amdgpuBusId != ""); 398 message = "When NVIDIA PRIME is enabled, the GPU bus IDs must be configured."; 399 } 400 401 { 402 assertion = offloadCfg.enable -> lib.versionAtLeast nvidia_x11.version "435.21"; 403 message = "NVIDIA PRIME render offload is currently only supported on versions >= 435.21."; 404 } 405 406 { 407 assertion = 408 (reverseSyncCfg.enable && pCfg.amdgpuBusId != "") -> lib.versionAtLeast nvidia_x11.version "470.0"; 409 message = "NVIDIA PRIME render offload for AMD APUs is currently only supported on versions >= 470 beta."; 410 } 411 412 { 413 assertion = !(syncCfg.enable && offloadCfg.enable); 414 message = "PRIME Sync and Offload cannot be both enabled"; 415 } 416 417 { 418 assertion = !(syncCfg.enable && reverseSyncCfg.enable); 419 message = "PRIME Sync and PRIME Reverse Sync cannot be both enabled"; 420 } 421 422 { 423 assertion = !(syncCfg.enable && cfg.powerManagement.finegrained); 424 message = "Sync precludes powering down the NVIDIA GPU."; 425 } 426 427 { 428 assertion = cfg.powerManagement.finegrained -> offloadCfg.enable; 429 message = "Fine-grained power management requires offload to be enabled."; 430 } 431 432 { 433 assertion = cfg.powerManagement.enable -> lib.versionAtLeast nvidia_x11.version "430.09"; 434 message = "Required files for driver based power management only exist on versions >= 430.09."; 435 } 436 437 { 438 assertion = cfg.gsp.enable -> (cfg.package ? firmware); 439 message = "This version of NVIDIA driver does not provide a GSP firmware."; 440 } 441 442 { 443 assertion = useOpenModules -> (cfg.package ? open); 444 message = "This version of NVIDIA driver does not provide a corresponding opensource kernel driver."; 445 } 446 447 { 448 assertion = useOpenModules -> cfg.gsp.enable; 449 message = "The GSP cannot be disabled when using the opensource kernel driver."; 450 } 451 452 { 453 assertion = cfg.dynamicBoost.enable -> lib.versionAtLeast nvidia_x11.version "510.39.01"; 454 message = "NVIDIA's Dynamic Boost feature only exists on versions >= 510.39.01"; 455 } 456 ]; 457 458 # If Optimus/PRIME is enabled, we: 459 # - Specify the configured NVIDIA GPU bus ID in the Device section for the 460 # "nvidia" driver. 461 # - Add the AllowEmptyInitialConfiguration option to the Screen section for the 462 # "nvidia" driver, in order to allow the X server to start without any outputs. 463 # - Add a separate Device section for the Intel GPU, using the "modesetting" 464 # driver and with the configured BusID. 465 # - OR add a separate Device section for the AMD APU, using the "amdgpu" 466 # driver and with the configures BusID. 467 # - Reference that Device section from the ServerLayout section as an inactive 468 # device. 469 # - Configure the display manager to run specific `xrandr` commands which will 470 # configure/enable displays connected to the Intel iGPU / AMD APU. 471 472 # reverse sync implies offloading 473 hardware.nvidia.prime.offload.enable = lib.mkDefault reverseSyncCfg.enable; 474 475 services.xserver.drivers = 476 lib.optional primeEnabled { 477 name = igpuDriver; 478 display = offloadCfg.enable; 479 modules = lib.optional (igpuDriver == "amdgpu") pkgs.xorg.xf86videoamdgpu; 480 deviceSection = 481 '' 482 BusID "${igpuBusId}" 483 '' 484 + lib.optionalString (syncCfg.enable && igpuDriver != "amdgpu") '' 485 Option "AccelMethod" "none" 486 ''; 487 } 488 ++ lib.singleton { 489 name = "nvidia"; 490 modules = [ nvidia_x11.bin ]; 491 display = !offloadCfg.enable; 492 deviceSection = 493 '' 494 Option "SidebandSocketPath" "/run/nvidia-xdriver/" 495 '' 496 + lib.optionalString primeEnabled '' 497 BusID "${pCfg.nvidiaBusId}" 498 '' 499 + lib.optionalString pCfg.allowExternalGpu '' 500 Option "AllowExternalGpus" 501 ''; 502 screenSection = 503 '' 504 Option "RandRRotation" "on" 505 '' 506 + lib.optionalString syncCfg.enable '' 507 Option "AllowEmptyInitialConfiguration" 508 '' 509 + lib.optionalString cfg.forceFullCompositionPipeline '' 510 Option "metamodes" "nvidia-auto-select +0+0 {ForceFullCompositionPipeline=On}" 511 Option "AllowIndirectGLXProtocol" "off" 512 Option "TripleBuffer" "on" 513 ''; 514 }; 515 516 services.xserver.serverLayoutSection = 517 lib.optionalString syncCfg.enable '' 518 Inactive "Device-${igpuDriver}[0]" 519 '' 520 + lib.optionalString reverseSyncCfg.enable '' 521 Inactive "Device-nvidia[0]" 522 '' 523 + lib.optionalString offloadCfg.enable '' 524 Option "AllowNVIDIAGPUScreens" 525 ''; 526 527 services.xserver.displayManager.setupCommands = 528 let 529 gpuProviderName = 530 if igpuDriver == "amdgpu" then 531 # find the name of the provider if amdgpu 532 "`${lib.getExe pkgs.xorg.xrandr} --listproviders | ${lib.getExe pkgs.gnugrep} -i AMD | ${lib.getExe pkgs.gnused} -n 's/^.*name://p'`" 533 else 534 igpuDriver; 535 providerCmdParams = 536 if syncCfg.enable then "\"${gpuProviderName}\" NVIDIA-0" else "NVIDIA-G0 \"${gpuProviderName}\""; 537 in 538 lib.optionalString 539 (syncCfg.enable || (reverseSyncCfg.enable && reverseSyncCfg.setupCommands.enable)) 540 '' 541 # Added by nvidia configuration module for Optimus/PRIME. 542 ${lib.getExe pkgs.xorg.xrandr} --setprovideroutputsource ${providerCmdParams} 543 ${lib.getExe pkgs.xorg.xrandr} --auto 544 ''; 545 546 environment.etc = { 547 "nvidia/nvidia-application-profiles-rc" = lib.mkIf nvidia_x11.useProfiles { 548 source = "${nvidia_x11.bin}/share/nvidia/nvidia-application-profiles-rc"; 549 }; 550 551 # 'nvidia_x11' installs it's files to /run/opengl-driver/... 552 "egl/egl_external_platform.d".source = "/run/opengl-driver/share/egl/egl_external_platform.d/"; 553 }; 554 555 hardware.graphics.extraPackages = lib.optional cfg.videoAcceleration pkgs.nvidia-vaapi-driver; 556 557 environment.systemPackages = 558 lib.optional cfg.nvidiaSettings nvidia_x11.settings 559 ++ lib.optional cfg.nvidiaPersistenced nvidia_x11.persistenced 560 ++ lib.optional offloadCfg.enableOffloadCmd ( 561 pkgs.writeShellScriptBin "nvidia-offload" '' 562 export __NV_PRIME_RENDER_OFFLOAD=1 563 export __NV_PRIME_RENDER_OFFLOAD_PROVIDER=NVIDIA-G0 564 export __GLX_VENDOR_LIBRARY_NAME=nvidia 565 export __VK_LAYER_NV_optimus=NVIDIA_only 566 exec "$@" 567 '' 568 ); 569 570 systemd.packages = lib.optional cfg.powerManagement.enable nvidia_x11.out; 571 572 systemd.services = 573 let 574 nvidiaService = state: { 575 description = "NVIDIA system ${state} actions"; 576 path = [ pkgs.kbd ]; 577 serviceConfig = { 578 Type = "oneshot"; 579 ExecStart = "${nvidia_x11.out}/bin/nvidia-sleep.sh '${state}'"; 580 }; 581 before = [ "systemd-${state}.service" ]; 582 requiredBy = [ "systemd-${state}.service" ]; 583 }; 584 in 585 lib.mkMerge [ 586 (lib.mkIf cfg.powerManagement.enable { 587 nvidia-suspend = nvidiaService "suspend"; 588 nvidia-hibernate = nvidiaService "hibernate"; 589 nvidia-resume = (nvidiaService "resume") // { 590 before = [ ]; 591 after = [ 592 "systemd-suspend.service" 593 "systemd-hibernate.service" 594 ]; 595 requiredBy = [ 596 "systemd-suspend.service" 597 "systemd-hibernate.service" 598 ]; 599 }; 600 }) 601 (lib.mkIf cfg.nvidiaPersistenced { 602 "nvidia-persistenced" = { 603 description = "NVIDIA Persistence Daemon"; 604 wantedBy = [ "multi-user.target" ]; 605 serviceConfig = { 606 Type = "forking"; 607 Restart = "always"; 608 PIDFile = "/var/run/nvidia-persistenced/nvidia-persistenced.pid"; 609 ExecStart = "${lib.getExe nvidia_x11.persistenced} --verbose"; 610 ExecStopPost = "${pkgs.coreutils}/bin/rm -rf /var/run/nvidia-persistenced"; 611 }; 612 }; 613 }) 614 (lib.mkIf cfg.dynamicBoost.enable { 615 "nvidia-powerd" = { 616 description = "nvidia-powerd service"; 617 path = [ 618 pkgs.util-linux # nvidia-powerd wants lscpu 619 ]; 620 wantedBy = [ "multi-user.target" ]; 621 serviceConfig = { 622 Type = "dbus"; 623 BusName = "nvidia.powerd.server"; 624 ExecStart = "${nvidia_x11.bin}/bin/nvidia-powerd"; 625 }; 626 }; 627 }) 628 ]; 629 630 services.acpid.enable = true; 631 632 services.dbus.packages = lib.optional cfg.dynamicBoost.enable nvidia_x11.bin; 633 634 hardware.firmware = lib.optional cfg.gsp.enable nvidia_x11.firmware; 635 636 systemd.tmpfiles.rules = 637 [ 638 # Remove the following log message: 639 # (WW) NVIDIA: Failed to bind sideband socket to 640 # (WW) NVIDIA: '/var/run/nvidia-xdriver-b4f69129' Permission denied 641 # 642 # https://bbs.archlinux.org/viewtopic.php?pid=1909115#p1909115 643 "d /run/nvidia-xdriver 0770 root users" 644 ] 645 ++ lib.optional (nvidia_x11.persistenced != null && config.virtualisation.docker.enableNvidia) 646 "L+ /run/nvidia-docker/extras/bin/nvidia-persistenced - - - - ${nvidia_x11.persistenced}/origBin/nvidia-persistenced"; 647 648 boot = { 649 extraModulePackages = if useOpenModules then [ nvidia_x11.open ] else [ nvidia_x11.bin ]; 650 # nvidia-uvm is required by CUDA applications. 651 kernelModules = lib.optionals config.services.xserver.enable [ 652 "nvidia" 653 "nvidia_modeset" 654 "nvidia_drm" 655 ]; 656 657 # If requested enable modesetting via kernel parameters. 658 kernelParams = 659 lib.optional (offloadCfg.enable || cfg.modesetting.enable) "nvidia-drm.modeset=1" 660 ++ lib.optional ( 661 (offloadCfg.enable || cfg.modesetting.enable) && lib.versionAtLeast nvidia_x11.version "545" 662 ) "nvidia-drm.fbdev=1" 663 ++ lib.optional cfg.powerManagement.enable "nvidia.NVreg_PreserveVideoMemoryAllocations=1" 664 ++ lib.optional useOpenModules "nvidia.NVreg_OpenRmEnableUnsupportedGpus=1" 665 ++ lib.optional (config.boot.kernelPackages.kernel.kernelAtLeast "6.2" && !ibtSupport) "ibt=off"; 666 667 # enable finegrained power management 668 extraModprobeConfig = lib.optionalString cfg.powerManagement.finegrained '' 669 options nvidia "NVreg_DynamicPowerManagement=0x02" 670 ''; 671 }; 672 services.udev.extraRules = lib.optionalString cfg.powerManagement.finegrained ( 673 lib.optionalString (lib.versionOlder config.boot.kernelPackages.kernel.version "5.5") '' 674 # Remove NVIDIA USB xHCI Host Controller devices, if present 675 ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x0c0330", ATTR{remove}="1" 676 677 # Remove NVIDIA USB Type-C UCSI devices, if present 678 ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x0c8000", ATTR{remove}="1" 679 680 # Remove NVIDIA Audio devices, if present 681 ACTION=="add", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x040300", ATTR{remove}="1" 682 '' 683 + '' 684 # Enable runtime PM for NVIDIA VGA/3D controller devices on driver bind 685 ACTION=="bind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030000", TEST=="power/control", ATTR{power/control}="auto" 686 ACTION=="bind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030200", TEST=="power/control", ATTR{power/control}="auto" 687 688 # Disable runtime PM for NVIDIA VGA/3D controller devices on driver unbind 689 ACTION=="unbind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030000", TEST=="power/control", ATTR{power/control}="on" 690 ACTION=="unbind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030200", TEST=="power/control", ATTR{power/control}="on" 691 '' 692 ); 693 }) 694 # Data Center 695 (lib.mkIf (cfg.datacenter.enable) { 696 boot.extraModulePackages = [ nvidia_x11.bin ]; 697 698 systemd = { 699 tmpfiles.rules = 700 lib.optional (nvidia_x11.persistenced != null && config.virtualisation.docker.enableNvidia) 701 "L+ /run/nvidia-docker/extras/bin/nvidia-persistenced - - - - ${nvidia_x11.persistenced}/origBin/nvidia-persistenced"; 702 703 services = lib.mkMerge [ 704 ({ 705 nvidia-fabricmanager = { 706 enable = true; 707 description = "Start NVIDIA NVLink Management"; 708 wantedBy = [ "multi-user.target" ]; 709 unitConfig.After = [ "network-online.target" ]; 710 unitConfig.Requires = [ "network-online.target" ]; 711 serviceConfig = { 712 Type = "forking"; 713 TimeoutStartSec = 240; 714 ExecStart = 715 let 716 # Since these rely on the `nvidia_x11.fabricmanager` derivation, they're 717 # unsuitable to be mentioned in the configuration defaults, but they _can_ 718 # be overridden in `cfg.datacenter.settings` if needed. 719 fabricManagerConfDefaults = { 720 TOPOLOGY_FILE_PATH = "${nvidia_x11.fabricmanager}/share/nvidia-fabricmanager/nvidia/nvswitch"; 721 DATABASE_PATH = "${nvidia_x11.fabricmanager}/share/nvidia-fabricmanager/nvidia/nvswitch"; 722 }; 723 nv-fab-conf = settingsFormat.generate "fabricmanager.conf" ( 724 fabricManagerConfDefaults // cfg.datacenter.settings 725 ); 726 in 727 "${lib.getExe nvidia_x11.fabricmanager} -c ${nv-fab-conf}"; 728 LimitCORE = "infinity"; 729 }; 730 }; 731 }) 732 (lib.mkIf cfg.nvidiaPersistenced { 733 "nvidia-persistenced" = { 734 description = "NVIDIA Persistence Daemon"; 735 wantedBy = [ "multi-user.target" ]; 736 serviceConfig = { 737 Type = "forking"; 738 Restart = "always"; 739 PIDFile = "/var/run/nvidia-persistenced/nvidia-persistenced.pid"; 740 ExecStart = "${lib.getExe nvidia_x11.persistenced} --verbose"; 741 ExecStopPost = "${pkgs.coreutils}/bin/rm -rf /var/run/nvidia-persistenced"; 742 }; 743 }; 744 }) 745 ]; 746 }; 747 748 environment.systemPackages = 749 lib.optional cfg.datacenter.enable nvidia_x11.fabricmanager 750 ++ lib.optional cfg.nvidiaPersistenced nvidia_x11.persistenced; 751 }) 752 ] 753 ); 754}