Adding linux-arm-kernel and devicetree (look for "raw-pfn"), since this
impacts directly on those.

On Mon, Feb 13, 2017 at 08:02:29PM +0800, zhouxianr...@huawei.com wrote:
> From: zhouxianrong <zhouxianr...@huawei.com>
> 
> just like freeing no-map area's memmap we could free reserved
> area's memmap as well only when user of reserved area indicate
> that we can do this in dts or drivers. that is, user of reserved
> area know how to use the reserved area who could not memblock_free
> or free_reserved_xxx the reserved area and regard the area as raw
> pfn usage. the patch supply a way to users who want to utilize the
> memmap memory corresponding to raw pfn reserved areas as many as
> possible.

I don't really understand this. Can you point me at a specific use-case,
please? Is CMA involved here?

Will

(entire patch follows, for the benefit of the extra CCs)

> Signed-off-by: zhouxianrong <zhouxianr...@huawei.com>
> ---
>  arch/arm64/mm/init.c         |   14 +++++++++++++-
>  drivers/of/fdt.c             |   31 +++++++++++++++++++++++--------
>  drivers/of/of_reserved_mem.c |   21 ++++++++++++++-------
>  include/linux/memblock.h     |    3 +++
>  include/linux/of_fdt.h       |    2 +-
>  mm/memblock.c                |   24 ++++++++++++++++++++++++
>  6 files changed, 78 insertions(+), 17 deletions(-)
> 
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index 380ebe7..7e62ef8 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -358,7 +358,7 @@ static inline void free_memmap(unsigned long start_pfn, 
> unsigned long end_pfn)
>   */
>  static void __init free_unused_memmap(void)
>  {
> -     unsigned long start, prev_end = 0;
> +     unsigned long start, end, prev_end = 0;
>       struct memblock_region *reg;
>  
>       for_each_memblock(memory, reg) {
> @@ -391,6 +391,18 @@ static void __init free_unused_memmap(void)
>       if (!IS_ALIGNED(prev_end, PAGES_PER_SECTION))
>               free_memmap(prev_end, ALIGN(prev_end, PAGES_PER_SECTION));
>  #endif
> +
> +     for_each_memblock(reserved, reg) {
> +             if (!(reg->flags & MEMBLOCK_RAW_PFN))
> +                     continue;
> +
> +             start = memblock_region_memory_base_pfn(reg);
> +             end = round_down(memblock_region_memory_end_pfn(reg),
> +                              MAX_ORDER_NR_PAGES);
> +
> +             if (start < end)
> +                     free_memmap(start, end);
> +     }
>  }
>  #endif       /* !CONFIG_SPARSEMEM_VMEMMAP */
>  
> diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
> index c9b5cac..39e7474 100644
> --- a/drivers/of/fdt.c
> +++ b/drivers/of/fdt.c
> @@ -582,7 +582,7 @@ static int __init __reserved_mem_reserve_reg(unsigned 
> long node,
>       phys_addr_t base, size;
>       int len;
>       const __be32 *prop;
> -     int nomap, first = 1;
> +     int nomap, raw_pfn, first = 1;
>  
>       prop = of_get_flat_dt_prop(node, "reg", &len);
>       if (!prop)
> @@ -595,13 +595,15 @@ static int __init __reserved_mem_reserve_reg(unsigned 
> long node,
>       }
>  
>       nomap = of_get_flat_dt_prop(node, "no-map", NULL) != NULL;
> +     raw_pfn = of_get_flat_dt_prop(node, "raw-pfn", NULL) != NULL;
>  
>       while (len >= t_len) {
>               base = dt_mem_next_cell(dt_root_addr_cells, &prop);
>               size = dt_mem_next_cell(dt_root_size_cells, &prop);
>  
>               if (size &&
> -                 early_init_dt_reserve_memory_arch(base, size, nomap) == 0)
> +                 early_init_dt_reserve_memory_arch(base, size, nomap,
> +                             raw_pfn) == 0)
>                       pr_debug("Reserved memory: reserved region for node 
> '%s': base %pa, size %ld MiB\n",
>                               uname, &base, (unsigned long)size / SZ_1M);
>               else
> @@ -699,7 +701,7 @@ void __init early_init_fdt_scan_reserved_mem(void)
>               fdt_get_mem_rsv(initial_boot_params, n, &base, &size);
>               if (!size)
>                       break;
> -             early_init_dt_reserve_memory_arch(base, size, 0);
> +             early_init_dt_reserve_memory_arch(base, size, 0, 0);
>       }
>  
>       of_scan_flat_dt(__fdt_scan_reserved_mem, NULL);
> @@ -717,6 +719,7 @@ void __init early_init_fdt_reserve_self(void)
>       /* Reserve the dtb region */
>       early_init_dt_reserve_memory_arch(__pa(initial_boot_params),
>                                         fdt_totalsize(initial_boot_params),
> +                                       0,
>                                         0);
>  }
>  
> @@ -1161,11 +1164,21 @@ int __init __weak 
> early_init_dt_mark_hotplug_memory_arch(u64 base, u64 size)
>  }
>  
>  int __init __weak early_init_dt_reserve_memory_arch(phys_addr_t base,
> -                                     phys_addr_t size, bool nomap)
> +                                     phys_addr_t size, bool nomap,
> +                                     bool raw_pfn)
>  {
> +     int err;
> +
>       if (nomap)
>               return memblock_remove(base, size);
> -     return memblock_reserve(base, size);
> +
> +     err = memblock_reserve(base, size);
> +     if (err == 0) {
> +             if (raw_pfn)
> +                     memblock_mark_raw_pfn(base, size);
> +     }
> +
> +     return err;
>  }
>  
>  /*
> @@ -1188,10 +1201,12 @@ int __init __weak 
> early_init_dt_mark_hotplug_memory_arch(u64 base, u64 size)
>  }
>  
>  int __init __weak early_init_dt_reserve_memory_arch(phys_addr_t base,
> -                                     phys_addr_t size, bool nomap)
> +                                     phys_addr_t size, bool nomap,
> +                                     bool raw_pfn)
>  {
> -     pr_err("Reserved memory not supported, ignoring range %pa - %pa%s\n",
> -               &base, &size, nomap ? " (nomap)" : "");
> +     pr_err("Reserved memory not supported, ignoring range %pa - %pa%s - 
> %pa%s\n",
> +               &base, &size, nomap ? " (nomap)" : "",
> +               raw_pfn ? " (raw-pfn)" : "");
>       return -ENOSYS;
>  }
>  
> diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
> index 366d8c3..d7d9255 100644
> --- a/drivers/of/of_reserved_mem.c
> +++ b/drivers/of/of_reserved_mem.c
> @@ -33,7 +33,7 @@
>  #include <linux/memblock.h>
>  int __init __weak early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
>       phys_addr_t align, phys_addr_t start, phys_addr_t end, bool nomap,
> -     phys_addr_t *res_base)
> +     bool raw_pfn, phys_addr_t *res_base)
>  {
>       phys_addr_t base;
>       /*
> @@ -56,15 +56,19 @@ int __init __weak 
> early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
>       *res_base = base;
>       if (nomap)
>               return memblock_remove(base, size);
> +
> +     if (raw_pfn)
> +             memblock_mark_raw_pfn(base, size);
> +
>       return 0;
>  }
>  #else
>  int __init __weak early_init_dt_alloc_reserved_memory_arch(phys_addr_t size,
>       phys_addr_t align, phys_addr_t start, phys_addr_t end, bool nomap,
> -     phys_addr_t *res_base)
> +     bool raw_pfn, phys_addr_t *res_base)
>  {
> -     pr_err("Reserved memory not supported, ignoring region 0x%llx%s\n",
> -               size, nomap ? " (nomap)" : "");
> +     pr_err("Reserved memory not supported, ignoring region 0x%llx%s 
> 0x%llx%s\n",
> +               size, nomap ? " (nomap)" : "", raw_pfn ? " (raw-pfn)" : "");
>       return -ENOSYS;
>  }
>  #endif
> @@ -103,7 +107,7 @@ static int __init __reserved_mem_alloc_size(unsigned long 
> node,
>       phys_addr_t base = 0, align = 0, size;
>       int len;
>       const __be32 *prop;
> -     int nomap;
> +     int nomap, raw_pfn;
>       int ret;
>  
>       prop = of_get_flat_dt_prop(node, "size", &len);
> @@ -117,6 +121,7 @@ static int __init __reserved_mem_alloc_size(unsigned long 
> node,
>       size = dt_mem_next_cell(dt_root_size_cells, &prop);
>  
>       nomap = of_get_flat_dt_prop(node, "no-map", NULL) != NULL;
> +     raw_pfn = of_get_flat_dt_prop(node, "raw-pfn", NULL) != NULL;
>  
>       prop = of_get_flat_dt_prop(node, "alignment", &len);
>       if (prop) {
> @@ -156,7 +161,8 @@ static int __init __reserved_mem_alloc_size(unsigned long 
> node,
>                                                      &prop);
>  
>                       ret = early_init_dt_alloc_reserved_memory_arch(size,
> -                                     align, start, end, nomap, &base);
> +                                     align, start, end, nomap,
> +                                     raw_pfn, &base);
>                       if (ret == 0) {
>                               pr_debug("allocated memory for '%s' node: base 
> %pa, size %ld MiB\n",
>                                       uname, &base,
> @@ -168,7 +174,8 @@ static int __init __reserved_mem_alloc_size(unsigned long 
> node,
>  
>       } else {
>               ret = early_init_dt_alloc_reserved_memory_arch(size, align,
> -                                                     0, 0, nomap, &base);
> +                                                     0, 0, nomap,
> +                                                     raw_pfn, &base);
>               if (ret == 0)
>                       pr_debug("allocated memory for '%s' node: base %pa, 
> size %ld MiB\n",
>                               uname, &base, (unsigned long)size / SZ_1M);
> diff --git a/include/linux/memblock.h b/include/linux/memblock.h
> index 5b759c9..7266be1 100644
> --- a/include/linux/memblock.h
> +++ b/include/linux/memblock.h
> @@ -26,6 +26,7 @@ enum {
>       MEMBLOCK_HOTPLUG        = 0x1,  /* hotpluggable region */
>       MEMBLOCK_MIRROR         = 0x2,  /* mirrored region */
>       MEMBLOCK_NOMAP          = 0x4,  /* don't add to kernel direct mapping */
> +     MEMBLOCK_RAW_PFN        = 0x8,  /* raw pfn region's memmap never used */
>  };
>  
>  struct memblock_region {
> @@ -92,6 +93,8 @@ bool memblock_overlaps_region(struct memblock_type *type,
>  int memblock_clear_hotplug(phys_addr_t base, phys_addr_t size);
>  int memblock_mark_mirror(phys_addr_t base, phys_addr_t size);
>  int memblock_mark_nomap(phys_addr_t base, phys_addr_t size);
> +int memblock_mark_raw_pfn(phys_addr_t base, phys_addr_t size);
> +int memblock_clear_raw_pfn(phys_addr_t base, phys_addr_t size);
>  ulong choose_memblock_flags(void);
>  
>  /* Low level functions */
> diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
> index 271b3fd..29284d7 100644
> --- a/include/linux/of_fdt.h
> +++ b/include/linux/of_fdt.h
> @@ -73,7 +73,7 @@ extern int early_init_dt_scan_memory(unsigned long node, 
> const char *uname,
>  extern void early_init_dt_add_memory_arch(u64 base, u64 size);
>  extern int early_init_dt_mark_hotplug_memory_arch(u64 base, u64 size);
>  extern int early_init_dt_reserve_memory_arch(phys_addr_t base, phys_addr_t 
> size,
> -                                          bool no_map);
> +                                          bool no_map, bool raw_pfn);
>  extern void * early_init_dt_alloc_memory_arch(u64 size, u64 align);
>  extern u64 dt_mem_next_cell(int s, const __be32 **cellp);
>  
> diff --git a/mm/memblock.c b/mm/memblock.c
> index 7608bc3..c103b94 100644
> --- a/mm/memblock.c
> +++ b/mm/memblock.c
> @@ -814,6 +814,30 @@ int __init_memblock memblock_mark_nomap(phys_addr_t 
> base, phys_addr_t size)
>  }
>  
>  /**
> + * memblock_mark_raw_pfn - Mark raw pfn memory with flag MEMBLOCK_RAW_PFN.
> + * @base: the base phys addr of the region
> + * @size: the size of the region
> + *
> + * Return 0 on succees, -errno on failure.
> + */
> +int __init_memblock memblock_mark_raw_pfn(phys_addr_t base, phys_addr_t size)
> +{
> +     return memblock_setclr_flag(base, size, 1, MEMBLOCK_RAW_PFN);
> +}
> +
> +/**
> + * memblock_clear_raw_pfn - Clear flag MEMBLOCK_RAW_PFN for a specified 
> region.
> + * @base: the base phys addr of the region
> + * @size: the size of the region
> + *
> + * Return 0 on succees, -errno on failure.
> + */
> +int __init_memblock memblock_clear_raw_pfn(phys_addr_t base, phys_addr_t 
> size)
> +{
> +     return memblock_setclr_flag(base, size, 0, MEMBLOCK_RAW_PFN);
> +}
> +
> +/**
>   * __next_reserved_mem_region - next function for for_each_reserved_region()
>   * @idx: pointer to u64 loop variable
>   * @out_start: ptr to phys_addr_t for start address of the region, can be 
> %NULL
> -- 
> 1.7.9.5
> 

Reply via email to