From patchwork Thu Sep 13 10:20:46 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Pieralisi X-Patchwork-Id: 1451311 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from merlin.infradead.org (unknown [205.233.59.134]) by patchwork2.kernel.org (Postfix) with ESMTP id B2D50DF24C for ; Thu, 13 Sep 2012 10:40:30 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TC6Zg-0000Iy-NL; Thu, 13 Sep 2012 10:23:08 +0000 Received: from service87.mimecast.com ([91.220.42.44]) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TC6Yl-0000DD-DN for linux-arm-kernel@lists.infradead.org; Thu, 13 Sep 2012 10:22:14 +0000 Received: from cam-owa1.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.21]) by service87.mimecast.com; Thu, 13 Sep 2012 11:21:06 +0100 Received: from e102568-lin.cambridge.arm.com ([10.1.255.212]) by cam-owa1.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.0); Thu, 13 Sep 2012 11:21:04 +0100 From: Lorenzo Pieralisi To: linux-arm-kernel@lists.infradead.org Subject: [RFC PATCH 1/6] ARM: mm: define LoUIS API for cache maintenance ops Date: Thu, 13 Sep 2012 11:20:46 +0100 Message-Id: <1347531651-28218-2-git-send-email-lorenzo.pieralisi@arm.com> X-Mailer: git-send-email 1.7.12 In-Reply-To: <1347531651-28218-1-git-send-email-lorenzo.pieralisi@arm.com> References: <1347531651-28218-1-git-send-email-lorenzo.pieralisi@arm.com> X-OriginalArrivalTime: 13 Sep 2012 10:21:04.0393 (UTC) FILETIME=[7B0A9F90:01CD9199] X-MC-Unique: 112091311210700301 X-Spam-Note: CRM114 invocation failed X-Spam-Score: -2.6 (--) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-2.6 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [91.220.42.44 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: Nicolas Pitre , Dave Martin , Lorenzo Pieralisi , Russell King , Catalin Marinas , Daniel Lezcano , Will Deacon , Amit Kucheria , Santosh Shilimkar , Colin Cross , linux-omap@vger.kernel.org, Wenzeng Chen X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org ARM v7 architecture introduced the concept of cache levels and related coherency requirements. New processors like A7 and A15 embed an L2 unified cache controller that becomes part of the cache level hierarchy. Some operations in the kernel like cpu_suspend and __cpu_disable does not require a flush of the entire cache hierarchy to DRAM but just the cache levels belonging to the Level of Unification Inner Shareable (LoUIS), which in most of ARM v7 systems correspond to L1. The current cache flushing API used in cpu_suspend and __cpu_disable, flush_cache_all(), ends up flushing the whole cache hierarchy since for v7 it cleans and invalidates all cache levels up to Level of Coherency (LoC) which cripples system performance when used in hot paths like hotplug and cpuidle. Therefore a new kernel cache maintenance API must be added to the cpu_cache_fns structure of pointers to cope with latest ARM system requirements. This patch adds flush_cache_louis() to the ARM kernel cache maintenance API. This function cleans and invalidates all data cache levels up to the level of unification inner shareable (LoUIS) and invalidates the instruction cache. The cpu_cache_fns struct reflects this change by adding a new function pointer that is initialized by arch specific assembly files. By default, all existing ARM archs do not instantiate any cache LoUIS function pointer, and flush_dcache_louis just falls back to flush_kern_all. Reviewed-by: Santosh Shilimkar Signed-off-by: Lorenzo Pieralisi --- arch/arm/include/asm/cacheflush.h | 17 +++++++++++++++++ arch/arm/mm/proc-macros.S | 7 ++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h index c6e2ed9..7683316 100644 --- a/arch/arm/include/asm/cacheflush.h +++ b/arch/arm/include/asm/cacheflush.h @@ -50,6 +50,13 @@ * * Unconditionally clean and invalidate the entire cache. * + * flush_kern_cache_louis() + * + * Flush data cache levels up to the level of unification + * inner shareable and invalidate the I-cache. + * Only needed from v7 onwards, falls back to flush_cache_all() + * for all other processor versions. + * * flush_user_all() * * Clean and invalidate all user space cache entries @@ -98,6 +105,7 @@ struct cpu_cache_fns { void (*flush_icache_all)(void); void (*flush_kern_all)(void); + void (*flush_kern_cache_louis)(void); void (*flush_user_all)(void); void (*flush_user_range)(unsigned long, unsigned long, unsigned int); @@ -200,6 +208,15 @@ extern void copy_to_user_page(struct vm_area_struct *, struct page *, #define __flush_icache_preferred __flush_icache_all_generic #endif +/* + * Flush caches up to Level of Unification Inner Shareable + */ +#ifdef MULTI_CACHE +#define flush_cache_louis() cpu_cache.flush_kern_cache_louis() +#else +#define flush_cache_louis() __cpuc_flush_kern_all() +#endif + static inline void __flush_icache_all(void) { __flush_icache_preferred(); diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S index 2d8ff3a..28e91f8 100644 --- a/arch/arm/mm/proc-macros.S +++ b/arch/arm/mm/proc-macros.S @@ -293,12 +293,17 @@ ENTRY(\name\()_processor_functions) .size \name\()_processor_functions, . - \name\()_processor_functions .endm -.macro define_cache_functions name:req +.macro define_cache_functions name:req, cachelouis=0 .align 2 .type \name\()_cache_fns, #object ENTRY(\name\()_cache_fns) .long \name\()_flush_icache_all .long \name\()_flush_kern_cache_all + .if \cachelouis + .long \name\()_flush_kern_cache_louis + .else + .long \name\()_flush_kern_cache_all + .endif .long \name\()_flush_user_cache_all .long \name\()_flush_user_cache_range .long \name\()_coherent_kern_range