Skip to content

Commit 105b623

Browse files
djbwweiny2
authored andcommitted
cxl/port: Prevent out-of-order decoder allocation
With the recent change to allow out-of-order decoder de-commit it highlights a need to strengthen the in-order decoder commit guarantees. As it stands match_free_decoder() ensures that if 2 regions are racing decoder allocations the one that wins the race will get the lower id decoder, but that still leaves the race to *commit* the decoder. Rather than have this complicated case of "reserved in-order, but may still commit out-of-order", just arrange for the reservation order to match the commit-order. In other words, prevent subsequent allocations until the last reservation is committed. This precludes overlapping region creation events and requires the previous regionN to either move forward to the decoder commit stage or drop its reservation before regionN+1 can move forward. That is, provided that regionN and regionN+1 decode through the same switch port. As a side effect this allows match_free_decoder() to drop its dependency on needing write access to the device_find_child() @DaTa parameter [1]. Reported-by: Zijun Hu <[email protected]> Closes: http://lore.kernel.org/[email protected] Cc: Davidlohr Bueso <[email protected]> Cc: Vishal Verma <[email protected]> Cc: Alison Schofield <[email protected]> Cc: Jonathan Cameron <[email protected]> Signed-off-by: Dan Williams <[email protected]> Reviewed-by: Jonathan Cameron <[email protected]> Reviewed-by: Ira Weiny <[email protected]> Link: https://patch.msgid.link/172964783668.81806.14962699553881333486.stgit@dwillia2-xfh.jf.intel.com Signed-off-by: Ira Weiny <[email protected]>
1 parent 101c268 commit 105b623

File tree

1 file changed

+33
-10
lines changed

1 file changed

+33
-10
lines changed

drivers/cxl/core/region.c

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -778,26 +778,50 @@ static size_t show_targetN(struct cxl_region *cxlr, char *buf, int pos)
778778
return rc;
779779
}
780780

781+
static int check_commit_order(struct device *dev, const void *data)
782+
{
783+
struct cxl_decoder *cxld = to_cxl_decoder(dev);
784+
785+
/*
786+
* if port->commit_end is not the only free decoder, then out of
787+
* order shutdown has occurred, block further allocations until
788+
* that is resolved
789+
*/
790+
if (((cxld->flags & CXL_DECODER_F_ENABLE) == 0))
791+
return -EBUSY;
792+
return 0;
793+
}
794+
781795
static int match_free_decoder(struct device *dev, void *data)
782796
{
797+
struct cxl_port *port = to_cxl_port(dev->parent);
783798
struct cxl_decoder *cxld;
784-
int *id = data;
799+
int rc;
785800

786801
if (!is_switch_decoder(dev))
787802
return 0;
788803

789804
cxld = to_cxl_decoder(dev);
790805

791-
/* enforce ordered allocation */
792-
if (cxld->id != *id)
806+
if (cxld->id != port->commit_end + 1)
793807
return 0;
794808

795-
if (!cxld->region)
796-
return 1;
797-
798-
(*id)++;
809+
if (cxld->region) {
810+
dev_dbg(dev->parent,
811+
"next decoder to commit (%s) is already reserved (%s)\n",
812+
dev_name(dev), dev_name(&cxld->region->dev));
813+
return 0;
814+
}
799815

800-
return 0;
816+
rc = device_for_each_child_reverse_from(dev->parent, dev, NULL,
817+
check_commit_order);
818+
if (rc) {
819+
dev_dbg(dev->parent,
820+
"unable to allocate %s due to out of order shutdown\n",
821+
dev_name(dev));
822+
return 0;
823+
}
824+
return 1;
801825
}
802826

803827
static int match_auto_decoder(struct device *dev, void *data)
@@ -824,7 +848,6 @@ cxl_region_find_decoder(struct cxl_port *port,
824848
struct cxl_region *cxlr)
825849
{
826850
struct device *dev;
827-
int id = 0;
828851

829852
if (port == cxled_to_port(cxled))
830853
return &cxled->cxld;
@@ -833,7 +856,7 @@ cxl_region_find_decoder(struct cxl_port *port,
833856
dev = device_find_child(&port->dev, &cxlr->params,
834857
match_auto_decoder);
835858
else
836-
dev = device_find_child(&port->dev, &id, match_free_decoder);
859+
dev = device_find_child(&port->dev, NULL, match_free_decoder);
837860
if (!dev)
838861
return NULL;
839862
/*

0 commit comments

Comments
 (0)