Commit cc2a4878 authored by Dan Williams's avatar Dan Williams

cxl/mem: Add a debugfs version of 'iomem' for DPA, 'dpamem'

Dump the device-physical-address map for a CXL expander in /proc/iomem
style format. E.g.:

  cat /sys/kernel/debug/cxl/mem1/dpamem
  00000000-0fffffff : ram
  10000000-1fffffff : pmem
Reviewed-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
Link: https://lore.kernel.org/r/165603885318.551046.8308248564880066726.stgit@dwillia2-xfhSigned-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent 9b99ecf5
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* Copyright(c) 2022 Intel Corporation. All rights reserved. */ /* Copyright(c) 2022 Intel Corporation. All rights reserved. */
#include <linux/io-64-nonatomic-hi-lo.h> #include <linux/io-64-nonatomic-hi-lo.h>
#include <linux/seq_file.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/delay.h> #include <linux/delay.h>
...@@ -16,6 +17,8 @@ ...@@ -16,6 +17,8 @@
* for enumerating these registers and capabilities. * for enumerating these registers and capabilities.
*/ */
static DECLARE_RWSEM(cxl_dpa_rwsem);
static int add_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld, static int add_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
int *target_map) int *target_map)
{ {
...@@ -128,6 +131,28 @@ struct cxl_hdm *devm_cxl_setup_hdm(struct cxl_port *port) ...@@ -128,6 +131,28 @@ struct cxl_hdm *devm_cxl_setup_hdm(struct cxl_port *port)
} }
EXPORT_SYMBOL_NS_GPL(devm_cxl_setup_hdm, CXL); EXPORT_SYMBOL_NS_GPL(devm_cxl_setup_hdm, CXL);
static void __cxl_dpa_debug(struct seq_file *file, struct resource *r, int depth)
{
unsigned long long start = r->start, end = r->end;
seq_printf(file, "%*s%08llx-%08llx : %s\n", depth * 2, "", start, end,
r->name);
}
void cxl_dpa_debug(struct seq_file *file, struct cxl_dev_state *cxlds)
{
struct resource *p1, *p2;
down_read(&cxl_dpa_rwsem);
for (p1 = cxlds->dpa_res.child; p1; p1 = p1->sibling) {
__cxl_dpa_debug(file, p1, 0);
for (p2 = p1->child; p2; p2 = p2->sibling)
__cxl_dpa_debug(file, p2, 1);
}
up_read(&cxl_dpa_rwsem);
}
EXPORT_SYMBOL_NS_GPL(cxl_dpa_debug, CXL);
static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld, static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
int *target_map, void __iomem *hdm, int which) int *target_map, void __iomem *hdm, int which)
{ {
......
...@@ -1506,6 +1506,7 @@ struct dentry *cxl_debugfs_create_dir(const char *dir) ...@@ -1506,6 +1506,7 @@ struct dentry *cxl_debugfs_create_dir(const char *dir)
{ {
return debugfs_create_dir(dir, cxl_debugfs); return debugfs_create_dir(dir, cxl_debugfs);
} }
EXPORT_SYMBOL_NS_GPL(cxl_debugfs_create_dir, CXL);
static __init int cxl_core_init(void) static __init int cxl_core_init(void)
{ {
......
...@@ -372,4 +372,8 @@ struct cxl_hdm { ...@@ -372,4 +372,8 @@ struct cxl_hdm {
unsigned int interleave_mask; unsigned int interleave_mask;
struct cxl_port *port; struct cxl_port *port;
}; };
struct seq_file;
struct dentry *cxl_debugfs_create_dir(const char *dir);
void cxl_dpa_debug(struct seq_file *file, struct cxl_dev_state *cxlds);
#endif /* __CXL_MEM_H__ */ #endif /* __CXL_MEM_H__ */
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/* Copyright(c) 2022 Intel Corporation. All rights reserved. */ /* Copyright(c) 2022 Intel Corporation. All rights reserved. */
#include <linux/debugfs.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/pci.h> #include <linux/pci.h>
...@@ -56,10 +57,26 @@ static void enable_suspend(void *data) ...@@ -56,10 +57,26 @@ static void enable_suspend(void *data)
cxl_mem_active_dec(); cxl_mem_active_dec();
} }
static void remove_debugfs(void *dentry)
{
debugfs_remove_recursive(dentry);
}
static int cxl_mem_dpa_show(struct seq_file *file, void *data)
{
struct device *dev = file->private;
struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
cxl_dpa_debug(file, cxlmd->cxlds);
return 0;
}
static int cxl_mem_probe(struct device *dev) static int cxl_mem_probe(struct device *dev)
{ {
struct cxl_memdev *cxlmd = to_cxl_memdev(dev); struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
struct cxl_port *parent_port; struct cxl_port *parent_port;
struct dentry *dentry;
int rc; int rc;
/* /*
...@@ -73,6 +90,12 @@ static int cxl_mem_probe(struct device *dev) ...@@ -73,6 +90,12 @@ static int cxl_mem_probe(struct device *dev)
if (work_pending(&cxlmd->detach_work)) if (work_pending(&cxlmd->detach_work))
return -EBUSY; return -EBUSY;
dentry = cxl_debugfs_create_dir(dev_name(dev));
debugfs_create_devm_seqfile(dev, "dpamem", dentry, cxl_mem_dpa_show);
rc = devm_add_action_or_reset(dev, remove_debugfs, dentry);
if (rc)
return rc;
rc = devm_cxl_enumerate_ports(cxlmd); rc = devm_cxl_enumerate_ports(cxlmd);
if (rc) if (rc)
return rc; return rc;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment