mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-02-06 02:25:23 +00:00
devices: block: track flush timer armed state
Rather than querying the flush timerfd state repeatedly on every write, just track the state in a variable. This avoids an extra timerfd_gettime() syscall on every write. BUG=None TEST=Verify that the flush timer still fires via strace Change-Id: I5437d26570de466f05b496d3e0dce08a521c4fde Signed-off-by: Daniel Verkamp <dverkamp@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1247443 Reviewed-by: Dylan Reid <dgreid@chromium.org>
This commit is contained in:
parent
46f70e8c16
commit
b605850bce
1 changed files with 14 additions and 5 deletions
|
@ -174,7 +174,6 @@ fn discard_write_zeroes_segment(
|
|||
#[derive(Debug)]
|
||||
enum ExecuteError {
|
||||
/// Error arming the flush timer.
|
||||
ArmingTimer(SysError),
|
||||
Flush(io::Error),
|
||||
Read {
|
||||
addr: GuestAddress,
|
||||
|
@ -208,7 +207,6 @@ enum ExecuteError {
|
|||
impl ExecuteError {
|
||||
fn status(&self) -> u8 {
|
||||
match self {
|
||||
&ExecuteError::ArmingTimer(_) => VIRTIO_BLK_S_IOERR,
|
||||
&ExecuteError::Flush(_) => VIRTIO_BLK_S_IOERR,
|
||||
&ExecuteError::Read{ .. } => VIRTIO_BLK_S_IOERR,
|
||||
&ExecuteError::Seek{ .. } => VIRTIO_BLK_S_IOERR,
|
||||
|
@ -366,6 +364,7 @@ impl Request {
|
|||
read_only: bool,
|
||||
disk: &mut T,
|
||||
flush_timer: &mut TimerFd,
|
||||
flush_timer_armed: &mut bool,
|
||||
mem: &GuestMemory,
|
||||
) -> result::Result<u32, ExecuteError> {
|
||||
// Delay after a write when the file is auto-flushed.
|
||||
|
@ -396,10 +395,11 @@ impl Request {
|
|||
sector: self.sector,
|
||||
guestmemerr: e,
|
||||
})?;
|
||||
if !flush_timer.is_armed().map_err(ExecuteError::ArmingTimer)? {
|
||||
if !*flush_timer_armed {
|
||||
flush_timer
|
||||
.reset(flush_delay, None)
|
||||
.map_err(ExecuteError::TimerFd)?;
|
||||
*flush_timer_armed = true;
|
||||
}
|
||||
}
|
||||
RequestType::Discard | RequestType::WriteZeroes => {
|
||||
|
@ -437,6 +437,7 @@ impl Request {
|
|||
RequestType::Flush => {
|
||||
disk.flush().map_err(ExecuteError::Flush)?;
|
||||
flush_timer.clear().map_err(ExecuteError::TimerFd)?;
|
||||
*flush_timer_armed = false;
|
||||
}
|
||||
RequestType::Unsupported(t) => return Err(ExecuteError::Unsupported(t)),
|
||||
};
|
||||
|
@ -454,7 +455,12 @@ struct Worker<T: DiskFile> {
|
|||
}
|
||||
|
||||
impl<T: DiskFile> Worker<T> {
|
||||
fn process_queue(&mut self, queue_index: usize, flush_timer: &mut TimerFd) -> bool {
|
||||
fn process_queue(
|
||||
&mut self,
|
||||
queue_index: usize,
|
||||
flush_timer: &mut TimerFd,
|
||||
flush_timer_armed: &mut bool,
|
||||
) -> bool {
|
||||
let queue = &mut self.queues[queue_index];
|
||||
|
||||
let mut used_desc_heads = [(0, 0); QUEUE_SIZE as usize];
|
||||
|
@ -467,6 +473,7 @@ impl<T: DiskFile> Worker<T> {
|
|||
self.read_only,
|
||||
&mut self.disk_image,
|
||||
flush_timer,
|
||||
flush_timer_armed,
|
||||
&self.mem,
|
||||
) {
|
||||
Ok(l) => {
|
||||
|
@ -521,6 +528,7 @@ impl<T: DiskFile> Worker<T> {
|
|||
return;
|
||||
}
|
||||
};
|
||||
let mut flush_timer_armed = false;
|
||||
|
||||
let poll_ctx: PollContext<Token> =
|
||||
match PollContext::new()
|
||||
|
@ -561,7 +569,8 @@ impl<T: DiskFile> Worker<T> {
|
|||
error!("failed reading queue EventFd: {:?}", e);
|
||||
break 'poll;
|
||||
}
|
||||
needs_interrupt |= self.process_queue(0, &mut flush_timer);
|
||||
needs_interrupt |=
|
||||
self.process_queue(0, &mut flush_timer, &mut flush_timer_armed);
|
||||
}
|
||||
Token::Kill => break 'poll,
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue