Skip to content

Commit c8c3735

Browse files
committed
parisc: Enhance detection of synchronous cr16 clocksources
The cr16 clocks of the physical PARISC CPUs are usually nonsynchronous. Nevertheless, it seems that each CPU socket (which holds two cores) of PA8800 and PA8900 CPUs (e.g. in a C8000 workstation) is fed by the same clock source, which makes the cr16 clocks of each CPU socket syncronous. Let's try to detect such situations and mark the cr16 clocksource stable on single-socket and single-core machines. Signed-off-by: Helge Deller <[email protected]>
1 parent c3e5523 commit c8c3735

File tree

3 files changed

+26
-5
lines changed

3 files changed

+26
-5
lines changed

arch/parisc/include/asm/processor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ struct cpuinfo_parisc {
103103
unsigned long bh_count; /* number of times bh was invoked */
104104
unsigned long fp_rev;
105105
unsigned long fp_model;
106+
unsigned long cpu_num; /* CPU number from PAT firmware */
107+
unsigned long cpu_loc; /* CPU location from PAT firmware */
106108
unsigned int state;
107109
struct parisc_device *dev;
108110
unsigned long loops_per_jiffy;

arch/parisc/kernel/processor.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ static int processor_probe(struct parisc_device *dev)
9494
unsigned long txn_addr;
9595
unsigned long cpuid;
9696
struct cpuinfo_parisc *p;
97-
struct pdc_pat_cpu_num cpu_info __maybe_unused;
97+
struct pdc_pat_cpu_num cpu_info = { };
9898

9999
#ifdef CONFIG_SMP
100100
if (num_online_cpus() >= nr_cpu_ids) {
@@ -113,6 +113,7 @@ static int processor_probe(struct parisc_device *dev)
113113
*/
114114
cpuid = boot_cpu_data.cpu_count;
115115
txn_addr = dev->hpa.start; /* for legacy PDC */
116+
cpu_info.cpu_num = cpu_info.cpu_loc = cpuid;
116117

117118
#ifdef CONFIG_64BIT
118119
if (is_pdc_pat()) {
@@ -180,6 +181,8 @@ static int processor_probe(struct parisc_device *dev)
180181
p->hpa = dev->hpa.start; /* save CPU hpa */
181182
p->cpuid = cpuid; /* save CPU id */
182183
p->txn_addr = txn_addr; /* save CPU IRQ address */
184+
p->cpu_num = cpu_info.cpu_num;
185+
p->cpu_loc = cpu_info.cpu_loc;
183186
#ifdef CONFIG_SMP
184187
/*
185188
** FIXME: review if any other initialization is clobbered

arch/parisc/kernel/time.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -243,14 +243,30 @@ void __init time_init(void)
243243
static int __init init_cr16_clocksource(void)
244244
{
245245
/*
246-
* The cr16 interval timers are not syncronized across CPUs, so mark
247-
* them unstable and lower rating on SMP systems.
246+
* The cr16 interval timers are not syncronized across CPUs on
247+
* different sockets, so mark them unstable and lower rating on
248+
* multi-socket SMP systems.
248249
*/
249250
if (num_online_cpus() > 1) {
250-
clocksource_cr16.flags = CLOCK_SOURCE_UNSTABLE;
251-
clocksource_cr16.rating = 0;
251+
int cpu;
252+
unsigned long cpu0_loc;
253+
cpu0_loc = per_cpu(cpu_data, 0).cpu_loc;
254+
255+
for_each_online_cpu(cpu) {
256+
if (cpu0_loc == per_cpu(cpu_data, cpu).cpu_loc)
257+
continue;
258+
259+
clocksource_cr16.name = "cr16_unstable";
260+
clocksource_cr16.flags = CLOCK_SOURCE_UNSTABLE;
261+
clocksource_cr16.rating = 0;
262+
break;
263+
}
252264
}
253265

266+
/* XXX: We may want to mark sched_clock stable here if cr16 clocks are
267+
* in sync:
268+
* (clocksource_cr16.flags == CLOCK_SOURCE_IS_CONTINUOUS) */
269+
254270
/* register at clocksource framework */
255271
clocksource_register_hz(&clocksource_cr16,
256272
100 * PAGE0->mem_10msec);

0 commit comments

Comments
 (0)