Skip to content

Commit d03fcf5

Browse files
djbwdavejiang
authored andcommitted
cxl: Convert to ACQUIRE() for conditional rwsem locking
Use ACQUIRE() to cleanup conditional locking paths in the CXL driver The ACQUIRE() macro and its associated ACQUIRE_ERR() helpers, like scoped_cond_guard(), arrange for scoped-based conditional locking. Unlike scoped_cond_guard(), these macros arrange for an ERR_PTR() to be retrieved representing the state of the conditional lock. The goal of this conversion is to complete the removal of all explicit unlock calls in the subsystem. I.e. the methods to acquire a lock are solely via guard(), scoped_guard() (for limited cases), or ACQUIRE(). All unlock is implicit / scope-based. In order to make sure all lock sites are converted, the existing rwsem's are consolidated and renamed in 'struct cxl_rwsem'. While that makes the patch noisier it gives a clean cut-off between old-world (explicit unlock allowed), and new world (explicit unlock deleted). Cc: David Lechner <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Fabio M. De Francesco <[email protected]> Cc: Davidlohr Bueso <[email protected]> Cc: Jonathan Cameron <[email protected]> Cc: Dave Jiang <[email protected]> Cc: Alison Schofield <[email protected]> Cc: Vishal Verma <[email protected]> Cc: Ira Weiny <[email protected]> Cc: Shiju Jose <[email protected]> Acked-by: Peter Zijlstra (Intel) <[email protected]> Signed-off-by: Dan Williams <[email protected]> Reviewed-by: Jonathan Cameron <[email protected]> Reviewed-by: Fabio M. De Francesco <[email protected]> Reviewed-by: Dave Jiang <[email protected]> Tested-by: Shiju Jose <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Dave Jiang <[email protected]>
1 parent b3a8822 commit d03fcf5

File tree

10 files changed

+212
-279
lines changed

10 files changed

+212
-279
lines changed

drivers/cxl/core/cdat.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ static int match_cxlrd_hb(struct device *dev, void *data)
336336
cxlrd = to_cxl_root_decoder(dev);
337337
cxlsd = &cxlrd->cxlsd;
338338

339-
guard(rwsem_read)(&cxl_region_rwsem);
339+
guard(rwsem_read)(&cxl_rwsem.region);
340340
for (int i = 0; i < cxlsd->nr_targets; i++) {
341341
if (host_bridge == cxlsd->target[i]->dport_dev)
342342
return 1;
@@ -987,7 +987,7 @@ void cxl_region_shared_upstream_bandwidth_update(struct cxl_region *cxlr)
987987
bool is_root;
988988
int rc;
989989

990-
lockdep_assert_held(&cxl_dpa_rwsem);
990+
lockdep_assert_held(&cxl_rwsem.dpa);
991991

992992
struct xarray *usp_xa __free(free_perf_xa) =
993993
kzalloc(sizeof(*usp_xa), GFP_KERNEL);
@@ -1057,7 +1057,7 @@ void cxl_region_perf_data_calculate(struct cxl_region *cxlr,
10571057
{
10581058
struct cxl_dpa_perf *perf;
10591059

1060-
lockdep_assert_held(&cxl_dpa_rwsem);
1060+
lockdep_assert_held(&cxl_rwsem.dpa);
10611061

10621062
perf = cxled_get_dpa_perf(cxled);
10631063
if (IS_ERR(perf))

drivers/cxl/core/core.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#define __CXL_CORE_H__
66

77
#include <cxl/mailbox.h>
8+
#include <linux/rwsem.h>
89

910
extern const struct device_type cxl_nvdimm_bridge_type;
1011
extern const struct device_type cxl_nvdimm_type;
@@ -107,8 +108,20 @@ u16 cxl_rcrb_to_aer(struct device *dev, resource_size_t rcrb);
107108
#define PCI_RCRB_CAP_HDR_NEXT_MASK GENMASK(15, 8)
108109
#define PCI_CAP_EXP_SIZEOF 0x3c
109110

110-
extern struct rw_semaphore cxl_dpa_rwsem;
111-
extern struct rw_semaphore cxl_region_rwsem;
111+
struct cxl_rwsem {
112+
/*
113+
* All changes to HPA (interleave configuration) occur with this
114+
* lock held for write.
115+
*/
116+
struct rw_semaphore region;
117+
/*
118+
* All changes to a device DPA space occur with this lock held
119+
* for write.
120+
*/
121+
struct rw_semaphore dpa;
122+
};
123+
124+
extern struct cxl_rwsem cxl_rwsem;
112125

113126
int cxl_memdev_init(void);
114127
void cxl_memdev_exit(void);

drivers/cxl/core/edac.c

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,9 @@ static int cxl_scrub_get_attrbs(struct cxl_patrol_scrub_context *cxl_ps_ctx,
115115
flags, min_cycle);
116116
}
117117

118-
struct rw_semaphore *region_lock __free(rwsem_read_release) =
119-
rwsem_read_intr_acquire(&cxl_region_rwsem);
120-
if (!region_lock)
121-
return -EINTR;
118+
ACQUIRE(rwsem_read_intr, rwsem)(&cxl_rwsem.region);
119+
if ((ret = ACQUIRE_ERR(rwsem_read_intr, &rwsem)))
120+
return ret;
122121

123122
cxlr = cxl_ps_ctx->cxlr;
124123
p = &cxlr->params;
@@ -158,10 +157,9 @@ static int cxl_scrub_set_attrbs_region(struct device *dev,
158157
struct cxl_region *cxlr;
159158
int ret, i;
160159

161-
struct rw_semaphore *region_lock __free(rwsem_read_release) =
162-
rwsem_read_intr_acquire(&cxl_region_rwsem);
163-
if (!region_lock)
164-
return -EINTR;
160+
ACQUIRE(rwsem_read_intr, rwsem)(&cxl_rwsem.region);
161+
if ((ret = ACQUIRE_ERR(rwsem_read_intr, &rwsem)))
162+
return ret;
165163

166164
cxlr = cxl_ps_ctx->cxlr;
167165
p = &cxlr->params;
@@ -1340,16 +1338,15 @@ cxl_mem_perform_sparing(struct device *dev,
13401338
struct cxl_memdev_sparing_in_payload sparing_pi;
13411339
struct cxl_event_dram *rec = NULL;
13421340
u16 validity_flags = 0;
1341+
int ret;
13431342

1344-
struct rw_semaphore *region_lock __free(rwsem_read_release) =
1345-
rwsem_read_intr_acquire(&cxl_region_rwsem);
1346-
if (!region_lock)
1347-
return -EINTR;
1343+
ACQUIRE(rwsem_read_intr, region_rwsem)(&cxl_rwsem.region);
1344+
if ((ret = ACQUIRE_ERR(rwsem_read_intr, &region_rwsem)))
1345+
return ret;
13481346

1349-
struct rw_semaphore *dpa_lock __free(rwsem_read_release) =
1350-
rwsem_read_intr_acquire(&cxl_dpa_rwsem);
1351-
if (!dpa_lock)
1352-
return -EINTR;
1347+
ACQUIRE(rwsem_read_intr, dpa_rwsem)(&cxl_rwsem.dpa);
1348+
if ((ret = ACQUIRE_ERR(rwsem_read_intr, &dpa_rwsem)))
1349+
return ret;
13531350

13541351
if (!cxl_sparing_ctx->cap_safe_when_in_use) {
13551352
/* Memory to repair must be offline */
@@ -1787,16 +1784,15 @@ static int cxl_mem_perform_ppr(struct cxl_ppr_context *cxl_ppr_ctx)
17871784
struct cxl_memdev_ppr_maintenance_attrbs maintenance_attrbs;
17881785
struct cxl_memdev *cxlmd = cxl_ppr_ctx->cxlmd;
17891786
struct cxl_mem_repair_attrbs attrbs = { 0 };
1787+
int ret;
17901788

1791-
struct rw_semaphore *region_lock __free(rwsem_read_release) =
1792-
rwsem_read_intr_acquire(&cxl_region_rwsem);
1793-
if (!region_lock)
1794-
return -EINTR;
1789+
ACQUIRE(rwsem_read_intr, region_rwsem)(&cxl_rwsem.region);
1790+
if ((ret = ACQUIRE_ERR(rwsem_read_intr, &region_rwsem)))
1791+
return ret;
17951792

1796-
struct rw_semaphore *dpa_lock __free(rwsem_read_release) =
1797-
rwsem_read_intr_acquire(&cxl_dpa_rwsem);
1798-
if (!dpa_lock)
1799-
return -EINTR;
1793+
ACQUIRE(rwsem_read_intr, dpa_rwsem)(&cxl_rwsem.dpa);
1794+
if ((ret = ACQUIRE_ERR(rwsem_read_intr, &dpa_rwsem)))
1795+
return ret;
18001796

18011797
if (!cxl_ppr_ctx->media_accessible || !cxl_ppr_ctx->data_retained) {
18021798
/* Memory to repair must be offline */

drivers/cxl/core/hdm.c

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@
1616
* for enumerating these registers and capabilities.
1717
*/
1818

19-
DECLARE_RWSEM(cxl_dpa_rwsem);
19+
struct cxl_rwsem cxl_rwsem = {
20+
.region = __RWSEM_INITIALIZER(cxl_rwsem.region),
21+
.dpa = __RWSEM_INITIALIZER(cxl_rwsem.dpa),
22+
};
2023

2124
static int add_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
2225
int *target_map)
@@ -214,7 +217,7 @@ void cxl_dpa_debug(struct seq_file *file, struct cxl_dev_state *cxlds)
214217
{
215218
struct resource *p1, *p2;
216219

217-
guard(rwsem_read)(&cxl_dpa_rwsem);
220+
guard(rwsem_read)(&cxl_rwsem.dpa);
218221
for (p1 = cxlds->dpa_res.child; p1; p1 = p1->sibling) {
219222
__cxl_dpa_debug(file, p1, 0);
220223
for (p2 = p1->child; p2; p2 = p2->sibling)
@@ -266,7 +269,7 @@ static void __cxl_dpa_release(struct cxl_endpoint_decoder *cxled)
266269
struct resource *res = cxled->dpa_res;
267270
resource_size_t skip_start;
268271

269-
lockdep_assert_held_write(&cxl_dpa_rwsem);
272+
lockdep_assert_held_write(&cxl_rwsem.dpa);
270273

271274
/* save @skip_start, before @res is released */
272275
skip_start = res->start - cxled->skip;
@@ -281,7 +284,7 @@ static void __cxl_dpa_release(struct cxl_endpoint_decoder *cxled)
281284

282285
static void cxl_dpa_release(void *cxled)
283286
{
284-
guard(rwsem_write)(&cxl_dpa_rwsem);
287+
guard(rwsem_write)(&cxl_rwsem.dpa);
285288
__cxl_dpa_release(cxled);
286289
}
287290

@@ -293,7 +296,7 @@ static void devm_cxl_dpa_release(struct cxl_endpoint_decoder *cxled)
293296
{
294297
struct cxl_port *port = cxled_to_port(cxled);
295298

296-
lockdep_assert_held_write(&cxl_dpa_rwsem);
299+
lockdep_assert_held_write(&cxl_rwsem.dpa);
297300
devm_remove_action(&port->dev, cxl_dpa_release, cxled);
298301
__cxl_dpa_release(cxled);
299302
}
@@ -361,7 +364,7 @@ static int __cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
361364
struct resource *res;
362365
int rc;
363366

364-
lockdep_assert_held_write(&cxl_dpa_rwsem);
367+
lockdep_assert_held_write(&cxl_rwsem.dpa);
365368

366369
if (!len) {
367370
dev_warn(dev, "decoder%d.%d: empty reservation attempted\n",
@@ -470,7 +473,7 @@ int cxl_dpa_setup(struct cxl_dev_state *cxlds, const struct cxl_dpa_info *info)
470473
{
471474
struct device *dev = cxlds->dev;
472475

473-
guard(rwsem_write)(&cxl_dpa_rwsem);
476+
guard(rwsem_write)(&cxl_rwsem.dpa);
474477

475478
if (cxlds->nr_partitions)
476479
return -EBUSY;
@@ -516,9 +519,8 @@ int devm_cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
516519
struct cxl_port *port = cxled_to_port(cxled);
517520
int rc;
518521

519-
down_write(&cxl_dpa_rwsem);
520-
rc = __cxl_dpa_reserve(cxled, base, len, skipped);
521-
up_write(&cxl_dpa_rwsem);
522+
scoped_guard(rwsem_write, &cxl_rwsem.dpa)
523+
rc = __cxl_dpa_reserve(cxled, base, len, skipped);
522524

523525
if (rc)
524526
return rc;
@@ -529,7 +531,7 @@ EXPORT_SYMBOL_NS_GPL(devm_cxl_dpa_reserve, "CXL");
529531

530532
resource_size_t cxl_dpa_size(struct cxl_endpoint_decoder *cxled)
531533
{
532-
guard(rwsem_read)(&cxl_dpa_rwsem);
534+
guard(rwsem_read)(&cxl_rwsem.dpa);
533535
if (cxled->dpa_res)
534536
return resource_size(cxled->dpa_res);
535537

@@ -540,7 +542,7 @@ resource_size_t cxl_dpa_resource_start(struct cxl_endpoint_decoder *cxled)
540542
{
541543
resource_size_t base = -1;
542544

543-
lockdep_assert_held(&cxl_dpa_rwsem);
545+
lockdep_assert_held(&cxl_rwsem.dpa);
544546
if (cxled->dpa_res)
545547
base = cxled->dpa_res->start;
546548

@@ -552,7 +554,7 @@ int cxl_dpa_free(struct cxl_endpoint_decoder *cxled)
552554
struct cxl_port *port = cxled_to_port(cxled);
553555
struct device *dev = &cxled->cxld.dev;
554556

555-
guard(rwsem_write)(&cxl_dpa_rwsem);
557+
guard(rwsem_write)(&cxl_rwsem.dpa);
556558
if (!cxled->dpa_res)
557559
return 0;
558560
if (cxled->cxld.region) {
@@ -582,7 +584,7 @@ int cxl_dpa_set_part(struct cxl_endpoint_decoder *cxled,
582584
struct device *dev = &cxled->cxld.dev;
583585
int part;
584586

585-
guard(rwsem_write)(&cxl_dpa_rwsem);
587+
guard(rwsem_write)(&cxl_rwsem.dpa);
586588
if (cxled->cxld.flags & CXL_DECODER_F_ENABLE)
587589
return -EBUSY;
588590

@@ -614,7 +616,7 @@ static int __cxl_dpa_alloc(struct cxl_endpoint_decoder *cxled, u64 size)
614616
struct resource *p, *last;
615617
int part;
616618

617-
guard(rwsem_write)(&cxl_dpa_rwsem);
619+
guard(rwsem_write)(&cxl_rwsem.dpa);
618620
if (cxled->cxld.region) {
619621
dev_dbg(dev, "decoder attached to %s\n",
620622
dev_name(&cxled->cxld.region->dev));
@@ -842,9 +844,8 @@ static int cxl_decoder_commit(struct cxl_decoder *cxld)
842844
}
843845
}
844846

845-
down_read(&cxl_dpa_rwsem);
846-
setup_hw_decoder(cxld, hdm);
847-
up_read(&cxl_dpa_rwsem);
847+
scoped_guard(rwsem_read, &cxl_rwsem.dpa)
848+
setup_hw_decoder(cxld, hdm);
848849

849850
port->commit_end++;
850851
rc = cxld_await_commit(hdm, cxld->id);
@@ -882,7 +883,7 @@ void cxl_port_commit_reap(struct cxl_decoder *cxld)
882883
{
883884
struct cxl_port *port = to_cxl_port(cxld->dev.parent);
884885

885-
lockdep_assert_held_write(&cxl_region_rwsem);
886+
lockdep_assert_held_write(&cxl_rwsem.region);
886887

887888
/*
888889
* Once the highest committed decoder is disabled, free any other
@@ -1030,7 +1031,7 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
10301031
else
10311032
cxld->target_type = CXL_DECODER_DEVMEM;
10321033

1033-
guard(rwsem_write)(&cxl_region_rwsem);
1034+
guard(rwsem_write)(&cxl_rwsem.region);
10341035
if (cxld->id != cxl_num_decoders_committed(port)) {
10351036
dev_warn(&port->dev,
10361037
"decoder%d.%d: Committed out of order\n",

drivers/cxl/core/mbox.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -909,8 +909,8 @@ void cxl_event_trace_record(const struct cxl_memdev *cxlmd,
909909
* translations. Take topology mutation locks and lookup
910910
* { HPA, REGION } from { DPA, MEMDEV } in the event record.
911911
*/
912-
guard(rwsem_read)(&cxl_region_rwsem);
913-
guard(rwsem_read)(&cxl_dpa_rwsem);
912+
guard(rwsem_read)(&cxl_rwsem.region);
913+
guard(rwsem_read)(&cxl_rwsem.dpa);
914914

915915
dpa = le64_to_cpu(evt->media_hdr.phys_addr) & CXL_DPA_MASK;
916916
cxlr = cxl_dpa_to_region(cxlmd, dpa);
@@ -1265,7 +1265,7 @@ int cxl_mem_sanitize(struct cxl_memdev *cxlmd, u16 cmd)
12651265
/* synchronize with cxl_mem_probe() and decoder write operations */
12661266
guard(device)(&cxlmd->dev);
12671267
endpoint = cxlmd->endpoint;
1268-
guard(rwsem_read)(&cxl_region_rwsem);
1268+
guard(rwsem_read)(&cxl_rwsem.region);
12691269
/*
12701270
* Require an endpoint to be safe otherwise the driver can not
12711271
* be sure that the device is unmapped.

0 commit comments

Comments
 (0)