Re: [PATCH v2 1/4] kernel/resource: Introduce managed SOFT RESERVED resources

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Jan 16, 2025 at 11:42:05AM -0600, Nathan Fontenot wrote:
> Introduce the ability to manage SOFT RESERVED kernel resources prior to
> these resources being  placed in the iomem resource tree. This provides
> the ability for drivers to update SOFT RESERVED resources that intersect
> with their memory resources.
> 
> During boot, any resources marked as IORES_DESC_SOFT_RESERVED are placed
> on the soft reserve resource tree. Once boot completes all resources
> are placed on the iomem resource tree. This behavior is gated by a new
> kernel option CONFIG_SOFT_RESERVED_MANAGED.
> 
> As part of this update two new interfaces are added for management of
> the SOFT RESERVED resources. The release_srmem_region_adjustable()
> routine allows for removing pieces of SOFT RESERVED resources. The
> the merge_srmem_resources() allows drivers to merge any remaining SOFT
> RESERVED resources into the iomem resource tree once updatea are complete.
> 
> Signed-off-by: Nathan Fontenot <nathan.fontenot@xxxxxxx>
> ---
>  include/linux/ioport.h |  9 +++++
>  kernel/resource.c      | 79 +++++++++++++++++++++++++++++++++++++++---
>  lib/Kconfig            |  4 +++
>  3 files changed, 87 insertions(+), 5 deletions(-)
> 
> diff --git a/include/linux/ioport.h b/include/linux/ioport.h
> index 6e9fb667a1c5..2c95cf0be45e 100644
> --- a/include/linux/ioport.h
> +++ b/include/linux/ioport.h
> @@ -249,6 +249,15 @@ struct resource *lookup_resource(struct resource *root, resource_size_t start);
>  int adjust_resource(struct resource *res, resource_size_t start,
>  		    resource_size_t size);
>  resource_size_t resource_alignment(struct resource *res);
> +
> +#ifdef CONFIG_SOFT_RESERVED_MANAGED
> +void merge_srmem_resources(void);
> +extern void release_srmem_region_adjustable(resource_size_t start,
> +					    resource_size_t size);
> +#else
> +static inline void merge_srmem_resources(void) { }
> +#endif
> +
>  static inline resource_size_t resource_size(const struct resource *res)
>  {
>  	return res->end - res->start + 1;
> diff --git a/kernel/resource.c b/kernel/resource.c
> index a83040fde236..9db420078a3f 100644
> --- a/kernel/resource.c
> +++ b/kernel/resource.c
> @@ -48,6 +48,14 @@ struct resource iomem_resource = {
>  };
>  EXPORT_SYMBOL(iomem_resource);
>  
> +static struct resource srmem_resource = {
> +	.name	= "Soft Reserved mem",
> +	.start	= 0,
> +	.end	= -1,
> +	.flags	= IORESOURCE_MEM,
> +	.desc	= IORES_DESC_SOFT_RESERVED,
> +};
> +
>  static DEFINE_RWLOCK(resource_lock);
>  
>  static struct resource *next_resource(struct resource *p, bool skip_children)
> @@ -818,6 +826,19 @@ static struct resource * __insert_resource(struct resource *parent, struct resou
>  {
>  	struct resource *first, *next;
>  
> +	if (IS_ENABLED(CONFIG_SOFT_RESERVED_MANAGED)) {
> +		/*
> +		 * During boot SOFT RESERVED resources are placed on the srmem
> +		 * resource tree. These resources may be updated later in boot,
> +		 * for example see the CXL driver, prior to being merged into
> +		 * the iomem resource tree.
> +		 */
> +		if (system_state < SYSTEM_RUNNING &&
> +		    parent == &iomem_resource &&
> +		    new->desc == IORES_DESC_SOFT_RESERVED)
> +			parent = &srmem_resource;
> +	}
> +
>  	for (;; parent = first) {
>  		first = __request_resource(parent, new);
>  		if (!first)
> @@ -1336,11 +1357,12 @@ void __release_region(struct resource *parent, resource_size_t start,
>  }
>  EXPORT_SYMBOL(__release_region);
>  
> -#ifdef CONFIG_MEMORY_HOTREMOVE

If CONFIG_MEMORY_HOTREMOVE not defined, it seems we do not have a
user for release_region_adjustable as
release_mem_region_adjustable() will not exist.

Fan
>  /**
> - * release_mem_region_adjustable - release a previously reserved memory region
> + * release_region_adjustable - release a previously reserved memory region
> + * @parent: resource tree to release resource from
>   * @start: resource start address
>   * @size: resource region size
> + * @busy_check: check for IORESOURCE_BUSY
>   *
>   * This interface is intended for memory hot-delete.  The requested region
>   * is released from a currently busy memory resource.  The requested region
> @@ -1356,9 +1378,11 @@ EXPORT_SYMBOL(__release_region);
>   *   assumes that all children remain in the lower address entry for
>   *   simplicity.  Enhance this logic when necessary.
>   */
> -void release_mem_region_adjustable(resource_size_t start, resource_size_t size)
> +static void release_region_adjustable(struct resource *parent,
> +				      resource_size_t start,
> +				      resource_size_t size,
> +				      bool busy_check)
>  {
> -	struct resource *parent = &iomem_resource;
>  	struct resource *new_res = NULL;
>  	bool alloc_nofail = false;
>  	struct resource **p;
> @@ -1395,7 +1419,7 @@ void release_mem_region_adjustable(resource_size_t start, resource_size_t size)
>  		if (!(res->flags & IORESOURCE_MEM))
>  			break;
>  
> -		if (!(res->flags & IORESOURCE_BUSY)) {
> +		if (busy_check && !(res->flags & IORESOURCE_BUSY)) {
>  			p = &res->child;
>  			continue;
>  		}
> @@ -1445,6 +1469,51 @@ void release_mem_region_adjustable(resource_size_t start, resource_size_t size)
>  	write_unlock(&resource_lock);
>  	free_resource(new_res);
>  }
> +
> +#ifdef CONFIG_SOFT_RESERVED_MANAGED
> +/**
> + * merge_srmem_resources - merge srmem resources into the iomem resource tree
> + *
> + * This is intended to allow kernel drivers that manage the SOFT RESERVED
> + * resources to merge any remaining resources into the iomem resource tree
> + * once any updates have been made.
> + */
> +void merge_srmem_resources(void)
> +{
> +	struct resource *res, *next;
> +	int rc;
> +
> +	for (res = srmem_resource.child; res; res = next) {
> +		next = next_resource(res, true);
> +
> +		write_lock(&resource_lock);
> +
> +		if (WARN_ON(__release_resource(res, true))) {
> +			write_unlock(&resource_lock);
> +			continue;
> +		}
> +
> +		if (WARN_ON(__insert_resource(&iomem_resource, res)))
> +			__insert_resource(&srmem_resource, res);
> +
> +		write_unlock(&resource_lock);
> +	}
> +}
> +EXPORT_SYMBOL_GPL(merge_srmem_resources);
> +
> +void release_srmem_region_adjustable(resource_size_t start,
> +				     resource_size_t size)
> +{
> +	release_region_adjustable(&srmem_resource, start, size, false);
> +}
> +EXPORT_SYMBOL(release_srmem_region_adjustable);
> +#endif
> +
> +#ifdef CONFIG_MEMORY_HOTREMOVE
> +void release_mem_region_adjustable(resource_size_t start, resource_size_t size)
> +{
> +	release_region_adjustable(&iomem_resource, start, size, true);
> +}
>  #endif	/* CONFIG_MEMORY_HOTREMOVE */
>  
>  #ifdef CONFIG_MEMORY_HOTPLUG
> diff --git a/lib/Kconfig b/lib/Kconfig
> index b38849af6f13..4f4011334051 100644
> --- a/lib/Kconfig
> +++ b/lib/Kconfig
> @@ -777,3 +777,7 @@ config POLYNOMIAL
>  
>  config FIRMWARE_TABLE
>  	bool
> +
> +config SOFT_RESERVED_MANAGED
> +	bool
> +	default n
> -- 
> 2.43.0
> 




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux