From 7444c3a0c5fd30846eb7e414d73b555cd4fae50f Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Fri, 10 Dec 2021 14:17:18 +0000 Subject: [PATCH] pci: vfio_user: Batch IRQ enabling into batches of 16 The sendmsg() syscall is limited in the number of fds it can handle. This number matches that used by the vfio-user library and is conservative (since we've seen it work with 64 fds.) Fixes: #3401 Signed-off-by: Rob Bradford --- pci/src/vfio_user.rs | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/pci/src/vfio_user.rs b/pci/src/vfio_user.rs index 104691030..56b48ac2f 100644 --- a/pci/src/vfio_user.rs +++ b/pci/src/vfio_user.rs @@ -326,17 +326,33 @@ impl Vfio for VfioUserClientWrapper { ); let fds: Vec = event_fds.iter().map(|e| e.as_raw_fd()).collect(); - self.client - .lock() - .unwrap() - .set_irqs( - irq_index, - VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_TRIGGER, - 0, - event_fds.len() as u32, - &fds, - ) - .map_err(VfioError::VfioUser) + // Batch into blocks of 16 fds as sendmsg() has a size limit + let mut sent_fds = 0; + let num_fds = event_fds.len() as u32; + while sent_fds < num_fds { + let remaining_fds = num_fds - sent_fds; + let count = if remaining_fds > 16 { + 16 + } else { + remaining_fds + }; + + self.client + .lock() + .unwrap() + .set_irqs( + irq_index, + VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_TRIGGER, + sent_fds, + count, + &fds[sent_fds as usize..(sent_fds + count) as usize], + ) + .map_err(VfioError::VfioUser)?; + + sent_fds += count; + } + + Ok(()) } fn disable_irq(&self, irq_index: u32) -> Result<(), VfioError> {