Skip to content

Commit 5fbe650

Browse files
davejiangvinodkoul
authored andcommitted
dmanegine: idxd: add debugfs for event log dump
Add debugfs entry to dump the content of the event log for debugging. The function will dump all non-zero entries in the event log. It will note which entries are processed and which entries are still pending processing at the time of the dump. The entries may not always be in chronological order due to the log is a circular buffer. Tested-by: Tony Zhu <tony.zhu@intel.com> Signed-off-by: Dave Jiang <dave.jiang@intel.com> Co-developed-by: Fenghua Yu <fenghua.yu@intel.com> Signed-off-by: Fenghua Yu <fenghua.yu@intel.com> Link: https://lore.kernel.org/r/20230407203143.2189681-6-fenghua.yu@intel.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
1 parent 2f431ba commit 5fbe650

File tree

5 files changed

+164
-3
lines changed

5 files changed

+164
-3
lines changed

drivers/dma/idxd/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
ccflags-y += -DDEFAULT_SYMBOL_NAMESPACE=IDXD
22

33
obj-$(CONFIG_INTEL_IDXD) += idxd.o
4-
idxd-y := init.o irq.o device.o sysfs.o submit.o dma.o cdev.o
4+
idxd-y := init.o irq.o device.o sysfs.o submit.o dma.o cdev.o debugfs.o
55

66
idxd-$(CONFIG_INTEL_IDXD_PERFMON) += perfmon.o
77

drivers/dma/idxd/debugfs.c

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/* Copyright(c) 2021 Intel Corporation. All rights rsvd. */
3+
#include <linux/init.h>
4+
#include <linux/kernel.h>
5+
#include <linux/module.h>
6+
#include <linux/pci.h>
7+
#include <linux/debugfs.h>
8+
#include <linux/io-64-nonatomic-lo-hi.h>
9+
#include <uapi/linux/idxd.h>
10+
#include "idxd.h"
11+
#include "registers.h"
12+
13+
static struct dentry *idxd_debugfs_dir;
14+
15+
static void dump_event_entry(struct idxd_device *idxd, struct seq_file *s,
16+
u16 index, int *count, bool processed)
17+
{
18+
struct idxd_evl *evl = idxd->evl;
19+
struct dsa_evl_entry *entry;
20+
struct dsa_completion_record *cr;
21+
u64 *raw;
22+
int i;
23+
int evl_strides = evl_ent_size(idxd) / sizeof(u64);
24+
25+
entry = (struct dsa_evl_entry *)evl->log + index;
26+
27+
if (!entry->e.desc_valid)
28+
return;
29+
30+
seq_printf(s, "Event Log entry %d (real index %u) processed: %u\n",
31+
*count, index, processed);
32+
33+
seq_printf(s, "desc valid %u wq idx valid %u\n"
34+
"batch %u fault rw %u priv %u error 0x%x\n"
35+
"wq idx %u op %#x pasid %u batch idx %u\n"
36+
"fault addr %#llx\n",
37+
entry->e.desc_valid, entry->e.wq_idx_valid,
38+
entry->e.batch, entry->e.fault_rw, entry->e.priv,
39+
entry->e.error, entry->e.wq_idx, entry->e.operation,
40+
entry->e.pasid, entry->e.batch_idx, entry->e.fault_addr);
41+
42+
cr = &entry->cr;
43+
seq_printf(s, "status %#x result %#x fault_info %#x bytes_completed %u\n"
44+
"fault addr %#llx inv flags %#x\n\n",
45+
cr->status, cr->result, cr->fault_info, cr->bytes_completed,
46+
cr->fault_addr, cr->invalid_flags);
47+
48+
raw = (u64 *)entry;
49+
50+
for (i = 0; i < evl_strides; i++)
51+
seq_printf(s, "entry[%d] = %#llx\n", i, raw[i]);
52+
53+
seq_puts(s, "\n");
54+
*count += 1;
55+
}
56+
57+
static int debugfs_evl_show(struct seq_file *s, void *d)
58+
{
59+
struct idxd_device *idxd = s->private;
60+
struct idxd_evl *evl = idxd->evl;
61+
union evl_status_reg evl_status;
62+
u16 h, t, evl_size, i;
63+
int count = 0;
64+
bool processed = true;
65+
66+
if (!evl || !evl->log)
67+
return 0;
68+
69+
spin_lock(&evl->lock);
70+
71+
h = evl->head;
72+
evl_status.bits = ioread64(idxd->reg_base + IDXD_EVLSTATUS_OFFSET);
73+
t = evl_status.tail;
74+
evl_size = evl->size;
75+
76+
seq_printf(s, "Event Log head %u tail %u interrupt pending %u\n\n",
77+
evl_status.head, evl_status.tail, evl_status.int_pending);
78+
79+
i = t;
80+
while (1) {
81+
i = (i + 1) % evl_size;
82+
if (i == t)
83+
break;
84+
85+
if (processed && i == h)
86+
processed = false;
87+
dump_event_entry(idxd, s, i, &count, processed);
88+
}
89+
90+
spin_unlock(&evl->lock);
91+
return 0;
92+
}
93+
94+
DEFINE_SHOW_ATTRIBUTE(debugfs_evl);
95+
96+
int idxd_device_init_debugfs(struct idxd_device *idxd)
97+
{
98+
if (IS_ERR_OR_NULL(idxd_debugfs_dir))
99+
return 0;
100+
101+
idxd->dbgfs_dir = debugfs_create_dir(dev_name(idxd_confdev(idxd)), idxd_debugfs_dir);
102+
if (IS_ERR(idxd->dbgfs_dir))
103+
return PTR_ERR(idxd->dbgfs_dir);
104+
105+
if (idxd->evl) {
106+
idxd->dbgfs_evl_file = debugfs_create_file("event_log", 0400,
107+
idxd->dbgfs_dir, idxd,
108+
&debugfs_evl_fops);
109+
if (IS_ERR(idxd->dbgfs_evl_file)) {
110+
debugfs_remove_recursive(idxd->dbgfs_dir);
111+
idxd->dbgfs_dir = NULL;
112+
return PTR_ERR(idxd->dbgfs_evl_file);
113+
}
114+
}
115+
116+
return 0;
117+
}
118+
119+
void idxd_device_remove_debugfs(struct idxd_device *idxd)
120+
{
121+
debugfs_remove_recursive(idxd->dbgfs_dir);
122+
}
123+
124+
int idxd_init_debugfs(void)
125+
{
126+
if (!debugfs_initialized())
127+
return 0;
128+
129+
idxd_debugfs_dir = debugfs_create_dir(KBUILD_MODNAME, NULL);
130+
if (IS_ERR(idxd_debugfs_dir))
131+
return PTR_ERR(idxd_debugfs_dir);
132+
return 0;
133+
}
134+
135+
void idxd_remove_debugfs(void)
136+
{
137+
debugfs_remove_recursive(idxd_debugfs_dir);
138+
}

drivers/dma/idxd/idxd.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,9 @@ struct idxd_device {
330330

331331
unsigned long *opcap_bmap;
332332
struct idxd_evl *evl;
333+
334+
struct dentry *dbgfs_dir;
335+
struct dentry *dbgfs_evl_file;
333336
};
334337

335338
static inline unsigned int evl_ent_size(struct idxd_device *idxd)
@@ -704,4 +707,10 @@ static inline void perfmon_init(void) {}
704707
static inline void perfmon_exit(void) {}
705708
#endif
706709

710+
/* debugfs */
711+
int idxd_device_init_debugfs(struct idxd_device *idxd);
712+
void idxd_device_remove_debugfs(struct idxd_device *idxd);
713+
int idxd_init_debugfs(void);
714+
void idxd_remove_debugfs(void);
715+
707716
#endif

drivers/dma/idxd/init.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,10 @@ static int idxd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
669669
goto err_dev_register;
670670
}
671671

672+
rc = idxd_device_init_debugfs(idxd);
673+
if (rc)
674+
dev_warn(dev, "IDXD debugfs failed to setup\n");
675+
672676
dev_info(&pdev->dev, "Intel(R) Accelerator Device (v%x)\n",
673677
idxd->hw.version);
674678

@@ -731,6 +735,7 @@ static void idxd_remove(struct pci_dev *pdev)
731735
idxd_shutdown(pdev);
732736
if (device_pasid_enabled(idxd))
733737
idxd_disable_system_pasid(idxd);
738+
idxd_device_remove_debugfs(idxd);
734739

735740
irq_entry = idxd_get_ie(idxd, 0);
736741
free_irq(irq_entry->vector, irq_entry);
@@ -788,13 +793,19 @@ static int __init idxd_init_module(void)
788793
if (err)
789794
goto err_cdev_register;
790795

796+
err = idxd_init_debugfs();
797+
if (err)
798+
goto err_debugfs;
799+
791800
err = pci_register_driver(&idxd_pci_driver);
792801
if (err)
793802
goto err_pci_register;
794803

795804
return 0;
796805

797806
err_pci_register:
807+
idxd_remove_debugfs();
808+
err_debugfs:
798809
idxd_cdev_remove();
799810
err_cdev_register:
800811
idxd_driver_unregister(&idxd_user_drv);
@@ -815,5 +826,6 @@ static void __exit idxd_exit_module(void)
815826
pci_unregister_driver(&idxd_pci_driver);
816827
idxd_cdev_remove();
817828
perfmon_exit();
829+
idxd_remove_debugfs();
818830
}
819831
module_exit(idxd_exit_module);

include/uapi/linux/idxd.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,8 @@ struct dsa_completion_record {
311311
uint8_t result;
312312
uint8_t dif_status;
313313
};
314-
uint16_t rsvd;
314+
uint8_t fault_info;
315+
uint8_t rsvd;
315316
uint32_t bytes_completed;
316317
uint64_t fault_addr;
317318
union {
@@ -368,7 +369,8 @@ struct dsa_raw_completion_record {
368369
struct iax_completion_record {
369370
volatile uint8_t status;
370371
uint8_t error_code;
371-
uint16_t rsvd;
372+
uint8_t fault_info;
373+
uint8_t rsvd;
372374
uint32_t bytes_completed;
373375
uint64_t fault_addr;
374376
uint32_t invalid_flags;

0 commit comments

Comments
 (0)