Linux CXL
 help / color / mirror / Atom feed
From: Dongsheng Yang <dongsheng.yang@easystack.cn>
To: dave@stgolabs.net, jonathan.cameron@huawei.com,
	ave.jiang@intel.com, alison.schofield@intel.com,
	vishal.l.verma@intel.com, ira.weiny@intel.com,
	dan.j.williams@intel.com
Cc: linux-cxl@vger.kernel.org
Subject: Re: [RFC PATCH 1/4] cxl: move some function from acpi module to core module
Date: Thu, 28 Dec 2023 14:43:44 +0800	[thread overview]
Message-ID: <6a9f225f-9937-fd2a-ddc5-7006f8c1a16c@easystack.cn> (raw)
In-Reply-To: <20231228060510.1178981-2-dongsheng.yang@easystack.cn>



在 2023/12/28 星期四 下午 2:05, Dongsheng Yang 写道:
> cxl_virt module will create root_port without cxl_acpi_probe(),
> export these symbol to allow cxl_virt to create it's own root_port.
> 
> Signed-off-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
> ---
>   drivers/cxl/acpi.c      | 143 +--------------------------------------
>   drivers/cxl/core/port.c | 145 ++++++++++++++++++++++++++++++++++++++++
>   drivers/cxl/cxl.h       |   5 ++
>   3 files changed, 151 insertions(+), 142 deletions(-)
> 
> diff --git a/drivers/cxl/acpi.c b/drivers/cxl/acpi.c
> index 2034eb4ce83f..a60ed4156a5e 100644
> --- a/drivers/cxl/acpi.c
> +++ b/drivers/cxl/acpi.c
> @@ -447,7 +447,7 @@ static int add_host_bridge_dport(struct device *match, void *arg)
>    * A host bridge is a dport to a CFMWS decode and it is a uport to the
>    * dport (PCIe Root Ports) in the host bridge.
>    */
> -static int add_host_bridge_uport(struct device *match, void *arg)
> +int add_host_bridge_uport(struct device *match, void *arg)

This change is included by mistake, it will be revert in next version

Thanx
>   {
>   	struct cxl_port *root_port = arg;
>   	struct device *host = root_port->dev.parent;
> @@ -504,30 +504,6 @@ static int add_host_bridge_uport(struct device *match, void *arg)
>   	return 0;
>   }
>   
> -static int add_root_nvdimm_bridge(struct device *match, void *data)
> -{
> -	struct cxl_decoder *cxld;
> -	struct cxl_port *root_port = data;
> -	struct cxl_nvdimm_bridge *cxl_nvb;
> -	struct device *host = root_port->dev.parent;
> -
> -	if (!is_root_decoder(match))
> -		return 0;
> -
> -	cxld = to_cxl_decoder(match);
> -	if (!(cxld->flags & CXL_DECODER_F_PMEM))
> -		return 0;
> -
> -	cxl_nvb = devm_cxl_add_nvdimm_bridge(host, root_port);
> -	if (IS_ERR(cxl_nvb)) {
> -		dev_dbg(host, "failed to register pmem\n");
> -		return PTR_ERR(cxl_nvb);
> -	}
> -	dev_dbg(host, "%s: add: %s\n", dev_name(&root_port->dev),
> -		dev_name(&cxl_nvb->dev));
> -	return 1;
> -}
> -
>   static struct lock_class_key cxl_root_key;
>   
>   static void cxl_acpi_lock_reset_class(void *dev)
> @@ -535,123 +511,6 @@ static void cxl_acpi_lock_reset_class(void *dev)
>   	device_lock_reset_class(dev);
>   }
>   
> -static void del_cxl_resource(struct resource *res)
> -{
> -	kfree(res->name);
> -	kfree(res);
> -}
> -
> -static void cxl_set_public_resource(struct resource *priv, struct resource *pub)
> -{
> -	priv->desc = (unsigned long) pub;
> -}
> -
> -static struct resource *cxl_get_public_resource(struct resource *priv)
> -{
> -	return (struct resource *) priv->desc;
> -}
> -
> -static void remove_cxl_resources(void *data)
> -{
> -	struct resource *res, *next, *cxl = data;
> -
> -	for (res = cxl->child; res; res = next) {
> -		struct resource *victim = cxl_get_public_resource(res);
> -
> -		next = res->sibling;
> -		remove_resource(res);
> -
> -		if (victim) {
> -			remove_resource(victim);
> -			kfree(victim);
> -		}
> -
> -		del_cxl_resource(res);
> -	}
> -}
> -
> -/**
> - * add_cxl_resources() - reflect CXL fixed memory windows in iomem_resource
> - * @cxl_res: A standalone resource tree where each CXL window is a sibling
> - *
> - * Walk each CXL window in @cxl_res and add it to iomem_resource potentially
> - * expanding its boundaries to ensure that any conflicting resources become
> - * children. If a window is expanded it may then conflict with a another window
> - * entry and require the window to be truncated or trimmed. Consider this
> - * situation:
> - *
> - * |-- "CXL Window 0" --||----- "CXL Window 1" -----|
> - * |--------------- "System RAM" -------------|
> - *
> - * ...where platform firmware has established as System RAM resource across 2
> - * windows, but has left some portion of window 1 for dynamic CXL region
> - * provisioning. In this case "Window 0" will span the entirety of the "System
> - * RAM" span, and "CXL Window 1" is truncated to the remaining tail past the end
> - * of that "System RAM" resource.
> - */
> -static int add_cxl_resources(struct resource *cxl_res)
> -{
> -	struct resource *res, *new, *next;
> -
> -	for (res = cxl_res->child; res; res = next) {
> -		new = kzalloc(sizeof(*new), GFP_KERNEL);
> -		if (!new)
> -			return -ENOMEM;
> -		new->name = res->name;
> -		new->start = res->start;
> -		new->end = res->end;
> -		new->flags = IORESOURCE_MEM;
> -		new->desc = IORES_DESC_CXL;
> -
> -		/*
> -		 * Record the public resource in the private cxl_res tree for
> -		 * later removal.
> -		 */
> -		cxl_set_public_resource(res, new);
> -
> -		insert_resource_expand_to_fit(&iomem_resource, new);
> -
> -		next = res->sibling;
> -		while (next && resource_overlaps(new, next)) {
> -			if (resource_contains(new, next)) {
> -				struct resource *_next = next->sibling;
> -
> -				remove_resource(next);
> -				del_cxl_resource(next);
> -				next = _next;
> -			} else
> -				next->start = new->end + 1;
> -		}
> -	}
> -	return 0;
> -}
> -
> -static int pair_cxl_resource(struct device *dev, void *data)
> -{
> -	struct resource *cxl_res = data;
> -	struct resource *p;
> -
> -	if (!is_root_decoder(dev))
> -		return 0;
> -
> -	for (p = cxl_res->child; p; p = p->sibling) {
> -		struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(dev);
> -		struct cxl_decoder *cxld = &cxlrd->cxlsd.cxld;
> -		struct resource res = {
> -			.start = cxld->hpa_range.start,
> -			.end = cxld->hpa_range.end,
> -			.flags = IORESOURCE_MEM,
> -		};
> -
> -		if (resource_contains(p, &res)) {
> -			cxlrd->res = cxl_get_public_resource(p);
> -			break;
> -		}
> -	}
> -
> -	return 0;
> -}
> -
>   static int cxl_acpi_probe(struct platform_device *pdev)
>   {
>   	int rc;
> diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
> index 38441634e4c6..d8dae028e8a4 100644
> --- a/drivers/cxl/core/port.c
> +++ b/drivers/cxl/core/port.c
> @@ -989,6 +989,151 @@ static int add_dport(struct cxl_port *port, struct cxl_dport *dport)
>   	return 0;
>   }
>   
> +int add_root_nvdimm_bridge(struct device *match, void *data)
> +{
> +	struct cxl_decoder *cxld;
> +	struct cxl_port *root_port = data;
> +	struct cxl_nvdimm_bridge *cxl_nvb;
> +	struct device *host = root_port->dev.parent;
> +
> +	if (!is_root_decoder(match))
> +		return 0;
> +
> +	cxld = to_cxl_decoder(match);
> +	if (!(cxld->flags & CXL_DECODER_F_PMEM))
> +		return 0;
> +
> +	cxl_nvb = devm_cxl_add_nvdimm_bridge(host, root_port);
> +	if (IS_ERR(cxl_nvb)) {
> +		dev_dbg(host, "failed to register pmem\n");
> +		return PTR_ERR(cxl_nvb);
> +	}
> +	dev_dbg(host, "%s: add: %s\n", dev_name(&root_port->dev),
> +		dev_name(&cxl_nvb->dev));
> +	return 1;
> +}
> +EXPORT_SYMBOL_NS_GPL(add_root_nvdimm_bridge, CXL);
> +
> +static void del_cxl_resource(struct resource *res)
> +{
> +	kfree(res->name);
> +	kfree(res);
> +}
> +
> +static void cxl_set_public_resource(struct resource *priv, struct resource *pub)
> +{
> +	priv->desc = (unsigned long) pub;
> +}
> +
> +static struct resource *cxl_get_public_resource(struct resource *priv)
> +{
> +	return (struct resource *) priv->desc;
> +}
> +
> +void remove_cxl_resources(void *data)
> +{
> +	struct resource *res, *next, *cxl = data;
> +
> +	for (res = cxl->child; res; res = next) {
> +		struct resource *victim = cxl_get_public_resource(res);
> +
> +		next = res->sibling;
> +		remove_resource(res);
> +
> +		if (victim) {
> +			remove_resource(victim);
> +			kfree(victim);
> +		}
> +
> +		del_cxl_resource(res);
> +	}
> +}
> +EXPORT_SYMBOL_NS_GPL(remove_cxl_resources, CXL);
> +
> +/**
> + * add_cxl_resources() - reflect CXL fixed memory windows in iomem_resource
> + * @cxl_res: A standalone resource tree where each CXL window is a sibling
> + *
> + * Walk each CXL window in @cxl_res and add it to iomem_resource potentially
> + * expanding its boundaries to ensure that any conflicting resources become
> + * children. If a window is expanded it may then conflict with a another window
> + * entry and require the window to be truncated or trimmed. Consider this
> + * situation:
> + *
> + * |-- "CXL Window 0" --||----- "CXL Window 1" -----|
> + * |--------------- "System RAM" -------------|
> + *
> + * ...where platform firmware has established as System RAM resource across 2
> + * windows, but has left some portion of window 1 for dynamic CXL region
> + * provisioning. In this case "Window 0" will span the entirety of the "System
> + * RAM" span, and "CXL Window 1" is truncated to the remaining tail past the end
> + * of that "System RAM" resource.
> + */
> +int add_cxl_resources(struct resource *cxl_res)
> +{
> +	struct resource *res, *new, *next;
> +
> +	for (res = cxl_res->child; res; res = next) {
> +		new = kzalloc(sizeof(*new), GFP_KERNEL);
> +		if (!new)
> +			return -ENOMEM;
> +		new->name = res->name;
> +		new->start = res->start;
> +		new->end = res->end;
> +		new->flags = IORESOURCE_MEM;
> +		new->desc = IORES_DESC_CXL;
> +
> +		/*
> +		 * Record the public resource in the private cxl_res tree for
> +		 * later removal.
> +		 */
> +		cxl_set_public_resource(res, new);
> +
> +		insert_resource_expand_to_fit(&iomem_resource, new);
> +
> +		next = res->sibling;
> +		while (next && resource_overlaps(new, next)) {
> +			if (resource_contains(new, next)) {
> +				struct resource *_next = next->sibling;
> +
> +				remove_resource(next);
> +				del_cxl_resource(next);
> +				next = _next;
> +			} else
> +				next->start = new->end + 1;
> +		}
> +	}
> +	return 0;
> +}
> +EXPORT_SYMBOL_NS_GPL(add_cxl_resources, CXL);
> +
> +int pair_cxl_resource(struct device *dev, void *data)
> +{
> +	struct resource *cxl_res = data;
> +	struct resource *p;
> +
> +	if (!is_root_decoder(dev))
> +		return 0;
> +
> +	for (p = cxl_res->child; p; p = p->sibling) {
> +		struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(dev);
> +		struct cxl_decoder *cxld = &cxlrd->cxlsd.cxld;
> +		struct resource res = {
> +			.start = cxld->hpa_range.start,
> +			.end = cxld->hpa_range.end,
> +			.flags = IORESOURCE_MEM,
> +		};
> +
> +		if (resource_contains(p, &res)) {
> +			cxlrd->res = cxl_get_public_resource(p);
> +			break;
> +		}
> +	}
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_NS_GPL(pair_cxl_resource, CXL);
> +
>   /*
>    * Since root-level CXL dports cannot be enumerated by PCI they are not
>    * enumerated by the common port driver that acquires the port lock over
> diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
> index 687043ece101..1397f66d943b 100644
> --- a/drivers/cxl/cxl.h
> +++ b/drivers/cxl/cxl.h
> @@ -839,6 +839,11 @@ static inline struct cxl_dax_region *to_cxl_dax_region(struct device *dev)
>   }
>   #endif
>   
> +void remove_cxl_resources(void *data);
> +int add_cxl_resources(struct resource *cxl_res);
> +int pair_cxl_resource(struct device *dev, void *data);
> +int add_root_nvdimm_bridge(struct device *match, void *data);
> +
>   /*
>    * Unit test builds overrides this to __weak, find the 'strong' version
>    * of these symbols in tools/testing/cxl/.
> 

  reply	other threads:[~2023-12-28  7:08 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-28  6:05 [RFC PATCH 0/4] cxl: introduce CXL Virtualization module Dongsheng Yang
2023-12-28  6:05 ` [RFC PATCH 1/4] cxl: move some function from acpi module to core module Dongsheng Yang
2023-12-28  6:43   ` Dongsheng Yang [this message]
2023-12-28  6:05 ` [RFC PATCH 3/4] cxl/port: introduce cxl_disable_port() function Dongsheng Yang
2023-12-28  6:05 ` [RFC PATCH 4/4] cxl: introduce CXL Virtualization module Dongsheng Yang
2024-01-03 17:22 ` [RFC PATCH 0/4] " Ira Weiny
2024-01-08 12:28   ` Jonathan Cameron
2024-01-10  2:07   ` Dongsheng Yang
2024-01-03 20:48 ` Dan Williams
     [not found]   ` <a32d859f-054f-11ca-e8a3-dff7a5234d0a@easystack.cn>
2024-01-25  3:49     ` Dan Williams
2024-01-25  6:49       ` Dongsheng Yang
2024-01-25  7:46         ` Dan Williams
2024-05-03  5:12 ` Hyeongtak Ji

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=6a9f225f-9937-fd2a-ddc5-7006f8c1a16c@easystack.cn \
    --to=dongsheng.yang@easystack.cn \
    --cc=alison.schofield@intel.com \
    --cc=ave.jiang@intel.com \
    --cc=dan.j.williams@intel.com \
    --cc=dave@stgolabs.net \
    --cc=ira.weiny@intel.com \
    --cc=jonathan.cameron@huawei.com \
    --cc=linux-cxl@vger.kernel.org \
    --cc=vishal.l.verma@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox