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 <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford 2021-12-10 14:17:18 +00:00
parent 35d3c1f611
commit 7444c3a0c5

View File

@ -326,17 +326,33 @@ impl Vfio for VfioUserClientWrapper {
); );
let fds: Vec<i32> = event_fds.iter().map(|e| e.as_raw_fd()).collect(); let fds: Vec<i32> = event_fds.iter().map(|e| e.as_raw_fd()).collect();
// 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 self.client
.lock() .lock()
.unwrap() .unwrap()
.set_irqs( .set_irqs(
irq_index, irq_index,
VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_TRIGGER, VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_TRIGGER,
0, sent_fds,
event_fds.len() as u32, count,
&fds, &fds[sent_fds as usize..(sent_fds + count) as usize],
) )
.map_err(VfioError::VfioUser) .map_err(VfioError::VfioUser)?;
sent_fds += count;
}
Ok(())
} }
fn disable_irq(&self, irq_index: u32) -> Result<(), VfioError> { fn disable_irq(&self, irq_index: u32) -> Result<(), VfioError> {