lkml.org 
[lkml]   [2010]   [Jan]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[PATCH] x86, UV: Fix RTC latency bug by reading replicated cachelines
Fix an RTC read latency bug by using replicated cachelines to read the RTC
timer on SGI UV node controllers (HUB) rev 2.0 or greater.

Signed-off-by: Dimitri Sivanich <sivanich@sgi.com>

---

Patch requires "Add function retrieving node controller revision number" patch.

arch/x86/kernel/uv_time.c | 13 ++++++++++++-
drivers/char/uv_mmtimer.c | 17 ++++++++++++-----
2 files changed, 24 insertions(+), 6 deletions(-)

Index: linux/arch/x86/kernel/uv_time.c
===================================================================
--- linux.orig/arch/x86/kernel/uv_time.c 2010-01-14 11:52:44.000000000 -0600
+++ linux/arch/x86/kernel/uv_time.c 2010-01-14 11:56:57.000000000 -0600
@@ -282,10 +282,21 @@ static int uv_rtc_unset_timer(int cpu, i

/*
* Read the RTC.
+ *
+ * Starting with HUB rev 2.0, the UV RTC register is replicated across all
+ * cachelines of it's own page. This allows faster simultaneous reads
+ * from a given socket.
*/
static cycle_t uv_read_rtc(struct clocksource *cs)
{
- return (cycle_t)uv_read_local_mmr(UVH_RTC);
+ unsigned long offset;
+
+ if (uv_get_min_hub_revision_id() == 1)
+ offset = 0;
+ else
+ offset = (uv_blade_processor_id() * L1_CACHE_BYTES) % PAGE_SIZE;
+
+ return (cycle_t)uv_read_local_mmr(UVH_RTC | offset);
}

/*
Index: linux/drivers/char/uv_mmtimer.c
===================================================================
--- linux.orig/drivers/char/uv_mmtimer.c 2010-01-14 11:52:45.000000000 -0600
+++ linux/drivers/char/uv_mmtimer.c 2010-01-14 11:56:57.000000000 -0600
@@ -89,12 +89,19 @@ static long uv_mmtimer_ioctl(struct file
switch (cmd) {
case MMTIMER_GETOFFSET: /* offset of the counter */
/*
- * UV RTC register is on its own page
+ * Starting with HUB rev 2.0, the UV RTC register is
+ * replicated across all cachelines of it's own page.
+ * This allows faster simultaneous reads from a given socket.
+ *
+ * The offset returned is in 64 bit units.
*/
- if (PAGE_SIZE <= (1 << 16))
- ret = ((UV_LOCAL_MMR_BASE | UVH_RTC) & (PAGE_SIZE-1))
- / 8;
- else
+ if (PAGE_SIZE <= (1 << 16)) {
+ if (uv_get_min_hub_revision_id() == 1)
+ ret = 0;
+ else
+ ret = ((uv_blade_processor_id() *
+ L1_CACHE_BYTES) % PAGE_SIZE) / 8;
+ } else
ret = -ENOSYS;
break;


\
 
 \ /
  Last update: 2010-01-19 15:43    [W:0.082 / U:0.784 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site