Skip to content
This repository was archived by the owner on Oct 24, 2022. It is now read-only.

Commit fea360e

Browse files
committed
Simplify vring lock acquisition
There are methods in which the vring lock is acquired multiple times. Instead, acquire it just once and reuse the instance through the method. Signed-off-by: Sergio Lopez <[email protected]>
1 parent 3da9056 commit fea360e

File tree

1 file changed

+28
-34
lines changed

1 file changed

+28
-34
lines changed

src/lib.rs

Lines changed: 28 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -712,9 +712,11 @@ impl<S: VhostUserBackend> VhostUserSlaveReqHandlerMut for VhostUserHandler<S> {
712712
available: u64,
713713
_log: u64,
714714
) -> VhostUserResult<()> {
715-
if index as usize >= self.num_queues {
715+
let mut vring_write = if index as usize >= self.num_queues {
716716
return Err(VhostUserError::InvalidParam);
717-
}
717+
} else {
718+
self.vrings[index as usize].write().unwrap()
719+
};
718720

719721
if !self.mappings.is_empty() {
720722
let desc_table = self.vmm_va_to_gpa(descriptor).map_err(|e| {
@@ -726,51 +728,47 @@ impl<S: VhostUserBackend> VhostUserSlaveReqHandlerMut for VhostUserHandler<S> {
726728
let used_ring = self.vmm_va_to_gpa(used).map_err(|e| {
727729
VhostUserError::ReqHandlerError(io::Error::new(io::ErrorKind::Other, e))
728730
})?;
729-
self.vrings[index as usize]
730-
.write()
731-
.unwrap()
732-
.queue
733-
.desc_table = GuestAddress(desc_table);
734-
self.vrings[index as usize]
735-
.write()
736-
.unwrap()
737-
.queue
738-
.avail_ring = GuestAddress(avail_ring);
739-
self.vrings[index as usize].write().unwrap().queue.used_ring = GuestAddress(used_ring);
731+
732+
vring_write.queue.desc_table = GuestAddress(desc_table);
733+
vring_write.queue.avail_ring = GuestAddress(avail_ring);
734+
vring_write.queue.used_ring = GuestAddress(used_ring);
735+
740736
Ok(())
741737
} else {
742738
Err(VhostUserError::InvalidParam)
743739
}
744740
}
745741

746742
fn set_vring_base(&mut self, index: u32, base: u32) -> VhostUserResult<()> {
747-
self.vrings[index as usize]
748-
.write()
749-
.unwrap()
750-
.queue
751-
.set_next_avail(base as u16);
743+
let mut vring_write = if index as usize >= self.num_queues {
744+
return Err(VhostUserError::InvalidParam);
745+
} else {
746+
self.vrings[index as usize].write().unwrap()
747+
};
748+
749+
vring_write.queue.set_next_avail(base as u16);
752750

753751
let event_idx: bool = (self.acked_features & (1 << VIRTIO_RING_F_EVENT_IDX)) != 0;
754-
self.vrings[index as usize]
755-
.write()
756-
.unwrap()
757-
.mut_queue()
758-
.set_event_idx(event_idx);
752+
vring_write.mut_queue().set_event_idx(event_idx);
759753
self.backend.write().unwrap().set_event_idx(event_idx);
754+
760755
Ok(())
761756
}
762757

763758
fn get_vring_base(&mut self, index: u32) -> VhostUserResult<VhostUserVringState> {
764-
if index as usize >= self.num_queues {
759+
let mut vring_write = if index as usize >= self.num_queues {
765760
return Err(VhostUserError::InvalidParam);
766-
}
761+
} else {
762+
self.vrings[index as usize].write().unwrap()
763+
};
764+
767765
// Quote from vhost-user specification:
768766
// Client must start ring upon receiving a kick (that is, detecting
769767
// that file descriptor is readable) on the descriptor specified by
770768
// VHOST_USER_SET_VRING_KICK, and stop ring upon receiving
771769
// VHOST_USER_GET_VRING_BASE.
772-
self.vrings[index as usize].write().unwrap().queue.ready = false;
773-
if let Some(fd) = self.vrings[index as usize].write().unwrap().kick.take() {
770+
vring_write.queue.ready = false;
771+
if let Some(fd) = vring_write.kick.take() {
774772
for (thread_index, queues_mask) in self.queues_per_thread.iter().enumerate() {
775773
let shifted_queues_mask = queues_mask >> index;
776774
if shifted_queues_mask & 1u64 == 1u64 {
@@ -787,18 +785,14 @@ impl<S: VhostUserBackend> VhostUserSlaveReqHandlerMut for VhostUserHandler<S> {
787785
}
788786
}
789787

790-
self.vrings[index as usize].write().unwrap().call = None;
788+
vring_write.call = None;
791789

792790
// Strictly speaking, we should do this upon receiving the first kick,
793791
// but it's actually easier to just do it here so we're ready in case
794792
// the vring gets re-initialized by the guest.
795-
self.vrings[index as usize].write().unwrap().queue.reset();
793+
vring_write.queue.reset();
796794

797-
let next_avail = self.vrings[index as usize]
798-
.read()
799-
.unwrap()
800-
.queue
801-
.next_avail();
795+
let next_avail = vring_write.queue.next_avail();
802796

803797
Ok(VhostUserVringState::new(index, u32::from(next_avail)))
804798
}

0 commit comments

Comments
 (0)