* [PATCH] KVM: x86: Run PIT work in own kthread
@ 2012-04-16 18:26 Jan Kiszka
2012-04-17 10:27 ` Avi Kivity
0 siblings, 1 reply; 4+ messages in thread
From: Jan Kiszka @ 2012-04-16 18:26 UTC (permalink / raw)
To: Avi Kivity, Marcelo Tosatti; +Cc: kvm, Linux Kernel Mailing List
We can't run PIT IRQ injection work in the interrupt context of the host
timer. This would allow the user to influence the handler complexity by
asking for a broadcast to a large number of VCPUs. Therefore, this work
was pushed into workqueue context in 9d244caf2e. However, this prevents
prioritizing the PIT injection over other task as workqueues share
kernel threads.
This replaces the workqueue with a kthread worker and gives that thread
a name in the format "kvm-pit/<owner-process-pid>". That allows to
identify and adjust the kthread priority according to the VM process
parameters.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
arch/x86/kvm/i8254.c | 31 +++++++++++++++++++------------
arch/x86/kvm/i8254.h | 7 +++++--
2 files changed, 24 insertions(+), 14 deletions(-)
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c
index d68f99d..adba28f 100644
--- a/arch/x86/kvm/i8254.c
+++ b/arch/x86/kvm/i8254.c
@@ -34,7 +34,6 @@
#include <linux/kvm_host.h>
#include <linux/slab.h>
-#include <linux/workqueue.h>
#include "irq.h"
#include "i8254.h"
@@ -249,7 +248,7 @@ static void kvm_pit_ack_irq(struct kvm_irq_ack_notifier *kian)
/* in this case, we had multiple outstanding pit interrupts
* that we needed to inject. Reinject
*/
- queue_work(ps->pit->wq, &ps->pit->expired);
+ queue_kthread_work(&ps->pit->worker, &ps->pit->expired);
ps->irq_ack = 1;
spin_unlock(&ps->inject_lock);
}
@@ -270,7 +269,7 @@ void __kvm_migrate_pit_timer(struct kvm_vcpu *vcpu)
static void destroy_pit_timer(struct kvm_pit *pit)
{
hrtimer_cancel(&pit->pit_state.pit_timer.timer);
- cancel_work_sync(&pit->expired);
+ flush_kthread_work(&pit->expired);
}
static bool kpit_is_periodic(struct kvm_timer *ktimer)
@@ -284,7 +283,7 @@ static struct kvm_timer_ops kpit_ops = {
.is_periodic = kpit_is_periodic,
};
-static void pit_do_work(struct work_struct *work)
+static void pit_do_work(struct kthread_work *work)
{
struct kvm_pit *pit = container_of(work, struct kvm_pit, expired);
struct kvm *kvm = pit->kvm;
@@ -328,7 +327,7 @@ static enum hrtimer_restart pit_timer_fn(struct hrtimer *data)
if (ktimer->reinject || !atomic_read(&ktimer->pending)) {
atomic_inc(&ktimer->pending);
- queue_work(pt->wq, &pt->expired);
+ queue_kthread_work(&pt->worker, &pt->expired);
}
if (ktimer->t_ops->is_periodic(ktimer)) {
@@ -353,7 +352,7 @@ static void create_pit_timer(struct kvm *kvm, u32 val, int is_period)
/* TODO The new value only affected after the retriggered */
hrtimer_cancel(&pt->timer);
- cancel_work_sync(&ps->pit->expired);
+ flush_kthread_work(&ps->pit->expired);
pt->period = interval;
ps->is_periodic = is_period;
@@ -669,6 +668,8 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags)
{
struct kvm_pit *pit;
struct kvm_kpit_state *pit_state;
+ struct pid *pid;
+ pid_t pid_nr;
int ret;
pit = kzalloc(sizeof(struct kvm_pit), GFP_KERNEL);
@@ -685,14 +686,20 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags)
mutex_lock(&pit->pit_state.lock);
spin_lock_init(&pit->pit_state.inject_lock);
- pit->wq = create_singlethread_workqueue("kvm-pit-wq");
- if (!pit->wq) {
+ pid = get_pid(task_tgid(current));
+ pid_nr = pid_vnr(pid);
+ put_pid(pid);
+
+ init_kthread_worker(&pit->worker);
+ pit->worker_task = kthread_run(kthread_worker_fn, &pit->worker,
+ "kvm-pit/%d", pid_nr);
+ if (IS_ERR(pit->worker_task)) {
mutex_unlock(&pit->pit_state.lock);
kvm_free_irq_source_id(kvm, pit->irq_source_id);
kfree(pit);
return NULL;
}
- INIT_WORK(&pit->expired, pit_do_work);
+ init_kthread_work(&pit->expired, pit_do_work);
kvm->arch.vpit = pit;
pit->kvm = kvm;
@@ -736,7 +743,7 @@ fail:
kvm_unregister_irq_mask_notifier(kvm, 0, &pit->mask_notifier);
kvm_unregister_irq_ack_notifier(kvm, &pit_state->irq_ack_notifier);
kvm_free_irq_source_id(kvm, pit->irq_source_id);
- destroy_workqueue(pit->wq);
+ kthread_stop(pit->worker_task);
kfree(pit);
return NULL;
}
@@ -756,10 +763,10 @@ void kvm_free_pit(struct kvm *kvm)
mutex_lock(&kvm->arch.vpit->pit_state.lock);
timer = &kvm->arch.vpit->pit_state.pit_timer.timer;
hrtimer_cancel(timer);
- cancel_work_sync(&kvm->arch.vpit->expired);
+ flush_kthread_work(&kvm->arch.vpit->expired);
+ kthread_stop(kvm->arch.vpit->worker_task);
kvm_free_irq_source_id(kvm, kvm->arch.vpit->irq_source_id);
mutex_unlock(&kvm->arch.vpit->pit_state.lock);
- destroy_workqueue(kvm->arch.vpit->wq);
kfree(kvm->arch.vpit);
}
}
diff --git a/arch/x86/kvm/i8254.h b/arch/x86/kvm/i8254.h
index 51a9742..fdf4042 100644
--- a/arch/x86/kvm/i8254.h
+++ b/arch/x86/kvm/i8254.h
@@ -1,6 +1,8 @@
#ifndef __I8254_H
#define __I8254_H
+#include <linux/kthread.h>
+
#include "iodev.h"
struct kvm_kpit_channel_state {
@@ -39,8 +41,9 @@ struct kvm_pit {
struct kvm_kpit_state pit_state;
int irq_source_id;
struct kvm_irq_mask_notifier mask_notifier;
- struct workqueue_struct *wq;
- struct work_struct expired;
+ struct kthread_worker worker;
+ struct task_struct *worker_task;
+ struct kthread_work expired;
};
#define KVM_PIT_BASE_ADDRESS 0x40
--
1.7.3.4
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [PATCH] KVM: x86: Run PIT work in own kthread
2012-04-16 18:26 [PATCH] KVM: x86: Run PIT work in own kthread Jan Kiszka
@ 2012-04-17 10:27 ` Avi Kivity
2012-04-17 11:18 ` Jan Kiszka
0 siblings, 1 reply; 4+ messages in thread
From: Avi Kivity @ 2012-04-17 10:27 UTC (permalink / raw)
To: Jan Kiszka; +Cc: Marcelo Tosatti, kvm, Linux Kernel Mailing List
On 04/16/2012 09:26 PM, Jan Kiszka wrote:
> We can't run PIT IRQ injection work in the interrupt context of the host
> timer. This would allow the user to influence the handler complexity by
> asking for a broadcast to a large number of VCPUs. Therefore, this work
> was pushed into workqueue context in 9d244caf2e. However, this prevents
> prioritizing the PIT injection over other task as workqueues share
> kernel threads.
>
> This replaces the workqueue with a kthread worker and gives that thread
> a name in the format "kvm-pit/<owner-process-pid>". That allows to
> identify and adjust the kthread priority according to the VM process
> parameters.
Is this a new ABI?
Patch looks reasonable.
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] KVM: x86: Run PIT work in own kthread
2012-04-17 10:27 ` Avi Kivity
@ 2012-04-17 11:18 ` Jan Kiszka
2012-04-17 11:57 ` Avi Kivity
0 siblings, 1 reply; 4+ messages in thread
From: Jan Kiszka @ 2012-04-17 11:18 UTC (permalink / raw)
To: Avi Kivity; +Cc: Marcelo Tosatti, kvm, Linux Kernel Mailing List
On 2012-04-17 12:27, Avi Kivity wrote:
> On 04/16/2012 09:26 PM, Jan Kiszka wrote:
>> We can't run PIT IRQ injection work in the interrupt context of the host
>> timer. This would allow the user to influence the handler complexity by
>> asking for a broadcast to a large number of VCPUs. Therefore, this work
>> was pushed into workqueue context in 9d244caf2e. However, this prevents
>> prioritizing the PIT injection over other task as workqueues share
>> kernel threads.
>>
>> This replaces the workqueue with a kthread worker and gives that thread
>> a name in the format "kvm-pit/<owner-process-pid>". That allows to
>> identify and adjust the kthread priority according to the VM process
>> parameters.
>
> Is this a new ABI?
Yep. Scripts will use it, maybe even QEMU. Do you want this to appear in
api.txt?
>
> Patch looks reasonable.
>
Jan
--
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] KVM: x86: Run PIT work in own kthread
2012-04-17 11:18 ` Jan Kiszka
@ 2012-04-17 11:57 ` Avi Kivity
0 siblings, 0 replies; 4+ messages in thread
From: Avi Kivity @ 2012-04-17 11:57 UTC (permalink / raw)
To: Jan Kiszka; +Cc: Marcelo Tosatti, kvm, Linux Kernel Mailing List
On 04/17/2012 02:18 PM, Jan Kiszka wrote:
> On 2012-04-17 12:27, Avi Kivity wrote:
> > On 04/16/2012 09:26 PM, Jan Kiszka wrote:
> >> We can't run PIT IRQ injection work in the interrupt context of the host
> >> timer. This would allow the user to influence the handler complexity by
> >> asking for a broadcast to a large number of VCPUs. Therefore, this work
> >> was pushed into workqueue context in 9d244caf2e. However, this prevents
> >> prioritizing the PIT injection over other task as workqueues share
> >> kernel threads.
> >>
> >> This replaces the workqueue with a kthread worker and gives that thread
> >> a name in the format "kvm-pit/<owner-process-pid>". That allows to
> >> identify and adjust the kthread priority according to the VM process
> >> parameters.
> >
> > Is this a new ABI?
>
> Yep. Scripts will use it, maybe even QEMU. Do you want this to appear in
> api.txt?
You already know the answer.
Please make it explicit that the thread is optional. This way, if we
gain real-time workqueue support, or eliminate it through some other
trick, userspace won't break.
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2012-04-17 11:57 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-04-16 18:26 [PATCH] KVM: x86: Run PIT work in own kthread Jan Kiszka
2012-04-17 10:27 ` Avi Kivity
2012-04-17 11:18 ` Jan Kiszka
2012-04-17 11:57 ` Avi Kivity
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox