Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d6e56a2a authored by Tony Luck's avatar Tony Luck
Browse files

[IA64] Fix CONFIG_PRINTK_TIME



There were two problems with enabling the PRINTK_TIME config
option:
1) The first calls to printk() occur before per-cpu data virtual
address is pinned into the TLB, so sched_clock() can fault.
2) sched_clock() is based on ar.itc, which may not be synchronized
across cpus.

Ken Chen started this patch, Tony Luck tinkered with it, and Jes
Sorensen perfected it.

Signed-off-by: default avatarTony Luck <tony.luck@intel.com>
parent 9d78f43d
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -352,6 +352,7 @@ start_ap:
	mov ar.rsc=0		// place RSE in enforced lazy mode
	mov ar.rsc=0		// place RSE in enforced lazy mode
	;;
	;;
	loadrs			// clear the dirty partition
	loadrs			// clear the dirty partition
	mov IA64_KR(PER_CPU_DATA)=r0	// clear physical per-CPU base
	;;
	;;
	mov ar.bspstore=r2	// establish the new RSE stack
	mov ar.bspstore=r2	// establish the new RSE stack
	;;
	;;
+4 −0
Original line number Original line Diff line number Diff line
@@ -71,6 +71,8 @@ unsigned long __per_cpu_offset[NR_CPUS];
EXPORT_SYMBOL(__per_cpu_offset);
EXPORT_SYMBOL(__per_cpu_offset);
#endif
#endif


extern void ia64_setup_printk_clock(void);

DEFINE_PER_CPU(struct cpuinfo_ia64, cpu_info);
DEFINE_PER_CPU(struct cpuinfo_ia64, cpu_info);
DEFINE_PER_CPU(unsigned long, local_per_cpu_offset);
DEFINE_PER_CPU(unsigned long, local_per_cpu_offset);
DEFINE_PER_CPU(unsigned long, ia64_phys_stacked_size_p8);
DEFINE_PER_CPU(unsigned long, ia64_phys_stacked_size_p8);
@@ -445,6 +447,8 @@ setup_arch (char **cmdline_p)
	/* process SAL system table: */
	/* process SAL system table: */
	ia64_sal_init(efi.sal_systab);
	ia64_sal_init(efi.sal_systab);


	ia64_setup_printk_clock();

#ifdef CONFIG_SMP
#ifdef CONFIG_SMP
	cpu_physical_id(0) = hard_smp_processor_id();
	cpu_physical_id(0) = hard_smp_processor_id();


+27 −0
Original line number Original line Diff line number Diff line
@@ -278,3 +278,30 @@ udelay (unsigned long usecs)
	}
	}
}
}
EXPORT_SYMBOL(udelay);
EXPORT_SYMBOL(udelay);

static unsigned long long ia64_itc_printk_clock(void)
{
	if (ia64_get_kr(IA64_KR_PER_CPU_DATA))
		return sched_clock();
	return 0;
}

static unsigned long long ia64_default_printk_clock(void)
{
	return (unsigned long long)(jiffies_64 - INITIAL_JIFFIES) *
		(1000000000/HZ);
}

unsigned long long (*ia64_printk_clock)(void) = &ia64_default_printk_clock;

unsigned long long printk_clock(void)
{
	return ia64_printk_clock();
}

void __init
ia64_setup_printk_clock(void)
{
	if (!(sal_platform_features & IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT))
		ia64_printk_clock = ia64_itc_printk_clock;
}
+27 −13
Original line number Original line Diff line number Diff line
@@ -67,6 +67,7 @@ extern unsigned long last_time_offset;
extern void (*ia64_mark_idle) (int);
extern void (*ia64_mark_idle) (int);
extern void snidle(int);
extern void snidle(int);
extern unsigned char acpi_kbd_controller_present;
extern unsigned char acpi_kbd_controller_present;
extern unsigned long long (*ia64_printk_clock)(void);


unsigned long sn_rtc_cycles_per_second;
unsigned long sn_rtc_cycles_per_second;
EXPORT_SYMBOL(sn_rtc_cycles_per_second);
EXPORT_SYMBOL(sn_rtc_cycles_per_second);
@@ -372,6 +373,16 @@ sn_scan_pcdp(void)
	}
	}
}
}


static unsigned long sn2_rtc_initial;

static unsigned long long ia64_sn2_printk_clock(void)
{
	unsigned long rtc_now = rtc_time();

	return (rtc_now - sn2_rtc_initial) *
		(1000000000 / sn_rtc_cycles_per_second);
}

/**
/**
 * sn_setup - SN platform setup routine
 * sn_setup - SN platform setup routine
 * @cmdline_p: kernel command line
 * @cmdline_p: kernel command line
@@ -386,6 +397,7 @@ void __init sn_setup(char **cmdline_p)
	u32 version = sn_sal_rev();
	u32 version = sn_sal_rev();
	extern void sn_cpu_init(void);
	extern void sn_cpu_init(void);


	sn2_rtc_initial = rtc_time();
	ia64_sn_plat_set_error_handling_features();	// obsolete
	ia64_sn_plat_set_error_handling_features();	// obsolete
	ia64_sn_set_os_feature(OSF_MCA_SLV_TO_OS_INIT_SLV);
	ia64_sn_set_os_feature(OSF_MCA_SLV_TO_OS_INIT_SLV);
	ia64_sn_set_os_feature(OSF_FEAT_LOG_SBES);
	ia64_sn_set_os_feature(OSF_FEAT_LOG_SBES);
@@ -437,19 +449,6 @@ void __init sn_setup(char **cmdline_p)
	 */
	 */
	build_cnode_tables();
	build_cnode_tables();


	/*
	 * Old PROMs do not provide an ACPI FADT. Disable legacy keyboard
	 * support here so we don't have to listen to failed keyboard probe
	 * messages.
	 */
	if (version <= 0x0209 && acpi_kbd_controller_present) {
		printk(KERN_INFO "Disabling legacy keyboard support as prom "
		       "is too old and doesn't provide FADT\n");
		acpi_kbd_controller_present = 0;
	}

	printk("SGI SAL version %x.%02x\n", version >> 8, version & 0x00FF);

	status =
	status =
	    ia64_sal_freq_base(SAL_FREQ_BASE_REALTIME_CLOCK, &ticks_per_sec,
	    ia64_sal_freq_base(SAL_FREQ_BASE_REALTIME_CLOCK, &ticks_per_sec,
			       &drift);
			       &drift);
@@ -463,6 +462,21 @@ void __init sn_setup(char **cmdline_p)


	platform_intr_list[ACPI_INTERRUPT_CPEI] = IA64_CPE_VECTOR;
	platform_intr_list[ACPI_INTERRUPT_CPEI] = IA64_CPE_VECTOR;


	ia64_printk_clock = ia64_sn2_printk_clock;

	/*
	 * Old PROMs do not provide an ACPI FADT. Disable legacy keyboard
	 * support here so we don't have to listen to failed keyboard probe
	 * messages.
	 */
	if (version <= 0x0209 && acpi_kbd_controller_present) {
		printk(KERN_INFO "Disabling legacy keyboard support as prom "
		       "is too old and doesn't provide FADT\n");
		acpi_kbd_controller_present = 0;
	}

	printk("SGI SAL version %x.%02x\n", version >> 8, version & 0x00FF);

	/*
	/*
	 * we set the default root device to /dev/hda
	 * we set the default root device to /dev/hda
	 * to make simulation easy
	 * to make simulation easy