Merge with upstream 2026-04-21 1/2 2e1df462c1b base: Add more safety nets for checking cpu online status 2fccff2c766 base: Consolidate vcpu properties into one unified data structure 513b08b62ac Roll recipe dependencies (trivial). 525839a1bf3 Roll recipe dependencies (trivial). 666ae802456 devices: usb: add isochronous IN transfer handler 16aebad45d6 Reland "devices: usb: add build_isochronous_transfer to trait" f407b047bee Reland "devices: usb: add methods to get max payload length" 125adf13172 devices: usb: allow triggering ring controller early 9b1952608a5 devices: usb: ensure all transfers complete before detach bf36139328b infra: Update README for luci 36a1614852d crosvm: add GuestPanic exit state for SystemEventCrash https://chromium.googlesource.com/crosvm/crosvm/+log/eec58549a5379347e51f880982e1d42f89876f02..2e1df462c1b95edef475dc8d7e210c672aca08cd BUG=b:417615888 BUG=b:499190661 BUG=498448415, 502869543 Change-Id: I0e20ac2a6dcafc91dfb9c29b13b83875ffb09b4c Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/7780039 Bot-Commit: crosvm LUCI CI <crosvm-luci-ci-builder@crosvm-infra.iam.gserviceaccount.com> Commit-Queue: Vineeth Pillai <vineethrp@google.com>
diff --git a/Cargo.lock b/Cargo.lock index 40fd01a..c6cbfb8 100644 --- a/Cargo.lock +++ b/Cargo.lock
@@ -1957,9 +1957,9 @@ [[package]] name = "mesa3d_util" -version = "0.1.76-alpha.0" +version = "0.1.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "659fee097888a000ce2412571495943fe505cd3552d751009286ae635957a284" +checksum = "61c76e90ba0bde4c5eb7c1b23d9b0b87333ce3e3db9a3f5fd44b2caae3c99358" dependencies = [ "cfg-if", "libc", @@ -2715,9 +2715,9 @@ [[package]] name = "rutabaga_gfx" -version = "0.1.76-alpha.0" +version = "0.1.76-chromeos" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "988c93caed844e77bcb3c3988d89d249408aa772702b543c980d49b6665fb5fd" +checksum = "5a806736e3d23fb7c430b67f8a3162233d98a9a34790a3f533278bcc140041af" dependencies = [ "cfg-if", "libc",
diff --git a/Cargo.toml b/Cargo.toml index 0ff3f6e..ea2da6a 100644 --- a/Cargo.toml +++ b/Cargo.toml
@@ -202,7 +202,7 @@ libc = "0.2.153" rand = "0.9.2" remain = "0.2" -rutabaga_gfx = "=0.1.76-alpha.0" +rutabaga_gfx = "0.1.76-chromeos" serde = "1.0" serde_json = "1" static_assertions = "1.1"
diff --git a/OWNERS b/OWNERS index 3c37195..f449679 100644 --- a/OWNERS +++ b/OWNERS
@@ -28,7 +28,8 @@ crosvm-luci-ci-builder@crosvm-infra.iam.gserviceaccount.com #{LAST_RESORT_SUGGESTION} # Changes to Cargo.lock will require additional reviews by the crosvm council. -per-file Cargo.lock = set noparent -per-file Cargo.lock = file:OWNERS_COUNCIL +# -- For chrome os branch, we don't need that extra approval. +# per-file Cargo.lock = set noparent +# per-file Cargo.lock = file:OWNERS_COUNCIL # OWNERS_COUNCIL file itself requires additional reviews by the crosvm council. -per-file OWNERS_COUNCIL = file:OWNERS_COUNCIL +# per-file OWNERS_COUNCIL = file:OWNERS_COUNCIL
diff --git a/base/src/sys/linux/sched.rs b/base/src/sys/linux/sched.rs index 9f0e459..6aad98a 100644 --- a/base/src/sys/linux/sched.rs +++ b/base/src/sys/linux/sched.rs
@@ -124,7 +124,7 @@ } // SAFETY: Safe because we check the return value to prctl. - let ret = unsafe { + let ret = match unsafe { prctl( PR_SCHED_CORE, PR_SCHED_CORE_CREATE, @@ -132,6 +132,14 @@ pid_type::PIDTYPE_PID as i32, // PID scopes to this thread only 0, // ignored by PR_SCHED_CORE_CREATE command ) + } { + -1 => { + // Chrome OS has an pre-upstream version of this functionality which might work. + const PR_SET_CORE_SCHED: i32 = 0x200; + // SAFETY: Safe because we check the return value to prctl. + unsafe { prctl(PR_SET_CORE_SCHED, 1) } + } + ret => ret, }; if ret == -1 { let error = Error::last();
diff --git a/common/audio_streams/Cargo.toml b/common/audio_streams/Cargo.toml index a7f2210..cce7db7 100644 --- a/common/audio_streams/Cargo.toml +++ b/common/audio_streams/Cargo.toml
@@ -9,7 +9,7 @@ [dependencies] async-trait = "0.1.36" -remain = { workspace = true } -thiserror = { workspace = true } +remain = "0.2" +thiserror = "1.0.20" futures = "0.3" -serde = { workspace = true, features = ["derive"] } +serde = { version = "1.0", features = ["derive"] }
diff --git a/profiles/benchmarks.profdata.xz b/profiles/benchmarks.profdata.xz new file mode 100644 index 0000000..49d1bc6 --- /dev/null +++ b/profiles/benchmarks.profdata.xz Binary files differ
diff --git a/vendor/chromeos/metrics/Cargo.toml b/vendor/chromeos/metrics/Cargo.toml new file mode 100644 index 0000000..48e271b --- /dev/null +++ b/vendor/chromeos/metrics/Cargo.toml
@@ -0,0 +1,14 @@ +[package] +name = "metrics_chromeos" +version = "0.1.0" +authors = ["The ChromiumOS Authors"] +edition = "2021" + +[dependencies] +anyhow = "*" +base = { path = "../../../base" } +metrics_events = { path = "../../../metrics_events" } +metrics_rs = { version="0.1.0" } +serde = { version = "1", features = ["derive"] } +sync = { path = "../../../common/sync" } +virtio_sys = { path = "../../../virtio_sys" }
diff --git a/vendor/chromeos/metrics/src/client.rs b/vendor/chromeos/metrics/src/client.rs new file mode 100644 index 0000000..4539fb5 --- /dev/null +++ b/vendor/chromeos/metrics/src/client.rs
@@ -0,0 +1,125 @@ +// Copyright 2024 The ChromiumOS Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +use base::warn; +use base::AsRawDescriptor; +use base::RawDescriptor; +use base::SendTube; +use metrics_events::MetricEventType; +use metrics_events::RecordDetails; +use sync::Mutex; + +use crate::metrics_requests::MetricsRequest; +use crate::MetricsClientDestructor; +use crate::MetricsRequestHandler; + +/// Tube connected to the metrics controller. +static CONTROLLER_TUBE: Mutex<Option<SendTube>> = Mutex::new(None); + +/// Sets the Tube where metrics are sent. Panics if called more than once. +pub fn initialize(send_tube: SendTube) { + let mut tube = CONTROLLER_TUBE.lock(); + if tube.is_some() { + // Technically we could replace tube; however: + // 1. this would EPIPE the other end. + // 2. this should never be done in production. + panic!("Attempt to initialize metrics client twice."); + } + *tube = Some(send_tube); +} + +#[cfg(test)] +pub fn force_initialize(send_tube: SendTube) { + // Safe because: + // 1. CLIENT_TUBE is guaranteed to be initialized. + // 2. Holding the lock prevents any other thread from accessing it. + let mut tube = CONTROLLER_TUBE.lock(); + *tube = Some(send_tube); +} + +pub fn push_descriptors(keep_rds: &mut Vec<RawDescriptor>) { + if let Some(tube) = CONTROLLER_TUBE.lock().as_ref() { + keep_rds.push(tube.as_raw_descriptor()); + } +} + +pub fn get_destructor() -> MetricsClientDestructor { + MetricsClientDestructor::new(|| { + // Let Tube close by going out of scope. + let _ = CONTROLLER_TUBE.lock().take(); + }) +} + +/// Returns true if the metrics client is initialized. +pub fn is_initialized() -> bool { + CONTROLLER_TUBE.lock().is_some() +} + +pub fn set_auth_token(_: &str) {} +pub fn set_graphics_api(_: &str) {} +pub fn set_package_name(_: &str) {} +pub fn merge_session_invariants(_: &[u8]) {} + +pub fn log_descriptor(event_code: MetricEventType, descriptor: i64) { + if MetricsRequestHandler::will_log_event(&event_code) { + send_request(MetricsRequest::Enum { + event_code, + sample: descriptor, + }) + } +} + +pub fn log_event(event_code: MetricEventType) { + if MetricsRequestHandler::will_log_event(&event_code) { + send_request(MetricsRequest::EventCount { event_code }) + } +} + +pub fn log_metric(event_code: MetricEventType, value: i64) { + if MetricsRequestHandler::will_log_event(&event_code) { + send_request(MetricsRequest::RegularHistogram { + event_code, + sample: value, + }) + } +} + +pub fn log_metric_with_details(event_code: MetricEventType, _: i64, _: &RecordDetails) { + if MetricsRequestHandler::will_log_event(&event_code) { + unimplemented!() + } +} + +pub fn log_histogram_metric(event_code: MetricEventType, value: i64) { + log_metric(event_code, value) +} + +pub fn log_high_frequency_descriptor_event(event_code: MetricEventType, _: i64, _: i64) { + if MetricsRequestHandler::will_log_event(&event_code) { + unimplemented!() + } +} + +pub fn log_event_with_details(event_code: MetricEventType, _: &RecordDetails) { + if MetricsRequestHandler::will_log_event(&event_code) { + unimplemented!() + } +} + +/// Sends a metrics request to the server. Does nothing if the metrics client is not initialized. +fn send_request(req: MetricsRequest) { + let controller_lock = CONTROLLER_TUBE.lock(); + match controller_lock.as_ref() { + Some(controller_tube) => { + if let Err(e) = controller_tube.send(&req) { + warn!("Failed to send metrics to metrics controller: {}", e); + } + } + None => { + warn!( + "Failed to send metrics to metrics controller because no controller Tube was set." + ); + } + } +}
diff --git a/vendor/chromeos/metrics/src/lib.rs b/vendor/chromeos/metrics/src/lib.rs new file mode 100644 index 0000000..525c091 --- /dev/null +++ b/vendor/chromeos/metrics/src/lib.rs
@@ -0,0 +1,38 @@ +// Copyright 2024 The ChromiumOS Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +//! Provides ChromeOS implementations of metrics interfaces that reports +//! UMA metrics. + +mod client; +mod metrics_requests; +mod periodic_logger; +mod request_handler; + +mod metrics_cleanup; + +use std::time::Duration; + +#[cfg(test)] +pub use client::force_initialize; +pub use client::get_destructor; +pub use client::initialize; +pub use client::is_initialized; +pub use client::log_descriptor; +pub use client::log_event; +pub use client::log_event_with_details; +pub use client::log_high_frequency_descriptor_event; +pub use client::log_histogram_metric; +pub use client::log_metric; +pub use client::log_metric_with_details; +pub use client::merge_session_invariants; +pub use client::push_descriptors; +pub use client::set_auth_token; +pub use client::set_graphics_api; +pub use client::set_package_name; +pub use metrics_cleanup::MetricsClientDestructor; +pub use periodic_logger::PeriodicLogger; +pub use request_handler::MetricsRequestHandler; + +pub const METRICS_UPLOAD_INTERVAL: Duration = Duration::from_secs(60);
diff --git a/vendor/chromeos/metrics/src/metrics_cleanup.rs b/vendor/chromeos/metrics/src/metrics_cleanup.rs new file mode 100644 index 0000000..9e9855b --- /dev/null +++ b/vendor/chromeos/metrics/src/metrics_cleanup.rs
@@ -0,0 +1,22 @@ +// Copyright 2024 The ChromiumOS Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +//! Provides a tool for metrics client cleanup which may hold global state. + +/// Ensures any cleanup necessary is performed on drop. Can be used to ensure cleanup is done +/// regardless of how the caller exits. Should be idempotent. +pub struct MetricsClientDestructor(Box<dyn FnMut()>); +impl MetricsClientDestructor { + pub fn new<T: 'static + FnMut()>(cleanup: T) -> Self { + MetricsClientDestructor(Box::new(cleanup)) + } + /// A convenience method for immediately dropping self and invoking drop logic on the contained + /// object. + pub fn cleanup(self) {} +} +impl Drop for MetricsClientDestructor { + fn drop(&mut self) { + self.0(); + } +}
diff --git a/vendor/chromeos/metrics/src/metrics_requests.rs b/vendor/chromeos/metrics/src/metrics_requests.rs new file mode 100644 index 0000000..238085c --- /dev/null +++ b/vendor/chromeos/metrics/src/metrics_requests.rs
@@ -0,0 +1,24 @@ +// Copyright 2024 The ChromiumOS Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +//! Structs used to transport log requests between client processes and the logging controller + +use metrics_events::MetricEventType; +use serde::Deserialize; +use serde::Serialize; + +#[derive(Serialize, Deserialize, Debug)] +pub enum MetricsRequest { + EventCount { + event_code: MetricEventType, + }, + Enum { + event_code: MetricEventType, + sample: i64, + }, + RegularHistogram { + event_code: MetricEventType, + sample: i64, + }, +}
diff --git a/vendor/chromeos/metrics/src/periodic_logger.rs b/vendor/chromeos/metrics/src/periodic_logger.rs new file mode 100644 index 0000000..42dfc3f --- /dev/null +++ b/vendor/chromeos/metrics/src/periodic_logger.rs
@@ -0,0 +1,28 @@ +// Copyright 2024 The ChromiumOS Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +use std::result::Result; +use std::time::Duration; + +use metrics_events::MetricEventType; + +use crate::MetricsRequestHandler; + +/// A logging struct meant for use in tracking and periodically +/// logging a single metric. The metric is aggregated over the +/// designated time period. Intended for use with high-frequency metrics. +pub struct PeriodicLogger; + +impl PeriodicLogger { + pub fn new(event_code: MetricEventType, _: Duration) -> Result<PeriodicLogger, String> { + if MetricsRequestHandler::will_log_event(&event_code) { + unimplemented!() + } + Ok(PeriodicLogger) + } + + /// Indicate the event has occurred with the given + /// value to be aggregated over the given time period. + pub fn log(&self, _: i64) {} +}
diff --git a/vendor/chromeos/metrics/src/request_handler.rs b/vendor/chromeos/metrics/src/request_handler.rs new file mode 100644 index 0000000..6aee5cb --- /dev/null +++ b/vendor/chromeos/metrics/src/request_handler.rs
@@ -0,0 +1,105 @@ +// Copyright 2024 The ChromiumOS Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +use base::error; +use base::warn; +use base::RecvTube; +use metrics_events::MetricEventType; +use metrics_rs::MetricsLibrary; +use virtio_sys::virtio_ids; + +use crate::metrics_requests::MetricsRequest; + +#[derive(Default)] +pub struct MetricsRequestHandler { + connected: bool, +} + +const K_ONE_HOUR_MS: i32 = 60 * 60 * 1000; + +fn virtio_id_to_wakeup_metric(virtio_id: u32) -> &'static str { + match virtio_id { + virtio_ids::VIRTIO_ID_NET => "Arc.Wakeup.VirtioNet", + virtio_ids::VIRTIO_ID_BLOCK => "Arc.Wakeup.VirtioBlock", + virtio_ids::VIRTIO_ID_BALLOON => "Arc.Wakeup.VirtioBalloon", + virtio_ids::VIRTIO_ID_GPU => "Arc.Wakeup.VirtioGpu", + virtio_ids::VIRTIO_ID_VSOCK => "Arc.Wakeup.VirtioVsock", + virtio_ids::VIRTIO_ID_FS => "Arc.Wakeup.VirtioFs", + virtio_ids::VIRTIO_ID_WL => "Arc.Wakeup.VirtioWayland", + _ => "Arc.Wakeup.VirtioOther", + } +} + +impl MetricsRequestHandler { + pub fn new() -> Self { + let connected = MetricsLibrary::get().is_some(); + if !connected { + error!("Failed to initialize metrics library"); + } + + MetricsRequestHandler { connected } + } + + pub fn handle_tube_readable(&self, tube: &RecvTube) { + if !self.connected { + return; + } + + let req = match tube.recv::<MetricsRequest>() { + Ok(req) => req, + Err(e) => { + warn!("unexpected error receiving agent metrics request: {}", e); + return; + } + }; + + let metrics = MetricsLibrary::get().expect("metrics disappeared"); + let mut metrics = metrics.lock().expect("poisioned lock"); + + let res = match req { + #[allow(unreachable_code, unused_variables, clippy::match_single_binding)] + MetricsRequest::Enum { event_code, sample } => { + let (name, max): (&str, i32) = match event_code { + _ => return, + }; + if sample > max as i64 { + warn!("Enum value {} too large for {}", sample, name); + return; + } + metrics.send_enum_to_uma(name, sample as i32, max) + } + #[allow(unreachable_code, unused_variables, clippy::match_single_binding)] + MetricsRequest::EventCount { event_code } => { + let name = match event_code { + _ => return, + }; + // See MetricsLibrary::SendBoolToUMA + metrics.send_enum_to_uma(name, 1, 2) + } + MetricsRequest::RegularHistogram { event_code, sample } => { + let (name, min, max, nbuckets) = match event_code { + MetricEventType::RtcWakeup => ("Arc.Wakeup.RTC", 0, K_ONE_HOUR_MS, 50), + MetricEventType::VirtioWakeup { virtio_id } => { + (virtio_id_to_wakeup_metric(virtio_id), 0, K_ONE_HOUR_MS, 50) + } + _ => return, + }; + let sample = sample.try_into().unwrap_or(i32::MAX); + metrics.send_to_uma(name, sample, min, max, nbuckets) + } + }; + if let Err(err) = res { + error!("Failed to upload metrics: {:?}", err); + } + } + + pub fn shutdown(&self) {} + + pub fn will_log_event(event_code: &MetricEventType) -> bool { + matches!( + event_code, + MetricEventType::RtcWakeup | MetricEventType::VirtioWakeup { .. } + ) + } +}