Skip to content

Commit a32320b

Browse files
committed
cxl/region: Add region autodiscovery
Region autodiscovery is an asynchronous state machine advanced by cxl_port_probe(). After the decoders on an endpoint port are enumerated they are scanned for actively enabled instances. Each active decoder is flagged for auto-assembly CXL_DECODER_F_AUTO and attached to a region. If a region does not already exist for the address range setting of the decoder one is created. That creation process may race with other decoders of the same region being discovered since cxl_port_probe() is asynchronous. A new 'struct cxl_root_decoder' lock, @range_lock, is introduced to mitigate that race. Once all decoders have arrived, "p->nr_targets == p->interleave_ways", they are sorted by their relative decode position. The sort algorithm involves finding the point in the cxl_port topology where one leg of the decode leads to deviceA and the other deviceB. At that point in the topology the target order in the 'struct cxl_switch_decoder' indicates the relative position of those endpoint decoders in the region. >From that point the region goes through the same setup and validation steps as user-created regions, but instead of programming the decoders it validates that driver would have written the same values to the decoders as were already present. Tested-by: Fan Ni <[email protected]> Reviewed-by: Vishal Verma <[email protected]> Reviewed-by: Jonathan Cameron <[email protected]> Link: https://lore.kernel.org/r/167601999958.1924368.9366954455835735048.stgit@dwillia2-xfh.jf.intel.com Signed-off-by: Dan Williams <[email protected]>
1 parent 32ce3f1 commit a32320b

File tree

5 files changed

+580
-11
lines changed

5 files changed

+580
-11
lines changed

drivers/cxl/core/hdm.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,14 @@ static int cxl_decoder_reset(struct cxl_decoder *cxld)
676676
port->commit_end--;
677677
cxld->flags &= ~CXL_DECODER_F_ENABLE;
678678

679+
/* Userspace is now responsible for reconfiguring this decoder */
680+
if (is_endpoint_decoder(&cxld->dev)) {
681+
struct cxl_endpoint_decoder *cxled;
682+
683+
cxled = to_cxl_endpoint_decoder(&cxld->dev);
684+
cxled->state = CXL_DECODER_STATE_MANUAL;
685+
}
686+
679687
return 0;
680688
}
681689

@@ -783,6 +791,9 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
783791
return rc;
784792
}
785793
*dpa_base += dpa_size + skip;
794+
795+
cxled->state = CXL_DECODER_STATE_AUTO;
796+
786797
return 0;
787798
}
788799

drivers/cxl/core/port.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,7 @@ bool is_endpoint_decoder(struct device *dev)
446446
{
447447
return dev->type == &cxl_decoder_endpoint_type;
448448
}
449+
EXPORT_SYMBOL_NS_GPL(is_endpoint_decoder, CXL);
449450

450451
bool is_root_decoder(struct device *dev)
451452
{
@@ -1628,6 +1629,7 @@ struct cxl_root_decoder *cxl_root_decoder_alloc(struct cxl_port *port,
16281629
}
16291630

16301631
cxlrd->calc_hb = calc_hb;
1632+
mutex_init(&cxlrd->range_lock);
16311633

16321634
cxld = &cxlsd->cxld;
16331635
cxld->dev.type = &cxl_decoder_root_type;

0 commit comments

Comments
 (0)