Commit aca3bb59 authored by Dimitri Sivanich's avatar Dimitri Sivanich Committed by Ingo Molnar

x86, UV: Fix RTC latency bug by reading replicated cachelines

For SGI UV node controllers (HUB) rev 2.0 or greater, use
replicated cachelines to read the RTC timer.  This optimization
allows faster simulataneous reads from a given socket.
Signed-off-by: default avatarDimitri Sivanich <sivanich@sgi.com>
Cc: Jack Steiner <steiner@sgi.com>
LKML-Reference: <20100122154140.GB4975@sgi.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent e0b5f80d
...@@ -282,10 +282,21 @@ static int uv_rtc_unset_timer(int cpu, int force) ...@@ -282,10 +282,21 @@ static int uv_rtc_unset_timer(int cpu, int force)
/* /*
* Read the RTC. * 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) 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);
} }
/* /*
......
...@@ -89,13 +89,17 @@ static long uv_mmtimer_ioctl(struct file *file, unsigned int cmd, ...@@ -89,13 +89,17 @@ static long uv_mmtimer_ioctl(struct file *file, unsigned int cmd,
switch (cmd) { switch (cmd) {
case MMTIMER_GETOFFSET: /* offset of the counter */ 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)) if (uv_get_min_hub_revision_id() == 1)
ret = ((UV_LOCAL_MMR_BASE | UVH_RTC) & (PAGE_SIZE-1)) ret = 0;
/ 8;
else else
ret = -ENOSYS; ret = ((uv_blade_processor_id() * L1_CACHE_BYTES) %
PAGE_SIZE) / 8;
break; break;
case MMTIMER_GETRES: /* resolution of the clock in 10^-15 s */ case MMTIMER_GETRES: /* resolution of the clock in 10^-15 s */
...@@ -115,8 +119,8 @@ static long uv_mmtimer_ioctl(struct file *file, unsigned int cmd, ...@@ -115,8 +119,8 @@ static long uv_mmtimer_ioctl(struct file *file, unsigned int cmd,
ret = hweight64(UVH_RTC_REAL_TIME_CLOCK_MASK); ret = hweight64(UVH_RTC_REAL_TIME_CLOCK_MASK);
break; break;
case MMTIMER_MMAPAVAIL: /* can we mmap the clock into userspace? */ case MMTIMER_MMAPAVAIL:
ret = (PAGE_SIZE <= (1 << 16)) ? 1 : 0; ret = 1;
break; break;
case MMTIMER_GETCOUNTER: case MMTIMER_GETCOUNTER:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment