Okay, so I'm not done with my errors yet. I've gotten to the point where reading everything works... Almost, anyway. I get a response. I ask my completion queue to start reading entries. It gets to the 256th one and then faults. I've altered my code to allocate enough space for the entire queue -- in this instance 2047 entries for both -- and it does that. But its failing to get any further than entry 256. (Obviously, there's only one response, but I can't know that for sure, so I just have it blast through the queue and ignore all non-new entries.) Here's how I go about doing that:
Code: Select all
pub(crate) fn read_new_entries(
&mut self,
entry_storage_queue: &mut MiniVec<CompletionQueueEntry>,
) {
let addr: DynamicVolBlock<u128> =
unsafe { DynamicVolBlock::new(self.addr, self.entries as usize) };
(0..self.entries as usize).for_each(|i| {
info!("Reading entry {}", i);
let entry = addr.index((self.qhead as usize) + i).read();
if entry.get_bit(112) == self.phase {
self.qhead = self.qhead.wrapping_add(1) % self.entries;
let cqe = CompletionQueueEntry {
cmdret: entry.get_bits(0..32) as u32,
_rsvd: 0,
sqhd: entry.get_bits(64..80) as u16,
sqid: entry.get_bits(80..96) as u16,
cid: entry.get_bits(96..112) as u16,
phase: entry.get_bit(112),
status: entry.get_bits(113..128) as u16,
};
entry_storage_queue.push(cqe);
}
});
self.phase = !self.phase;
}
I'm not really sure what's wrong here. I allocate my memory like this:
Code: Select all
let asqaddr = get_aligned_free_addr((size_of::<queues::SubmissionQueueEntry>() as u64)*asqsize, 4096);
let acqaddr = get_aligned_free_addr((size_of::<queues::CompletionQueueEntry>() as u64)*acqsize, 4096);
Both those variables -- asqsize and acqsize -- are calculated like so:
Code: Select all
let asqsize = if self.read_cap().get_bits(0..16) > 4095 {
0x3FFC0
} else {
self.read_cap().get_bits(0..16)
};
let acqsize = if self.read_cap().get_bits(0..16) > 4095 {
0xFFF0
} else {
self.read_cap().get_bits(0..16)
};
Any ideas as to what the problem with this is? Is my math incorrect?