* [PATCH v5 16/40] cxl/core/port: Use dedicated lock for decoder target list
[not found] <164316562430.3437160.122223070771602475.stgit@dwillia2-desk3.amr.corp.intel.com>
@ 2022-01-31 23:35 ` Dan Williams
2022-02-01 10:52 ` Jonathan Cameron
0 siblings, 1 reply; 2+ messages in thread
From: Dan Williams @ 2022-01-31 23:35 UTC (permalink / raw)
To: linux-cxl; +Cc: Ben Widawsky, linux-pci, nvdimm
Lockdep reports:
======================================================
WARNING: possible circular locking dependency detected
5.16.0-rc1+ #142 Tainted: G OE
------------------------------------------------------
cxl/1220 is trying to acquire lock:
ffff979b85475460 (kn->active#144){++++}-{0:0}, at: __kernfs_remove+0x1ab/0x1e0
but task is already holding lock:
ffff979b87ab38e8 (&dev->lockdep_mutex#2/4){+.+.}-{3:3}, at: cxl_remove_ep+0x50c/0x5c0 [cxl_core]
...where cxl_remove_ep() is a helper that wants to delete ports while
holding a lock on the host device for that port. That sets up a lockdep
violation whereby target_list_show() can not rely holding the decoder's
device lock while walking the target_list. Switch to a dedicated seqlock
for this purpose.
Reported-by: Ben Widawsky <ben.widawsky@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
Changes since v4:
- Cleanup error exit condition (Jonathan)
drivers/cxl/core/port.c | 30 +++++++++++++++++++++++-------
drivers/cxl/cxl.h | 2 ++
2 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
index 9285cdb734b2..fc5d86222bc3 100644
--- a/drivers/cxl/core/port.c
+++ b/drivers/cxl/core/port.c
@@ -104,14 +104,11 @@ static ssize_t target_type_show(struct device *dev,
}
static DEVICE_ATTR_RO(target_type);
-static ssize_t target_list_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t emit_target_list(struct cxl_decoder *cxld, char *buf)
{
- struct cxl_decoder *cxld = to_cxl_decoder(dev);
ssize_t offset = 0;
int i, rc = 0;
- cxl_device_lock(dev);
for (i = 0; i < cxld->interleave_ways; i++) {
struct cxl_dport *dport = cxld->target[i];
struct cxl_dport *next = NULL;
@@ -124,13 +121,29 @@ static ssize_t target_list_show(struct device *dev,
rc = sysfs_emit_at(buf, offset, "%d%s", dport->port_id,
next ? "," : "");
if (rc < 0)
- break;
+ return rc;
offset += rc;
}
- cxl_device_unlock(dev);
+
+ return offset;
+}
+
+static ssize_t target_list_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct cxl_decoder *cxld = to_cxl_decoder(dev);
+ ssize_t offset;
+ unsigned int seq;
+ int rc;
+
+ do {
+ seq = read_seqbegin(&cxld->target_lock);
+ rc = emit_target_list(cxld, buf);
+ } while (read_seqretry(&cxld->target_lock, seq));
if (rc < 0)
return rc;
+ offset = rc;
rc = sysfs_emit_at(buf, offset, "\n");
if (rc < 0)
@@ -494,15 +507,17 @@ static int decoder_populate_targets(struct cxl_decoder *cxld,
goto out_unlock;
}
+ write_seqlock(&cxld->target_lock);
for (i = 0; i < cxld->nr_targets; i++) {
struct cxl_dport *dport = find_dport(port, target_map[i]);
if (!dport) {
rc = -ENXIO;
- goto out_unlock;
+ break;
}
cxld->target[i] = dport;
}
+ write_sequnlock(&cxld->target_lock);
out_unlock:
cxl_device_unlock(&port->dev);
@@ -543,6 +558,7 @@ static struct cxl_decoder *cxl_decoder_alloc(struct cxl_port *port,
cxld->id = rc;
cxld->nr_targets = nr_targets;
+ seqlock_init(&cxld->target_lock);
dev = &cxld->dev;
device_initialize(dev);
device_set_pm_not_required(dev);
diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
index 6a38d2e1f3dd..e79162999088 100644
--- a/drivers/cxl/cxl.h
+++ b/drivers/cxl/cxl.h
@@ -185,6 +185,7 @@ enum cxl_decoder_type {
* @interleave_granularity: data stride per dport
* @target_type: accelerator vs expander (type2 vs type3) selector
* @flags: memory type capabilities and locking
+ * @target_lock: coordinate coherent reads of the target list
* @nr_targets: number of elements in @target
* @target: active ordered target list in current decoder configuration
*/
@@ -199,6 +200,7 @@ struct cxl_decoder {
int interleave_granularity;
enum cxl_decoder_type target_type;
unsigned long flags;
+ seqlock_t target_lock;
int nr_targets;
struct cxl_dport *target[];
};
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH v5 16/40] cxl/core/port: Use dedicated lock for decoder target list
2022-01-31 23:35 ` [PATCH v5 16/40] cxl/core/port: Use dedicated lock for decoder target list Dan Williams
@ 2022-02-01 10:52 ` Jonathan Cameron
0 siblings, 0 replies; 2+ messages in thread
From: Jonathan Cameron @ 2022-02-01 10:52 UTC (permalink / raw)
To: Dan Williams; +Cc: linux-cxl, Ben Widawsky, linux-pci, nvdimm
On Mon, 31 Jan 2022 15:35:18 -0800
Dan Williams <dan.j.williams@intel.com> wrote:
> Lockdep reports:
>
> ======================================================
> WARNING: possible circular locking dependency detected
> 5.16.0-rc1+ #142 Tainted: G OE
> ------------------------------------------------------
> cxl/1220 is trying to acquire lock:
> ffff979b85475460 (kn->active#144){++++}-{0:0}, at: __kernfs_remove+0x1ab/0x1e0
>
> but task is already holding lock:
> ffff979b87ab38e8 (&dev->lockdep_mutex#2/4){+.+.}-{3:3}, at: cxl_remove_ep+0x50c/0x5c0 [cxl_core]
>
> ...where cxl_remove_ep() is a helper that wants to delete ports while
> holding a lock on the host device for that port. That sets up a lockdep
> violation whereby target_list_show() can not rely holding the decoder's
> device lock while walking the target_list. Switch to a dedicated seqlock
> for this purpose.
>
> Reported-by: Ben Widawsky <ben.widawsky@intel.com>
> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2022-02-01 10:52 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <164316562430.3437160.122223070771602475.stgit@dwillia2-desk3.amr.corp.intel.com>
2022-01-31 23:35 ` [PATCH v5 16/40] cxl/core/port: Use dedicated lock for decoder target list Dan Williams
2022-02-01 10:52 ` Jonathan Cameron
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox