Merge with upstream 2025-06-08 2/2
7083e31d2 rutabaga_gfx: ffi: fix windows build
175474738 rutagaba: add the missing import for cfg(goldfish)
0c1f69de2 Roll recipe dependencies (trivial).
f047d43c0 Roll recipe dependencies (trivial).
8c50e5ba9 Roll recipe dependencies (trivial).
d8e388a6b Roll recipe dependencies (trivial).
9ed0cca78 Roll recipe dependencies (trivial).
754973f3a rutabaga: add host-host transfer support
4287898ca Roll recipe dependencies (trivial).
a1c0254c8 tools/testvm: Uprev testvm
https://chromium.googlesource.com/crosvm/crosvm/+log/4299752ed4614afc1593aaa536fac803eee28d53..7083e31d219cdcd57866c70144e1b39ddc008f0f
BUG=422984461
Change-Id: Idca79151eab1da3cd01db1984f96f43644ac8117
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/6629430
Bot-Commit: crosvm LUCI CI <crosvm-luci-ci-builder@crosvm-infra.iam.gserviceaccount.com>
Commit-Queue: Yuan Yao <yuanyaogoog@chromium.org>
diff --git a/OWNERS b/OWNERS
index 7a877f3..d0b875b 100644
--- a/OWNERS
+++ b/OWNERS
@@ -29,5 +29,6 @@
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
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..b14de00
--- /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 { .. }
+ )
+ }
+}