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

google / alioth / 17016642693

17 Aug 2025 04:19AM UTC coverage: 10.406% (-0.01%) from 10.419%
17016642693

Pull #273

github

web-flow
Merge ef274b67c into 3c18ccbb6
Pull Request #273: feat: virtio packed queue

50 of 111 new or added lines in 8 files covered. (45.05%)

97 existing lines in 5 files now uncovered.

713 of 6852 relevant lines covered (10.41%)

16.14 hits per line

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

93.18
/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
#[cfg(test)]
17
#[path = "queue_test.rs"]
18
mod tests;
19

20
use std::io::{ErrorKind, IoSlice, IoSliceMut, Read, Write};
21
use std::sync::atomic::{AtomicBool, AtomicU16, AtomicU64, Ordering, fence};
22

23
use crate::virtio::{IrqSender, Result};
24

25
pub const QUEUE_SIZE_MAX: u16 = 256;
26

27
#[derive(Debug, Default)]
28
pub struct QueueReg {
29
    pub size: AtomicU16,
30
    pub desc: AtomicU64,
31
    pub driver: AtomicU64,
32
    pub device: AtomicU64,
33
    pub enabled: AtomicBool,
34
}
35

36
#[derive(Debug)]
37
pub struct DescChain<'m> {
38
    pub id: u16,
39
    pub readable: Vec<IoSlice<'m>>,
40
    pub writable: Vec<IoSliceMut<'m>>,
41
}
42

43
pub trait VirtQueue<'m> {
44
    fn reg(&self) -> &QueueReg;
45
    fn size(&self) -> u16;
46
    fn next_desc_chain(&self) -> Option<Result<DescChain<'m>>>;
47
    fn avail_index(&self) -> u16;
48
    fn get_desc_chain(&self, index: u16) -> Result<DescChain<'m>>;
49
    fn has_next_desc(&self) -> bool;
50
    fn push_used(&mut self, desc: DescChain, len: u32) -> u16;
51
    fn enable_notification(&self, enabled: bool);
52
    fn interrupt_enabled(&self) -> bool;
53

54
    fn handle_desc(
34✔
55
        &mut self,
56
        q_index: u16,
57
        irq_sender: &impl IrqSender,
58
        mut op: impl FnMut(&mut DescChain) -> Result<Option<u32>>,
59
    ) -> Result<()> {
60
        let mut send_irq = false;
66✔
61
        let mut ret = Ok(());
66✔
NEW
62
        'out: loop {
×
63
            if !self.has_next_desc() {
48✔
64
                break;
20✔
65
            }
66
            self.enable_notification(false);
50✔
67
            while let Some(chain) = self.next_desc_chain() {
64✔
68
                let mut chain = chain?;
28✔
NEW
69
                match op(&mut chain) {
6✔
70
                    Err(e) => {
6✔
71
                        ret = Err(e);
10✔
72
                        self.enable_notification(true);
10✔
73
                        break 'out;
4✔
74
                    }
75
                    Ok(None) => break 'out,
8✔
76
                    Ok(Some(len)) => {
14✔
NEW
77
                        self.push_used(chain, len);
2✔
78
                        send_irq = send_irq || self.interrupt_enabled();
14✔
79
                    }
80
                }
81
            }
82
            self.enable_notification(true);
14✔
NEW
83
            fence(Ordering::SeqCst);
2✔
84
        }
85
        if send_irq {
34✔
86
            fence(Ordering::SeqCst);
26✔
87
            irq_sender.queue_irq(q_index)
38✔
88
        }
NEW
89
        ret
2✔
90
    }
91

92
    fn copy_from_reader(
17✔
93
        &mut self,
94
        q_index: u16,
95
        irq_sender: &impl IrqSender,
96
        mut reader: impl Read,
97
    ) -> Result<()> {
98
        self.handle_desc(q_index, irq_sender, |chain| {
78✔
99
            let ret = reader.read_vectored(&mut chain.writable);
49✔
100
            match ret {
6✔
NEW
101
                Ok(0) => {
×
102
                    let size: usize = chain.writable.iter().map(|s| s.len()).sum();
12✔
103
                    if size == 0 { Ok(Some(0)) } else { Ok(None) }
5✔
104
                }
105
                Ok(len) => Ok(Some(len as u32)),
9✔
106
                Err(e) if e.kind() == ErrorKind::WouldBlock => Ok(None),
13✔
107
                Err(e) => Err(e)?,
6✔
108
            }
109
        })
110
    }
111

112
    fn copy_to_writer(
17✔
113
        &mut self,
114
        q_index: u16,
115
        irq_sender: &impl IrqSender,
116
        mut writer: impl Write,
117
    ) -> Result<()> {
118
        self.handle_desc(q_index, irq_sender, |chain| {
78✔
119
            let ret = writer.write_vectored(&chain.readable);
49✔
120
            match ret {
6✔
NEW
121
                Ok(0) => {
×
122
                    let size: usize = chain.readable.iter().map(|s| s.len()).sum();
12✔
123
                    if size == 0 { Ok(Some(0)) } else { Ok(None) }
5✔
124
                }
125
                Ok(_) => Ok(Some(0)),
5✔
126
                Err(e) if e.kind() == ErrorKind::WouldBlock => Ok(None),
13✔
127
                Err(e) => Err(e)?,
6✔
128
            }
129
        })
130
    }
131
}
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