qemu: iothreads: Add iothread support for scsi

Add a hypervisor configuration to specify if IO should
be handled in a separate thread. Add support for iothreads for
virtio-scsi for now. Since we attach all scsi drives to the
same scsi controller, all the drives will be handled in a separate
IO thread which would still give better performance.

Going forward we need to assess if adding more controllers and
attaching iothreasds to each of them with distributing drives
among teh scsi controllers should be done, based on more performance
analysis.

Signed-off-by: Archana Shinde <archana.m.shinde@intel.com>
This commit is contained in:
Archana Shinde
2018-03-29 00:09:30 -07:00
parent 09c5bbd2dc
commit 82e42b5dc5
4 changed files with 30 additions and 5 deletions

View File

@@ -201,6 +201,10 @@ type HypervisorConfig struct {
// DisableBlockDeviceUse disallows a block device from being used. // DisableBlockDeviceUse disallows a block device from being used.
DisableBlockDeviceUse bool DisableBlockDeviceUse bool
// EnableIOThreads enables IO to be processed in a separate thread.
// Supported currently for virtio-scsi driver.
EnableIOThreads bool
// Debug changes the default hypervisor and kernel parameters to // Debug changes the default hypervisor and kernel parameters to
// enable debug output where available. // enable debug output where available.
Debug bool Debug bool

View File

@@ -379,8 +379,9 @@ func (q *qemu) createPod(podConfig PodConfig) error {
return err return err
} }
var ioThread *govmmQemu.IOThread
if q.config.BlockDeviceDriver == VirtioSCSI { if q.config.BlockDeviceDriver == VirtioSCSI {
devices = q.arch.appendSCSIController(devices) devices, ioThread = q.arch.appendSCSIController(devices, q.config.EnableIOThreads)
} }
cpuModel := q.arch.cpuModel() cpuModel := q.arch.cpuModel()
@@ -414,6 +415,10 @@ func (q *qemu) createPod(podConfig PodConfig) error {
Bios: firmwarePath, Bios: firmwarePath,
} }
if ioThread != nil {
qemuConfig.IOThreads = []govmmQemu.IOThread{*ioThread}
}
q.qemuConfig = qemuConfig q.qemuConfig = qemuConfig
return nil return nil

View File

@@ -66,7 +66,7 @@ type qemuArch interface {
appendImage(devices []govmmQemu.Device, path string) ([]govmmQemu.Device, error) appendImage(devices []govmmQemu.Device, path string) ([]govmmQemu.Device, error)
// appendSCSIController appens a SCSI controller to devices // appendSCSIController appens a SCSI controller to devices
appendSCSIController(devices []govmmQemu.Device) []govmmQemu.Device appendSCSIController(devices []govmmQemu.Device, enableIOThreads bool) ([]govmmQemu.Device, *govmmQemu.IOThread)
// appendBridges appends bridges to devices // appendBridges appends bridges to devices
appendBridges(devices []govmmQemu.Device, bridges []Bridge) []govmmQemu.Device appendBridges(devices []govmmQemu.Device, bridges []Bridge) []govmmQemu.Device
@@ -300,15 +300,27 @@ func (q *qemuArchBase) appendImage(devices []govmmQemu.Device, path string) ([]g
return q.appendBlockDevice(devices, drive), nil return q.appendBlockDevice(devices, drive), nil
} }
func (q *qemuArchBase) appendSCSIController(devices []govmmQemu.Device) []govmmQemu.Device { func (q *qemuArchBase) appendSCSIController(devices []govmmQemu.Device, enableIOThreads bool) ([]govmmQemu.Device, *govmmQemu.IOThread) {
scsiController := govmmQemu.SCSIController{ scsiController := govmmQemu.SCSIController{
ID: scsiControllerID, ID: scsiControllerID,
DisableModern: q.nestedRun, DisableModern: q.nestedRun,
} }
var t *govmmQemu.IOThread
if enableIOThreads {
randBytes, _ := generateRandomBytes(8)
t = &govmmQemu.IOThread{
ID: fmt.Sprintf("%s-%s", "iothread", hex.EncodeToString(randBytes)),
}
scsiController.IOThread = t.ID
}
devices = append(devices, scsiController) devices = append(devices, scsiController)
return devices return devices, t
} }
// appendBridges appends to devices the given bridges // appendBridges appends to devices the given bridges

View File

@@ -470,6 +470,10 @@ func TestQemuArchBaseAppendSCSIController(t *testing.T) {
}, },
} }
devices = qemuArchBase.appendSCSIController(devices) devices, ioThread := qemuArchBase.appendSCSIController(devices, false)
assert.Equal(expectedOut, devices) assert.Equal(expectedOut, devices)
assert.Nil(ioThread)
_, ioThread = qemuArchBase.appendSCSIController(devices, true)
assert.NotNil(ioThread)
} }