• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

google / alioth / 16866018918

10 Aug 2025 08:28PM UTC coverage: 7.185% (+0.04%) from 7.146%
16866018918

Pull #267

github

web-flow
Merge 58df90b46 into d49daec05
Pull Request #267: Add unit tests for mod virtio

19 of 83 new or added lines in 11 files covered. (22.89%)

43 existing lines in 1 file now uncovered.

486 of 6764 relevant lines covered (7.19%)

14.89 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/alioth/src/virtio/queue/queue.rs
1
// Copyright 2024 Google LLC
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     https://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15
pub mod split;
16

17
use std::io::{ErrorKind, IoSlice, IoSliceMut, Read, Write};
18
use std::sync::atomic::{AtomicBool, AtomicU16, AtomicU64, Ordering, fence};
19

20
use crate::virtio::{IrqSender, Result};
21

22
pub const QUEUE_SIZE_MAX: u16 = 256;
23

24
#[derive(Debug, Default)]
25
pub struct Queue {
26
    pub size: AtomicU16,
27
    pub desc: AtomicU64,
28
    pub driver: AtomicU64,
29
    pub device: AtomicU64,
30
    pub enabled: AtomicBool,
31
}
32

33
#[derive(Debug)]
34
pub struct Descriptor<'m> {
35
    pub id: u16,
36
    pub readable: Vec<IoSlice<'m>>,
37
    pub writable: Vec<IoSliceMut<'m>>,
38
}
39

40
pub trait VirtQueue<'m> {
41
    fn reg(&self) -> &Queue;
42
    fn size(&self) -> u16;
43
    fn next_desc(&self) -> Option<Result<Descriptor<'m>>>;
44
    fn avail_index(&self) -> u16;
45
    fn get_descriptor(&self, index: u16) -> Result<Descriptor<'m>>;
46
    fn has_next_desc(&self) -> bool;
47
    fn push_used(&mut self, desc: Descriptor, len: usize) -> u16;
48
    fn enable_notification(&self, enabled: bool);
49
    fn interrupt_enabled(&self) -> bool;
50

NEW
51
    fn handle_desc(
×
52
        &mut self,
53
        q_index: u16,
54
        dev_name: &str,
55
        irq_sender: &impl IrqSender,
56
        mut op: impl FnMut(&mut Descriptor) -> Result<Option<usize>>,
57
    ) -> Result<()> {
NEW
58
        let mut send_irq = false;
×
NEW
59
        'out: loop {
×
NEW
60
            if !self.has_next_desc() {
×
NEW
61
                break;
×
62
            }
NEW
63
            self.enable_notification(false);
×
NEW
64
            while let Some(desc) = self.next_desc() {
×
NEW
65
                let mut desc = desc?;
×
NEW
66
                match op(&mut desc) {
×
NEW
67
                    Err(e) => {
×
NEW
68
                        log::error!("{dev_name}: queue {q_index}: {e}");
×
NEW
69
                        self.enable_notification(true);
×
NEW
70
                        break 'out;
×
71
                    }
NEW
72
                    Ok(None) => break 'out,
×
NEW
73
                    Ok(Some(len)) => {
×
NEW
74
                        self.push_used(desc, len);
×
NEW
75
                        send_irq = send_irq || self.interrupt_enabled();
×
76
                    }
77
                }
78
            }
NEW
79
            self.enable_notification(true);
×
NEW
80
            fence(Ordering::SeqCst);
×
81
        }
NEW
82
        if send_irq {
×
NEW
83
            fence(Ordering::SeqCst);
×
NEW
84
            irq_sender.queue_irq(q_index)
×
85
        }
NEW
86
        Ok(())
×
87
    }
88

NEW
89
    fn copy_from_reader(
×
90
        &mut self,
91
        q_index: u16,
92
        dev_name: &str,
93
        irq_sender: &impl IrqSender,
94
        mut reader: impl Read,
95
    ) -> Result<()> {
NEW
96
        self.handle_desc(q_index, dev_name, irq_sender, |desc| {
×
NEW
97
            let ret = reader.read_vectored(&mut desc.writable);
×
NEW
98
            match ret {
×
NEW
99
                Ok(0) => Err(std::io::Error::from(ErrorKind::UnexpectedEof))?,
×
NEW
100
                Ok(len) => Ok(Some(len)),
×
NEW
101
                Err(e) if e.kind() == ErrorKind::WouldBlock => Ok(None),
×
NEW
102
                Err(e) => Err(e)?,
×
103
            }
104
        })
105
    }
106

NEW
107
    fn copy_to_writer(
×
108
        &mut self,
109
        q_index: u16,
110
        dev_name: &str,
111
        irq_sender: &impl IrqSender,
112
        mut writer: impl Write,
113
    ) -> Result<()> {
NEW
114
        self.handle_desc(q_index, dev_name, irq_sender, |desc| {
×
NEW
115
            let ret = writer.write_vectored(&desc.readable);
×
NEW
116
            match ret {
×
NEW
117
                Ok(0) => Err(std::io::Error::from(ErrorKind::WriteZero))?,
×
NEW
118
                Ok(len) => Ok(Some(len)),
×
NEW
119
                Err(e) if e.kind() == ErrorKind::WouldBlock => Ok(None),
×
NEW
120
                Err(e) => Err(e)?,
×
121
            }
122
        })
123
    }
124
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc