Skip to content

Commit

Permalink
cxl: Add tracepoints
Browse files Browse the repository at this point in the history
This patch adds tracepoints throughout the cxl driver, which can provide
insight into:

- Context lifetimes
- Commands sent to the PSL and AFU and their completion status
- Segment and page table misses and their resolution
- PSL and AFU interrupts
- slbia calls from the powerpc copro_fault code

These tracepoints are mostly intended to aid in debugging (particularly
for new AFU designs), and may be useful standalone or in conjunction
with hardware traces collected by the PSL (read out via the trace
interface in debugfs) and AFUs.

Signed-off-by: Ian Munsie <imunsie@au1.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
  • Loading branch information
Ian Munsie authored and Michael Ellerman committed Jan 22, 2015
1 parent d3383aa commit 9bcf28c
Show file tree
Hide file tree
Showing 8 changed files with 520 additions and 9 deletions.
5 changes: 4 additions & 1 deletion drivers/misc/cxl/Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
cxl-y += main.o file.o irq.o fault.o native.o context.o sysfs.o debugfs.o pci.o
cxl-y += main.o file.o irq.o fault.o native.o context.o sysfs.o debugfs.o pci.o trace.o
obj-$(CONFIG_CXL) += cxl.o
obj-$(CONFIG_CXL_BASE) += base.o

# For tracepoints to include our trace.h from tracepoint infrastructure:
CFLAGS_trace.o := -I$(src)
5 changes: 5 additions & 0 deletions drivers/misc/cxl/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <asm/mmu.h>

#include "cxl.h"
#include "trace.h"

static bool sste_matches(struct cxl_sste *sste, struct copro_slb *slb)
{
Expand Down Expand Up @@ -75,6 +76,7 @@ static void cxl_load_segment(struct cxl_context *ctx, struct copro_slb *slb)

pr_devel("CXL Populating SST[%li]: %#llx %#llx\n",
sste - ctx->sstp, slb->vsid, slb->esid);
trace_cxl_ste_write(ctx, sste - ctx->sstp, slb->esid, slb->vsid);

sste->vsid_data = cpu_to_be64(slb->vsid);
sste->esid_data = cpu_to_be64(slb->esid);
Expand Down Expand Up @@ -116,6 +118,7 @@ static int cxl_handle_segment_miss(struct cxl_context *ctx,
int rc;

pr_devel("CXL interrupt: Segment fault pe: %i ea: %#llx\n", ctx->pe, ea);
trace_cxl_ste_miss(ctx, ea);

if ((rc = cxl_fault_segment(ctx, mm, ea)))
cxl_ack_ae(ctx);
Expand All @@ -135,6 +138,8 @@ static void cxl_handle_page_fault(struct cxl_context *ctx,
int result;
unsigned long access, flags, inv_flags = 0;

trace_cxl_pte_miss(ctx, dsisr, dar);

if ((result = copro_handle_mm_fault(mm, dar, dsisr, &flt))) {
pr_devel("copro_handle_mm_fault failed: %#x\n", result);
return cxl_ack_ae(ctx);
Expand Down
3 changes: 3 additions & 0 deletions drivers/misc/cxl/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <asm/copro.h>

#include "cxl.h"
#include "trace.h"

#define CXL_NUM_MINORS 256 /* Total to reserve */
#define CXL_DEV_MINORS 13 /* 1 control + 4 AFUs * 3 (dedicated/master/shared) */
Expand Down Expand Up @@ -184,6 +185,8 @@ static long afu_ioctl_start_work(struct cxl_context *ctx,
*/
ctx->pid = get_pid(get_task_pid(current, PIDTYPE_PID));

trace_cxl_attach(ctx, work.work_element_descriptor, work.num_interrupts, amr);

if ((rc = cxl_attach_process(ctx, false, work.work_element_descriptor,
amr))) {
afu_release_irqs(ctx);
Expand Down
4 changes: 4 additions & 0 deletions drivers/misc/cxl/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <misc/cxl.h>

#include "cxl.h"
#include "trace.h"

/* XXX: This is implementation specific */
static irqreturn_t handle_psl_slice_error(struct cxl_context *ctx, u64 dsisr, u64 errstat)
Expand Down Expand Up @@ -100,6 +101,8 @@ static irqreturn_t cxl_irq(int irq, void *data, struct cxl_irq_info *irq_info)
dsisr = irq_info->dsisr;
dar = irq_info->dar;

trace_cxl_psl_irq(ctx, irq, dsisr, dar);

pr_devel("CXL interrupt %i for afu pe: %i DSISR: %#llx DAR: %#llx\n", irq, ctx->pe, dsisr, dar);

if (dsisr & CXL_PSL_DSISR_An_DS) {
Expand Down Expand Up @@ -237,6 +240,7 @@ static irqreturn_t cxl_irq_afu(int irq, void *data)
return IRQ_HANDLED;
}

trace_cxl_afu_irq(ctx, afu_irq, irq, hwirq);
pr_devel("Received AFU interrupt %i for pe: %i (virq %i hwirq %lx)\n",
afu_irq, ctx->pe, irq, hwirq);

Expand Down
2 changes: 2 additions & 0 deletions drivers/misc/cxl/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <misc/cxl.h>

#include "cxl.h"
#include "trace.h"

static DEFINE_SPINLOCK(adapter_idr_lock);
static DEFINE_IDR(cxl_adapter_idr);
Expand All @@ -48,6 +49,7 @@ static inline void _cxl_slbia(struct cxl_context *ctx, struct mm_struct *mm)
ctx->afu->adapter->adapter_num, ctx->afu->slice, ctx->pe);

spin_lock_irqsave(&ctx->sste_lock, flags);
trace_cxl_slbia(ctx);
memset(ctx->sstp, 0, ctx->sst_size);
spin_unlock_irqrestore(&ctx->sste_lock, flags);
mb();
Expand Down
38 changes: 30 additions & 8 deletions drivers/misc/cxl/native.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,28 @@
#include <misc/cxl.h>

#include "cxl.h"
#include "trace.h"

static int afu_control(struct cxl_afu *afu, u64 command,
u64 result, u64 mask, bool enabled)
{
u64 AFU_Cntl = cxl_p2n_read(afu, CXL_AFU_Cntl_An);
unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT);
int rc = 0;

spin_lock(&afu->afu_cntl_lock);
pr_devel("AFU command starting: %llx\n", command);

trace_cxl_afu_ctrl(afu, command);

cxl_p2n_write(afu, CXL_AFU_Cntl_An, AFU_Cntl | command);

AFU_Cntl = cxl_p2n_read(afu, CXL_AFU_Cntl_An);
while ((AFU_Cntl & mask) != result) {
if (time_after_eq(jiffies, timeout)) {
dev_warn(&afu->dev, "WARNING: AFU control timed out!\n");
spin_unlock(&afu->afu_cntl_lock);
return -EBUSY;
rc = -EBUSY;
goto out;
}
pr_devel_ratelimited("AFU control... (0x%.16llx)\n",
AFU_Cntl | command);
Expand All @@ -44,9 +48,11 @@ static int afu_control(struct cxl_afu *afu, u64 command,
};
pr_devel("AFU command complete: %llx\n", command);
afu->enabled = enabled;
out:
trace_cxl_afu_ctrl_done(afu, command, rc);
spin_unlock(&afu->afu_cntl_lock);

return 0;
return rc;
}

static int afu_enable(struct cxl_afu *afu)
Expand Down Expand Up @@ -91,6 +97,9 @@ int cxl_psl_purge(struct cxl_afu *afu)
u64 dsisr, dar;
u64 start, end;
unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT);
int rc = 0;

trace_cxl_psl_ctrl(afu, CXL_PSL_SCNTL_An_Pc);

pr_devel("PSL purge request\n");

Expand All @@ -107,7 +116,8 @@ int cxl_psl_purge(struct cxl_afu *afu)
== CXL_PSL_SCNTL_An_Ps_Pending) {
if (time_after_eq(jiffies, timeout)) {
dev_warn(&afu->dev, "WARNING: PSL Purge timed out!\n");
return -EBUSY;
rc = -EBUSY;
goto out;
}
dsisr = cxl_p2n_read(afu, CXL_PSL_DSISR_An);
pr_devel_ratelimited("PSL purging... PSL_CNTL: 0x%.16llx PSL_DSISR: 0x%.16llx\n", PSL_CNTL, dsisr);
Expand All @@ -128,7 +138,9 @@ int cxl_psl_purge(struct cxl_afu *afu)

cxl_p1n_write(afu, CXL_PSL_SCNTL_An,
PSL_CNTL & ~CXL_PSL_SCNTL_An_Pc);
return 0;
out:
trace_cxl_psl_ctrl_done(afu, CXL_PSL_SCNTL_An_Pc, rc);
return rc;
}

static int spa_max_procs(int spa_size)
Expand Down Expand Up @@ -279,6 +291,9 @@ static int do_process_element_cmd(struct cxl_context *ctx,
{
u64 state;
unsigned long timeout = jiffies + (HZ * CXL_TIMEOUT);
int rc = 0;

trace_cxl_llcmd(ctx, cmd);

WARN_ON(!ctx->afu->enabled);

Expand All @@ -290,12 +305,14 @@ static int do_process_element_cmd(struct cxl_context *ctx,
while (1) {
if (time_after_eq(jiffies, timeout)) {
dev_warn(&ctx->afu->dev, "WARNING: Process Element Command timed out!\n");
return -EBUSY;
rc = -EBUSY;
goto out;
}
state = be64_to_cpup(ctx->afu->sw_command_status);
if (state == ~0ULL) {
pr_err("cxl: Error adding process element to AFU\n");
return -1;
rc = -1;
goto out;
}
if ((state & (CXL_SPA_SW_CMD_MASK | CXL_SPA_SW_STATE_MASK | CXL_SPA_SW_LINK_MASK)) ==
(cmd | (cmd >> 16) | ctx->pe))
Expand All @@ -310,7 +327,9 @@ static int do_process_element_cmd(struct cxl_context *ctx,
schedule();

}
return 0;
out:
trace_cxl_llcmd_done(ctx, cmd, rc);
return rc;
}

static int add_process_element(struct cxl_context *ctx)
Expand Down Expand Up @@ -630,6 +649,8 @@ static inline int detach_process_native_afu_directed(struct cxl_context *ctx)

int cxl_detach_process(struct cxl_context *ctx)
{
trace_cxl_detach(ctx);

if (ctx->afu->current_mode == CXL_MODE_DEDICATED)
return detach_process_native_dedicated(ctx);

Expand Down Expand Up @@ -668,6 +689,7 @@ static void recover_psl_err(struct cxl_afu *afu, u64 errstat)

int cxl_ack_irq(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask)
{
trace_cxl_psl_irq_ack(ctx, tfc);
if (tfc)
cxl_p2n_write(ctx->afu, CXL_PSL_TFC_An, tfc);
if (psl_reset_mask)
Expand Down
13 changes: 13 additions & 0 deletions drivers/misc/cxl/trace.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* Copyright 2015 IBM Corp.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/

#ifndef __CHECKER__
#define CREATE_TRACE_POINTS
#include "trace.h"
#endif
Loading

0 comments on commit 9bcf28c

Please sign in to comment.