@@ -839,19 +839,22 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
cxld->target_type = CXL_DECODER_HOSTONLYMEM;
else
cxld->target_type = CXL_DECODER_DEVMEM;
- if (cxld->id != cxl_num_decoders_committed(port)) {
+
+ if (size == 0) {
dev_warn(&port->dev,
- "decoder%d.%d: Committed out of order\n",
+ "decoder%d.%d: Committed with zero size\n",
port->id, cxld->id);
return -ENXIO;
}
- if (size == 0) {
+ guard(rwsem_write)(&cxl_region_rwsem);
+ if (cxld->id != cxl_num_decoders_committed(port)) {
dev_warn(&port->dev,
- "decoder%d.%d: Committed with zero size\n",
+ "decoder%d.%d: Committed out of order\n",
port->id, cxld->id);
return -ENXIO;
}
+
port->commit_end = cxld->id;
} else {
if (cxled) {
init_hdm_decoder() modifies port->commit_end without taking the cxl_region_rwsem. An assert splat emitted by cxl_num_decoders_committed(). However looking at the code, it looks like the write version of the rwsem needs to be taken due to the modification of commit_end. Wrap the write version of the rwsem around reading and writing of commit_end. Fixes: 176baefb2eb5 ("cxl/hdm: Commit decoder state to hardware") Signed-off-by: Dave Jiang <dave.jiang@intel.com> --- v2: - Add changes from Ira and moving the lock block - Add suggestion from Dan on using guard() --- drivers/cxl/core/hdm.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)