From patchwork Tue Jun 15 13:55:29 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Hansen X-Patchwork-Id: 106208 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o5FDvacR012980 for ; Tue, 15 Jun 2010 13:57:37 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932097Ab0FON4i (ORCPT ); Tue, 15 Jun 2010 09:56:38 -0400 Received: from e9.ny.us.ibm.com ([32.97.182.139]:49725 "EHLO e9.ny.us.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932156Ab0FONze (ORCPT ); Tue, 15 Jun 2010 09:55:34 -0400 Received: from d01relay03.pok.ibm.com (d01relay03.pok.ibm.com [9.56.227.235]) by e9.ny.us.ibm.com (8.14.4/8.13.1) with ESMTP id o5FDenWY014511; Tue, 15 Jun 2010 09:40:49 -0400 Received: from d03av01.boulder.ibm.com (d03av01.boulder.ibm.com [9.17.195.167]) by d01relay03.pok.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id o5FDtXaC100136; Tue, 15 Jun 2010 09:55:33 -0400 Received: from d03av01.boulder.ibm.com (loopback [127.0.0.1]) by d03av01.boulder.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id o5FDtTGZ029514; Tue, 15 Jun 2010 07:55:30 -0600 Received: from kernel.beaverton.ibm.com (kernel.beaverton.ibm.com [9.47.67.96]) by d03av01.boulder.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id o5FDtTxe029493; Tue, 15 Jun 2010 07:55:29 -0600 Received: from localhost.localdomain (localhost [127.0.0.1]) by kernel.beaverton.ibm.com (Postfix) with ESMTP id 1C49B1E74F9; Tue, 15 Jun 2010 06:55:29 -0700 (PDT) Subject: [RFC][PATCH 8/9] reduce kvm_lock hold times in mmu_skrink() To: linux-kernel@vger.kernel.org Cc: kvm@vger.kernel.org, Dave Hansen From: Dave Hansen Date: Tue, 15 Jun 2010 06:55:29 -0700 References: <20100615135518.BC244431@kernel.beaverton.ibm.com> In-Reply-To: <20100615135518.BC244431@kernel.beaverton.ibm.com> Message-Id: <20100615135528.01AC8966@kernel.beaverton.ibm.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Tue, 15 Jun 2010 13:57:37 +0000 (UTC) diff -puN arch/x86/kvm/mmu.c~optimize_shrinker-3 arch/x86/kvm/mmu.c --- linux-2.6.git/arch/x86/kvm/mmu.c~optimize_shrinker-3 2010-06-11 08:39:17.000000000 -0700 +++ linux-2.6.git-dave/arch/x86/kvm/mmu.c 2010-06-11 08:39:17.000000000 -0700 @@ -2930,7 +2930,8 @@ static int kvm_mmu_remove_some_alloc_mmu static int shrink_kvm_mmu(struct kvm *kvm, int nr_to_scan) { - int idx, freed_pages; + int idx; + int freed_pages = 0; idx = srcu_read_lock(&kvm->srcu); spin_lock(&kvm->mmu_lock); @@ -2950,23 +2951,50 @@ static int shrink_kvm_mmu(struct kvm *kv static int mmu_shrink(int nr_to_scan, gfp_t gfp_mask) { + int err; + int freed; struct kvm *kvm; if (nr_to_scan == 0) goto out; +retry: + nr_to_scan--; spin_lock(&kvm_lock); - - list_for_each_entry(kvm, &vm_list, vm_list) { - int freed = shrink_kvm_mmu(kvm, nr_to_scan); - if (!freed) - continue; - - list_move_tail(&kvm->vm_list, &vm_list); - break; + if (list_empty(&vm_list)) { + spin_unlock(&kvm_lock); + goto out; } - + kvm = list_first_entry(&vm_list, struct kvm, vm_list); + /* + * With a reference to the kvm object, it can not go away + * nor get removed from the vm_list. + */ + err = kvm_get_kvm(kvm); + /* Did someone race and start destroying the kvm object? */ + if (err) { + spin_unlock(&kvm_lock); + goto retry; + } + /* + * Stick this kvm on the end of the list so the next + * interation will shrink a different one. Do this here + * so that we normally don't have to reacquire the lock. + */ + list_move_tail(&kvm->vm_list, &vm_list); + /* + * Which lets us release the global lock, holding it for + * the minimal amount of time possible, and ensuring that + * we don't hold it during the (presumably slow) shrink + * operation itself. + */ spin_unlock(&kvm_lock); + freed = shrink_kvm_mmu(kvm, nr_to_scan); + + kvm_put_kvm(kvm); + + if (!freed && nr_to_scan > 0) + goto retry; out: return kvm_total_used_mmu_pages; diff -puN virt/kvm/kvm_main.c~optimize_shrinker-3 virt/kvm/kvm_main.c diff -puN kernel/profile.c~optimize_shrinker-3 kernel/profile.c --- linux-2.6.git/kernel/profile.c~optimize_shrinker-3 2010-06-11 09:09:43.000000000 -0700 +++ linux-2.6.git-dave/kernel/profile.c 2010-06-11 09:12:24.000000000 -0700 @@ -314,6 +314,8 @@ void profile_hits(int type, void *__pc, if (prof_on != type || !prof_buffer) return; pc = min((pc - (unsigned long)_stext) >> prof_shift, prof_len - 1); + if ((pc == prof_len - 1) && printk_ratelimit()) + printk("profile_hits(%d, %p, %d)\n", type, __pc, nr_hits); i = primary = (pc & (NR_PROFILE_GRP - 1)) << PROFILE_GRPSHIFT; secondary = (~(pc << 1) & (NR_PROFILE_GRP - 1)) << PROFILE_GRPSHIFT; cpu = get_cpu();