From b220eac0d3e735955449a973714a0cb46549b1cf Mon Sep 17 00:00:00 2001 From: John Bates Date: Mon, 14 Sep 2020 17:03:02 -0700 Subject: [PATCH] devices: gpu: add support for mesa gpu shader cache When requested with the --gpu=cache-path=/path arg, crosvm will pass it to Mesa via env var MESA_GLSL_CACHE_DIR. In addition, the cache-size will also be passed along if provided. BUG=b:168540438 TEST=run with --gpu=cache-path=/tmp,cache-size=50M and confirm that files are created in /tmp/mesa_shader_cache. Change-Id: I2525597749d654a65373a723cefeab6cf2be62d7 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2415509 Tested-by: John Bates Tested-by: kokoro Reviewed-by: David Riley --- devices/src/virtio/gpu/mod.rs | 4 ++++ seccomp/x86_64/gpu_device.policy | 8 ++++++++ src/linux.rs | 25 +++++++++++++++++++++++++ src/main.rs | 2 ++ 4 files changed, 39 insertions(+) diff --git a/devices/src/virtio/gpu/mod.rs b/devices/src/virtio/gpu/mod.rs index 924a12097d..3670900d2b 100644 --- a/devices/src/virtio/gpu/mod.rs +++ b/devices/src/virtio/gpu/mod.rs @@ -76,6 +76,8 @@ pub struct GpuParameters { #[cfg(feature = "gfxstream")] pub gfxstream_support_vulkan: bool, pub mode: GpuMode, + pub cache_path: Option, + pub cache_size: Option, } // First queue is for virtio gpu commands. Second queue is for cursor commands, which we expect @@ -101,6 +103,8 @@ impl Default for GpuParameters { #[cfg(feature = "gfxstream")] gfxstream_support_vulkan: true, mode: GpuMode::Mode3D, + cache_path: None, + cache_size: None, } } } diff --git a/seccomp/x86_64/gpu_device.policy b/seccomp/x86_64/gpu_device.policy index 2ccfd57d03..f55671475f 100644 --- a/seccomp/x86_64/gpu_device.policy +++ b/seccomp/x86_64/gpu_device.policy @@ -71,6 +71,14 @@ stat: 1 statx: 1 sysinfo: 1 +# Rules for Mesa's shader binary cache. +flock: 1 +mkdir: 1 +newfstatat: 1 +rename: 1 +setpriority: 1 +unlink: 1 + # Rules specific to AMD gpus. uname: 1 sched_setscheduler: 1 diff --git a/src/linux.rs b/src/linux.rs index 4d3abda94e..f50d0c983b 100644 --- a/src/linux.rs +++ b/src/linux.rs @@ -4,6 +4,8 @@ use std::cmp::{max, Reverse}; use std::convert::TryFrom; +#[cfg(feature = "gpu")] +use std::env; use std::error::Error as StdError; use std::ffi::CStr; use std::fmt::{self, Display}; @@ -736,6 +738,29 @@ fn create_gpu_device( jail.mount_bind(drm_dri_path, drm_dri_path, false)?; } + // Prepare GPU shader disk cache directory. + if let Some(cache_dir) = cfg + .gpu_parameters + .as_ref() + .and_then(|params| params.cache_path.as_ref()) + { + if cfg!(any(target_arch = "arm", target_arch = "aarch64")) && cfg.sandbox { + warn!("shader caching not yet supported on ARM with sandbox enabled"); + env::set_var("MESA_GLSL_CACHE_DISABLE", "true"); + } else { + env::set_var("MESA_GLSL_CACHE_DIR", cache_dir); + if let Some(cache_size) = cfg + .gpu_parameters + .as_ref() + .and_then(|params| params.cache_size.as_ref()) + { + env::set_var("MESA_GLSL_CACHE_MAX_SIZE", cache_size); + } + let shadercache_path = Path::new(cache_dir); + jail.mount_bind(shadercache_path, shadercache_path, true)?; + } + } + // If the ARM specific devices exist on the host, bind mount them in. let mali0_path = Path::new("/dev/mali0"); if mali0_path.exists() { diff --git a/src/main.rs b/src/main.rs index f4d1c46d18..af5d62bd79 100644 --- a/src/main.rs +++ b/src/main.rs @@ -322,6 +322,8 @@ fn parse_gpu_options(s: Option<&str>) -> argument::Result { ), })?; } + "cache-path" => gpu_params.cache_path = Some(v.to_string()), + "cache-size" => gpu_params.cache_size = Some(v.to_string()), "" => {} _ => { return Err(argument::Error::UnknownArgument(format!(