powerpc/pseries: Factor out DTL buffer allocation and registration routines

Introduce new helpers for DTL buffer allocation and registration and
have the existing code use those.

Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
[mpe: Don't split error messages across lines, for grepability]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
Naveen N. Rao 2019-07-03 22:33:56 +05:30 committed by Michael Ellerman
parent 5b3306f084
commit 1c85a2a194
3 changed files with 54 additions and 50 deletions

View File

@ -175,6 +175,9 @@ extern struct kmem_cache *dtl_cache;
*/
extern void (*dtl_consumer)(struct dtl_entry *entry, u64 index);
extern void register_dtl_buffer(int cpu);
extern void alloc_dtl_buffers(void);
#endif /* CONFIG_PPC_BOOK3S */
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_LPPACA_H */

View File

@ -65,13 +65,59 @@ EXPORT_SYMBOL(plpar_hcall);
EXPORT_SYMBOL(plpar_hcall9);
EXPORT_SYMBOL(plpar_hcall_norets);
void alloc_dtl_buffers(void)
{
int cpu;
struct paca_struct *pp;
struct dtl_entry *dtl;
for_each_possible_cpu(cpu) {
pp = paca_ptrs[cpu];
dtl = kmem_cache_alloc(dtl_cache, GFP_KERNEL);
if (!dtl) {
pr_warn("Failed to allocate dispatch trace log for cpu %d\n",
cpu);
pr_warn("Stolen time statistics will be unreliable\n");
break;
}
pp->dtl_ridx = 0;
pp->dispatch_log = dtl;
pp->dispatch_log_end = dtl + N_DISPATCH_LOG;
pp->dtl_curr = dtl;
}
}
void register_dtl_buffer(int cpu)
{
long ret;
struct paca_struct *pp;
struct dtl_entry *dtl;
int hwcpu = get_hard_smp_processor_id(cpu);
pp = paca_ptrs[cpu];
dtl = pp->dispatch_log;
if (dtl) {
pp->dtl_ridx = 0;
pp->dtl_curr = dtl;
lppaca_of(cpu).dtl_idx = 0;
/* hypervisor reads buffer length from this field */
dtl->enqueue_to_dispatch_time = cpu_to_be32(DISPATCH_LOG_BYTES);
ret = register_dtl(hwcpu, __pa(dtl));
if (ret)
pr_err("WARNING: DTL registration of cpu %d (hw %d) failed with %ld\n",
cpu, hwcpu, ret);
lppaca_of(cpu).dtl_enable_mask = DTL_LOG_PREEMPT;
}
}
void vpa_init(int cpu)
{
int hwcpu = get_hard_smp_processor_id(cpu);
unsigned long addr;
long ret;
struct paca_struct *pp;
struct dtl_entry *dtl;
/*
* The spec says it "may be problematic" if CPU x registers the VPA of
@ -112,22 +158,7 @@ void vpa_init(int cpu)
/*
* Register dispatch trace log, if one has been allocated.
*/
pp = paca_ptrs[cpu];
dtl = pp->dispatch_log;
if (dtl) {
pp->dtl_ridx = 0;
pp->dtl_curr = dtl;
lppaca_of(cpu).dtl_idx = 0;
/* hypervisor reads buffer length from this field */
dtl->enqueue_to_dispatch_time = cpu_to_be32(DISPATCH_LOG_BYTES);
ret = register_dtl(hwcpu, __pa(dtl));
if (ret)
pr_err("WARNING: DTL registration of cpu %d (hw %d) "
"failed with %ld\n", smp_processor_id(),
hwcpu, ret);
lppaca_of(cpu).dtl_enable_mask = DTL_LOG_PREEMPT;
}
register_dtl_buffer(cpu);
}
#ifdef CONFIG_PPC_BOOK3S_64

View File

@ -279,46 +279,16 @@ struct kmem_cache *dtl_cache;
*/
static int alloc_dispatch_logs(void)
{
int cpu, ret;
struct paca_struct *pp;
struct dtl_entry *dtl;
if (!firmware_has_feature(FW_FEATURE_SPLPAR))
return 0;
if (!dtl_cache)
return 0;
for_each_possible_cpu(cpu) {
pp = paca_ptrs[cpu];
dtl = kmem_cache_alloc(dtl_cache, GFP_KERNEL);
if (!dtl) {
pr_warn("Failed to allocate dispatch trace log for cpu %d\n",
cpu);
pr_warn("Stolen time statistics will be unreliable\n");
break;
}
pp->dtl_ridx = 0;
pp->dispatch_log = dtl;
pp->dispatch_log_end = dtl + N_DISPATCH_LOG;
pp->dtl_curr = dtl;
}
alloc_dtl_buffers();
/* Register the DTL for the current (boot) cpu */
dtl = get_paca()->dispatch_log;
get_paca()->dtl_ridx = 0;
get_paca()->dtl_curr = dtl;
get_paca()->lppaca_ptr->dtl_idx = 0;
/* hypervisor reads buffer length from this field */
dtl->enqueue_to_dispatch_time = cpu_to_be32(DISPATCH_LOG_BYTES);
ret = register_dtl(hard_smp_processor_id(), __pa(dtl));
if (ret)
pr_err("WARNING: DTL registration of cpu %d (hw %d) failed "
"with %d\n", smp_processor_id(),
hard_smp_processor_id(), ret);
get_paca()->lppaca_ptr->dtl_enable_mask = DTL_LOG_PREEMPT;
register_dtl_buffer(smp_processor_id());
return 0;
}