x86, UV: Add function retrieving node controller revision number
Subsystems (3)
PATCH 1/1 x86, UV: Add function retrieving node controller revision number
Add function for determining the revision id of the SGI UV node controller chip (HUB). This function is needed in a subsequent patch.
--- arch/x86/include/asm/uv/uv_hub.h | 12 ++++++++++++ arch/x86/kernel/apic/x2apic_uv_x.c | 6 ++++++ 2 files changed, 18 insertions(+)
arch/x86/include/asm/uv/uv_hub.h +12 -0
@@ -496,5 +496,17 @@ static inline void uv_hub_send_ipi(int puv_write_global_mmr64 (pnode,UVH_IPI_INT , val); } +/* +* Get the minimum revision number of the hub chips within the partition. +* 1 - initial rev 1.0 silicon +* 2 - rev 2.0 production silicon +*/ +static inline int uv_get_min_hub_revision_id (void ) +{ +extern int uv_min_hub_revision_id; + +return uv_min_hub_revision_id; +} +#endif /* CONFIG_X86_64 */ #endif /* _ASM_X86_UV_UV_HUB_H */
arch/x86/kernel/apic/x2apic_uv_x.c +6 -0
@@ -36,6 +36,8 @@ DEFINE_PER_CPU(int, x2apic_extra_bits);static enum uv_system_type uv_system_type;static u64 gru_start_paddr, gru_end_paddr; +int uv_min_hub_revision_id; +EXPORT_SYMBOL_GPL (uv_min_hub_revision_id);static inline bool is_GRU_range (u64 start,u64 end) {
@@ -55,6 +57,10 @@ static int early_get_nodeid(void) mmr =early_ioremap (UV_LOCAL_MMR_BASE |UVH_NODE_ID ,sizeof (*mmr)); node_id.v = *mmr;early_iounmap (mmr,sizeof (*mmr)); + +/* Currently, all blades have same revision number */ + uv_min_hub_revision_id = node_id.s.revision; +return node_id.s.node_id; }
Quoted 10 lines · Jack Steiner
Add function for determining the revision id of the SGI UV node controller chip (HUB). This function is needed in a subsequent patch.
Signed-off-by Jack Steiner <[email protected]>--- arch/x86/include/asm/uv/uv_hub.h | 12 ++++++++++++ arch/x86/kernel/apic/x2apic_uv_x.c | 6 ++++++ 2 files changed, 18 insertions(+)
We'd need to see those two patches together i guess.
Ingo
PATCH 1/1 x86, UV: Read RTC using 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.
---
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(-)
arch/x86/kernel/uv_time.c +12 -1
@@ -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); }/*
drivers/char/uv_mmtimer.c +12 -5
@@ -89,12 +89,19 @@ static long uv_mmtimer_ioctl(struct fileswitch (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 ;
[tip:x86/urgent] x86, uv: Add function retrieving node controller revision number
In reply to Jack SteinerCommit-ID: 7a1110e861b2666ac09f5708d6fbe71d18ce64bb Gitweb: http://git.kernel.org/tip/7a1110e861b2666ac09f5708d6fbe71d18ce64bb Author: Jack Steiner <[email protected]> AuthorDate: Tue, 12 Jan 2010 15:09:04 -0600 Committer: H. Peter Anvin <[email protected]> CommitDate: Fri, 15 Jan 2010 11:08:55 -0800
x86, uv: Add function retrieving node controller revision number
Add function for determining the revision id of the SGI UV node controller chip (HUB). This function is needed in a subsequent patch.
LKML-Reference: <[email protected]>
--- arch/x86/include/asm/uv/uv_hub.h | 12 ++++++++++++ arch/x86/kernel/apic/x2apic_uv_x.c | 6 ++++++ 2 files changed, 18 insertions(+), 0 deletions(-)
arch/x86/include/asm/uv/uv_hub.h +12 -0
@@ -495,5 +495,17 @@ static inline void uv_hub_send_ipi(int pnode, int apicid, int vector)uv_write_global_mmr64 (pnode,UVH_IPI_INT , val); } +/* +* Get the minimum revision number of the hub chips within the partition. +* 1 - initial rev 1.0 silicon +* 2 - rev 2.0 production silicon +*/ +static inline int uv_get_min_hub_revision_id (void ) +{ +extern int uv_min_hub_revision_id; + +return uv_min_hub_revision_id; +} +#endif /* CONFIG_X86_64 */ #endif /* _ASM_X86_UV_UV_HUB_H */
arch/x86/kernel/apic/x2apic_uv_x.c +6 -0
@@ -36,6 +36,8 @@ DEFINE_PER_CPU(int, x2apic_extra_bits);static enum uv_system_type uv_system_type;static u64 gru_start_paddr, gru_end_paddr; +int uv_min_hub_revision_id; +EXPORT_SYMBOL_GPL (uv_min_hub_revision_id);static inline bool is_GRU_range (u64 start,u64 end) {
@@ -55,6 +57,10 @@ static int early_get_nodeid(void) mmr =early_ioremap (UV_LOCAL_MMR_BASE |UVH_NODE_ID ,sizeof (*mmr)); node_id.v = *mmr;early_iounmap (mmr,sizeof (*mmr)); + +/* Currently, all blades have same revision number */ + uv_min_hub_revision_id = node_id.s.revision; +return node_id.s.node_id; }
PATCH 1/1 x86, UV: Fix RTC latency bug by reading replicated cachelines
In reply to Dimitri SivanichFix 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.
---
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(-)
arch/x86/kernel/uv_time.c +12 -1
@@ -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); }/*
drivers/char/uv_mmtimer.c +12 -5
@@ -89,12 +89,19 @@ static long uv_mmtimer_ioctl(struct fileswitch (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 ;
Re: [PATCH] x86, UV: Fix RTC latency bug by reading replicated cachelines
Quoted 13 lines · Dimitri Sivanich
+++
linux/drivers/char/uv_mmtimer.c2010-01-14 11:56:57.000000000 -0600drivers/char/uv_mmtimer.c +5
-2@@ -89,12 +89,19 @@ static long uv_mmtimer_ioctl(struct fileswitch (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 ))
drivers/char/uv_mmtimer.c static long uv_mmtimer_ioctl(struct file · line 104
Quoted 10 lines
drivers/char/uv_mmtimer.c +7
-3- 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
That 64K PAGE_SIZE check in the ioctl looks rather weird. What is the purpose of it?
Ingo
Re: [PATCH] x86, UV: Fix RTC latency bug by reading replicated cachelines
Quoted 21 lines · Ingo Molnar
Quoted 18 lines · Dimitri Sivanich
+++
linux/drivers/char/uv_mmtimer.c2010-01-14 11:56:57.000000000 -0600drivers/char/uv_mmtimer.c +7
-5@@ -89,12 +89,19 @@ static long uv_mmtimer_ioctl(struct fileswitch (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 )
Quoted 8 lines
drivers/char/uv_mmtimer.c static long uv_mmtimer_ioctl(struct file · line 104
Quoted 5 lines
drivers/char/uv_mmtimer.c +5
-0+ ret =0 ; + else + ret = ((uv_blade_processor_id () * +L1_CACHE_BYTES ) %PAGE_SIZE ) /8 ; + }else That 64K
PAGE_SIZEcheck in the ioctl looks rather weird. What is the purpose of it?
Checking for > 64k pages is really a holdover from similar code on ia64. I've taken it out with a modified version of this patch that I'll send shortly.
Re: [PATCH] x86, UV: Fix RTC latency bug by reading replicated cachelines
In reply to Ingo MolnarFor 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.
---
arch/x86/kernel/uv_time.c | 13 ++++++++++++- drivers/char/uv_mmtimer.c | 18 +++++++++++------- 2 files changed, 23 insertions(+), 8 deletions(-)
arch/x86/kernel/uv_time.c +12 -1
@@ -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); }/*
drivers/char/uv_mmtimer.c +11 -7
@@ -89,13 +89,17 @@ static long uv_mmtimer_ioctl(struct fileswitch (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 */
@@ -115,8 +119,8 @@ static long uv_mmtimer_ioctl(struct file 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 :
[tip:x86/urgent] x86, UV: Fix RTC latency bug by reading replicated cachelines
Commit-ID: aca3bb5910119d4cf6c28568a642582efb4cc14a Gitweb: http://git.kernel.org/tip/aca3bb5910119d4cf6c28568a642582efb4cc14a Author: Dimitri Sivanich <[email protected]> AuthorDate: Fri, 22 Jan 2010 09:41:40 -0600 Committer: Ingo Molnar <[email protected]> CommitDate: Wed, 27 Jan 2010 11:33:53 +0100
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.
LKML-Reference: <[email protected]>
--- arch/x86/kernel/uv_time.c | 13 ++++++++++++- drivers/char/uv_mmtimer.c | 18 +++++++++++------- 2 files changed, 23 insertions(+), 8 deletions(-)
arch/x86/kernel/uv_time.c +12 -1
@@ -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); }/*
drivers/char/uv_mmtimer.c +11 -7
@@ -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 */
@@ -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 :