Re: [PATCH v3 3/3] cxl/hdm: Restore commit_end when decoder enumeration fails

Alison Schofield <[email protected]>
Newsgroups org.kernel.vger.linux-cxl
Message-ID <[email protected]>
On Mon, Jul 20, 2026 at 02:14:30PM +0800, Li Ming wrote:
> 
> 在 2026/7/18 05:42, Alison Schofield 写道:
> > commit_end tracks the highest committed decoder on a port. It gets
> > advanced before decoder enumeration is complete, so a later failure
> > leaves it pointing at a decoder that was never added. The next probe
> > then rejects decoder0 as out of order and enumeration fails.
> > 
> > Reset commit_end to the none committed baseline once the decoders are
> > torn down, so a subsequent probe rebuilds it from scratch. Register the
> > reset before the decoders are added so that on unwind it runs after
> > every decoder has been unregistered. This prevents commit_end from
> > dropping below the highest committed decoder still registered and
> > exposing an inconsistent value to a concurrent reader.
> > 
> > Protect the commit_end advance in the DVSEC emulation path against
> > concurrent readers, matching the register-programmed path.
> > 
> > Fixes: 176baefb2eb5 ("cxl/hdm: Commit decoder state to hardware")
> > Fixes: b777e9bec960 ("cxl/hdm: Emulate HDM decoder from DVSEC range registers")
> > Signed-off-by: Alison Schofield <[email protected]>
> > ---
> >   drivers/cxl/core/hdm.c | 23 ++++++++++++++++++++---
> >   1 file changed, 20 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c
> > index 4aaadb842d90..6dc6e53c28c6 100644
> > --- a/drivers/cxl/core/hdm.c
> > +++ b/drivers/cxl/core/hdm.c
> > @@ -955,7 +955,8 @@ static int cxl_setup_hdm_decoder_from_dvsec(
> >   	 * change the range registers at run time.
> >   	 */
> >   	cxld->flags |= CXL_DECODER_F_ENABLE | CXL_DECODER_F_LOCK;
> > -	port->commit_end = cxld->id;
> > +	scoped_guard(rwsem_write, &cxl_rwsem.region)
> > +		port->commit_end = cxld->id;
> >   	rc = devm_cxl_dpa_reserve(cxled, *dpa_base, len, 0);
> >   	if (rc) {
> > @@ -1183,18 +1184,34 @@ static void cxl_settle_decoders(struct cxl_hdm *cxlhdm)
> >    * @cxlhdm: Structure to populate with HDM capabilities
> >    * @info: cached DVSEC range register info
> >    */
> > +static void cxl_reset_commit_end(void *data)
> > +{
> > +	struct cxl_port *port = data;
> > +
> > +	guard(rwsem_write)(&cxl_rwsem.region);
> > +	port->commit_end = -1;
> > +}
> > +
> >   static int devm_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm,
> >   				       struct cxl_endpoint_dvsec_info *info)
> >   {
> >   	void __iomem *hdm = cxlhdm->regs.hdm_decoder;
> >   	struct cxl_port *port = cxlhdm->port;
> > -	int i;
> >   	u64 dpa_base = 0;
> > +	int i, rc;
> >   	cxl_settle_decoders(cxlhdm);
> > +	/*
> > +	 * Reset commit_end after all decoders have been torn down so a
> > +	 * subsequent probe rebuilds it from scratch.
> > +	 */
> > +	rc = devm_add_action_or_reset(&port->dev, cxl_reset_commit_end, port);
> > +	if (rc)
> > +		return rc;
> 
> Seems like devm_add_action() is enough here. port->commit_end is -1 already.

Agree. The reset on fail would only write -1 over -1.
Changed in v4. Please take a look.

-- Alison
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.