diff mbox series

[11/46] cxl/core: Define a 'struct cxl_endpoint_decoder' for tracking DPA resources

Message ID 165603878173.551046.17541236959392713646.stgit@dwillia2-xfh
State New
Headers show
Series CXL PMEM Region Provisioning | expand

Commit Message

Dan Williams June 24, 2022, 2:46 a.m. UTC
Previously the target routing specifics of switch decoders and platfom
CXL window resource tracking of root decoders were factored out of
'struct cxl_decoder'. While switch decoders translate from SPA to
downstream ports, endpoint decoders translate from SPA to DPA.

This patch, 3 of 3, adds a 'struct cxl_endpoint_decoder' that tracks an
endpoint-specific Device Physical Address (DPA) resource. For now this
just defines ->dpa_res, a follow-on patch will handle requesting DPA
resource ranges from a device-DPA resource tree.

Co-developed-by: Ben Widawsky <bwidawsk@kernel.org>
Signed-off-by: Ben Widawsky <bwidawsk@kernel.org>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 drivers/cxl/core/hdm.c       |   12 +++++++++---
 drivers/cxl/core/port.c      |   36 +++++++++++++++++++++++++++---------
 drivers/cxl/cxl.h            |   15 ++++++++++++++-
 tools/testing/cxl/test/cxl.c |   11 +++++++++--
 4 files changed, 59 insertions(+), 15 deletions(-)

Comments

Jonathan Cameron June 28, 2022, 4:55 p.m. UTC | #1
On Thu, 23 Jun 2022 19:46:21 -0700
Dan Williams <dan.j.williams@intel.com> wrote:

> Previously the target routing specifics of switch decoders and platfom
> CXL window resource tracking of root decoders were factored out of
> 'struct cxl_decoder'. While switch decoders translate from SPA to
> downstream ports, endpoint decoders translate from SPA to DPA.
> 
> This patch, 3 of 3, adds a 'struct cxl_endpoint_decoder' that tracks an
> endpoint-specific Device Physical Address (DPA) resource. For now this
> just defines ->dpa_res, a follow-on patch will handle requesting DPA
> resource ranges from a device-DPA resource tree.
> 
> Co-developed-by: Ben Widawsky <bwidawsk@kernel.org>
> Signed-off-by: Ben Widawsky <bwidawsk@kernel.org>
> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
> ---
>  drivers/cxl/core/hdm.c       |   12 +++++++++---
>  drivers/cxl/core/port.c      |   36 +++++++++++++++++++++++++++---------
>  drivers/cxl/cxl.h            |   15 ++++++++++++++-
>  tools/testing/cxl/test/cxl.c |   11 +++++++++--
>  4 files changed, 59 insertions(+), 15 deletions(-)
> 



> diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
> index 6dd1e4c57a67..579f2d802396 100644


>  int cxl_decoder_add(struct cxl_decoder *cxld, int *target_map);
> -struct cxl_decoder *cxl_endpoint_decoder_alloc(struct cxl_port *port);
> +struct cxl_endpoint_decoder *cxl_endpoint_decoder_alloc(struct cxl_port *port);
>  int cxl_decoder_add_locked(struct cxl_decoder *cxld, int *target_map);
>  int cxl_decoder_autoremove(struct device *host, struct cxl_decoder *cxld);
>  int cxl_endpoint_autoremove(struct cxl_memdev *cxlmd, struct cxl_port *endpoint);
> diff --git a/tools/testing/cxl/test/cxl.c b/tools/testing/cxl/test/cxl.c
> index 68288354b419..f52a5dd69d36 100644
> --- a/tools/testing/cxl/test/cxl.c
> +++ b/tools/testing/cxl/test/cxl.c
> @@ -459,8 +459,15 @@ static int mock_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm)
>  				cxld = ERR_CAST(cxlsd);
>  			else
>  				cxld = &cxlsd->cxld;
> -		} else
> -			cxld = cxl_endpoint_decoder_alloc(port);
> +		} else {
> +			struct cxl_endpoint_decoder *cxled;
> +
> +			cxled = cxl_endpoint_decoder_alloc(port);
> +			if (IS_ERR(cxled))
> +				cxld = ERR_CAST(cxled);

It's my favourite code pattern to moan about today :)
Same thing - just handle error here and it'll be easier to read for cost of a few
lines of additional code.  Few other cases of it in here.


> +			else
> +				cxld = &cxled->cxld;
> +		}
>  		if (IS_ERR(cxld)) {
>  			dev_warn(&port->dev,
>  				 "Failed to allocate the decoder\n");
>
Dan Williams July 10, 2022, 2:40 a.m. UTC | #2
Jonathan Cameron wrote:
> On Thu, 23 Jun 2022 19:46:21 -0700
> Dan Williams <dan.j.williams@intel.com> wrote:
> 
> > Previously the target routing specifics of switch decoders and platfom
> > CXL window resource tracking of root decoders were factored out of
> > 'struct cxl_decoder'. While switch decoders translate from SPA to
> > downstream ports, endpoint decoders translate from SPA to DPA.
> > 
> > This patch, 3 of 3, adds a 'struct cxl_endpoint_decoder' that tracks an
> > endpoint-specific Device Physical Address (DPA) resource. For now this
> > just defines ->dpa_res, a follow-on patch will handle requesting DPA
> > resource ranges from a device-DPA resource tree.
> > 
> > Co-developed-by: Ben Widawsky <bwidawsk@kernel.org>
> > Signed-off-by: Ben Widawsky <bwidawsk@kernel.org>
> > Signed-off-by: Dan Williams <dan.j.williams@intel.com>
> > ---
> >  drivers/cxl/core/hdm.c       |   12 +++++++++---
> >  drivers/cxl/core/port.c      |   36 +++++++++++++++++++++++++++---------
> >  drivers/cxl/cxl.h            |   15 ++++++++++++++-
> >  tools/testing/cxl/test/cxl.c |   11 +++++++++--
> >  4 files changed, 59 insertions(+), 15 deletions(-)
> > 
> 
> 
> 
> > diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
> > index 6dd1e4c57a67..579f2d802396 100644
> 
> 
> >  int cxl_decoder_add(struct cxl_decoder *cxld, int *target_map);
> > -struct cxl_decoder *cxl_endpoint_decoder_alloc(struct cxl_port *port);
> > +struct cxl_endpoint_decoder *cxl_endpoint_decoder_alloc(struct cxl_port *port);
> >  int cxl_decoder_add_locked(struct cxl_decoder *cxld, int *target_map);
> >  int cxl_decoder_autoremove(struct device *host, struct cxl_decoder *cxld);
> >  int cxl_endpoint_autoremove(struct cxl_memdev *cxlmd, struct cxl_port *endpoint);
> > diff --git a/tools/testing/cxl/test/cxl.c b/tools/testing/cxl/test/cxl.c
> > index 68288354b419..f52a5dd69d36 100644
> > --- a/tools/testing/cxl/test/cxl.c
> > +++ b/tools/testing/cxl/test/cxl.c
> > @@ -459,8 +459,15 @@ static int mock_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm)
> >  				cxld = ERR_CAST(cxlsd);
> >  			else
> >  				cxld = &cxlsd->cxld;
> > -		} else
> > -			cxld = cxl_endpoint_decoder_alloc(port);
> > +		} else {
> > +			struct cxl_endpoint_decoder *cxled;
> > +
> > +			cxled = cxl_endpoint_decoder_alloc(port);
> > +			if (IS_ERR(cxled))
> > +				cxld = ERR_CAST(cxled);
> 
> It's my favourite code pattern to moan about today :)
> Same thing - just handle error here and it'll be easier to read for cost of a few
> lines of additional code.  Few other cases of it in here.

Done and done.
diff mbox series

Patch

diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c
index 2d1f3e6eebea..2223d151b61b 100644
--- a/drivers/cxl/core/hdm.c
+++ b/drivers/cxl/core/hdm.c
@@ -224,9 +224,15 @@  int devm_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm)
 		int rc, target_count = cxlhdm->target_count;
 		struct cxl_decoder *cxld;
 
-		if (is_cxl_endpoint(port))
-			cxld = cxl_endpoint_decoder_alloc(port);
-		else {
+		if (is_cxl_endpoint(port)) {
+			struct cxl_endpoint_decoder *cxled;
+
+			cxled = cxl_endpoint_decoder_alloc(port);
+			if (IS_ERR(cxled))
+				cxld = ERR_CAST(cxled);
+			else
+				cxld = &cxled->cxld;
+		} else {
 			struct cxl_switch_decoder *cxlsd;
 
 			cxlsd = cxl_switch_decoder_alloc(port, target_count);
diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
index abf3455c4eff..b5f5fb9aa4b7 100644
--- a/drivers/cxl/core/port.c
+++ b/drivers/cxl/core/port.c
@@ -243,12 +243,12 @@  static void __cxl_decoder_release(struct cxl_decoder *cxld)
 	put_device(&port->dev);
 }
 
-static void cxl_decoder_release(struct device *dev)
+static void cxl_endpoint_decoder_release(struct device *dev)
 {
-	struct cxl_decoder *cxld = to_cxl_decoder(dev);
+	struct cxl_endpoint_decoder *cxled = to_cxl_endpoint_decoder(dev);
 
-	__cxl_decoder_release(cxld);
-	kfree(cxld);
+	__cxl_decoder_release(&cxled->cxld);
+	kfree(cxled);
 }
 
 static void cxl_switch_decoder_release(struct device *dev)
@@ -278,7 +278,7 @@  static void cxl_root_decoder_release(struct device *dev)
 
 static const struct device_type cxl_decoder_endpoint_type = {
 	.name = "cxl_decoder_endpoint",
-	.release = cxl_decoder_release,
+	.release = cxl_endpoint_decoder_release,
 	.groups = cxl_decoder_endpoint_attribute_groups,
 };
 
@@ -320,6 +320,15 @@  struct cxl_decoder *to_cxl_decoder(struct device *dev)
 }
 EXPORT_SYMBOL_NS_GPL(to_cxl_decoder, CXL);
 
+struct cxl_endpoint_decoder *to_cxl_endpoint_decoder(struct device *dev)
+{
+	if (dev_WARN_ONCE(dev, !is_endpoint_decoder(dev),
+			  "not a cxl_endpoint_decoder device\n"))
+		return NULL;
+	return container_of(dev, struct cxl_endpoint_decoder, cxld.dev);
+}
+EXPORT_SYMBOL_NS_GPL(to_cxl_endpoint_decoder, CXL);
+
 static struct cxl_switch_decoder *to_cxl_switch_decoder(struct device *dev)
 {
 	if (dev_WARN_ONCE(dev, !is_switch_decoder(dev),
@@ -1258,8 +1267,12 @@  static struct cxl_decoder *cxl_decoder_alloc(struct cxl_port *port,
 			cxld = &cxlsd->cxld;
 		}
 	} else {
-		alloc = kzalloc(sizeof(*cxld), GFP_KERNEL);
-		cxld = alloc;
+		struct cxl_endpoint_decoder *cxled;
+
+		alloc = kzalloc(sizeof(*cxled), GFP_KERNEL);
+		cxled = alloc;
+		if (cxled)
+			cxld = &cxled->cxld;
 	}
 	if (!alloc)
 		return ERR_PTR(-ENOMEM);
@@ -1357,12 +1370,17 @@  EXPORT_SYMBOL_NS_GPL(cxl_switch_decoder_alloc, CXL);
  *
  * Return: A new cxl decoder to be registered by cxl_decoder_add()
  */
-struct cxl_decoder *cxl_endpoint_decoder_alloc(struct cxl_port *port)
+struct cxl_endpoint_decoder *cxl_endpoint_decoder_alloc(struct cxl_port *port)
 {
+	struct cxl_decoder *cxld;
+
 	if (!is_cxl_endpoint(port))
 		return ERR_PTR(-EINVAL);
 
-	return cxl_decoder_alloc(port, 0);
+	cxld = cxl_decoder_alloc(port, 0);
+	if (IS_ERR(cxld))
+		return ERR_CAST(cxld);
+	return to_cxl_endpoint_decoder(&cxld->dev);
 }
 EXPORT_SYMBOL_NS_GPL(cxl_endpoint_decoder_alloc, CXL);
 
diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
index 6dd1e4c57a67..579f2d802396 100644
--- a/drivers/cxl/cxl.h
+++ b/drivers/cxl/cxl.h
@@ -239,6 +239,18 @@  struct cxl_decoder {
 	unsigned long flags;
 };
 
+/**
+ * struct cxl_endpoint_decoder - Endpoint  / SPA to DPA decoder
+ * @cxld: base cxl_decoder_object
+ * @dpa_res: actively claimed DPA span of this decoder
+ * @skip: offset into @dpa_res where @cxld.hpa_range maps
+ */
+struct cxl_endpoint_decoder {
+	struct cxl_decoder cxld;
+	struct resource *dpa_res;
+	resource_size_t skip;
+};
+
 /**
  * struct cxl_switch_decoder - Switch specific CXL HDM Decoder
  * @cxld: base cxl_decoder object
@@ -379,6 +391,7 @@  struct cxl_dport *cxl_find_dport_by_dev(struct cxl_port *port,
 
 struct cxl_decoder *to_cxl_decoder(struct device *dev);
 struct cxl_root_decoder *to_cxl_root_decoder(struct device *dev);
+struct cxl_endpoint_decoder *to_cxl_endpoint_decoder(struct device *dev);
 bool is_root_decoder(struct device *dev);
 bool is_endpoint_decoder(struct device *dev);
 struct cxl_root_decoder *cxl_root_decoder_alloc(struct cxl_port *port,
@@ -386,7 +399,7 @@  struct cxl_root_decoder *cxl_root_decoder_alloc(struct cxl_port *port,
 struct cxl_switch_decoder *cxl_switch_decoder_alloc(struct cxl_port *port,
 						    unsigned int nr_targets);
 int cxl_decoder_add(struct cxl_decoder *cxld, int *target_map);
-struct cxl_decoder *cxl_endpoint_decoder_alloc(struct cxl_port *port);
+struct cxl_endpoint_decoder *cxl_endpoint_decoder_alloc(struct cxl_port *port);
 int cxl_decoder_add_locked(struct cxl_decoder *cxld, int *target_map);
 int cxl_decoder_autoremove(struct device *host, struct cxl_decoder *cxld);
 int cxl_endpoint_autoremove(struct cxl_memdev *cxlmd, struct cxl_port *endpoint);
diff --git a/tools/testing/cxl/test/cxl.c b/tools/testing/cxl/test/cxl.c
index 68288354b419..f52a5dd69d36 100644
--- a/tools/testing/cxl/test/cxl.c
+++ b/tools/testing/cxl/test/cxl.c
@@ -459,8 +459,15 @@  static int mock_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm)
 				cxld = ERR_CAST(cxlsd);
 			else
 				cxld = &cxlsd->cxld;
-		} else
-			cxld = cxl_endpoint_decoder_alloc(port);
+		} else {
+			struct cxl_endpoint_decoder *cxled;
+
+			cxled = cxl_endpoint_decoder_alloc(port);
+			if (IS_ERR(cxled))
+				cxld = ERR_CAST(cxled);
+			else
+				cxld = &cxled->cxld;
+		}
 		if (IS_ERR(cxld)) {
 			dev_warn(&port->dev,
 				 "Failed to allocate the decoder\n");