mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-14 17:53:39 +00:00
x86/oprofile: Implement multiplexing setup/shutdown functions
This patch implements nmi_setup_mux() and nmi_shutdown_mux() functions to setup/shutdown multiplexing. Multiplexing code in nmi_int.c is now much more separated. Signed-off-by: Robert Richter <robert.richter@amd.com>
This commit is contained in:
parent
7e7478c6bc
commit
6ab82f958a
@ -106,9 +106,35 @@ inline int op_x86_phys_to_virt(int phys)
|
|||||||
return __get_cpu_var(switch_index) + phys;
|
return __get_cpu_var(switch_index) + phys;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void nmi_shutdown_mux(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for_each_possible_cpu(i) {
|
||||||
|
kfree(per_cpu(cpu_msrs, i).multiplex);
|
||||||
|
per_cpu(cpu_msrs, i).multiplex = NULL;
|
||||||
|
per_cpu(switch_index, i) = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int nmi_setup_mux(void)
|
||||||
|
{
|
||||||
|
size_t multiplex_size =
|
||||||
|
sizeof(struct op_msr) * model->num_virt_counters;
|
||||||
|
int i;
|
||||||
|
for_each_possible_cpu(i) {
|
||||||
|
per_cpu(cpu_msrs, i).multiplex =
|
||||||
|
kmalloc(multiplex_size, GFP_KERNEL);
|
||||||
|
if (!per_cpu(cpu_msrs, i).multiplex)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
inline int op_x86_phys_to_virt(int phys) { return phys; }
|
inline int op_x86_phys_to_virt(int phys) { return phys; }
|
||||||
|
static inline void nmi_shutdown_mux(void) { }
|
||||||
|
static inline int nmi_setup_mux(void) { return 1; }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -120,51 +146,27 @@ static void free_msrs(void)
|
|||||||
per_cpu(cpu_msrs, i).counters = NULL;
|
per_cpu(cpu_msrs, i).counters = NULL;
|
||||||
kfree(per_cpu(cpu_msrs, i).controls);
|
kfree(per_cpu(cpu_msrs, i).controls);
|
||||||
per_cpu(cpu_msrs, i).controls = NULL;
|
per_cpu(cpu_msrs, i).controls = NULL;
|
||||||
|
|
||||||
#ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX
|
|
||||||
kfree(per_cpu(cpu_msrs, i).multiplex);
|
|
||||||
per_cpu(cpu_msrs, i).multiplex = NULL;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int allocate_msrs(void)
|
static int allocate_msrs(void)
|
||||||
{
|
{
|
||||||
int success = 1;
|
|
||||||
size_t controls_size = sizeof(struct op_msr) * model->num_controls;
|
size_t controls_size = sizeof(struct op_msr) * model->num_controls;
|
||||||
size_t counters_size = sizeof(struct op_msr) * model->num_counters;
|
size_t counters_size = sizeof(struct op_msr) * model->num_counters;
|
||||||
#ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX
|
|
||||||
size_t multiplex_size = sizeof(struct op_msr) * model->num_virt_counters;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for_each_possible_cpu(i) {
|
for_each_possible_cpu(i) {
|
||||||
per_cpu(cpu_msrs, i).counters = kmalloc(counters_size,
|
per_cpu(cpu_msrs, i).counters = kmalloc(counters_size,
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!per_cpu(cpu_msrs, i).counters) {
|
if (!per_cpu(cpu_msrs, i).counters)
|
||||||
success = 0;
|
return 0;
|
||||||
break;
|
|
||||||
}
|
|
||||||
per_cpu(cpu_msrs, i).controls = kmalloc(controls_size,
|
per_cpu(cpu_msrs, i).controls = kmalloc(controls_size,
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!per_cpu(cpu_msrs, i).controls) {
|
if (!per_cpu(cpu_msrs, i).controls)
|
||||||
success = 0;
|
return 0;
|
||||||
break;
|
|
||||||
}
|
|
||||||
#ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX
|
|
||||||
per_cpu(cpu_msrs, i).multiplex =
|
|
||||||
kmalloc(multiplex_size, GFP_KERNEL);
|
|
||||||
if (!per_cpu(cpu_msrs, i).multiplex) {
|
|
||||||
success = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!success)
|
return 1;
|
||||||
free_msrs();
|
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX
|
#ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX
|
||||||
@ -218,11 +220,15 @@ static int nmi_setup(void)
|
|||||||
int cpu;
|
int cpu;
|
||||||
|
|
||||||
if (!allocate_msrs())
|
if (!allocate_msrs())
|
||||||
return -ENOMEM;
|
err = -ENOMEM;
|
||||||
|
else if (!nmi_setup_mux())
|
||||||
|
err = -ENOMEM;
|
||||||
|
else
|
||||||
|
err = register_die_notifier(&profile_exceptions_nb);
|
||||||
|
|
||||||
err = register_die_notifier(&profile_exceptions_nb);
|
|
||||||
if (err) {
|
if (err) {
|
||||||
free_msrs();
|
free_msrs();
|
||||||
|
nmi_shutdown_mux();
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,9 +320,6 @@ static void nmi_cpu_shutdown(void *dummy)
|
|||||||
apic_write(APIC_LVTPC, per_cpu(saved_lvtpc, cpu));
|
apic_write(APIC_LVTPC, per_cpu(saved_lvtpc, cpu));
|
||||||
apic_write(APIC_LVTERR, v);
|
apic_write(APIC_LVTERR, v);
|
||||||
nmi_cpu_restore_registers(msrs);
|
nmi_cpu_restore_registers(msrs);
|
||||||
#ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX
|
|
||||||
per_cpu(switch_index, cpu) = 0;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nmi_shutdown(void)
|
static void nmi_shutdown(void)
|
||||||
@ -326,6 +329,7 @@ static void nmi_shutdown(void)
|
|||||||
nmi_enabled = 0;
|
nmi_enabled = 0;
|
||||||
on_each_cpu(nmi_cpu_shutdown, NULL, 1);
|
on_each_cpu(nmi_cpu_shutdown, NULL, 1);
|
||||||
unregister_die_notifier(&profile_exceptions_nb);
|
unregister_die_notifier(&profile_exceptions_nb);
|
||||||
|
nmi_shutdown_mux();
|
||||||
msrs = &get_cpu_var(cpu_msrs);
|
msrs = &get_cpu_var(cpu_msrs);
|
||||||
model->shutdown(msrs);
|
model->shutdown(msrs);
|
||||||
free_msrs();
|
free_msrs();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user