Skip to content

Commit

Permalink
vsock: Move iter outside of loop in process_tx_queue.
Browse files Browse the repository at this point in the history
the iter() function is used for produce a queue iterator to iterate over the descriptors.

But usually, it shouldn't be in the while loop, which might brings more unnecessary overhead.

So move iter outside of the while loop.

Signed-off-by: Li Zebin <cutelizebin@gmail.com>
  • Loading branch information
cutelizebin committed Sep 7, 2023
1 parent be8a7ac commit ae31c18
Showing 1 changed file with 60 additions and 53 deletions.
113 changes: 60 additions & 53 deletions crates/vsock/src/vhu_vsock_thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -621,68 +621,75 @@ impl VhostUserVsockThread {
None => return Err(Error::NoMemoryConfigured),
};

while let Some(mut avail_desc) = vring
.get_mut()
.get_queue_mut()
.iter(atomic_mem.memory())
.map_err(|_| Error::IterateQueue)?
.next()
{
used_any = true;
let mem = atomic_mem.clone().memory();

let head_idx = avail_desc.head_index();
let pkt = match VsockPacket::from_tx_virtq_chain(
mem.deref(),
&mut avail_desc,
self.tx_buffer_size,
) {
Ok(pkt) => pkt,
Err(e) => {
dbg!("vsock: error reading TX packet: {:?}", e);
continue;
}
};

if self.thread_backend.send_pkt(&pkt).is_err() {
vring
.get_mut()
.get_queue_mut()
.iter(mem)
.unwrap()
.go_to_previous_position();
break;
}
let mut vring_mut = vring.get_mut();

let queue = vring_mut.get_queue_mut();

// TODO: Check if the protocol requires read length to be correct
let used_len = 0;
let mut iter_has_elemnt = true;
while iter_has_elemnt {
let queue_iter = queue
.iter(atomic_mem.memory())
.map_err(|_| Error::IterateQueue)?;

let vring = vring.clone();
let event_idx = self.event_idx;
iter_has_elemnt = false;
for mut avail_desc in queue_iter {
iter_has_elemnt = true;
used_any = true;
let mem = atomic_mem.clone().memory();

self.pool.spawn_ok(async move {
if event_idx {
if vring.add_used(head_idx, used_len as u32).is_err() {
warn!("Could not return used descriptors to ring");
let head_idx = avail_desc.head_index();
let pkt = match VsockPacket::from_tx_virtq_chain(
mem.deref(),
&mut avail_desc,
self.tx_buffer_size,
) {
Ok(pkt) => pkt,
Err(e) => {
dbg!("vsock: error reading TX packet: {:?}", e);
continue;
}
match vring.needs_notification() {
Err(_) => {
warn!("Could not check if queue needs to be notified");
vring.signal_used_queue().unwrap();
};

if self.thread_backend.send_pkt(&pkt).is_err() {
vring
.get_mut()
.get_queue_mut()
.iter(mem)
.unwrap()
.go_to_previous_position();
break;
}

// TODO: Check if the protocol requires read length to be correct
let used_len = 0;

let vring = vring.clone();
let event_idx = self.event_idx;

self.pool.spawn_ok(async move {
if event_idx {
if vring.add_used(head_idx, used_len as u32).is_err() {
warn!("Could not return used descriptors to ring");
}
Ok(needs_notification) => {
if needs_notification {
match vring.needs_notification() {
Err(_) => {
warn!("Could not check if queue needs to be notified");
vring.signal_used_queue().unwrap();
}
Ok(needs_notification) => {
if needs_notification {
vring.signal_used_queue().unwrap();
}
}
}
} else {
if vring.add_used(head_idx, used_len as u32).is_err() {
warn!("Could not return used descriptors to ring");
}
vring.signal_used_queue().unwrap();
}
} else {
if vring.add_used(head_idx, used_len as u32).is_err() {
warn!("Could not return used descriptors to ring");
}
vring.signal_used_queue().unwrap();
}
});
});
}
}

Ok(used_any)
Expand Down

0 comments on commit ae31c18

Please sign in to comment.