factory_ufs: Add support for enabling per-LU WB
This change adds write booster support for devices that only support
per-LU WB, without this, such devices would have potentially 1/3rd of
the write performance.
BUG=b:433333075
TEST=chromeos-install on xol, verified dLUNumWriteBoosterBufferAllocUnits for LUN0
and fWriteBoosterEn := 0x1
Change-Id: Icb11b956b4a6d3a8359cc7b6dffd1ed379fc6b98
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/factory_installer/+/6803510
Commit-Queue: Sarthak Kukreti <sarthakkukreti@google.com>
Reviewed-by: Sarthak Kukreti <sarthakkukreti@google.com>
Tested-by: Alexis Savery <asavery@chromium.org>
Auto-Submit: Alexis Savery <asavery@chromium.org>
Tested-by: Sarthak Kukreti <sarthakkukreti@google.com>
diff --git a/rust/src/factory_ufs/action/provision.rs b/rust/src/factory_ufs/action/provision.rs
index 5196d56..c6f5bbe 100644
--- a/rust/src/factory_ufs/action/provision.rs
+++ b/rust/src/factory_ufs/action/provision.rs
@@ -249,6 +249,10 @@
}
_ => false,
};
+ let support_lu_based_buffer = match FromPrimitive::from_u32(wb_sup_wb_type) {
+ Some(SupportedWBBufferTypes::LUBased) | Some(SupportedWBBufferTypes::SupportBoth) => true,
+ _ => false,
+ };
println!(
"DEVICE_DESC.dExtendedUFSFeaturesSupport: {}",
@@ -280,6 +284,22 @@
"{} units is allocated for write booster buffer.",
wb_alloc_units
);
+ } else if support_write_booster && support_preserver_user_space && support_lu_based_buffer {
+ // Reads the GEOM_DESC.dWriteBoosterBufferMaxNAllocUnits bits.
+ // This is the maximum total write booster buffer size which is
+ // supported by the entire device.
+ let wb_max_alloc_units =
+ file_utils::read_geometry_descriptor(&sys_dev_path, "wb_max_alloc_units")?;
+ println!(
+ "GEOM_DESC.dWriteBoosterBufferMaxNAllocUnits: {}",
+ wb_max_alloc_units
+ );
+ println!("Enable LU-based write booster...");
+ let wb_alloc_units = ufs_config.enable_lu_write_booster(wb_max_alloc_units)?;
+ println!(
+ "{} units is allocated for write booster buffer.",
+ wb_alloc_units
+ );
} else {
println!("Disable write booster...");
ufs_config.disable_write_booster()?;
diff --git a/rust/src/factory_ufs/ufs/descriptor/config.rs b/rust/src/factory_ufs/ufs/descriptor/config.rs
index 4080445..44bb684 100644
--- a/rust/src/factory_ufs/ufs/descriptor/config.rs
+++ b/rust/src/factory_ufs/ufs/descriptor/config.rs
@@ -1,4 +1,4 @@
-// Copyright 2022 The ChromiumOS Authors.
+// Copyright 2022 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -7,7 +7,7 @@
use crate::factory_ufs::ufs::descriptor::common::CommonDescriptorTrait;
use crate::factory_ufs::ufs::descriptor::device::WriteBooster;
-use crate::factory_ufs::ufs::descriptor::unit::{GetUnitField, ProvisionLun};
+use crate::factory_ufs::ufs::descriptor::unit::{EnableLUWriteBooster, GetUnitField, ProvisionLun};
/// Defines the the config descriptor for UFS provisioning.
///
@@ -64,13 +64,14 @@
pub trait WriteBoosterConfig {
fn support_write_booster(&self) -> bool;
fn enable_write_booster(&mut self, wb_max_alloc_units: u32) -> Result<u32>;
+ fn enable_lu_write_booster(&mut self, wb_max_alloc_units: u32) -> Result<u32>;
fn disable_write_booster(&mut self) -> Result<()>;
}
impl<D, U> WriteBoosterConfig for ConfigDescriptor<D, U>
where
D: WriteBooster,
- U: GetUnitField,
+ U: GetUnitField + EnableLUWriteBooster,
{
fn support_write_booster(&self) -> bool {
self.device_config.support_write_booster()
@@ -81,6 +82,12 @@
.enable_write_booster(wb_max_alloc_units, self.units_config[0].get_alloc_units())
}
+ fn enable_lu_write_booster(&mut self, wb_max_alloc_units: u32) -> Result<u32> {
+ self.device_config.enable_lu_write_booster()?;
+ self.units_config[0]
+ .enable_lu_write_booster(wb_max_alloc_units, self.units_config[0].get_alloc_units())
+ }
+
fn disable_write_booster(&mut self) -> Result<()> {
self.device_config.disable_write_booster()
}
diff --git a/rust/src/factory_ufs/ufs/descriptor/device.rs b/rust/src/factory_ufs/ufs/descriptor/device.rs
index bc3a7c7..ed859a2 100644
--- a/rust/src/factory_ufs/ufs/descriptor/device.rs
+++ b/rust/src/factory_ufs/ufs/descriptor/device.rs
@@ -1,4 +1,4 @@
-// Copyright 2022 The ChromiumOS Authors.
+// Copyright 2022 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -12,6 +12,7 @@
wb_max_alloc_units: u32,
lun0_alloc_units: u32,
) -> Result<u32>;
+ fn enable_lu_write_booster(&mut self) -> Result<()>;
fn disable_write_booster(&mut self) -> Result<()>;
}
diff --git a/rust/src/factory_ufs/ufs/descriptor/unit.rs b/rust/src/factory_ufs/ufs/descriptor/unit.rs
index 39bcdd1..62f0ac0 100644
--- a/rust/src/factory_ufs/ufs/descriptor/unit.rs
+++ b/rust/src/factory_ufs/ufs/descriptor/unit.rs
@@ -1,7 +1,9 @@
-// Copyright 2022 The ChromiumOS Authors.
+// Copyright 2022 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+use anyhow::Result;
+
pub trait ProvisionLun {
fn provision_lun(&mut self, alloc_units: u32);
}
@@ -11,3 +13,11 @@
fn get_lu_enabled(&self) -> u8;
fn get_provisioning_type(&self) -> u8;
}
+
+pub trait EnableLUWriteBooster {
+ fn enable_lu_write_booster(
+ &mut self,
+ wb_max_alloc_units: u32,
+ lun0_alloc_units: u32,
+ ) -> Result<u32>;
+}
diff --git a/rust/src/factory_ufs/ufs/spec/ufs_2_1.rs b/rust/src/factory_ufs/ufs/spec/ufs_2_1.rs
index 1d320e2..704d310 100644
--- a/rust/src/factory_ufs/ufs/spec/ufs_2_1.rs
+++ b/rust/src/factory_ufs/ufs/spec/ufs_2_1.rs
@@ -8,7 +8,7 @@
use crate::factory_ufs::ufs::descriptor::common::CommonDescriptorTrait;
use crate::factory_ufs::ufs::descriptor::config::ConfigDescriptor;
use crate::factory_ufs::ufs::descriptor::device::{GetDeviceField, WriteBooster};
-use crate::factory_ufs::ufs::descriptor::unit::{GetUnitField, ProvisionLun};
+use crate::factory_ufs::ufs::descriptor::unit::{EnableLUWriteBooster, GetUnitField, ProvisionLun};
use crate::factory_ufs::ufs::spec::constants;
use crate::utils::error::Error;
@@ -79,6 +79,10 @@
anyhow::bail!(Error::NotImplementedError)
}
+ fn enable_lu_write_booster(&mut self) -> Result<()> {
+ anyhow::bail!(Error::NotImplementedError)
+ }
+
fn disable_write_booster(&mut self) -> Result<()> {
anyhow::bail!(Error::NotImplementedError)
}
@@ -139,6 +143,16 @@
}
}
+impl EnableLUWriteBooster for UnitConfigDescriptor {
+ fn enable_lu_write_booster(
+ &mut self,
+ _wb_max_alloc_units: u32,
+ _lun0_alloc_units: u32,
+ ) -> Result<u32> {
+ anyhow::bail!(Error::NotImplementedError)
+ }
+}
+
impl CommonDescriptorTrait<'_> for UnitConfigDescriptor {}
pub type UFS2ConfigDescriptor = ConfigDescriptor<DeviceConfigDescriptor, UnitConfigDescriptor>;
diff --git a/rust/src/factory_ufs/ufs/spec/ufs_3_1.rs b/rust/src/factory_ufs/ufs/spec/ufs_3_1.rs
index 620db75..f630865 100644
--- a/rust/src/factory_ufs/ufs/spec/ufs_3_1.rs
+++ b/rust/src/factory_ufs/ufs/spec/ufs_3_1.rs
@@ -1,4 +1,4 @@
-// Copyright 2022 The ChromiumOS Authors.
+// Copyright 2022 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -10,7 +10,7 @@
use crate::factory_ufs::ufs::descriptor::common::CommonDescriptorTrait;
use crate::factory_ufs::ufs::descriptor::config::ConfigDescriptor;
use crate::factory_ufs::ufs::descriptor::device::{GetDeviceField, WriteBooster};
-use crate::factory_ufs::ufs::descriptor::unit::{GetUnitField, ProvisionLun};
+use crate::factory_ufs::ufs::descriptor::unit::{EnableLUWriteBooster, GetUnitField, ProvisionLun};
use crate::factory_ufs::ufs::spec::constants;
/// Defines the config descriptor for device.
@@ -96,6 +96,13 @@
Ok(self.d_num_shared_write_booster_buffer_alloc_units)
}
+ fn enable_lu_write_booster(&mut self) -> Result<()> {
+ self.b_write_booster_buffer_preserve_user_space_en = 0x1;
+ self.b_write_booster_buffer_type = 0x0;
+ self.d_num_shared_write_booster_buffer_alloc_units = 0x0;
+ Ok(())
+ }
+
fn disable_write_booster(&mut self) -> Result<()> {
self.b_write_booster_buffer_preserve_user_space_en = 0x0;
self.b_write_booster_buffer_type = 0x0;
@@ -121,10 +128,10 @@
pub w_context_capabilities: u16,
pub reserved_empty_1: u16,
pub reserved_empty_2: u8,
- pub reserved_hpb: u16,
+ pub w_lu_max_active_hpb_regions: u16,
pub w_hpb_pinned_region_start_idx: u16,
pub w_num_hpb_pinned_regions: u16,
- pub w_lu_max_active_hpb_regions: u32,
+ pub d_lu_num_write_booster_buffer_alloc_units: u32,
}
impl Default for UnitConfigDescriptor {
@@ -141,10 +148,10 @@
w_context_capabilities: 0x0,
reserved_empty_1: 0x0,
reserved_empty_2: 0x0,
- reserved_hpb: 0x0,
+ w_lu_max_active_hpb_regions: 0x0,
w_hpb_pinned_region_start_idx: 0x0,
w_num_hpb_pinned_regions: 0x0,
- w_lu_max_active_hpb_regions: 0x0,
+ d_lu_num_write_booster_buffer_alloc_units: 0x0,
}
}
}
@@ -169,6 +176,20 @@
}
}
+impl EnableLUWriteBooster for UnitConfigDescriptor {
+ fn enable_lu_write_booster(
+ &mut self,
+ wb_max_alloc_units: u32,
+ lun0_alloc_units: u32,
+ ) -> Result<u32> {
+ // min(10% of total capacity, the maximum allowed value)
+ let ten_percent_total_alloc = lun0_alloc_units / 10;
+ self.d_lu_num_write_booster_buffer_alloc_units =
+ min(ten_percent_total_alloc, wb_max_alloc_units);
+ Ok(self.d_lu_num_write_booster_buffer_alloc_units)
+ }
+}
+
impl CommonDescriptorTrait<'_> for UnitConfigDescriptor {}
pub type UFS3ConfigDescriptor = ConfigDescriptor<DeviceConfigDescriptor, UnitConfigDescriptor>;