From 5c2af3e3082081dff175c175e4b009e74466b1ef Mon Sep 17 00:00:00 2001 From: David Gibson Date: Tue, 13 Apr 2021 13:52:18 +1000 Subject: [PATCH] runtime/device: Refactor hotplugVFIODevice() to have common exit path hotplugVFIODevice() has several different paths depending if we're plugging into a root port or a PCIE<->PCI bridge and if we're using a regular or mediated VFIO device. We're going to want some common code on the successful exit path here, so refactor the function to allow that without duplication. Signed-off-by: David Gibson --- src/runtime/virtcontainers/qemu.go | 55 ++++++++++++++++-------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/src/runtime/virtcontainers/qemu.go b/src/runtime/virtcontainers/qemu.go index 48252a0b5..fd48ad639 100644 --- a/src/runtime/virtcontainers/qemu.go +++ b/src/runtime/virtcontainers/qemu.go @@ -1474,39 +1474,42 @@ func (q *qemu) hotplugVFIODevice(ctx context.Context, device *config.VFIODev, op switch device.Type { case config.VFIODeviceNormalType: - return q.qmpMonitorCh.qmp.ExecuteVFIODeviceAdd(q.qmpMonitorCh.ctx, devID, device.BDF, device.Bus, romFile) + err = q.qmpMonitorCh.qmp.ExecuteVFIODeviceAdd(q.qmpMonitorCh.ctx, devID, device.BDF, device.Bus, romFile) case config.VFIODeviceMediatedType: if utils.IsAPVFIOMediatedDevice(device.SysfsDev) { - return q.qmpMonitorCh.qmp.ExecuteAPVFIOMediatedDeviceAdd(q.qmpMonitorCh.ctx, device.SysfsDev) + err = q.qmpMonitorCh.qmp.ExecuteAPVFIOMediatedDeviceAdd(q.qmpMonitorCh.ctx, device.SysfsDev) + } else { + err = q.qmpMonitorCh.qmp.ExecutePCIVFIOMediatedDeviceAdd(q.qmpMonitorCh.ctx, devID, device.SysfsDev, "", device.Bus, romFile) + } + default: + return fmt.Errorf("Incorrect VFIO device type found") + } + } else { + addr, bridge, err := q.arch.addDeviceToBridge(ctx, devID, types.PCI) + if err != nil { + return err + } + + defer func() { + if err != nil { + q.arch.removeDeviceFromBridge(devID) + } + }() + + switch device.Type { + case config.VFIODeviceNormalType: + err = q.qmpMonitorCh.qmp.ExecutePCIVFIODeviceAdd(q.qmpMonitorCh.ctx, devID, device.BDF, addr, bridge.ID, romFile) + case config.VFIODeviceMediatedType: + if utils.IsAPVFIOMediatedDevice(device.SysfsDev) { + err = q.qmpMonitorCh.qmp.ExecuteAPVFIOMediatedDeviceAdd(q.qmpMonitorCh.ctx, device.SysfsDev) + } else { + err = q.qmpMonitorCh.qmp.ExecutePCIVFIOMediatedDeviceAdd(q.qmpMonitorCh.ctx, devID, device.SysfsDev, addr, bridge.ID, romFile) } - return q.qmpMonitorCh.qmp.ExecutePCIVFIOMediatedDeviceAdd(q.qmpMonitorCh.ctx, devID, device.SysfsDev, "", device.Bus, romFile) default: return fmt.Errorf("Incorrect VFIO device type found") } } - - addr, bridge, err := q.arch.addDeviceToBridge(ctx, devID, types.PCI) - if err != nil { - return err - } - - defer func() { - if err != nil { - q.arch.removeDeviceFromBridge(devID) - } - }() - - switch device.Type { - case config.VFIODeviceNormalType: - return q.qmpMonitorCh.qmp.ExecutePCIVFIODeviceAdd(q.qmpMonitorCh.ctx, devID, device.BDF, addr, bridge.ID, romFile) - case config.VFIODeviceMediatedType: - if utils.IsAPVFIOMediatedDevice(device.SysfsDev) { - return q.qmpMonitorCh.qmp.ExecuteAPVFIOMediatedDeviceAdd(q.qmpMonitorCh.ctx, device.SysfsDev) - } - return q.qmpMonitorCh.qmp.ExecutePCIVFIOMediatedDeviceAdd(q.qmpMonitorCh.ctx, devID, device.SysfsDev, addr, bridge.ID, romFile) - default: - return fmt.Errorf("Incorrect VFIO device type found") - } + return err } else { q.Logger().WithField("dev-id", devID).Info("Start hot-unplug VFIO device")