Skip to content

Commit 2ab4704

Browse files
committed
cxl/region: Flag partially torn down regions as unusable
cxl_region_decode_reset() walks all the decoders associated with a given region and disables them. Due to decoder ordering rules it is possible that a switch in the topology notices that a given decoder can not be shutdown before another region with a higher HPA is shutdown first. That can leave the region in a partially committed state. Capture that state in a new CXL_REGION_F_NEEDS_RESET flag and require that a successful cxl_region_decode_reset() attempt must be completed before cxl_region_probe() accepts the region. This is a corollary for the bug that Jonathan identified in "CXL/region : commit reset of out of order region appears to succeed." [1]. Cc: Jonathan Cameron <Jonathan.Cameron@Huawei.com> Link: http://lore.kernel.org/r/20230316171441.0000205b@Huawei.com [1] Fixes: 176baef ("cxl/hdm: Commit decoder state to hardware") Reviewed-by: Dave Jiang <dave.jiang@intel.com> Link: https://lore.kernel.org/r/168696507423.3590522.16254212607926684429.stgit@dwillia2-xfh.jf.intel.com Signed-off-by: Dan Williams <dan.j.williams@intel.com>
1 parent d1257d0 commit 2ab4704

2 files changed

Lines changed: 20 additions & 0 deletions

File tree

drivers/cxl/core/region.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,14 +182,19 @@ static int cxl_region_decode_reset(struct cxl_region *cxlr, int count)
182182
rc = cxld->reset(cxld);
183183
if (rc)
184184
return rc;
185+
set_bit(CXL_REGION_F_NEEDS_RESET, &cxlr->flags);
185186
}
186187

187188
endpoint_reset:
188189
rc = cxled->cxld.reset(&cxled->cxld);
189190
if (rc)
190191
return rc;
192+
set_bit(CXL_REGION_F_NEEDS_RESET, &cxlr->flags);
191193
}
192194

195+
/* all decoders associated with this region have been torn down */
196+
clear_bit(CXL_REGION_F_NEEDS_RESET, &cxlr->flags);
197+
193198
return 0;
194199
}
195200

@@ -2864,6 +2869,13 @@ static int cxl_region_probe(struct device *dev)
28642869
goto out;
28652870
}
28662871

2872+
if (test_bit(CXL_REGION_F_NEEDS_RESET, &cxlr->flags)) {
2873+
dev_err(&cxlr->dev,
2874+
"failed to activate, re-commit region and retry\n");
2875+
rc = -ENXIO;
2876+
goto out;
2877+
}
2878+
28672879
/*
28682880
* From this point on any path that changes the region's state away from
28692881
* CXL_CONFIG_COMMIT is also responsible for releasing the driver.

drivers/cxl/cxl.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,14 @@ struct cxl_region_params {
469469
*/
470470
#define CXL_REGION_F_AUTO 0
471471

472+
/*
473+
* Require that a committed region successfully complete a teardown once
474+
* any of its associated decoders have been torn down. This maintains
475+
* the commit state for the region since there are committed decoders,
476+
* but blocks cxl_region_probe().
477+
*/
478+
#define CXL_REGION_F_NEEDS_RESET 1
479+
472480
/**
473481
* struct cxl_region - CXL region
474482
* @dev: This region's device

0 commit comments

Comments
 (0)