Skip to content

Commit

Permalink
cxl/region: Add region autodiscovery
Browse files Browse the repository at this point in the history
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 <fan.ni@samsung.com>
Reviewed-by: Vishal Verma <vishal.l.verma@intel.com>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Link: https://lore.kernel.org/r/167601999958.1924368.9366954455835735048.stgit@dwillia2-xfh.jf.intel.com
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
  • Loading branch information
djbw committed Feb 11, 2023
1 parent 32ce3f1 commit a32320b
Show file tree
Hide file tree
Showing 5 changed files with 580 additions and 11 deletions.
11 changes: 11 additions & 0 deletions drivers/cxl/core/hdm.c
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,14 @@ static int cxl_decoder_reset(struct cxl_decoder *cxld)
port->commit_end--;
cxld->flags &= ~CXL_DECODER_F_ENABLE;

/* Userspace is now responsible for reconfiguring this decoder */
if (is_endpoint_decoder(&cxld->dev)) {
struct cxl_endpoint_decoder *cxled;

cxled = to_cxl_endpoint_decoder(&cxld->dev);
cxled->state = CXL_DECODER_STATE_MANUAL;
}

return 0;
}

Expand Down Expand Up @@ -783,6 +791,9 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
return rc;
}
*dpa_base += dpa_size + skip;

cxled->state = CXL_DECODER_STATE_AUTO;

return 0;
}

Expand Down
2 changes: 2 additions & 0 deletions drivers/cxl/core/port.c
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,7 @@ bool is_endpoint_decoder(struct device *dev)
{
return dev->type == &cxl_decoder_endpoint_type;
}
EXPORT_SYMBOL_NS_GPL(is_endpoint_decoder, CXL);

bool is_root_decoder(struct device *dev)
{
Expand Down Expand Up @@ -1628,6 +1629,7 @@ struct cxl_root_decoder *cxl_root_decoder_alloc(struct cxl_port *port,
}

cxlrd->calc_hb = calc_hb;
mutex_init(&cxlrd->range_lock);

cxld = &cxlsd->cxld;
cxld->dev.type = &cxl_decoder_root_type;
Expand Down
Loading

0 comments on commit a32320b

Please sign in to comment.