mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2026-09-09 05:59:11 +08:00
* perf(virtiofs): batch non-DAX writeback Buffer writes in the generic page cache only after FUSE_WRITEBACK_CACHE is negotiated, then claim and submit bounded contiguous batches according to the negotiated write and page limits. Preserve Linux-compatible fsync, close, truncate, mmap, invalidation, stable EOF, redirty, short-write, and errseq behavior. Separate terminal writeback completion from generic page-cache workers so host invalidation cannot strand published Writeback pages behind its own waiters. Harden kernel-thread creation and wakeup ordering required by the new worker pools. Add exact FUSE/page-cache counters, benchmark phase reporting, focused FUSE regressions, and root-only kthread and completion-domain selftests. Validated with make kernel -j2, kernel formatting and diff checks, the completion-domain selftest, targeted close/flush coverage, and FuseExtended 69/69 in a DragonOS guest. Signed-off-by: longjin <longjin@dragonos.org> * refactor(fuse): group negotiated io limits Pass negotiated read, write, page, capability, and effective payload limits through a dedicated stats value object. This keeps the INIT statistics update cohesive and satisfies the project-wide Clippy argument-count lint enforced by make fmt without changing the negotiated values or publication ordering. Signed-off-by: longjin <longjin@dragonos.org> --------- Signed-off-by: longjin <longjin@dragonos.org>
124 lines
3.3 KiB
Rust
124 lines
3.3 KiB
Rust
use core::sync::atomic::{AtomicU64, Ordering};
|
|
|
|
#[derive(Debug, Default, Clone, Copy)]
|
|
pub struct PageCacheStatsSnapshot {
|
|
pub file_pages: u64,
|
|
pub file_mapped: u64,
|
|
pub file_dirty: u64,
|
|
pub file_writeback: u64,
|
|
pub shmem_pages: u64,
|
|
pub unevictable: u64,
|
|
pub drop_pagecache: u64,
|
|
pub read_dma_reservations: u64,
|
|
pub invalidation_launder_batches: u64,
|
|
pub invalidation_launder_pages: u64,
|
|
}
|
|
|
|
static FILE_PAGES: AtomicU64 = AtomicU64::new(0);
|
|
static FILE_MAPPED: AtomicU64 = AtomicU64::new(0);
|
|
static FILE_DIRTY: AtomicU64 = AtomicU64::new(0);
|
|
static FILE_WRITEBACK: AtomicU64 = AtomicU64::new(0);
|
|
static SHMEM_PAGES: AtomicU64 = AtomicU64::new(0);
|
|
static UNEVICTABLE: AtomicU64 = AtomicU64::new(0);
|
|
static DROP_PAGECACHE: AtomicU64 = AtomicU64::new(0);
|
|
static READ_DMA_RESERVATIONS: AtomicU64 = AtomicU64::new(0);
|
|
static INVALIDATION_LAUNDER_BATCHES: AtomicU64 = AtomicU64::new(0);
|
|
static INVALIDATION_LAUNDER_PAGES: AtomicU64 = AtomicU64::new(0);
|
|
|
|
#[inline]
|
|
pub fn inc_file_pages() {
|
|
FILE_PAGES.fetch_add(1, Ordering::Relaxed);
|
|
}
|
|
|
|
#[inline]
|
|
pub fn dec_file_pages() {
|
|
FILE_PAGES.fetch_sub(1, Ordering::Relaxed);
|
|
}
|
|
|
|
#[inline]
|
|
pub fn inc_file_mapped() {
|
|
FILE_MAPPED.fetch_add(1, Ordering::Relaxed);
|
|
}
|
|
|
|
#[inline]
|
|
pub fn dec_file_mapped() {
|
|
FILE_MAPPED.fetch_sub(1, Ordering::Relaxed);
|
|
}
|
|
|
|
#[inline]
|
|
pub fn inc_file_dirty() {
|
|
FILE_DIRTY.fetch_add(1, Ordering::Relaxed);
|
|
}
|
|
|
|
#[inline]
|
|
pub fn dec_file_dirty() {
|
|
FILE_DIRTY.fetch_sub(1, Ordering::Relaxed);
|
|
}
|
|
|
|
#[inline]
|
|
pub fn inc_file_writeback() {
|
|
FILE_WRITEBACK.fetch_add(1, Ordering::Relaxed);
|
|
}
|
|
|
|
#[inline]
|
|
pub fn dec_file_writeback() {
|
|
FILE_WRITEBACK.fetch_sub(1, Ordering::Relaxed);
|
|
}
|
|
|
|
#[inline]
|
|
pub fn inc_shmem_pages() {
|
|
SHMEM_PAGES.fetch_add(1, Ordering::Relaxed);
|
|
}
|
|
|
|
#[inline]
|
|
pub fn dec_shmem_pages() {
|
|
SHMEM_PAGES.fetch_sub(1, Ordering::Relaxed);
|
|
}
|
|
|
|
#[inline]
|
|
pub fn inc_unevictable() {
|
|
UNEVICTABLE.fetch_add(1, Ordering::Relaxed);
|
|
}
|
|
|
|
#[inline]
|
|
pub fn dec_unevictable() {
|
|
UNEVICTABLE.fetch_sub(1, Ordering::Relaxed);
|
|
}
|
|
|
|
#[inline]
|
|
pub fn inc_drop_pagecache() {
|
|
DROP_PAGECACHE.fetch_add(1, Ordering::Relaxed);
|
|
}
|
|
|
|
#[inline]
|
|
pub fn begin_read_dma_reservation() {
|
|
READ_DMA_RESERVATIONS.fetch_add(1, Ordering::AcqRel);
|
|
}
|
|
|
|
#[inline]
|
|
pub fn end_read_dma_reservation() {
|
|
READ_DMA_RESERVATIONS.fetch_sub(1, Ordering::AcqRel);
|
|
}
|
|
|
|
#[inline]
|
|
pub fn record_invalidation_launder_batch(pages: usize) {
|
|
INVALIDATION_LAUNDER_BATCHES.fetch_add(1, Ordering::Relaxed);
|
|
INVALIDATION_LAUNDER_PAGES.fetch_add(pages as u64, Ordering::Relaxed);
|
|
}
|
|
|
|
#[inline]
|
|
pub fn snapshot() -> PageCacheStatsSnapshot {
|
|
PageCacheStatsSnapshot {
|
|
file_pages: FILE_PAGES.load(Ordering::Relaxed),
|
|
file_mapped: FILE_MAPPED.load(Ordering::Relaxed),
|
|
file_dirty: FILE_DIRTY.load(Ordering::Relaxed),
|
|
file_writeback: FILE_WRITEBACK.load(Ordering::Relaxed),
|
|
shmem_pages: SHMEM_PAGES.load(Ordering::Relaxed),
|
|
unevictable: UNEVICTABLE.load(Ordering::Relaxed),
|
|
drop_pagecache: DROP_PAGECACHE.load(Ordering::Relaxed),
|
|
read_dma_reservations: READ_DMA_RESERVATIONS.load(Ordering::Acquire),
|
|
invalidation_launder_batches: INVALIDATION_LAUNDER_BATCHES.load(Ordering::Relaxed),
|
|
invalidation_launder_pages: INVALIDATION_LAUNDER_PAGES.load(Ordering::Relaxed),
|
|
}
|
|
}
|