From patchwork Fri Apr 17 12:46:57 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 6230521 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 0FA4F9F1C4 for ; Fri, 17 Apr 2015 12:47:59 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 175D820220 for ; Fri, 17 Apr 2015 12:47:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 0BE062021A for ; Fri, 17 Apr 2015 12:47:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752736AbbDQMry (ORCPT ); Fri, 17 Apr 2015 08:47:54 -0400 Received: from mx1.redhat.com ([209.132.183.28]:49803 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751148AbbDQMrw (ORCPT ); Fri, 17 Apr 2015 08:47:52 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t3HCl4nH023800 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 17 Apr 2015 08:47:04 -0400 Received: from [10.36.112.59] (ovpn-112-59.ams2.redhat.com [10.36.112.59]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t3HCkwA0001842 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Fri, 17 Apr 2015 08:47:00 -0400 Message-ID: <553100C1.5000408@redhat.com> Date: Fri, 17 Apr 2015 14:46:57 +0200 From: Paolo Bonzini User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.5.0 MIME-Version: 1.0 To: Peter Zijlstra CC: torvalds@linux-foundation.org, linux-kernel@vger.kernel.org, gleb@kernel.org, kvm@vger.kernel.org, Ralf Baechle , mtosatti@redhat.com, luto@kernel.org Subject: Re: [GIT PULL] First batch of KVM changes for 4.1 References: <1428678089-16291-1-git-send-email-pbonzini@redhat.com> <20150417085238.GJ17717@twins.programming.kicks-ass.net> <20150417091745.GA24151@twins.programming.kicks-ass.net> <5530DBED.5080508@redhat.com> <20150417103654.GE5029@twins.programming.kicks-ass.net> <5530E28F.2030401@redhat.com> <20150417105506.GF5029@twins.programming.kicks-ass.net> In-Reply-To: <20150417105506.GF5029@twins.programming.kicks-ass.net> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On 17/04/2015 12:55, Peter Zijlstra wrote: > Also, it looks like you already do exactly this for other things, look > at: > > kvm_sched_in() > kvm_arch_vcpu_load() > if (unlikely(vcpu->cpu != cpu) ... ) > > So no, I don't believe for one second you need this. You're missing that this snippet is running in the host, while this patch is concerned with the guest (paravirt). This notifier runs for _all_ tasks, not just for the KVM threads. In fact there will most likely be no KVM in the guest. There is no vcpu->cpu where this notifier is run. And frankly, I think the static key is snake oil. The cost of task migration in terms of cache misses and TLB misses is in no way comparable to the cost of filling in a structure on the stack, dereferencing the head of the notifiers list and seeing that it's NULL. If this was a real problem, it would be better solved by adding inlining in kernel/notifier.c: Also, move enough stuff to a header so that the fast path is inlined to a single pointer derefrence. Paolo --- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/kernel/notifier.c b/kernel/notifier.c index ae9fc7cc360e..9c0cd0f739e0 100644 --- a/kernel/notifier.c +++ b/kernel/notifier.c @@ -59,28 +59,14 @@ static int notifier_chain_unregister(struct notifier_block **nl, return -ENOENT; } -/** - * notifier_call_chain - Informs the registered notifiers about an event. - * @nl: Pointer to head of the blocking notifier chain - * @val: Value passed unmodified to notifier function - * @v: Pointer passed unmodified to notifier function - * @nr_to_call: Number of notifier functions to be called. Don't care - * value of this parameter is -1. - * @nr_calls: Records the number of notifications sent. Don't care - * value of this field is NULL. - * @returns: notifier_call_chain returns the value returned by the - * last notifier function called. - */ -static int notifier_call_chain(struct notifier_block **nl, - unsigned long val, void *v, - int nr_to_call, int *nr_calls) +static int __notifier_call_chain(struct notifier_block *nb, + unsigned long val, void *v, + int nr_to_call, int *nr_calls) { int ret = NOTIFY_DONE; - struct notifier_block *nb, *next_nb; - - nb = rcu_dereference_raw(*nl); + struct notifier_block *next_nb; - while (nb && nr_to_call) { + do { next_nb = rcu_dereference_raw(nb->next); #ifdef CONFIG_DEBUG_NOTIFIERS @@ -94,14 +80,38 @@ static int notifier_call_chain(struct notifier_block **nl, if (nr_calls) (*nr_calls)++; - - if ((ret & NOTIFY_STOP_MASK) == NOTIFY_STOP_MASK) - break; - nb = next_nb; - nr_to_call--; - } + } while (!(ret & NOTIFY_STOP_MASK) && + (nb = next_nb) != NULL && + --nr_to_call); return ret; } +NOKPROBE_SYMBOL(__notifier_call_chain); + +/** + * notifier_call_chain - Informs the registered notifiers about an event. + * @nl: Pointer to head of the blocking notifier chain + * @val: Value passed unmodified to notifier function + * @v: Pointer passed unmodified to notifier function + * @nr_to_call: Number of notifier functions to be called. Don't care + * value of this parameter is -1. + * @nr_calls: Records the number of notifications sent. Don't care + * value of this field is NULL. + * @returns: notifier_call_chain returns the value returned by the + * last notifier function called. + */ +static __always_inline int notifier_call_chain(struct notifier_block **nl, + unsigned long val, void *v, + int nr_to_call, int *nr_calls) +{ + struct notifier_block *nb = rcu_dereference_raw(*nl); + if (unlikely(nr_to_call == 0)) + return NOTIFY_DONE; + + if (!nb) + return NOTIFY_DONE; + + return __notifier_call_chain(nb, val, v, nr_to_call, nr_calls); +} NOKPROBE_SYMBOL(notifier_call_chain); /* @@ -190,7 +199,12 @@ NOKPROBE_SYMBOL(__atomic_notifier_call_chain); int atomic_notifier_call_chain(struct atomic_notifier_head *nh, unsigned long val, void *v) { - return __atomic_notifier_call_chain(nh, val, v, -1, NULL); + int ret; + + rcu_read_lock(); + ret = notifier_call_chain(&nh->head, val, v, -1, NULL); + rcu_read_unlock(); + return ret; } EXPORT_SYMBOL_GPL(atomic_notifier_call_chain); NOKPROBE_SYMBOL(atomic_notifier_call_chain);