Skip to content

Commit

Permalink
x86, UV: Fix RTC latency bug by reading replicated cachelines
Browse files Browse the repository at this point in the history
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: Dimitri Sivanich <sivanich@sgi.com>
Cc: Jack Steiner <steiner@sgi.com>
LKML-Reference: <20100122154140.GB4975@sgi.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
  • Loading branch information
Dimitri Sivanich authored and Ingo Molnar committed Jan 27, 2010
1 parent e0b5f80 commit aca3bb5
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 8 deletions.
13 changes: 12 additions & 1 deletion arch/x86/kernel/uv_time.c
Original file line number Diff line number Diff line change
Expand Up @@ -282,10 +282,21 @@ static int uv_rtc_unset_timer(int cpu, int force)

/*
* 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);
}

/*
Expand Down
18 changes: 11 additions & 7 deletions drivers/char/uv_mmtimer.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,17 @@ static long uv_mmtimer_ioctl(struct file *file, unsigned int cmd,
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;
if (uv_get_min_hub_revision_id() == 1)
ret = 0;
else
ret = -ENOSYS;
ret = ((uv_blade_processor_id() * L1_CACHE_BYTES) %
PAGE_SIZE) / 8;
break;

case MMTIMER_GETRES: /* resolution of the clock in 10^-15 s */
Expand All @@ -115,8 +119,8 @@ static long uv_mmtimer_ioctl(struct file *file, unsigned int cmd,
ret = hweight64(UVH_RTC_REAL_TIME_CLOCK_MASK);
break;

case MMTIMER_MMAPAVAIL: /* can we mmap the clock into userspace? */
ret = (PAGE_SIZE <= (1 << 16)) ? 1 : 0;
case MMTIMER_MMAPAVAIL:
ret = 1;
break;

case MMTIMER_GETCOUNTER:
Expand Down

0 comments on commit aca3bb5

Please sign in to comment.