From 82e42b5dc5726accf07dd04376e1d2ee1695c4f8 Mon Sep 17 00:00:00 2001 From: Archana Shinde Date: Thu, 29 Mar 2018 00:09:30 -0700 Subject: [PATCH] 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 --- virtcontainers/hypervisor.go | 4 ++++ virtcontainers/qemu.go | 7 ++++++- virtcontainers/qemu_arch_base.go | 18 +++++++++++++++--- virtcontainers/qemu_arch_base_test.go | 6 +++++- 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/virtcontainers/hypervisor.go b/virtcontainers/hypervisor.go index cfbd885fae..b5d0d3d8ce 100644 --- a/virtcontainers/hypervisor.go +++ b/virtcontainers/hypervisor.go @@ -201,6 +201,10 @@ type HypervisorConfig struct { // DisableBlockDeviceUse disallows a block device from being used. 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 // enable debug output where available. Debug bool diff --git a/virtcontainers/qemu.go b/virtcontainers/qemu.go index 93bcf2136e..1eca297402 100644 --- a/virtcontainers/qemu.go +++ b/virtcontainers/qemu.go @@ -379,8 +379,9 @@ func (q *qemu) createPod(podConfig PodConfig) error { return err } + var ioThread *govmmQemu.IOThread if q.config.BlockDeviceDriver == VirtioSCSI { - devices = q.arch.appendSCSIController(devices) + devices, ioThread = q.arch.appendSCSIController(devices, q.config.EnableIOThreads) } cpuModel := q.arch.cpuModel() @@ -414,6 +415,10 @@ func (q *qemu) createPod(podConfig PodConfig) error { Bios: firmwarePath, } + if ioThread != nil { + qemuConfig.IOThreads = []govmmQemu.IOThread{*ioThread} + } + q.qemuConfig = qemuConfig return nil diff --git a/virtcontainers/qemu_arch_base.go b/virtcontainers/qemu_arch_base.go index c377755a45..81fcf8a8eb 100644 --- a/virtcontainers/qemu_arch_base.go +++ b/virtcontainers/qemu_arch_base.go @@ -66,7 +66,7 @@ type qemuArch interface { appendImage(devices []govmmQemu.Device, path string) ([]govmmQemu.Device, error) // 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(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 } -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{ ID: scsiControllerID, 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) - return devices + return devices, t } // appendBridges appends to devices the given bridges diff --git a/virtcontainers/qemu_arch_base_test.go b/virtcontainers/qemu_arch_base_test.go index a91a06a586..451e01a68c 100644 --- a/virtcontainers/qemu_arch_base_test.go +++ b/virtcontainers/qemu_arch_base_test.go @@ -470,6 +470,10 @@ func TestQemuArchBaseAppendSCSIController(t *testing.T) { }, } - devices = qemuArchBase.appendSCSIController(devices) + devices, ioThread := qemuArchBase.appendSCSIController(devices, false) assert.Equal(expectedOut, devices) + assert.Nil(ioThread) + + _, ioThread = qemuArchBase.appendSCSIController(devices, true) + assert.NotNil(ioThread) }