linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: rmk+kernel@arm.linux.org.uk (Russell King)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 71/75] ARM: l2c: permit flush_all() on large flush_range() XXX Needs more thought XXX
Date: Fri, 28 Mar 2014 15:20:29 +0000	[thread overview]
Message-ID: <E1WTYa5-0007Hi-HD@rmk-PC.arm.linux.org.uk> (raw)
In-Reply-To: <20140328151249.GJ7528@n2100.arm.linux.org.uk>

In order to allow flush_all() to be used in normal operation, we need
some locking to prevent any other cache operations being issued while
a background flush_all() operation is proceeding.  The read-write
spinlock provides what's necessary here, but we must avoid bringing
lockdep issues into this code.  Hence we continue to use the raw_*
operations, and use the arch read/write spinlock implementation
directly.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mm/cache-l2x0.c | 90 ++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 79 insertions(+), 11 deletions(-)

diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index cbf036dff6d1..c1750f1bf572 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -53,6 +53,54 @@ struct l2x0_regs l2x0_saved_regs;
 /*
  * Common code for all cache controllers.
  */
+#ifdef CONFIG_SMP
+static arch_rwlock_t l2c_rw_lock = __ARCH_RW_LOCK_UNLOCKED;
+
+static unsigned long l2c_lock_exclusive(void)
+{
+	unsigned long flags;
+	raw_local_irq_save(flags);
+	arch_write_lock(&l2c_rw_lock);
+	return flags;
+}
+
+static void l2c_unlock_exclusive(unsigned long flags)
+{
+	arch_write_unlock(&l2c_rw_lock);
+	raw_local_irq_restore(flags);
+}
+
+static void l2c_lock_shared(void)
+{
+	arch_read_lock(&l2c_rw_lock);
+}
+
+static void l2c_unlock_shared(void)
+{
+	arch_read_unlock(&l2c_rw_lock);
+}
+#else
+static unsigned long l2c_lock_exclusive(void)
+{
+	unsigned long flags;
+	raw_local_irq_save(flags);
+	return flags;
+}
+
+static void l2c_unlock_exclusive(unsigned long flags)
+{
+	raw_local_irq_restore(flags);
+}
+
+static void l2c_lock_shared(void)
+{
+}
+
+static void l2c_unlock_shared(void)
+{
+}
+#endif
+
 static inline void l2c_wait_mask(void __iomem *reg, unsigned long mask)
 {
 	/* wait for cache operation by line or way to complete */
@@ -233,6 +281,7 @@ static void l2c210_inv_range(unsigned long start, unsigned long end)
 {
 	void __iomem *base = l2x0_base;
 
+	l2c_lock_shared();
 	if (start & (CACHE_LINE_SIZE - 1)) {
 		start &= ~(CACHE_LINE_SIZE - 1);
 		writel_relaxed(start, base + L2X0_CLEAN_INV_LINE_PA);
@@ -246,6 +295,7 @@ static void l2c210_inv_range(unsigned long start, unsigned long end)
 
 	__l2c210_op_pa_range(base + L2X0_INV_LINE_PA, start, end);
 	__l2c210_cache_sync(base);
+	l2c_unlock_shared();
 }
 
 static void l2c210_clean_range(unsigned long start, unsigned long end)
@@ -253,8 +303,10 @@ static void l2c210_clean_range(unsigned long start, unsigned long end)
 	void __iomem *base = l2x0_base;
 
 	start &= ~(CACHE_LINE_SIZE - 1);
+	l2c_lock_shared();
 	__l2c210_op_pa_range(base + L2X0_CLEAN_LINE_PA, start, end);
 	__l2c210_cache_sync(base);
+	l2c_unlock_shared();
 }
 
 static void l2c210_flush_range(unsigned long start, unsigned long end)
@@ -262,23 +314,33 @@ static void l2c210_flush_range(unsigned long start, unsigned long end)
 	void __iomem *base = l2x0_base;
 
 	start &= ~(CACHE_LINE_SIZE - 1);
+	if ((end - start) >= l2x0_size) {
+		outer_cache.flush_all();
+		return;
+	}
+
+	l2c_lock_shared();
 	__l2c210_op_pa_range(base + L2X0_CLEAN_INV_LINE_PA, start, end);
 	__l2c210_cache_sync(base);
+	l2c_unlock_shared();
 }
 
 static void l2c210_flush_all(void)
 {
 	void __iomem *base = l2x0_base;
+	unsigned long flags;
 
-	BUG_ON(!irqs_disabled());
-
+	flags = l2c_lock_exclusive();
 	__l2c_op_way(base + L2X0_CLEAN_INV_WAY);
 	__l2c210_cache_sync(base);
+	l2c_unlock_exclusive(flags);
 }
 
 static void l2c210_sync(void)
 {
+	l2c_lock_shared();
 	__l2c210_cache_sync(l2x0_base);
+	l2c_unlock_shared();
 }
 
 static void l2c210_resume(void)
@@ -501,7 +563,7 @@ static void l2c310_inv_range_erratum(unsigned long start, unsigned long end)
 		unsigned long flags;
 
 		/* Erratum 588369 for both clean+invalidate operations */
-		raw_spin_lock_irqsave(&l2x0_lock, flags);
+		flags = l2c_lock_exclusive();
 		l2c_set_debug(base, 0x03);
 
 		if (start & (CACHE_LINE_SIZE - 1)) {
@@ -518,20 +580,26 @@ static void l2c310_inv_range_erratum(unsigned long start, unsigned long end)
 		}
 
 		l2c_set_debug(base, 0x00);
-		raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+		l2c_unlock_exclusive(flags);
 	}
 
+	l2c_lock_shared();
 	__l2c210_op_pa_range(base + L2X0_INV_LINE_PA, start, end);
 	__l2c210_cache_sync(base);
+	l2c_unlock_shared();
 }
 
 static void l2c310_flush_range_erratum(unsigned long start, unsigned long end)
 {
-	raw_spinlock_t *lock = &l2x0_lock;
 	unsigned long flags;
 	void __iomem *base = l2x0_base;
 
-	raw_spin_lock_irqsave(lock, flags);
+	if ((end - start) >= l2x0_size) {
+		outer_cache.flush_all();
+		return;
+	}
+
+	flags = l2c_lock_exclusive();
 	while (start < end) {
 		unsigned long blk_end = start + min(end - start, 4096UL);
 
@@ -544,12 +612,12 @@ static void l2c310_flush_range_erratum(unsigned long start, unsigned long end)
 		l2c_set_debug(base, 0x00);
 
 		if (blk_end < end) {
-			raw_spin_unlock_irqrestore(lock, flags);
-			raw_spin_lock_irqsave(lock, flags);
+			l2c_unlock_exclusive(flags);
+			flags = l2c_lock_exclusive();
 		}
 	}
-	raw_spin_unlock_irqrestore(lock, flags);
 	__l2c210_cache_sync(base);
+	l2c_unlock_exclusive(flags);
 }
 
 static void l2c310_flush_all_erratum(void)
@@ -557,12 +625,12 @@ static void l2c310_flush_all_erratum(void)
 	void __iomem *base = l2x0_base;
 	unsigned long flags;
 
-	raw_spin_lock_irqsave(&l2x0_lock, flags);
+	flags = l2c_lock_exclusive();
 	l2c_set_debug(base, 0x03);
 	__l2c_op_way(base + L2X0_CLEAN_INV_WAY);
 	l2c_set_debug(base, 0x00);
 	__l2c210_cache_sync(base);
-	raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+	l2c_unlock_exclusive(flags);
 }
 
 static void __init l2c310_save(void __iomem *base)
-- 
1.8.3.1

  parent reply	other threads:[~2014-03-28 15:20 UTC|newest]

Thread overview: 141+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-03-28 15:12 [PATCH 00/75] l2c series Russell King - ARM Linux
2014-03-28 15:14 ` [PATCH 01/75] ARM: l2c: remove outer_inv_all() method Russell King
2014-03-28 15:14 ` [PATCH 02/75] ARM: l2c: remove unnecessary call to outer_flush_all() Russell King
2014-03-28 15:14 ` [PATCH 03/75] ARM: l2c: avoid calling outer_flush_all() unnecessarily (Spear) Russell King
2014-03-28 15:14 ` [PATCH 04/75] ARM: l2c: omap2: remove ES1.0 support Russell King
2014-03-28 15:54   ` Tony Lindgren
2014-03-28 15:14 ` [PATCH 05/75] ARM: l2c: remove unnecessary UL-suffix to mask values Russell King
2014-03-28 15:50   ` Rob Herring
2014-03-28 15:56     ` Russell King - ARM Linux
2014-03-28 15:14 ` [PATCH 06/75] ARM: outer cache: add documentation of outer cache functions Russell King
2014-04-02  9:30   ` Michal Simek
2014-04-03 19:03     ` Russell King - ARM Linux
2014-03-28 15:14 ` [PATCH 07/75] ARM: outer cache: add WARN_ON() to outer_disable() Russell King
2014-03-28 15:15 ` [PATCH 08/75] ARM: l2c: add helper for L2 cache controller DT IDs Russell King
2014-03-28 15:15 ` [PATCH 09/75] ARM: l2c: tidy up l2x0_of_data declarations Russell King
2014-03-28 15:15 ` [PATCH 10/75] ARM: l2c: rename OF specific things, making l2x0_of_data available to all Russell King
2014-03-28 15:15 ` [PATCH 11/75] ARM: l2c: provide generic function for calling set_debug method Russell King
2014-03-28 15:15 ` [PATCH 12/75] ARM: l2c: split out cache unlock code Russell King
2014-03-28 15:15 ` [PATCH 13/75] ARM: l2c: provide generic helper for way-based operations Russell King
2014-03-28 15:15 ` [PATCH 14/75] ARM: l2c: rename cache_wait_way() Russell King
2014-03-28 15:15 ` [PATCH 15/75] ARM: l2c: add and use L2C revision constants Russell King
2014-04-02  9:37   ` Michal Simek
2014-04-03 19:06     ` Russell King - ARM Linux
2014-03-28 15:15 ` [PATCH 16/75] ARM: l2c: clean up OF initialisation a bit Russell King
2014-03-28 15:15 ` [PATCH 17/75] ARM: l2c: pass iomem address into data->save function Russell King
2014-03-28 15:15 ` [PATCH 18/75] ARM: l2c: move l2c save function to __l2c_init() Russell King
2014-03-28 15:15 ` [PATCH 19/75] ARM: l2c: group implementation specific code together Russell King
2014-03-28 15:16 ` [PATCH 20/75] ARM: l2c: provide enable method Russell King
2014-03-28 15:16 ` [PATCH 21/75] ARM: l2c: write auxctrl register before unlocking Russell King
2014-03-28 15:16 ` [PATCH 22/75] ARM: l2c: only write the auxiliary control register if required Russell King
2014-03-28 15:16 ` [PATCH 23/75] ARM: l2c: move aurora broadcast setup to enable function Russell King
2014-03-28 15:16 ` [PATCH 24/75] ARM: l2c: implement fixups for L2 cache controller quirks/errata Russell King
2014-03-28 15:16 ` [PATCH 25/75] ARM: l2c: clean up L2 cache initialisation messages Russell King
2014-03-28 15:16 ` [PATCH 26/75] ARM: l2c: move and add ARM L2C-2x0/L2C-310 save/resume code to non-OF Russell King
2014-03-28 15:16 ` [PATCH 27/75] ARM: l2c: clean up save/resume functions Russell King
2014-03-28 15:16 ` [PATCH 28/75] ARM: l2c: simplify l2x0 unlocking code Russell King
2014-03-28 15:16 ` [PATCH 29/75] ARM: l2c: move pl310_set_debug() into l2c-310 code Russell King
2014-03-28 15:16 ` [PATCH 30/75] ARM: l2c: add L2C-210 specific handlers Russell King
2014-03-28 15:17 ` [PATCH 31/75] ARM: l2c: implement L2C-310 erratum 727915 as a method override Russell King
2014-03-28 15:17 ` [PATCH 32/75] ARM: l2c: implement L2C-310 erratum 588369 " Russell King
2014-03-28 20:41   ` Rob Herring
2014-03-28 20:54     ` Russell King - ARM Linux
2014-03-28 15:17 ` [PATCH 33/75] ARM: l2c: use L2C-210 handlers for L2C-310 errata-less implementations Russell King
2014-03-28 15:17 ` [PATCH 34/75] ARM: l2c: add L2C-220 specific handlers Russell King
2014-03-28 15:17 ` [PATCH 35/75] ARM: l2c: convert Broadcom L2C-310 to new code Russell King
2014-03-28 15:17 ` [PATCH 36/75] ARM: l2c: remove obsolete l2x0 ops for non-OF init Russell King
2014-03-28 15:17 ` [PATCH 37/75] ARM: l2c: move type string into l2c_init_data structure Russell King
2014-03-28 15:17 ` [PATCH 38/75] ARM: l2c: add decode for L2C-220 cache ways Russell King
2014-03-28 15:17 ` [PATCH 39/75] ARM: l2c: move way size calculation data into l2c_init_data Russell King
2014-03-28 15:17 ` [PATCH 40/75] ARM: l2c: move errata configuration options to arch/arm/mm/Kconfig Russell King
2014-03-28 15:17 ` [PATCH 41/75] ARM: l2c: provide generic hook to intercept writes to secure registers Russell King
2014-03-28 20:51   ` Josh Cartwright
2014-03-28 21:00     ` Russell King - ARM Linux
2014-03-28 15:18 ` [PATCH 42/75] ARM: l2c: omap2: implement new write_sec method Russell King
2014-03-28 15:56   ` Tony Lindgren
2014-03-28 15:18 ` [PATCH 43/75] ARM: l2c: omap2: remove explicit SMI calls to enable L2 cache Russell King
2014-03-28 15:56   ` Tony Lindgren
2014-03-28 15:18 ` [PATCH 44/75] ARM: l2c: highbank: implement new write_sec method Russell King
2014-03-28 15:18 ` [PATCH 45/75] ARM: l2c: highbank: remove explicit SMI call in L2 cache initialisation Russell King
2014-03-28 15:18 ` [PATCH 46/75] ARM: l2c: ux500: implement dummy write_sec method Russell King
2014-03-28 20:46   ` Linus Walleij
2014-03-28 15:18 ` [PATCH 47/75] ARM: l2c: remove old .set_debug method Russell King
2014-03-28 15:18 ` [PATCH 48/75] ARM: l2c: implement L2C-310 erratum 752271 in core L2C code Russell King
2014-03-28 15:18 ` [PATCH 49/75] ARM: l2c: fix register naming Russell King
2014-03-28 16:00   ` Tony Lindgren
2014-03-28 21:02     ` Russell King - ARM Linux
2014-03-28 22:15       ` Tony Lindgren
2014-03-28 16:01   ` Tony Lindgren
2014-03-28 18:51   ` [STLinux Kernel] " Maxime Coquelin
2014-03-28 19:01   ` Linus Walleij
2014-03-28 15:18 ` [PATCH 50/75] ARM: l2c: add automatic enable of early BRESP Russell King
2014-03-28 15:18 ` [PATCH 51/75] ARM: l2c: remove platforms/SoCs setting " Russell King
2014-03-28 16:02   ` Tony Lindgren
2014-03-28 15:18 ` [PATCH 52/75] ARM: l2c: tegra: remove associativity and way size from aux_ctrl Russell King
2014-03-28 15:18 ` [PATCH 53/75] ARM: l2c: ux500: " Russell King
2014-03-28 20:47   ` Linus Walleij
2014-03-28 15:19 ` [PATCH 54/75] ARM: l2c: ux500: don't try to change the L2 cache auxiliary control register Russell King
2014-03-28 20:48   ` Linus Walleij
2014-03-28 15:19 ` [PATCH 55/75] ARM: l2c: cns3xxx: remove cache size override Russell King
2014-03-28 15:19 ` [PATCH 56/75] ARM: l2c: exynos: " Russell King
2014-03-28 15:19 ` [PATCH 57/75] ARM: l2c: nomadik: " Russell King
2014-03-31  6:59   ` Linus Walleij
2014-03-28 15:19 ` [PATCH 58/75] ARM: l2c: omap2: " Russell King
2014-03-28 16:03   ` Tony Lindgren
2014-03-28 21:09     ` Russell King - ARM Linux
2014-03-28 22:21       ` Tony Lindgren
2014-03-31 10:55         ` Russell King - ARM Linux
2014-03-28 15:19 ` [PATCH 59/75] ARM: l2c: prima2: " Russell King
2014-04-04 13:40   ` Barry Song
2014-04-04 14:10     ` Russell King - ARM Linux
2014-04-04 14:56       ` Barry Song
2014-03-28 15:19 ` [PATCH 60/75] ARM: l2c: shmobile: " Russell King
2014-03-28 15:19 ` [PATCH 61/75] ARM: l2c: spear13xx: " Russell King
2014-03-28 15:19 ` [PATCH 62/75] ARM: l2c: sti: " Russell King
2014-03-31  8:28   ` [[PATCH " Maxime Coquelin
2014-03-28 15:19 ` [PATCH 63/75] ARM: l2c: zynq: " Russell King
2014-04-02  8:08   ` Michal Simek
2014-04-02 11:06     ` Michal Simek
2014-04-02 11:37     ` Sekhar Nori
2014-04-03 19:13       ` Russell King - ARM Linux
2014-04-04  5:40         ` Sekhar Nori
2014-04-03 19:11     ` Russell King - ARM Linux
2014-04-04  5:26       ` Michal Simek
2014-03-28 15:19 ` [PATCH 64/75] ARM: l2c: realview: improve commentry about the L2 cache requirements Russell King
2014-03-28 15:19 ` [PATCH 65/75] ARM: l2c: kill L2X0_AUX_CTRL_MASK before anyone else makes use of this Russell King
2014-03-28 15:20 ` [PATCH 66/75] ARM: l2c: print a warning with L2C-310 caches if the cache size is modified Russell King
2014-03-28 15:20 ` [PATCH 67/75] ARM: l2c: vexpress ca9x4: move L2 cache initialisation earlier Russell King
2014-03-28 15:20 ` [PATCH 68/75] ARM: l2c: add L2C-310 power control DT properties Russell King
2014-03-28 15:20 ` [PATCH 69/75] ARM: l2c: check that DT files specify the required "cache-unified" property Russell King
2014-03-28 15:20 ` [PATCH 70/75] ARM: l2c: add warnings for stuff modifying aux_ctrl register values Russell King
2014-03-28 15:20 ` Russell King [this message]
2014-03-28 15:20 ` [PATCH 72/75] ARM: l2c: trial at enabling some Cortex-A9 optimisations Russell King
2014-03-28 15:20 ` [PATCH 73/75] ARM: l2c: move L2 cache register saving to a more sensible location Russell King
2014-04-01 18:56   ` Stephen Warren
2014-04-01 19:03     ` Stephen Warren
2014-04-01 23:09       ` Russell King - ARM Linux
2014-04-02 19:21         ` Stephen Warren
2014-04-03 18:52           ` Russell King - ARM Linux
2014-04-04 22:10             ` Stephen Warren
2014-04-01 22:59     ` Russell King - ARM Linux
2014-03-28 15:20 ` [PATCH 74/75] ARM: l2c: always enable low power modes Russell King
2014-03-28 15:42   ` Rob Herring
2014-03-28 15:51     ` Russell King - ARM Linux
2014-04-04 16:53       ` Sören Brinkmann
2014-04-04 19:17         ` Russell King - ARM Linux
2014-04-04 20:47           ` Sören Brinkmann
2014-03-28 15:20 ` [PATCH 75/75] ARM: l2c: imx: remove direct write to power control register Russell King
2014-04-03  6:33   ` Shawn Guo
2014-04-03 18:53     ` Russell King - ARM Linux
2014-04-03 23:10       ` Shawn Guo
2014-03-28 18:39 ` [PATCH 00/75] l2c series - Olof's boot failures Russell King - ARM Linux
2014-03-28 19:35   ` Matt Porter
2014-04-03 14:55 ` [PATCH 00/75] l2c series Michal Simek
2014-04-03 19:33   ` Russell King - ARM Linux
2014-04-04  7:12     ` Michal Simek
2014-04-04 19:28       ` Russell King - ARM Linux
2014-04-07  6:22         ` Michal Simek
2014-04-07  9:00           ` Russell King - ARM Linux
2014-04-07  9:12             ` Michal Simek
2014-04-07 15:52               ` Punnaiah Choudary Kalluri
2014-04-07 15:58                 ` Russell King - ARM Linux

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=E1WTYa5-0007Hi-HD@rmk-PC.arm.linux.org.uk \
    --to=rmk+kernel@arm.linux.org.uk \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).