Skip to content

Commit c0e9e78

Browse files
committed
replacing custom AlignedBuffers with aligned-vec
1 parent 8ba2211 commit c0e9e78

File tree

1 file changed

+37
-77
lines changed
  • lib/llm/src/block_manager/storage

1 file changed

+37
-77
lines changed

lib/llm/src/block_manager/storage/disk.rs

Lines changed: 37 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
use super::*;
55

6+
use aligned_vec::{AVec, ConstAlign};
67
use anyhow::Context;
78
use core::ffi::c_char;
89
use nix::fcntl::{FallocateFlags, fallocate};
@@ -34,69 +35,30 @@ impl SystemAccessible for DiskStorage {}
3435
const ZERO_BUF_SIZE: usize = 16 * 1024 * 1024; // 16MB
3536
const PAGE_SIZE: usize = 4096; // Standard page size for O_DIRECT alignment
3637

37-
/// A page-aligned buffer for O_DIRECT I/O operations.
38+
// Type alias for 4096-byte (page size) aligned vectors
39+
type Align4096 = ConstAlign<4096>;
40+
41+
/// Create a page-aligned zero-filled buffer for O_DIRECT I/O operations.
3842
/// On filesystems like Lustre, O_DIRECT requires both buffer address and I/O size
3943
/// to be aligned to the filesystem block size (typically page size).
40-
struct AlignedBuffer {
41-
ptr: *mut u8,
42-
layout: std::alloc::Layout,
43-
len: usize,
44-
}
45-
46-
impl AlignedBuffer {
47-
/// Create a new page-aligned zero-filled buffer.
48-
/// Size will be rounded up to the nearest page boundary.
49-
fn new(size: usize) -> anyhow::Result<Self> {
50-
// Round up to nearest page size to ensure alignment requirements
51-
let aligned_size = size.div_ceil(PAGE_SIZE) * PAGE_SIZE;
52-
53-
let layout = std::alloc::Layout::from_size_align(aligned_size, PAGE_SIZE)
54-
.context("Failed to create aligned layout")?;
55-
56-
let ptr = unsafe { std::alloc::alloc_zeroed(layout) };
57-
58-
if ptr.is_null() {
59-
anyhow::bail!(
60-
"Failed to allocate aligned buffer of {} bytes",
61-
aligned_size
62-
);
63-
}
64-
65-
tracing::trace!(
66-
"Allocated aligned buffer: size={}, aligned_size={}, align={}",
67-
size,
68-
aligned_size,
69-
PAGE_SIZE
70-
);
71-
72-
Ok(Self {
73-
ptr,
74-
layout,
75-
len: aligned_size,
76-
})
77-
}
78-
79-
fn as_slice(&self) -> &[u8] {
80-
unsafe { std::slice::from_raw_parts(self.ptr, self.len) }
81-
}
82-
83-
fn len(&self) -> usize {
84-
self.len
85-
}
44+
fn create_aligned_buffer(size: usize) -> anyhow::Result<AVec<u8, Align4096>> {
45+
// Round up to nearest page size to ensure alignment requirements
46+
let aligned_size = size.div_ceil(PAGE_SIZE) * PAGE_SIZE;
47+
48+
// Create aligned vector with compile-time PAGE_SIZE alignment
49+
let mut buf = AVec::<u8, Align4096>::new(PAGE_SIZE);
50+
buf.resize(aligned_size, 0u8); // Zero-fill
51+
52+
tracing::trace!(
53+
"Allocated aligned buffer: size={}, aligned_size={}, align={}",
54+
size,
55+
aligned_size,
56+
PAGE_SIZE
57+
);
58+
59+
Ok(buf)
8660
}
8761

88-
impl Drop for AlignedBuffer {
89-
fn drop(&mut self) {
90-
unsafe {
91-
std::alloc::dealloc(self.ptr, self.layout);
92-
}
93-
}
94-
}
95-
96-
// Safety: AlignedBuffer owns its memory and is safe to send between threads
97-
unsafe impl Send for AlignedBuffer {}
98-
unsafe impl Sync for AlignedBuffer {}
99-
10062
fn allocate_file(fd: RawFd, size: u64) -> anyhow::Result<()> {
10163
match fallocate(fd, FallocateFlags::empty(), 0, size as i64) {
10264
Ok(_) => {
@@ -115,9 +77,8 @@ fn allocate_file(fd: RawFd, size: u64) -> anyhow::Result<()> {
11577
);
11678

11779
// Use page-aligned buffer for O_DIRECT compatibility (required on Lustre)
118-
let buf = AlignedBuffer::new(ZERO_BUF_SIZE)
80+
let buf = create_aligned_buffer(ZERO_BUF_SIZE)
11981
.context("Failed to allocate aligned zero buffer")?;
120-
let buf_slice = buf.as_slice();
12182

12283
let mut file =
12384
unsafe { File::from_raw_fd(nix::unistd::dup(fd).context("dup error")?) };
@@ -137,7 +98,7 @@ fn allocate_file(fd: RawFd, size: u64) -> anyhow::Result<()> {
13798
std::cmp::min(aligned, buf.len())
13899
};
139100

140-
match file.write(&buf_slice[..to_write]) {
101+
match file.write(&buf[..to_write]) {
141102
Ok(n) => {
142103
if n != to_write {
143104
tracing::error!(
@@ -177,7 +138,7 @@ fn allocate_file(fd: RawFd, size: u64) -> anyhow::Result<()> {
177138
to_write,
178139
written,
179140
size,
180-
buf_slice.as_ptr(),
141+
buf.as_ptr(),
181142
PAGE_SIZE
182143
);
183144

@@ -524,7 +485,7 @@ mod tests {
524485
}
525486
}
526487

527-
/// Test that AlignedBuffer satisfies strict O_DIRECT requirements.
488+
/// Test that aligned buffers satisfy strict O_DIRECT requirements.
528489
#[test]
529490
fn test_aligned_buffer_with_strict_writer() {
530491
let test_sizes = vec![
@@ -536,16 +497,17 @@ mod tests {
536497
];
537498

538499
for requested_size in test_sizes {
539-
let buf = AlignedBuffer::new(requested_size).expect("Failed to create aligned buffer");
500+
let buf =
501+
create_aligned_buffer(requested_size).expect("Failed to create aligned buffer");
540502

541503
let mut writer = StrictODirectWriter::new();
542504

543-
// This should succeed - AlignedBuffer meets strict requirements
544-
let result = writer.write(buf.as_slice());
505+
// This should succeed - aligned buffer meets strict requirements
506+
let result = writer.write(&buf[..]);
545507

546508
assert!(
547509
result.is_ok(),
548-
"AlignedBuffer write failed for size {}: {:?}",
510+
"Aligned buffer write failed for size {}: {:?}",
549511
requested_size,
550512
result.err()
551513
);
@@ -593,7 +555,7 @@ mod tests {
593555
];
594556

595557
for total_size in test_sizes {
596-
let buf = AlignedBuffer::new(ZERO_BUF_SIZE).expect("Failed to create buffer");
558+
let buf = create_aligned_buffer(ZERO_BUF_SIZE).expect("Failed to create buffer");
597559

598560
let mut writer = StrictODirectWriter::new();
599561
let mut written: u64 = 0;
@@ -609,14 +571,12 @@ mod tests {
609571
};
610572

611573
// This should always succeed with our aligned buffer
612-
writer
613-
.write_all(&buf.as_slice()[..to_write])
614-
.unwrap_or_else(|e| {
615-
panic!(
616-
"Write failed at offset {} for total size {}: {:?}",
617-
written, total_size, e
618-
)
619-
});
574+
writer.write_all(&buf[..to_write]).unwrap_or_else(|e| {
575+
panic!(
576+
"Write failed at offset {} for total size {}: {:?}",
577+
written, total_size, e
578+
)
579+
});
620580

621581
written += to_write as u64;
622582
}

0 commit comments

Comments
 (0)