All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/4] kvm tools: Thread virtio-blk
@ 2011-04-18 13:02 Sasha Levin
  2011-04-18 13:02 ` [PATCH 2/4] kvm tools: Use virtio_blk_parameters to configure virtio-blk Sasha Levin
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Sasha Levin @ 2011-04-18 13:02 UTC (permalink / raw)
  To: penberg; +Cc: mingo, asias.hejun, gorcunov, prasadjoshi124, kvm, Sasha Levin

Add I/O thread to handle I/O operations in virtio-blk.
There is currently support for multiple virtio queues but the kernel side supports only one virtio queue. It's not too much of a performance impact and the ABI does support multiple queues there - So I've prefered to do it like that to keep it flexible.

I/O performance itself doesn't increase much due to the patch, what changes is system responsiveness during I/O operations.
On an unthreaded system, The VCPU is frozen up until the I/O request is complete. On the other hand, On a threaded system the VCPU is free to do other work or queue more I/O while waiting for the original I/O request to complete.

Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
---
 tools/kvm/virtio-blk.c |   61 ++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 56 insertions(+), 5 deletions(-)

diff --git a/tools/kvm/virtio-blk.c b/tools/kvm/virtio-blk.c
index 124ce95..029f753 100644
--- a/tools/kvm/virtio-blk.c
+++ b/tools/kvm/virtio-blk.c
@@ -30,9 +30,13 @@ struct blk_device {
 	uint32_t			guest_features;
 	uint16_t			config_vector;
 	uint8_t				status;
+	pthread_t			io_thread;
+	pthread_mutex_t		io_mutex;
+	pthread_cond_t		io_cond;
 
 	/* virtio queue */
 	uint16_t			queue_selector;
+	uint64_t			virtio_blk_queue_set_flags;
 
 	struct virt_queue		vqs[NUM_VIRT_QUEUES];
 };
@@ -52,6 +56,9 @@ static struct blk_device blk_device = {
 	 * same applies to VIRTIO_BLK_F_BLK_SIZE
 	 */
 	.host_features		= (1UL << VIRTIO_BLK_F_SEG_MAX),
+
+	.io_mutex			= PTHREAD_MUTEX_INITIALIZER,
+	.io_cond			= PTHREAD_COND_INITIALIZER
 };
 
 static bool virtio_blk_pci_io_device_specific_in(void *data, unsigned long offset, int size, uint32_t count)
@@ -148,15 +155,57 @@ static bool virtio_blk_do_io_request(struct kvm *self, struct virt_queue *queue)
 	return true;
 }
 
-static void virtio_blk_handle_callback(struct kvm *self, uint16_t queue_index)
+
+
+static int virtio_blk_get_selected_queue(void)
 {
-	struct virt_queue *vq = &blk_device.vqs[queue_index];
+	int i;
 
-	while (virt_queue__available(vq))
-		virtio_blk_do_io_request(self, vq);
+	for (i = 0 ; i < NUM_VIRT_QUEUES ; i++) {
+		if (blk_device.virtio_blk_queue_set_flags & (1 << i)) {
+			blk_device.virtio_blk_queue_set_flags &= ~(1 << i);
+				return i;
+		}
+	}
 
-	kvm__irq_line(self, VIRTIO_BLK_IRQ, 1);
+	return -1;
+}
 
+static void *virtio_blk_io_thread(void *ptr)
+{
+	struct kvm *self = ptr;
+	int ret;
+	mutex_lock(&blk_device.io_mutex);
+	ret = pthread_cond_wait(&blk_device.io_cond, &blk_device.io_mutex);
+	while (ret == 0) {
+		int queue_index = virtio_blk_get_selected_queue();
+		mutex_unlock(&blk_device.io_mutex);
+		while (queue_index >= 0) {
+			struct virt_queue *vq = &blk_device.vqs[queue_index];
+
+			while (virt_queue__available(vq))
+				virtio_blk_do_io_request(self, vq);
+
+			kvm__irq_line(self, VIRTIO_BLK_IRQ, 1);
+
+			mutex_lock(&blk_device.io_mutex);
+			queue_index = virtio_blk_get_selected_queue();
+			mutex_unlock(&blk_device.io_mutex);
+		}
+		mutex_lock(&blk_device.io_mutex);
+		ret = pthread_cond_wait(&(blk_device.io_cond), &(blk_device.io_mutex));
+	}
+
+	return NULL;
+}
+
+static void virtio_blk_handle_callback(struct kvm *self, uint16_t queue_index)
+{
+	pthread_mutex_lock(&(blk_device.io_mutex));
+	blk_device.virtio_blk_queue_set_flags |= (1 << queue_index);
+	pthread_mutex_unlock(&(blk_device.io_mutex));
+
+	pthread_cond_signal(&(blk_device.io_cond));
 }
 
 static bool virtio_blk_pci_io_out(struct kvm *self, uint16_t port, void *data, int size, uint32_t count)
@@ -242,6 +291,8 @@ void virtio_blk__init(struct kvm *self)
 	if (!self->disk_image)
 		return;
 
+	pthread_create(&blk_device.io_thread, NULL, virtio_blk_io_thread, self);
+
 	blk_device.blk_config.capacity = self->disk_image->size / SECTOR_SIZE;
 
 	pci__register(&virtio_blk_pci_device, PCI_VIRTIO_BLK_DEVNUM);
-- 
1.7.5.rc1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2011-04-20  8:54 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-04-18 13:02 [PATCH 1/4] kvm tools: Thread virtio-blk Sasha Levin
2011-04-18 13:02 ` [PATCH 2/4] kvm tools: Use virtio_blk_parameters to configure virtio-blk Sasha Levin
2011-04-18 13:02 ` [PATCH 3/4] kvm tools: Add debug feature to test the IO thread Sasha Levin
2011-04-19 16:52   ` Pekka Enberg
2011-04-19 17:04     ` Sasha Levin
2011-04-19 17:11       ` Ingo Molnar
2011-04-19 23:10         ` Asias He
2011-04-20  5:41           ` Pekka Enberg
2011-04-20  8:54             ` Ingo Molnar
2011-04-18 13:02 ` [PATCH 4/4] kvm tools: Complete missing segments in a iov op using regular op Sasha Levin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.