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

cxl/core: Add locked variants of the poison inject and clear funcs

The core functions that validate and send inject and clear commands
to the memdev devices require holding both the dpa_rwsem and the
region_rwsem.

In preparation for another caller of these functions that must hold
the locks upon entry, split the work into a locked and unlocked pair.

Consideration was given to moving the locking to both callers,
however, the existing caller is not in the core (mem.c) and cannot
access the locks.

Signed-off-by: Alison Schofield <alison.schofield@intel.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Link: https://patch.msgid.link/1d601f586975195733984ca63d1b5789bbe8690f.1754290144.git.alison.schofield@intel.com
Signed-off-by: Dave Jiang <dave.jiang@intel.com>

authored by

Alison Schofield and committed by
Dave Jiang
25a02078 dc181170

+38 -16
+36 -16
drivers/cxl/core/memdev.c
··· 276 276 return 0; 277 277 } 278 278 279 - int cxl_inject_poison(struct cxl_memdev *cxlmd, u64 dpa) 279 + int cxl_inject_poison_locked(struct cxl_memdev *cxlmd, u64 dpa) 280 280 { 281 281 struct cxl_mailbox *cxl_mbox = &cxlmd->cxlds->cxl_mbox; 282 282 struct cxl_mbox_inject_poison inject; ··· 288 288 if (!IS_ENABLED(CONFIG_DEBUG_FS)) 289 289 return 0; 290 290 291 - ACQUIRE(rwsem_read_intr, region_rwsem)(&cxl_rwsem.region); 292 - if ((rc = ACQUIRE_ERR(rwsem_read_intr, &region_rwsem))) 293 - return rc; 294 - 295 - ACQUIRE(rwsem_read_intr, dpa_rwsem)(&cxl_rwsem.dpa); 296 - if ((rc = ACQUIRE_ERR(rwsem_read_intr, &dpa_rwsem))) 297 - return rc; 291 + lockdep_assert_held(&cxl_rwsem.dpa); 292 + lockdep_assert_held(&cxl_rwsem.region); 298 293 299 294 rc = cxl_validate_poison_dpa(cxlmd, dpa); 300 295 if (rc) ··· 319 324 320 325 return 0; 321 326 } 327 + 328 + int cxl_inject_poison(struct cxl_memdev *cxlmd, u64 dpa) 329 + { 330 + int rc; 331 + 332 + ACQUIRE(rwsem_read_intr, region_rwsem)(&cxl_rwsem.region); 333 + if ((rc = ACQUIRE_ERR(rwsem_read_intr, &region_rwsem))) 334 + return rc; 335 + 336 + ACQUIRE(rwsem_read_intr, dpa_rwsem)(&cxl_rwsem.dpa); 337 + if ((rc = ACQUIRE_ERR(rwsem_read_intr, &dpa_rwsem))) 338 + return rc; 339 + 340 + return cxl_inject_poison_locked(cxlmd, dpa); 341 + } 322 342 EXPORT_SYMBOL_NS_GPL(cxl_inject_poison, "CXL"); 323 343 324 - int cxl_clear_poison(struct cxl_memdev *cxlmd, u64 dpa) 344 + int cxl_clear_poison_locked(struct cxl_memdev *cxlmd, u64 dpa) 325 345 { 326 346 struct cxl_mailbox *cxl_mbox = &cxlmd->cxlds->cxl_mbox; 327 347 struct cxl_mbox_clear_poison clear; ··· 348 338 if (!IS_ENABLED(CONFIG_DEBUG_FS)) 349 339 return 0; 350 340 351 - ACQUIRE(rwsem_read_intr, region_rwsem)(&cxl_rwsem.region); 352 - if ((rc = ACQUIRE_ERR(rwsem_read_intr, &region_rwsem))) 353 - return rc; 354 - 355 - ACQUIRE(rwsem_read_intr, dpa_rwsem)(&cxl_rwsem.dpa); 356 - if ((rc = ACQUIRE_ERR(rwsem_read_intr, &dpa_rwsem))) 357 - return rc; 341 + lockdep_assert_held(&cxl_rwsem.dpa); 342 + lockdep_assert_held(&cxl_rwsem.region); 358 343 359 344 rc = cxl_validate_poison_dpa(cxlmd, dpa); 360 345 if (rc) ··· 387 382 trace_cxl_poison(cxlmd, cxlr, &record, 0, 0, CXL_POISON_TRACE_CLEAR); 388 383 389 384 return 0; 385 + } 386 + 387 + int cxl_clear_poison(struct cxl_memdev *cxlmd, u64 dpa) 388 + { 389 + int rc; 390 + 391 + ACQUIRE(rwsem_read_intr, region_rwsem)(&cxl_rwsem.region); 392 + if ((rc = ACQUIRE_ERR(rwsem_read_intr, &region_rwsem))) 393 + return rc; 394 + 395 + ACQUIRE(rwsem_read_intr, dpa_rwsem)(&cxl_rwsem.dpa); 396 + if ((rc = ACQUIRE_ERR(rwsem_read_intr, &dpa_rwsem))) 397 + return rc; 398 + 399 + return cxl_clear_poison_locked(cxlmd, dpa); 390 400 } 391 401 EXPORT_SYMBOL_NS_GPL(cxl_clear_poison, "CXL"); 392 402
+2
drivers/cxl/cxlmem.h
··· 869 869 int cxl_trigger_poison_list(struct cxl_memdev *cxlmd); 870 870 int cxl_inject_poison(struct cxl_memdev *cxlmd, u64 dpa); 871 871 int cxl_clear_poison(struct cxl_memdev *cxlmd, u64 dpa); 872 + int cxl_inject_poison_locked(struct cxl_memdev *cxlmd, u64 dpa); 873 + int cxl_clear_poison_locked(struct cxl_memdev *cxlmd, u64 dpa); 872 874 873 875 #ifdef CONFIG_CXL_EDAC_MEM_FEATURES 874 876 int devm_cxl_memdev_edac_register(struct cxl_memdev *cxlmd);