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@xxxxxxxxx> --- tools/kvm/include/kvm/threadpool.h | 29 ++++++++++++++++++++++++++--- tools/kvm/include/kvm/virtio-9p.h | 3 ++- tools/kvm/threadpool.c | 30 ++---------------------------- tools/kvm/virtio/9p.c | 7 +++---- tools/kvm/virtio/blk.c | 8 ++++---- tools/kvm/virtio/console.c | 10 +++++----- tools/kvm/virtio/rng.c | 16 ++++++++-------- 7 files changed, 50 insertions(+), 53 deletions(-) diff --git a/tools/kvm/include/kvm/threadpool.h b/tools/kvm/include/kvm/threadpool.h index 62826a6..768239f 100644 --- a/tools/kvm/include/kvm/threadpool.h +++ b/tools/kvm/include/kvm/threadpool.h @@ -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); -int thread_pool__init(unsigned long thread_count); +struct thread_pool__job { + kvm_thread_callback_fn_t callback; + struct kvm *kvm; + void *data; + + int signalcount; + pthread_mutex_t mutex; -void *thread_pool__add_job(struct kvm *kvm, kvm_thread_callback_fn_t callback, void *data); + 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__do_job(void *job); +void thread_pool__do_job(struct thread_pool__job *job); #endif diff --git a/tools/kvm/include/kvm/virtio-9p.h b/tools/kvm/include/kvm/virtio-9p.h index eb546bb..b9c10de 100644 --- a/tools/kvm/include/kvm/virtio-9p.h +++ b/tools/kvm/include/kvm/virtio-9p.h @@ -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 { diff --git a/tools/kvm/threadpool.c b/tools/kvm/threadpool.c index 2db02184..fdc5fa7 100644 --- a/tools/kvm/threadpool.c +++ b/tools/kvm/threadpool.c @@ -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); diff --git a/tools/kvm/virtio/9p.c b/tools/kvm/virtio/9p.c index 69e534f..d927688 100644 --- a/tools/kvm/virtio/9p.c +++ b/tools/kvm/virtio/9p.c @@ -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: diff --git a/tools/kvm/virtio/blk.c b/tools/kvm/virtio/blk.c index 8d54f5a..1fdfc1e 100644 --- a/tools/kvm/virtio/blk.c +++ b/tools/kvm/virtio/blk.c @@ -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) diff --git a/tools/kvm/virtio/console.c b/tools/kvm/virtio/console.c index 038e53f..e5d59c0 100644 --- a/tools/kvm/virtio/console.c +++ b/tools/kvm/virtio/console.c @@ -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: diff --git a/tools/kvm/virtio/rng.c b/tools/kvm/virtio/rng.c index ede0e2b..1a7f569 100644 --- a/tools/kvm/virtio/rng.c +++ b/tools/kvm/virtio/rng.c @@ -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) -- 1.7.6 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html