Re: [Xen-devel] [PATCH v4 07/12] x86/cpuidle: patch some indirect calls to direct ones

2018-10-04 Thread Andrew Cooper
On 02/10/18 11:15, Jan Beulich wrote:
> For now only the ones used during entering/exiting of idle states are
> converted. Additionally pm_idle{,_save} and lapic_timer_{on,off} can't
> be converted, as they may get established rather late (when Dom0 is
> already active).
>
> Note that for patching to be deferred until after the pre-SMP initcalls
> (from where cpuidle_init_cpu() runs the first time) the pointers need to
> start out as NULL.
>
> Signed-off-by: Jan Beulich 
> Reviewed-by: Wei Liu 

Reviewed-by: Andrew Cooper 

___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH v4 07/12] x86/cpuidle: patch some indirect calls to direct ones

2018-10-02 Thread Jan Beulich
For now only the ones used during entering/exiting of idle states are
converted. Additionally pm_idle{,_save} and lapic_timer_{on,off} can't
be converted, as they may get established rather late (when Dom0 is
already active).

Note that for patching to be deferred until after the pre-SMP initcalls
(from where cpuidle_init_cpu() runs the first time) the pointers need to
start out as NULL.

Signed-off-by: Jan Beulich 
Reviewed-by: Wei Liu 
---
v2: Drop open-coded numbers from macro invocations.

--- a/xen/arch/x86/acpi/cpu_idle.c
+++ b/xen/arch/x86/acpi/cpu_idle.c
@@ -102,8 +102,6 @@ bool lapic_timer_init(void)
 return true;
 }
 
-static uint64_t (*__read_mostly tick_to_ns)(uint64_t) = acpi_pm_tick_to_ns;
-
 void (*__read_mostly pm_idle_save)(void);
 unsigned int max_cstate __read_mostly = ACPI_PROCESSOR_MAX_POWER - 1;
 integer_param("max_cstate", max_cstate);
@@ -289,9 +287,9 @@ static uint64_t acpi_pm_ticks_elapsed(ui
 return ((0x - t1) + t2 +1);
 }
 
-uint64_t (*__read_mostly cpuidle_get_tick)(void) = get_acpi_pm_tick;
-static uint64_t (*__read_mostly ticks_elapsed)(uint64_t, uint64_t)
-= acpi_pm_ticks_elapsed;
+uint64_t (*__read_mostly cpuidle_get_tick)(void);
+static uint64_t (*__read_mostly tick_to_ns)(uint64_t);
+static uint64_t (*__read_mostly ticks_elapsed)(uint64_t, uint64_t);
 
 static void print_acpi_power(uint32_t cpu, struct acpi_processor_power *power)
 {
@@ -547,7 +545,7 @@ void update_idle_stats(struct acpi_proce
struct acpi_processor_cx *cx,
uint64_t before, uint64_t after)
 {
-int64_t sleep_ticks = ticks_elapsed(before, after);
+int64_t sleep_ticks = alternative_call(ticks_elapsed, before, after);
 /* Interrupts are disabled */
 
 spin_lock(>stat_lock);
@@ -555,7 +553,8 @@ void update_idle_stats(struct acpi_proce
 cx->usage++;
 if ( sleep_ticks > 0 )
 {
-power->last_residency = tick_to_ns(sleep_ticks) / 1000UL;
+power->last_residency = alternative_call(tick_to_ns, sleep_ticks) /
+1000UL;
 cx->time += sleep_ticks;
 }
 power->last_state = >states[0];
@@ -635,7 +634,7 @@ static void acpi_processor_idle(void)
 if ( cx->type == ACPI_STATE_C1 || local_apic_timer_c2_ok )
 {
 /* Get start time (ticks) */
-t1 = cpuidle_get_tick();
+t1 = alternative_call(cpuidle_get_tick);
 /* Trace cpu idle entry */
 TRACE_4D(TRC_PM_IDLE_ENTRY, cx->idx, t1, exp, pred);
 
@@ -644,7 +643,7 @@ static void acpi_processor_idle(void)
 /* Invoke C2 */
 acpi_idle_do_entry(cx);
 /* Get end time (ticks) */
-t2 = cpuidle_get_tick();
+t2 = alternative_call(cpuidle_get_tick);
 trace_exit_reason(irq_traced);
 /* Trace cpu idle exit */
 TRACE_6D(TRC_PM_IDLE_EXIT, cx->idx, t2,
@@ -666,7 +665,7 @@ static void acpi_processor_idle(void)
 lapic_timer_off();
 
 /* Get start time (ticks) */
-t1 = cpuidle_get_tick();
+t1 = alternative_call(cpuidle_get_tick);
 /* Trace cpu idle entry */
 TRACE_4D(TRC_PM_IDLE_ENTRY, cx->idx, t1, exp, pred);
 
@@ -717,7 +716,7 @@ static void acpi_processor_idle(void)
 }
 
 /* Get end time (ticks) */
-t2 = cpuidle_get_tick();
+t2 = alternative_call(cpuidle_get_tick);
 
 /* recovering TSC */
 cstate_restore_tsc();
@@ -827,11 +826,20 @@ int cpuidle_init_cpu(unsigned int cpu)
 {
 unsigned int i;
 
-if ( cpu == 0 && boot_cpu_has(X86_FEATURE_NONSTOP_TSC) )
+if ( cpu == 0 && system_state < SYS_STATE_active )
 {
-cpuidle_get_tick = get_stime_tick;
-ticks_elapsed = stime_ticks_elapsed;
-tick_to_ns = stime_tick_to_ns;
+if ( boot_cpu_has(X86_FEATURE_NONSTOP_TSC) )
+{
+cpuidle_get_tick = get_stime_tick;
+ticks_elapsed = stime_ticks_elapsed;
+tick_to_ns = stime_tick_to_ns;
+}
+else
+{
+cpuidle_get_tick = get_acpi_pm_tick;
+ticks_elapsed = acpi_pm_ticks_elapsed;
+tick_to_ns = acpi_pm_tick_to_ns;
+}
 }
 
 acpi_power = xzalloc(struct acpi_processor_power);
--- a/xen/arch/x86/cpu/mwait-idle.c
+++ b/xen/arch/x86/cpu/mwait-idle.c
@@ -778,7 +778,7 @@ static void mwait_idle(void)
if (!(lapic_timer_reliable_states & (1 << cstate)))
lapic_timer_off();
 
-   before = cpuidle_get_tick();
+   before = alternative_call(cpuidle_get_tick);
TRACE_4D(TRC_PM_IDLE_ENTRY, cx->type, before, exp, pred);
 
update_last_cx_stat(power, cx, before);
@@ -786,7 +786,7 @@ static void mwait_idle(void)
if (cpu_is_haltable(cpu))
mwait_idle_with_hints(eax, MWAIT_ECX_INTERRUPT_BREAK);
 
-   after =