mirror of
https://github.com/clearlinux/kvmtool.git
synced 2026-06-16 02:15:47 +00:00
kvm tools: Don't dynamically allocate threadpool jobs
To allow efficient use of shorter-term threadpool jobs, don't allocate them dynamically upon creation. Instead, store them within 'job' structures. This will prevent some overhead creating/destroying jobs which live for a short time. Signed-off-by: Sasha Levin <levinsasha928@gmail.com> Signed-off-by: Pekka Enberg <penberg@kernel.org>
This commit is contained in:
@@ -1,14 +1,37 @@
|
||||
#ifndef KVM__THREADPOOL_H
|
||||
#define KVM__THREADPOOL_H
|
||||
|
||||
#include "kvm/mutex.h"
|
||||
|
||||
#include <linux/list.h>
|
||||
|
||||
struct kvm;
|
||||
|
||||
typedef void (*kvm_thread_callback_fn_t)(struct kvm *kvm, void *data);
|
||||
|
||||
struct thread_pool__job {
|
||||
kvm_thread_callback_fn_t callback;
|
||||
struct kvm *kvm;
|
||||
void *data;
|
||||
|
||||
int signalcount;
|
||||
pthread_mutex_t mutex;
|
||||
|
||||
struct list_head queue;
|
||||
};
|
||||
|
||||
static inline void thread_pool__init_job(struct thread_pool__job *job, struct kvm *kvm, kvm_thread_callback_fn_t callback, void *data)
|
||||
{
|
||||
*job = (struct thread_pool__job) {
|
||||
.kvm = kvm,
|
||||
.callback = callback,
|
||||
.data = data,
|
||||
.mutex = PTHREAD_MUTEX_INITIALIZER,
|
||||
};
|
||||
}
|
||||
|
||||
int thread_pool__init(unsigned long thread_count);
|
||||
|
||||
void *thread_pool__add_job(struct kvm *kvm, kvm_thread_callback_fn_t callback, void *data);
|
||||
|
||||
void thread_pool__do_job(void *job);
|
||||
void thread_pool__do_job(struct thread_pool__job *job);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define KVM__VIRTIO_9P_H
|
||||
#include "kvm/virtio.h"
|
||||
#include "kvm/pci.h"
|
||||
#include "kvm/threadpool.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
@@ -34,7 +35,7 @@ struct p9_fid {
|
||||
struct p9_dev_job {
|
||||
struct virt_queue *vq;
|
||||
struct p9_dev *p9dev;
|
||||
void *job_id;
|
||||
struct thread_pool__job job_id;
|
||||
};
|
||||
|
||||
struct p9_dev {
|
||||
|
||||
+2
-28
@@ -6,17 +6,6 @@
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
struct thread_pool__job {
|
||||
kvm_thread_callback_fn_t callback;
|
||||
struct kvm *kvm;
|
||||
void *data;
|
||||
|
||||
int signalcount;
|
||||
pthread_mutex_t mutex;
|
||||
|
||||
struct list_head queue;
|
||||
};
|
||||
|
||||
static pthread_mutex_t job_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_mutex_t thread_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t job_cond = PTHREAD_COND_INITIALIZER;
|
||||
@@ -139,26 +128,11 @@ int thread_pool__init(unsigned long thread_count)
|
||||
return i;
|
||||
}
|
||||
|
||||
void *thread_pool__add_job(struct kvm *kvm,
|
||||
kvm_thread_callback_fn_t callback, void *data)
|
||||
{
|
||||
struct thread_pool__job *job = calloc(1, sizeof(*job));
|
||||
|
||||
*job = (struct thread_pool__job) {
|
||||
.kvm = kvm,
|
||||
.data = data,
|
||||
.callback = callback,
|
||||
.mutex = PTHREAD_MUTEX_INITIALIZER
|
||||
};
|
||||
|
||||
return job;
|
||||
}
|
||||
|
||||
void thread_pool__do_job(void *job)
|
||||
void thread_pool__do_job(struct thread_pool__job *job)
|
||||
{
|
||||
struct thread_pool__job *jobinfo = job;
|
||||
|
||||
if (jobinfo == NULL)
|
||||
if (jobinfo == NULL || jobinfo->callback == NULL)
|
||||
return;
|
||||
|
||||
mutex_lock(&jobinfo->mutex);
|
||||
|
||||
+3
-4
@@ -18,7 +18,6 @@
|
||||
#include <linux/virtio_9p.h>
|
||||
#include <net/9p/9p.h>
|
||||
|
||||
|
||||
/* Warning: Immediately use value returned from this function */
|
||||
static const char *rel_to_abs(struct p9_dev *p9dev,
|
||||
const char *path, char *abs_path)
|
||||
@@ -659,7 +658,7 @@ static void ioevent_callback(struct kvm *kvm, void *param)
|
||||
{
|
||||
struct p9_dev_job *job = param;
|
||||
|
||||
thread_pool__do_job(job->job_id);
|
||||
thread_pool__do_job(&job->job_id);
|
||||
}
|
||||
|
||||
static bool virtio_p9_pci_io_out(struct ioport *ioport, struct kvm *kvm,
|
||||
@@ -694,7 +693,7 @@ static bool virtio_p9_pci_io_out(struct ioport *ioport, struct kvm *kvm,
|
||||
.vq = queue,
|
||||
.p9dev = p9dev,
|
||||
};
|
||||
job->job_id = thread_pool__add_job(kvm, virtio_p9_do_io, job);
|
||||
thread_pool__init_job(&job->job_id, kvm, virtio_p9_do_io, job);
|
||||
|
||||
ioevent = (struct ioevent) {
|
||||
.io_addr = p9dev->base_addr + VIRTIO_PCI_QUEUE_NOTIFY,
|
||||
@@ -717,7 +716,7 @@ static bool virtio_p9_pci_io_out(struct ioport *ioport, struct kvm *kvm,
|
||||
u16 queue_index;
|
||||
|
||||
queue_index = ioport__read16(data);
|
||||
thread_pool__do_job(p9dev->jobs[queue_index].job_id);
|
||||
thread_pool__do_job(&p9dev->jobs[queue_index].job_id);
|
||||
break;
|
||||
}
|
||||
case VIRTIO_PCI_STATUS:
|
||||
|
||||
+4
-4
@@ -31,7 +31,7 @@
|
||||
struct blk_dev_job {
|
||||
struct virt_queue *vq;
|
||||
struct blk_dev *bdev;
|
||||
void *job_id;
|
||||
struct thread_pool__job job_id;
|
||||
};
|
||||
|
||||
struct blk_dev {
|
||||
@@ -206,7 +206,7 @@ static bool virtio_blk_pci_io_out(struct ioport *ioport, struct kvm *kvm, u16 po
|
||||
.bdev = bdev,
|
||||
};
|
||||
|
||||
job->job_id = thread_pool__add_job(kvm, virtio_blk_do_io, job);
|
||||
thread_pool__init_job(&job->job_id, kvm, virtio_blk_do_io, job);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -217,7 +217,7 @@ static bool virtio_blk_pci_io_out(struct ioport *ioport, struct kvm *kvm, u16 po
|
||||
u16 queue_index;
|
||||
|
||||
queue_index = ioport__read16(data);
|
||||
thread_pool__do_job(bdev->jobs[queue_index].job_id);
|
||||
thread_pool__do_job(&bdev->jobs[queue_index].job_id);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -248,7 +248,7 @@ static void ioevent_callback(struct kvm *kvm, void *param)
|
||||
{
|
||||
struct blk_dev_job *job = param;
|
||||
|
||||
thread_pool__do_job(job->job_id);
|
||||
thread_pool__do_job(&job->job_id);
|
||||
}
|
||||
|
||||
void virtio_blk__init(struct kvm *kvm, struct disk_image *disk)
|
||||
|
||||
+5
-5
@@ -51,7 +51,7 @@ struct con_dev {
|
||||
u16 queue_selector;
|
||||
u16 base_addr;
|
||||
|
||||
void *jobs[VIRTIO_CONSOLE_NUM_QUEUES];
|
||||
struct thread_pool__job jobs[VIRTIO_CONSOLE_NUM_QUEUES];
|
||||
};
|
||||
|
||||
static struct con_dev cdev = {
|
||||
@@ -93,7 +93,7 @@ static void virtio_console__inject_interrupt_callback(struct kvm *kvm, void *par
|
||||
|
||||
void virtio_console__inject_interrupt(struct kvm *kvm)
|
||||
{
|
||||
thread_pool__do_job(cdev.jobs[VIRTIO_CONSOLE_RX_QUEUE]);
|
||||
thread_pool__do_job(&cdev.jobs[VIRTIO_CONSOLE_RX_QUEUE]);
|
||||
}
|
||||
|
||||
static bool virtio_console_pci_io_device_specific_in(void *data, unsigned long offset, int size, u32 count)
|
||||
@@ -203,9 +203,9 @@ static bool virtio_console_pci_io_out(struct ioport *ioport, struct kvm *kvm, u1
|
||||
vring_init(&queue->vring, VIRTIO_CONSOLE_QUEUE_SIZE, p, VIRTIO_PCI_VRING_ALIGN);
|
||||
|
||||
if (cdev.queue_selector == VIRTIO_CONSOLE_TX_QUEUE)
|
||||
cdev.jobs[cdev.queue_selector] = thread_pool__add_job(kvm, virtio_console_handle_callback, queue);
|
||||
thread_pool__init_job(&cdev.jobs[cdev.queue_selector], kvm, virtio_console_handle_callback, queue);
|
||||
else if (cdev.queue_selector == VIRTIO_CONSOLE_RX_QUEUE)
|
||||
cdev.jobs[cdev.queue_selector] = thread_pool__add_job(kvm, virtio_console__inject_interrupt_callback, queue);
|
||||
thread_pool__init_job(&cdev.jobs[cdev.queue_selector], kvm, virtio_console__inject_interrupt_callback, queue);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -214,7 +214,7 @@ static bool virtio_console_pci_io_out(struct ioport *ioport, struct kvm *kvm, u1
|
||||
break;
|
||||
case VIRTIO_PCI_QUEUE_NOTIFY: {
|
||||
u16 queue_index = ioport__read16(data);
|
||||
thread_pool__do_job(cdev.jobs[queue_index]);
|
||||
thread_pool__do_job(&cdev.jobs[queue_index]);
|
||||
break;
|
||||
}
|
||||
case VIRTIO_PCI_STATUS:
|
||||
|
||||
+8
-8
@@ -21,13 +21,13 @@
|
||||
#include <sys/stat.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#define NUM_VIRT_QUEUES 1
|
||||
#define VIRTIO_RNG_QUEUE_SIZE 128
|
||||
#define NUM_VIRT_QUEUES 1
|
||||
#define VIRTIO_RNG_QUEUE_SIZE 128
|
||||
|
||||
struct rng_dev_job {
|
||||
struct virt_queue *vq;
|
||||
struct rng_dev *rdev;
|
||||
void *job_id;
|
||||
struct virt_queue *vq;
|
||||
struct rng_dev *rdev;
|
||||
struct thread_pool__job job_id;
|
||||
};
|
||||
|
||||
struct rng_dev {
|
||||
@@ -146,7 +146,7 @@ static bool virtio_rng_pci_io_out(struct ioport *ioport, struct kvm *kvm, u16 po
|
||||
.rdev = rdev,
|
||||
};
|
||||
|
||||
job->job_id = thread_pool__add_job(kvm, virtio_rng_do_io, job);
|
||||
thread_pool__init_job(&job->job_id, kvm, virtio_rng_do_io, job);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -156,7 +156,7 @@ static bool virtio_rng_pci_io_out(struct ioport *ioport, struct kvm *kvm, u16 po
|
||||
case VIRTIO_PCI_QUEUE_NOTIFY: {
|
||||
u16 queue_index;
|
||||
queue_index = ioport__read16(data);
|
||||
thread_pool__do_job(rdev->jobs[queue_index].job_id);
|
||||
thread_pool__do_job(&rdev->jobs[queue_index].job_id);
|
||||
break;
|
||||
}
|
||||
case VIRTIO_PCI_STATUS:
|
||||
@@ -182,7 +182,7 @@ static void ioevent_callback(struct kvm *kvm, void *param)
|
||||
{
|
||||
struct rng_dev_job *job = param;
|
||||
|
||||
thread_pool__do_job(job->job_id);
|
||||
thread_pool__do_job(&job->job_id);
|
||||
}
|
||||
|
||||
void virtio_rng__init(struct kvm *kvm)
|
||||
|
||||
Reference in New Issue
Block a user