Skip to content

Commit 134fdb8

Browse files
committed
Merge tag 'cxl-fixes-6.7-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/cxl/cxl
Pull CXL (Compute Express Link) fixes from Dan Williams: "A collection of CXL fixes. The touch outside of drivers/cxl/ is for a helper that allocates physical address space. Device hotplug tests showed that the driver failed to utilize (skipped over) valid capacity when allocating a new memory region. Outside of that, new tests uncovered a small crop of lockdep reports. There is also some miscellaneous error path and leak fixups that are not urgent, but useful to cleanup now. - Fix alloc_free_mem_region()'s scan for address space, prevent false negative out-of-space events - Fix sleeping lock acquisition from CXL trace event (atomic context) - Fix put_device() like for the new CXL PMU driver - Fix wrong pointer freed on error path - Fixup several lockdep reports (missing lock hold) from new assertion in cxl_num_decoders_committed() and new tests" * tag 'cxl-fixes-6.7-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/cxl/cxl: cxl/pmu: Ensure put_device on pmu devices cxl/cdat: Free correct buffer on checksum error cxl/hdm: Fix dpa translation locking kernel/resource: Increment by align value in get_free_mem_region() cxl: Add cxl_num_decoders_committed() usage to cxl_test cxl/memdev: Hold region_rwsem during inject and clear poison ops cxl/core: Always hold region_rwsem while reading poison lists cxl/hdm: Fix a benign lockdep splat
2 parents ef6a7c2 + ef3d5cf commit 134fdb8

File tree

10 files changed

+49
-24
lines changed

10 files changed

+49
-24
lines changed

drivers/cxl/core/hdm.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -363,10 +363,9 @@ resource_size_t cxl_dpa_resource_start(struct cxl_endpoint_decoder *cxled)
363363
{
364364
resource_size_t base = -1;
365365

366-
down_read(&cxl_dpa_rwsem);
366+
lockdep_assert_held(&cxl_dpa_rwsem);
367367
if (cxled->dpa_res)
368368
base = cxled->dpa_res->start;
369-
up_read(&cxl_dpa_rwsem);
370369

371370
return base;
372371
}
@@ -839,6 +838,8 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
839838
cxld->target_type = CXL_DECODER_HOSTONLYMEM;
840839
else
841840
cxld->target_type = CXL_DECODER_DEVMEM;
841+
842+
guard(rwsem_write)(&cxl_region_rwsem);
842843
if (cxld->id != cxl_num_decoders_committed(port)) {
843844
dev_warn(&port->dev,
844845
"decoder%d.%d: Committed out of order\n",

drivers/cxl/core/memdev.c

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -227,10 +227,16 @@ int cxl_trigger_poison_list(struct cxl_memdev *cxlmd)
227227
if (!port || !is_cxl_endpoint(port))
228228
return -EINVAL;
229229

230-
rc = down_read_interruptible(&cxl_dpa_rwsem);
230+
rc = down_read_interruptible(&cxl_region_rwsem);
231231
if (rc)
232232
return rc;
233233

234+
rc = down_read_interruptible(&cxl_dpa_rwsem);
235+
if (rc) {
236+
up_read(&cxl_region_rwsem);
237+
return rc;
238+
}
239+
234240
if (cxl_num_decoders_committed(port) == 0) {
235241
/* No regions mapped to this memdev */
236242
rc = cxl_get_poison_by_memdev(cxlmd);
@@ -239,6 +245,7 @@ int cxl_trigger_poison_list(struct cxl_memdev *cxlmd)
239245
rc = cxl_get_poison_by_endpoint(port);
240246
}
241247
up_read(&cxl_dpa_rwsem);
248+
up_read(&cxl_region_rwsem);
242249

243250
return rc;
244251
}
@@ -324,10 +331,16 @@ int cxl_inject_poison(struct cxl_memdev *cxlmd, u64 dpa)
324331
if (!IS_ENABLED(CONFIG_DEBUG_FS))
325332
return 0;
326333

327-
rc = down_read_interruptible(&cxl_dpa_rwsem);
334+
rc = down_read_interruptible(&cxl_region_rwsem);
328335
if (rc)
329336
return rc;
330337

338+
rc = down_read_interruptible(&cxl_dpa_rwsem);
339+
if (rc) {
340+
up_read(&cxl_region_rwsem);
341+
return rc;
342+
}
343+
331344
rc = cxl_validate_poison_dpa(cxlmd, dpa);
332345
if (rc)
333346
goto out;
@@ -355,6 +368,7 @@ int cxl_inject_poison(struct cxl_memdev *cxlmd, u64 dpa)
355368
trace_cxl_poison(cxlmd, cxlr, &record, 0, 0, CXL_POISON_TRACE_INJECT);
356369
out:
357370
up_read(&cxl_dpa_rwsem);
371+
up_read(&cxl_region_rwsem);
358372

359373
return rc;
360374
}
@@ -372,10 +386,16 @@ int cxl_clear_poison(struct cxl_memdev *cxlmd, u64 dpa)
372386
if (!IS_ENABLED(CONFIG_DEBUG_FS))
373387
return 0;
374388

375-
rc = down_read_interruptible(&cxl_dpa_rwsem);
389+
rc = down_read_interruptible(&cxl_region_rwsem);
376390
if (rc)
377391
return rc;
378392

393+
rc = down_read_interruptible(&cxl_dpa_rwsem);
394+
if (rc) {
395+
up_read(&cxl_region_rwsem);
396+
return rc;
397+
}
398+
379399
rc = cxl_validate_poison_dpa(cxlmd, dpa);
380400
if (rc)
381401
goto out;
@@ -412,6 +432,7 @@ int cxl_clear_poison(struct cxl_memdev *cxlmd, u64 dpa)
412432
trace_cxl_poison(cxlmd, cxlr, &record, 0, 0, CXL_POISON_TRACE_CLEAR);
413433
out:
414434
up_read(&cxl_dpa_rwsem);
435+
up_read(&cxl_region_rwsem);
415436

416437
return rc;
417438
}

drivers/cxl/core/pci.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -620,7 +620,7 @@ void read_cdat_data(struct cxl_port *port)
620620
struct pci_dev *pdev = NULL;
621621
struct cxl_memdev *cxlmd;
622622
size_t cdat_length;
623-
void *cdat_table;
623+
void *cdat_table, *cdat_buf;
624624
int rc;
625625

626626
if (is_cxl_memdev(uport)) {
@@ -651,16 +651,15 @@ void read_cdat_data(struct cxl_port *port)
651651
return;
652652
}
653653

654-
cdat_table = devm_kzalloc(dev, cdat_length + sizeof(__le32),
655-
GFP_KERNEL);
656-
if (!cdat_table)
654+
cdat_buf = devm_kzalloc(dev, cdat_length + sizeof(__le32), GFP_KERNEL);
655+
if (!cdat_buf)
657656
return;
658657

659-
rc = cxl_cdat_read_table(dev, cdat_doe, cdat_table, &cdat_length);
658+
rc = cxl_cdat_read_table(dev, cdat_doe, cdat_buf, &cdat_length);
660659
if (rc)
661660
goto err;
662661

663-
cdat_table = cdat_table + sizeof(__le32);
662+
cdat_table = cdat_buf + sizeof(__le32);
664663
if (cdat_checksum(cdat_table, cdat_length))
665664
goto err;
666665

@@ -670,7 +669,7 @@ void read_cdat_data(struct cxl_port *port)
670669

671670
err:
672671
/* Don't leave table data allocated on error */
673-
devm_kfree(dev, cdat_table);
672+
devm_kfree(dev, cdat_buf);
674673
dev_err(dev, "Failed to read/validate CDAT.\n");
675674
}
676675
EXPORT_SYMBOL_NS_GPL(read_cdat_data, CXL);

drivers/cxl/core/pmu.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ const struct device_type cxl_pmu_type = {
2323

2424
static void remove_dev(void *dev)
2525
{
26-
device_del(dev);
26+
device_unregister(dev);
2727
}
2828

2929
int devm_cxl_pmu_add(struct device *parent, struct cxl_pmu_regs *regs,

drivers/cxl/core/port.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,9 +226,9 @@ static ssize_t dpa_resource_show(struct device *dev, struct device_attribute *at
226226
char *buf)
227227
{
228228
struct cxl_endpoint_decoder *cxled = to_cxl_endpoint_decoder(dev);
229-
u64 base = cxl_dpa_resource_start(cxled);
230229

231-
return sysfs_emit(buf, "%#llx\n", base);
230+
guard(rwsem_read)(&cxl_dpa_rwsem);
231+
return sysfs_emit(buf, "%#llx\n", (u64)cxl_dpa_resource_start(cxled));
232232
}
233233
static DEVICE_ATTR_RO(dpa_resource);
234234

drivers/cxl/core/region.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2467,10 +2467,6 @@ int cxl_get_poison_by_endpoint(struct cxl_port *port)
24672467
struct cxl_poison_context ctx;
24682468
int rc = 0;
24692469

2470-
rc = down_read_interruptible(&cxl_region_rwsem);
2471-
if (rc)
2472-
return rc;
2473-
24742470
ctx = (struct cxl_poison_context) {
24752471
.port = port
24762472
};
@@ -2480,7 +2476,6 @@ int cxl_get_poison_by_endpoint(struct cxl_port *port)
24802476
rc = cxl_get_poison_unmapped(to_cxl_memdev(port->uport_dev),
24812477
&ctx);
24822478

2483-
up_read(&cxl_region_rwsem);
24842479
return rc;
24852480
}
24862481

kernel/resource.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1844,8 +1844,8 @@ get_free_mem_region(struct device *dev, struct resource *base,
18441844

18451845
write_lock(&resource_lock);
18461846
for (addr = gfr_start(base, size, align, flags);
1847-
gfr_continue(base, addr, size, flags);
1848-
addr = gfr_next(addr, size, flags)) {
1847+
gfr_continue(base, addr, align, flags);
1848+
addr = gfr_next(addr, align, flags)) {
18491849
if (__region_intersects(base, addr, size, 0, IORES_DESC_NONE) !=
18501850
REGION_DISJOINT)
18511851
continue;

tools/testing/cxl/Kbuild

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,5 +62,6 @@ cxl_core-$(CONFIG_TRACING) += $(CXL_CORE_SRC)/trace.o
6262
cxl_core-$(CONFIG_CXL_REGION) += $(CXL_CORE_SRC)/region.o
6363
cxl_core-y += config_check.o
6464
cxl_core-y += cxl_core_test.o
65+
cxl_core-y += cxl_core_exports.o
6566

6667
obj-m += test/

tools/testing/cxl/cxl_core_exports.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/* Copyright(c) 2022 Intel Corporation. All rights reserved. */
3+
4+
#include "cxl.h"
5+
6+
/* Exporting of cxl_core symbols that are only used by cxl_test */
7+
EXPORT_SYMBOL_NS_GPL(cxl_num_decoders_committed, CXL);

tools/testing/cxl/test/cxl.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -669,10 +669,11 @@ static int mock_decoder_commit(struct cxl_decoder *cxld)
669669
return 0;
670670

671671
dev_dbg(&port->dev, "%s commit\n", dev_name(&cxld->dev));
672-
if (port->commit_end + 1 != id) {
672+
if (cxl_num_decoders_committed(port) != id) {
673673
dev_dbg(&port->dev,
674674
"%s: out of order commit, expected decoder%d.%d\n",
675-
dev_name(&cxld->dev), port->id, port->commit_end + 1);
675+
dev_name(&cxld->dev), port->id,
676+
cxl_num_decoders_committed(port));
676677
return -EBUSY;
677678
}
678679

0 commit comments

Comments
 (0)