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();
self.client // Batch into blocks of 16 fds as sendmsg() has a size limit
.lock() let mut sent_fds = 0;
.unwrap() let num_fds = event_fds.len() as u32;
.set_irqs( while sent_fds < num_fds {
irq_index, let remaining_fds = num_fds - sent_fds;
VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_TRIGGER, let count = if remaining_fds > 16 {
0, 16
event_fds.len() as u32, } else {
&fds, remaining_fds
) };
.map_err(VfioError::VfioUser)
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> { fn disable_irq(&self, irq_index: u32) -> Result<(), VfioError> {