Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+49 -24
+3 -2
drivers/cxl/core/hdm.c
··· 363 363 { 364 364 resource_size_t base = -1; 365 365 366 - down_read(&cxl_dpa_rwsem); 366 + lockdep_assert_held(&cxl_dpa_rwsem); 367 367 if (cxled->dpa_res) 368 368 base = cxled->dpa_res->start; 369 - up_read(&cxl_dpa_rwsem); 370 369 371 370 return base; 372 371 } ··· 838 839 cxld->target_type = CXL_DECODER_HOSTONLYMEM; 839 840 else 840 841 cxld->target_type = CXL_DECODER_DEVMEM; 842 + 843 + guard(rwsem_write)(&cxl_region_rwsem); 841 844 if (cxld->id != cxl_num_decoders_committed(port)) { 842 845 dev_warn(&port->dev, 843 846 "decoder%d.%d: Committed out of order\n",
+24 -3
drivers/cxl/core/memdev.c
··· 227 227 if (!port || !is_cxl_endpoint(port)) 228 228 return -EINVAL; 229 229 230 - rc = down_read_interruptible(&cxl_dpa_rwsem); 230 + rc = down_read_interruptible(&cxl_region_rwsem); 231 231 if (rc) 232 232 return rc; 233 + 234 + rc = down_read_interruptible(&cxl_dpa_rwsem); 235 + if (rc) { 236 + up_read(&cxl_region_rwsem); 237 + return rc; 238 + } 233 239 234 240 if (cxl_num_decoders_committed(port) == 0) { 235 241 /* No regions mapped to this memdev */ ··· 245 239 rc = cxl_get_poison_by_endpoint(port); 246 240 } 247 241 up_read(&cxl_dpa_rwsem); 242 + up_read(&cxl_region_rwsem); 248 243 249 244 return rc; 250 245 } ··· 331 324 if (!IS_ENABLED(CONFIG_DEBUG_FS)) 332 325 return 0; 333 326 334 - rc = down_read_interruptible(&cxl_dpa_rwsem); 327 + rc = down_read_interruptible(&cxl_region_rwsem); 335 328 if (rc) 336 329 return rc; 330 + 331 + rc = down_read_interruptible(&cxl_dpa_rwsem); 332 + if (rc) { 333 + up_read(&cxl_region_rwsem); 334 + return rc; 335 + } 337 336 338 337 rc = cxl_validate_poison_dpa(cxlmd, dpa); 339 338 if (rc) ··· 368 355 trace_cxl_poison(cxlmd, cxlr, &record, 0, 0, CXL_POISON_TRACE_INJECT); 369 356 out: 370 357 up_read(&cxl_dpa_rwsem); 358 + up_read(&cxl_region_rwsem); 371 359 372 360 return rc; 373 361 } ··· 386 372 if (!IS_ENABLED(CONFIG_DEBUG_FS)) 387 373 return 0; 388 374 389 - rc = down_read_interruptible(&cxl_dpa_rwsem); 375 + rc = down_read_interruptible(&cxl_region_rwsem); 390 376 if (rc) 391 377 return rc; 378 + 379 + rc = down_read_interruptible(&cxl_dpa_rwsem); 380 + if (rc) { 381 + up_read(&cxl_region_rwsem); 382 + return rc; 383 + } 392 384 393 385 rc = cxl_validate_poison_dpa(cxlmd, dpa); 394 386 if (rc) ··· 432 412 trace_cxl_poison(cxlmd, cxlr, &record, 0, 0, CXL_POISON_TRACE_CLEAR); 433 413 out: 434 414 up_read(&cxl_dpa_rwsem); 415 + up_read(&cxl_region_rwsem); 435 416 436 417 return rc; 437 418 }
+6 -7
drivers/cxl/core/pci.c
··· 620 620 struct pci_dev *pdev = NULL; 621 621 struct cxl_memdev *cxlmd; 622 622 size_t cdat_length; 623 - void *cdat_table; 623 + void *cdat_table, *cdat_buf; 624 624 int rc; 625 625 626 626 if (is_cxl_memdev(uport)) { ··· 651 651 return; 652 652 } 653 653 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) 657 656 return; 658 657 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); 660 659 if (rc) 661 660 goto err; 662 661 663 - cdat_table = cdat_table + sizeof(__le32); 662 + cdat_table = cdat_buf + sizeof(__le32); 664 663 if (cdat_checksum(cdat_table, cdat_length)) 665 664 goto err; 666 665 ··· 669 670 670 671 err: 671 672 /* Don't leave table data allocated on error */ 672 - devm_kfree(dev, cdat_table); 673 + devm_kfree(dev, cdat_buf); 673 674 dev_err(dev, "Failed to read/validate CDAT.\n"); 674 675 } 675 676 EXPORT_SYMBOL_NS_GPL(read_cdat_data, CXL);
+1 -1
drivers/cxl/core/pmu.c
··· 23 23 24 24 static void remove_dev(void *dev) 25 25 { 26 - device_del(dev); 26 + device_unregister(dev); 27 27 } 28 28 29 29 int devm_cxl_pmu_add(struct device *parent, struct cxl_pmu_regs *regs,
+2 -2
drivers/cxl/core/port.c
··· 226 226 char *buf) 227 227 { 228 228 struct cxl_endpoint_decoder *cxled = to_cxl_endpoint_decoder(dev); 229 - u64 base = cxl_dpa_resource_start(cxled); 230 229 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)); 232 232 } 233 233 static DEVICE_ATTR_RO(dpa_resource); 234 234
-5
drivers/cxl/core/region.c
··· 2467 2467 struct cxl_poison_context ctx; 2468 2468 int rc = 0; 2469 2469 2470 - rc = down_read_interruptible(&cxl_region_rwsem); 2471 - if (rc) 2472 - return rc; 2473 - 2474 2470 ctx = (struct cxl_poison_context) { 2475 2471 .port = port 2476 2472 }; ··· 2476 2480 rc = cxl_get_poison_unmapped(to_cxl_memdev(port->uport_dev), 2477 2481 &ctx); 2478 2482 2479 - up_read(&cxl_region_rwsem); 2480 2483 return rc; 2481 2484 } 2482 2485
+2 -2
kernel/resource.c
··· 1844 1844 1845 1845 write_lock(&resource_lock); 1846 1846 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)) { 1849 1849 if (__region_intersects(base, addr, size, 0, IORES_DESC_NONE) != 1850 1850 REGION_DISJOINT) 1851 1851 continue;
+1
tools/testing/cxl/Kbuild
··· 62 62 cxl_core-$(CONFIG_CXL_REGION) += $(CXL_CORE_SRC)/region.o 63 63 cxl_core-y += config_check.o 64 64 cxl_core-y += cxl_core_test.o 65 + cxl_core-y += cxl_core_exports.o 65 66 66 67 obj-m += test/
+7
tools/testing/cxl/cxl_core_exports.c
··· 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);
+3 -2
tools/testing/cxl/test/cxl.c
··· 669 669 return 0; 670 670 671 671 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) { 673 673 dev_dbg(&port->dev, 674 674 "%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)); 676 677 return -EBUSY; 677 678 } 678 679