From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755341AbbGCPRS (ORCPT ); Fri, 3 Jul 2015 11:17:18 -0400 Received: from casper.infradead.org ([85.118.1.10]:57196 "EHLO casper.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755311AbbGCPQt (ORCPT ); Fri, 3 Jul 2015 11:16:49 -0400 Date: Fri, 3 Jul 2015 17:16:42 +0200 From: Peter Zijlstra To: Paolo Bonzini Cc: Pontus Fuchs , Linus Torvalds , mingo@redhat.com, "linux-kernel@vger.kernel.org" , gleb@kernel.org Subject: Re: [PATCH] sched,kvm: Fix KVM preempt_notifier usage Message-ID: <20150703151642.GQ18673@twins.programming.kicks-ass.net> References: <558BED42.1030000@gmail.com> <20150625120949.GZ3644@twins.programming.kicks-ass.net> <558BF0E4.50602@gmail.com> <20150625125514.GA3644@twins.programming.kicks-ass.net> <55966E0B.7060100@redhat.com> <20150703121907.GH19282@twins.programming.kicks-ass.net> <5596809D.4000905@redhat.com> <20150703131712.GJ19282@twins.programming.kicks-ass.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20150703131712.GJ19282@twins.programming.kicks-ass.net> User-Agent: Mutt/1.5.21 (2012-12-30) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, Jul 03, 2015 at 03:17:13PM +0200, Peter Zijlstra wrote: > But, could we rework the code so that you register the preempt notifier > when creating the vcpu thread and leave it installed forevermore? OK, it looks like there is no fixed relation between a thread and a vcpu :/ Would something like the below (on top of all the others) work for you? --- include/linux/preempt.h | 2 ++ kernel/sched/core.c | 18 +++++++++++++++--- virt/kvm/kvm_main.c | 7 +++++-- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/include/linux/preempt.h b/include/linux/preempt.h index 0f1534acaf60..84991f185173 100644 --- a/include/linux/preempt.h +++ b/include/linux/preempt.h @@ -293,6 +293,8 @@ struct preempt_notifier { struct preempt_ops *ops; }; +void preempt_notifier_inc(void); +void preempt_notifier_dec(void); void preempt_notifier_register(struct preempt_notifier *notifier); void preempt_notifier_unregister(struct preempt_notifier *notifier); diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 6169c167ac98..5ddbcb720fc6 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -2320,13 +2320,27 @@ void wake_up_new_task(struct task_struct *p) static struct static_key preempt_notifier_key = STATIC_KEY_INIT_FALSE; +void preempt_notifier_inc(void) +{ + static_key_slow_inc(&preempt_notifier_key); +} +EXPORT_SYMBOL_GPL(preempt_notifier_inc); + +void preempt_notifier_dec(void) +{ + static_key_slow_dec(&preempt_notifier_key); +} +EXPORT_SYMBOL_GPL(preempt_notifier_dec); + /** * preempt_notifier_register - tell me when current is being preempted & rescheduled * @notifier: notifier struct to register */ void preempt_notifier_register(struct preempt_notifier *notifier) { - static_key_slow_inc(&preempt_notifier_key); + if (!static_key_false(&preempt_notifier_key)) + WARN(1, "registering preempt_notifier while notifiers disabled\n"); + /* * Avoid preemption while changing the preempt notifier list. */ @@ -2350,8 +2364,6 @@ void preempt_notifier_unregister(struct preempt_notifier *notifier) preempt_disable(); hlist_del(¬ifier->link); preempt_enable(); - - static_key_slow_dec(&preempt_notifier_key); } EXPORT_SYMBOL_GPL(preempt_notifier_unregister); diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index d7aafa0458a0..8136be28d76c 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -128,9 +128,9 @@ int vcpu_load(struct kvm_vcpu *vcpu) if (mutex_lock_killable(&vcpu->mutex)) return -EINTR; - preempt_notifier_register(&vcpu->preempt_notifier); cpu = get_cpu(); + preempt_notifier_register(&vcpu->preempt_notifier); kvm_arch_vcpu_load(vcpu, cpu); put_cpu(); return 0; @@ -140,8 +140,8 @@ void vcpu_put(struct kvm_vcpu *vcpu) { preempt_disable(); kvm_arch_vcpu_put(vcpu); - preempt_enable(); preempt_notifier_unregister(&vcpu->preempt_notifier); + preempt_enable(); mutex_unlock(&vcpu->mutex); } @@ -513,6 +513,8 @@ static struct kvm *kvm_create_vm(unsigned long type) list_add(&kvm->vm_list, &vm_list); spin_unlock(&kvm_lock); + preempt_notifier_inc(); + return kvm; out_err: @@ -612,6 +614,7 @@ static void kvm_destroy_vm(struct kvm *kvm) cleanup_srcu_struct(&kvm->irq_srcu); cleanup_srcu_struct(&kvm->srcu); kvm_arch_free_vm(kvm); + preempt_notifier_dec(); hardware_disable_all(); mmdrop(mm); }