2022-07-11 12:58:35

by Li Chen

[permalink] [raw]
Subject: [PATCH 1/4] of: add struct page support to rmem

From: Li Chen <[email protected]>

This commit add a new config OF_RESERVED_MEM_DIO_SUPPORT and
some utilities to enables consumers to build struct pages on rmem.

Signed-off-by: Li Chen <[email protected]>
Change-Id: Iaba8874775c6d3a7096ac19575bb884db13351d1
---
drivers/of/Kconfig | 9 ++
drivers/of/of_reserved_mem.c | 218 +++++++++++++++++++++++++++++++-
include/linux/of_reserved_mem.h | 11 ++
3 files changed, 237 insertions(+), 1 deletion(-)

diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index 80b5fd44ab1c..0297c03328d8 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -73,6 +73,15 @@ config OF_IRQ
config OF_RESERVED_MEM
def_bool OF_EARLY_FLATTREE

+config OF_RESERVED_MEM_DIO_SUPPORT
+ bool "add Direct I/O support to reserved_mem"
+ depends on ZONE_DEVICE && ARCH_KEEP_MEMBLOCK
+ help
+ By default, reserved memory don't get struct page support, which
+ means you cannot do Direct I/O from this region. This config takes
+ uses of ZONE_DEVICE and treats rmem as hotplug mem to get struct
+ page and DIO support.
+
config OF_RESOLVE
bool

diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c
index 9da8835ba5a5..f4974da6df98 100644
--- a/drivers/of/of_reserved_mem.c
+++ b/drivers/of/of_reserved_mem.c
@@ -72,7 +72,6 @@ void __init fdt_reserved_mem_save_node(unsigned long node, const char *uname,
rmem->size = size;

reserved_mem_count++;
- return;
}

/*
@@ -447,3 +446,220 @@ struct reserved_mem *of_reserved_mem_lookup(struct device_node *np)
return NULL;
}
EXPORT_SYMBOL_GPL(of_reserved_mem_lookup);
+
+/**
+ * get_reserved_mem_from_dev() - get reserved_mem from a device node
+ * @dev: device pointer
+ *
+ * This function look for reserved_mem from given device.
+ *
+ * Returns a reserved_mem pointer, or NULL on error.
+ */
+struct reserved_mem *get_reserved_mem_from_dev(struct device *dev)
+{
+ struct device_node *np = dev_of_node(dev);
+ struct device_node *rmem_np;
+ struct reserved_mem *rmem = NULL;
+
+ rmem_np = of_parse_phandle(np, "memory-region", 0);
+ if (!rmem_np) {
+ dev_err(dev, "failed to get memory region node\n");
+ return ERR_PTR(-ENODEV);
+ }
+
+ rmem = of_reserved_mem_lookup(rmem_np);
+ if (!rmem) {
+ dev_err(dev, "Failed to lookup reserved memory\n");
+ return ERR_PTR(EINVAL);
+ }
+ return rmem;
+}
+EXPORT_SYMBOL_GPL(get_reserved_mem_from_dev);
+
+#ifdef CONFIG_OF_RESERVED_MEM_DIO_SUPPORT
+
+static int reserved_mem_dio_in_region(unsigned long addr,
+ unsigned long size,
+ const struct reserved_mem *rmem)
+{
+ if ((rmem && (addr >= rmem->base) &&
+ ((addr + size) <= (rmem->base + rmem->size))))
+ return 0;
+
+ return -EINVAL;
+}
+
+static int reserved_mem_dio_get_page(struct mm_struct *mm,
+ unsigned long start,
+ struct page **page,
+ const struct reserved_mem *rmem)
+{
+ unsigned long vaddr = start & PAGE_MASK, pfn;
+ int ret = -EFAULT;
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
+ p4d_t *p4d;
+
+ pgd = pgd_offset(mm, vaddr);
+ if (pgd_none(*pgd))
+ return ret;
+
+ p4d = p4d_offset(pgd, vaddr);
+ if (p4d_none(*p4d))
+ return ret;
+
+ pud = pud_offset(p4d, vaddr);
+ if (pud_none(*pud))
+ return ret;
+
+ pmd = pmd_offset(pud, vaddr);
+ if (pmd_none(*pmd))
+ return ret;
+
+ pte = pte_offset_map(pmd, vaddr);
+ if (pte_none(*pte))
+ goto out;
+
+ pfn = pte_pfn(*pte);
+ if (!pfn_valid(pfn))
+ goto out;
+
+ if (likely(reserved_mem_dio_in_region(pfn << PAGE_SHIFT, PAGE_SIZE, rmem) <
+ 0))
+ goto out;
+
+ if (page) {
+ *page = pfn_to_page(pfn);
+ get_page(*page);
+ }
+
+ ret = 0;
+
+out:
+ pte_unmap(pte);
+ return ret;
+}
+
+static struct page *reserved_mem_dio_find_special_page(struct vm_area_struct *vma,
+ unsigned long addr)
+{
+ struct page *page = NULL;
+
+ reserved_mem_dio_get_page(vma->vm_mm, addr, &page,
+ (struct reserved_mem *)vma->vm_private_data);
+ return page;
+}
+
+static const struct vm_operations_struct rmem_dio_vmops = {
+ .find_special_page = reserved_mem_dio_find_special_page,
+};
+
+/**
+ * reserved_mem_dio_mmap() - mmap helper function to map given rmem to userspace
+ * with struct pages support
+ * @file: file pointing to address space structure to wait for
+ * @vma: the vm area in which the mapping is added
+ * @rmem: reserved memory region from dts, which can be obtained from
+ * get_reserved_mem_from_dev(dev)
+ *
+ * Returns: 0 on success or a negative error-code on failure.
+ */
+int reserved_mem_dio_mmap(struct file *file, struct vm_area_struct *vma, struct reserved_mem *rmem)
+{
+ int ret = 0;
+ unsigned long nr_pages;
+
+ if (!rmem) {
+ pr_err("%s: failed to get rmem from private data\n", __func__);
+ return -ENOMEM;
+ }
+ if (!rmem->pages) {
+ pr_err("%s: failed to get struct pages from reserved mem\n", __func__);
+ return -ENOMEM;
+ }
+
+ if (!rmem->nr_pages) {
+ pr_err("%s: error: rmem nr_pages is 0\n", __func__);
+ return -ENOMEM;
+ }
+
+ if (vma->vm_end - vma->vm_start > rmem->size)
+ return -EINVAL;
+
+ vma->vm_private_data = rmem;
+
+ /* duplicitate nr_pages in that vm_insert_pages can change nr_pages */
+ nr_pages = rmem->nr_pages;
+
+ /*
+ * use vm_insert_pages instead of add remap_pfn_range variant
+ * because vm_insert_pages will invoke rmap functions to inc _mapcount,
+ * while latter don't do it. When unmap,
+ * kernel will warn if page's _mapcount is <= -1.
+ */
+ ret = vm_insert_pages(vma, vma->vm_start, rmem->pages, &nr_pages);
+ if (ret < 0)
+ pr_err("%s vm_insert_pages fail, error is %d\n", __func__, ret);
+
+ vma->vm_ops = &rmem_dio_vmops;
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(reserved_mem_dio_mmap);
+
+/**
+ * reserved_mem_memremap_pages() - build struct pages for reserved mem
+ * @dev: device pointer
+ * @rmem: reserved memory region from dts, which can be get by
+ * get_reserved_mem_from_dev(dev)
+ *
+ * Returns: 0 on success or a negative error-code on failure.
+ */
+void *reserved_mem_memremap_pages(struct device *dev, struct reserved_mem *rmem)
+{
+ struct dev_pagemap *pgmap_rmem_dio;
+ void *vaddr;
+ struct page **pages;
+ int i;
+ unsigned long offset = 0;
+ struct page *page;
+
+ rmem->nr_pages = DIV_ROUND_UP(rmem->size, PAGE_SIZE);
+ pages = kvmalloc_array(rmem->nr_pages, sizeof(*pages), GFP_KERNEL);
+ if (!pages)
+ return ERR_PTR(-ENOMEM);
+
+ pgmap_rmem_dio = devm_kzalloc(dev, sizeof(*pgmap_rmem_dio), GFP_KERNEL);
+
+ pgmap_rmem_dio->range.start = rmem->base;
+ pgmap_rmem_dio->range.end = rmem->base + rmem->size - 1;
+ pgmap_rmem_dio->nr_range = 1;
+ pgmap_rmem_dio->type = MEMORY_DEVICE_GENERIC;
+
+ pr_debug("%s, will do devm_memremap_pages, start from %llx, to %llx\n",
+ __func__, pgmap_rmem_dio->range.start, pgmap_rmem_dio->range.end);
+
+ vaddr = devm_memremap_pages(dev, pgmap_rmem_dio);
+
+ if (IS_ERR_OR_NULL(vaddr)) {
+ dev_err(dev, "%s %d: %ld", __func__, __LINE__, PTR_ERR(vaddr));
+ return vaddr;
+ }
+
+ rmem->pages = pages;
+
+ for (i = 0; i < rmem->nr_pages; offset += PAGE_SIZE) {
+ page = virt_to_page((unsigned long)vaddr + offset);
+ if (!page) {
+ pr_err("%s: virt_to_page fail\n", __func__);
+ return ERR_PTR(-ENOMEM);
+ }
+ pages[i++] = page;
+ }
+
+ return vaddr;
+}
+EXPORT_SYMBOL_GPL(reserved_mem_memremap_pages);
+#endif
diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h
index 4de2a24cadc9..0aa1ef883060 100644
--- a/include/linux/of_reserved_mem.h
+++ b/include/linux/of_reserved_mem.h
@@ -16,6 +16,10 @@ struct reserved_mem {
phys_addr_t base;
phys_addr_t size;
void *priv;
+#ifdef CONFIG_OF_RESERVED_MEM_DIO_SUPPORT
+ struct page **pages; /* point to array of struct pages of this region */
+ unsigned long nr_pages; /* number of struct page* */
+#endif
};

struct reserved_mem_ops {
@@ -81,4 +85,11 @@ static inline int of_reserved_mem_device_init(struct device *dev)
return of_reserved_mem_device_init_by_idx(dev, dev->of_node, 0);
}

+struct reserved_mem *get_reserved_mem_from_dev(struct device *dev);
+
+#ifdef CONFIG_OF_RESERVED_MEM_DIO_SUPPORT
+int reserved_mem_dio_mmap(struct file *file, struct vm_area_struct *vma, struct reserved_mem *rmem);
+void *reserved_mem_memremap_pages(struct device *dev, struct reserved_mem *rmem);
+#endif
+
#endif /* __OF_RESERVED_MEM_H */
--
2.25.1


2022-07-11 13:39:03

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH 1/4] of: add struct page support to rmem

On Mon, Jul 11, 2022 at 2:24 PM Li Chen <[email protected]> wrote:

> +config OF_RESERVED_MEM_DIO_SUPPORT
> + bool "add Direct I/O support to reserved_mem"
> + depends on ZONE_DEVICE && ARCH_KEEP_MEMBLOCK
> + help
> + By default, reserved memory don't get struct page support, which
> + means you cannot do Direct I/O from this region. This config takes
> + uses of ZONE_DEVICE and treats rmem as hotplug mem to get struct
> + page and DIO support.

This probably does not need to be user visible, it's enough to select it from
the drivers that need it.

> @@ -72,7 +72,6 @@ void __init fdt_reserved_mem_save_node(unsigned long node, const char *uname,
> rmem->size = size;
>
> reserved_mem_count++;
> - return;
> }

This change is not wrong, but it does not belong into the same patch
as the rest, just drop it.

> +/**
> + * get_reserved_mem_from_dev() - get reserved_mem from a device node
> + * @dev: device pointer
> + *
> + * This function look for reserved_mem from given device.
> + *
> + * Returns a reserved_mem pointer, or NULL on error.
> + */
> +struct reserved_mem *get_reserved_mem_from_dev(struct device *dev)
> +{
> + struct device_node *np = dev_of_node(dev);
> + struct device_node *rmem_np;
> + struct reserved_mem *rmem = NULL;
> +
> + rmem_np = of_parse_phandle(np, "memory-region", 0);
> + if (!rmem_np) {
> + dev_err(dev, "failed to get memory region node\n");
> + return ERR_PTR(-ENODEV);
> + }
> +
> + rmem = of_reserved_mem_lookup(rmem_np);
> + if (!rmem) {
> + dev_err(dev, "Failed to lookup reserved memory\n");
> + return ERR_PTR(EINVAL);

This needs to be a negative error code rather than the positive EINVAL.
No need to initialize rmem=NULL first if you override it here.

> + if (likely(reserved_mem_dio_in_region(pfn << PAGE_SHIFT, PAGE_SIZE, rmem) <
> + 0))
> + goto out;

It's not performance critical, so just drop the 'likely()' and put the
rest into one line.


> + if (page) {
> + *page = pfn_to_page(pfn);
> + get_page(*page);
> + }
> +
> + ret = 0;
> +
> +out:
> + pte_unmap(pte);
> + return ret;
> +}

Should you perhaps return an error when 'page' is NULL?

> +#ifdef CONFIG_OF_RESERVED_MEM_DIO_SUPPORT
> +int reserved_mem_dio_mmap(struct file *file, struct vm_area_struct *vma, struct reserved_mem *rmem);
> +void *reserved_mem_memremap_pages(struct device *dev, struct reserved_mem *rmem);
> +#endif

The '#ifdef' check can be dropped here, declarations are normally
not hidden like this.

Arnd

2022-07-11 15:26:51

by Li Chen

[permalink] [raw]
Subject: Re: [PATCH 1/4] of: add struct page support to rmem

Hi Arnd,

Thanks for your review!
---- On Mon, 11 Jul 2022 21:36:12 +0800 Arnd Bergmann <[email protected]> wrote ---
> On Mon, Jul 11, 2022 at 2:24 PM Li Chen <[email protected]> wrote:
>
> > +config OF_RESERVED_MEM_DIO_SUPPORT
> > + bool "add Direct I/O support to reserved_mem"
> > + depends on ZONE_DEVICE && ARCH_KEEP_MEMBLOCK
> > + help
> > + By default, reserved memory don't get struct page support, which
> > + means you cannot do Direct I/O from this region. This config takes
> > + uses of ZONE_DEVICE and treats rmem as hotplug mem to get struct
> > + page and DIO support.
>
> This probably does not need to be user visible, it's enough to select it from
> the drivers that need it.

When you say "user visible", do you mean the config can be dropped or something else like Kconfig type other than bool?

>
> > @@ -72,7 +72,6 @@ void __init fdt_reserved_mem_save_node(unsigned long node, const char *uname,
> > rmem->size = size;
> >
> > reserved_mem_count++;
> > - return;
> > }
>
> This change is not wrong, but it does not belong into the same patch
> as the rest, just drop it.
>
> > +/**
> > + * get_reserved_mem_from_dev() - get reserved_mem from a device node
> > + * @dev: device pointer
> > + *
> > + * This function look for reserved_mem from given device.
> > + *
> > + * Returns a reserved_mem pointer, or NULL on error.
> > + */
> > +struct reserved_mem *get_reserved_mem_from_dev(struct device *dev)
> > +{
> > + struct device_node *np = dev_of_node(dev);
> > + struct device_node *rmem_np;
> > + struct reserved_mem *rmem = NULL;
> > +
> > + rmem_np = of_parse_phandle(np, "memory-region", 0);
> > + if (!rmem_np) {
> > + dev_err(dev, "failed to get memory region node\n");
> > + return ERR_PTR(-ENODEV);
> > + }
> > +
> > + rmem = of_reserved_mem_lookup(rmem_np);
> > + if (!rmem) {
> > + dev_err(dev, "Failed to lookup reserved memory\n");
> > + return ERR_PTR(EINVAL);
>
> This needs to be a negative error code rather than the positive EINVAL.
> No need to initialize rmem=NULL first if you override it here.
>
> > + if (likely(reserved_mem_dio_in_region(pfn << PAGE_SHIFT, PAGE_SIZE, rmem) <
> > + 0))
> > + goto out;
>
> It's not performance critical, so just drop the 'likely()' and put the
> rest into one line.
>
>
> > + if (page) {
> > + *page = pfn_to_page(pfn);
> > + get_page(*page);
> > + }
> > +
> > + ret = 0;
> > +
> > +out:
> > + pte_unmap(pte);
> > + return ret;
> > +}
>
> Should you perhaps return an error when 'page' is NULL?
>
> > +#ifdef CONFIG_OF_RESERVED_MEM_DIO_SUPPORT
> > +int reserved_mem_dio_mmap(struct file *file, struct vm_area_struct *vma, struct reserved_mem *rmem);
> > +void *reserved_mem_memremap_pages(struct device *dev, struct reserved_mem *rmem);
> > +#endif
>
> The '#ifdef' check can be dropped here, declarations are normally
> not hidden like this.
>
> Arnd
>

These will be fixed in v2.

Regards,
Li

2022-07-11 15:38:15

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH 1/4] of: add struct page support to rmem

On Mon, Jul 11, 2022 at 4:51 PM Li Chen <[email protected]> wrote:
> ---- On Mon, 11 Jul 2022 21:36:12 +0800 Arnd Bergmann <[email protected]> wrote ---
> > On Mon, Jul 11, 2022 at 2:24 PM Li Chen <[email protected]> wrote:
> >
> > > +config OF_RESERVED_MEM_DIO_SUPPORT
> > > + bool "add Direct I/O support to reserved_mem"
> > > + depends on ZONE_DEVICE && ARCH_KEEP_MEMBLOCK
> > > + help
> > > + By default, reserved memory don't get struct page support, which
> > > + means you cannot do Direct I/O from this region. This config takes
> > > + uses of ZONE_DEVICE and treats rmem as hotplug mem to get struct
> > > + page and DIO support.
> >
> > This probably does not need to be user visible, it's enough to select it from
> > the drivers that need it.
>
> When you say "user visible", do you mean the config can be dropped or something else like Kconfig type other than bool?

I mean this can be a hidden option, which you can do by leaving out the
one-line description after the 'bool' keyword. The option will still
be selectable
in Kconfig files from other options, but not shown in 'make menuconfig'.

Arnd

2022-07-12 03:38:40

by Li Chen

[permalink] [raw]
Subject: Re: [PATCH 1/4] of: add struct page support to rmem

Hi Arnd,
---- On Mon, 11 Jul 2022 23:06:50 +0800 Arnd Bergmann <[email protected]> wrote ---
> On Mon, Jul 11, 2022 at 4:51 PM Li Chen <[email protected]> wrote:
> > ---- On Mon, 11 Jul 2022 21:36:12 +0800 Arnd Bergmann <[email protected]> wrote ---
> > > On Mon, Jul 11, 2022 at 2:24 PM Li Chen <[email protected]> wrote:
> > >
> > > > +config OF_RESERVED_MEM_DIO_SUPPORT
> > > > + bool "add Direct I/O support to reserved_mem"
> > > > + depends on ZONE_DEVICE && ARCH_KEEP_MEMBLOCK
> > > > + help
> > > > + By default, reserved memory don't get struct page support, which
> > > > + means you cannot do Direct I/O from this region. This config takes
> > > > + uses of ZONE_DEVICE and treats rmem as hotplug mem to get struct
> > > > + page and DIO support.
> > >
> > > This probably does not need to be user visible, it's enough to select it from
> > > the drivers that need it.
> >
> > When you say "user visible", do you mean the config can be dropped or something else like Kconfig type other than bool?
>
> I mean this can be a hidden option, which you can do by leaving out the
> one-line description after the 'bool' keyword. The option will still
> be selectable
> in Kconfig files from other options, but not shown in 'make menuconfig'.
>
> Arnd
>

Roger that. I will do it in v2.

Regards,
Li

2022-07-16 00:54:36

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH 1/4] of: add struct page support to rmem

Hi Li,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on robh/for-next]
[also build test WARNING on arm64/for-next/core arm-perf/for-next/perf linus/master v5.19-rc6 next-20220715]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Li-Chen/add-struct-page-and-Direct-I-O-support-to-reserved-memory/20220711-202957
base: https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
config: arm64-allyesconfig (https://download.01.org/0day-ci/archive/20220716/[email protected]/config)
compiler: aarch64-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/8b66b4b9614f1c7bb8b2d8fac17d5a2a73acf954
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Li-Chen/add-struct-page-and-Direct-I-O-support-to-reserved-memory/20220711-202957
git checkout 8b66b4b9614f1c7bb8b2d8fac17d5a2a73acf954
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=arm64 SHELL=/bin/bash drivers/mailbox/ drivers/of/

If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <[email protected]>

All warnings (new ones prefixed by >>):

drivers/of/of_reserved_mem.c: In function 'reserved_mem_memremap_pages':
drivers/of/of_reserved_mem.c:633:50: error: invalid application of 'sizeof' to incomplete type 'struct dev_pagemap'
633 | pgmap_rmem_dio = devm_kzalloc(dev, sizeof(*pgmap_rmem_dio), GFP_KERNEL);
| ^
drivers/of/of_reserved_mem.c:635:23: error: invalid use of undefined type 'struct dev_pagemap'
635 | pgmap_rmem_dio->range.start = rmem->base;
| ^~
drivers/of/of_reserved_mem.c:636:23: error: invalid use of undefined type 'struct dev_pagemap'
636 | pgmap_rmem_dio->range.end = rmem->base + rmem->size - 1;
| ^~
drivers/of/of_reserved_mem.c:637:23: error: invalid use of undefined type 'struct dev_pagemap'
637 | pgmap_rmem_dio->nr_range = 1;
| ^~
drivers/of/of_reserved_mem.c:638:23: error: invalid use of undefined type 'struct dev_pagemap'
638 | pgmap_rmem_dio->type = MEMORY_DEVICE_GENERIC;
| ^~
drivers/of/of_reserved_mem.c:638:32: error: 'MEMORY_DEVICE_GENERIC' undeclared (first use in this function)
638 | pgmap_rmem_dio->type = MEMORY_DEVICE_GENERIC;
| ^~~~~~~~~~~~~~~~~~~~~
drivers/of/of_reserved_mem.c:638:32: note: each undeclared identifier is reported only once for each function it appears in
In file included from include/linux/printk.h:584,
from include/linux/kernel.h:29,
from include/linux/cpumask.h:10,
from include/linux/smp.h:13,
from include/linux/lockdep.h:14,
from include/linux/mutex.h:17,
from include/linux/kernfs.h:11,
from include/linux/sysfs.h:16,
from include/linux/kobject.h:20,
from include/linux/of.h:17,
from drivers/of/of_reserved_mem.c:15:
drivers/of/of_reserved_mem.c:641:42: error: invalid use of undefined type 'struct dev_pagemap'
641 | __func__, pgmap_rmem_dio->range.start, pgmap_rmem_dio->range.end);
| ^~
include/linux/dynamic_debug.h:134:29: note: in definition of macro '__dynamic_func_call'
134 | func(&id, ##__VA_ARGS__); \
| ^~~~~~~~~~~
include/linux/dynamic_debug.h:162:9: note: in expansion of macro '_dynamic_func_call'
162 | _dynamic_func_call(fmt, __dynamic_pr_debug, \
| ^~~~~~~~~~~~~~~~~~
include/linux/printk.h:599:9: note: in expansion of macro 'dynamic_pr_debug'
599 | dynamic_pr_debug(fmt, ##__VA_ARGS__)
| ^~~~~~~~~~~~~~~~
drivers/of/of_reserved_mem.c:640:9: note: in expansion of macro 'pr_debug'
640 | pr_debug("%s, will do devm_memremap_pages, start from %llx, to %llx\n",
| ^~~~~~~~
drivers/of/of_reserved_mem.c:641:71: error: invalid use of undefined type 'struct dev_pagemap'
641 | __func__, pgmap_rmem_dio->range.start, pgmap_rmem_dio->range.end);
| ^~
include/linux/dynamic_debug.h:134:29: note: in definition of macro '__dynamic_func_call'
134 | func(&id, ##__VA_ARGS__); \
| ^~~~~~~~~~~
include/linux/dynamic_debug.h:162:9: note: in expansion of macro '_dynamic_func_call'
162 | _dynamic_func_call(fmt, __dynamic_pr_debug, \
| ^~~~~~~~~~~~~~~~~~
include/linux/printk.h:599:9: note: in expansion of macro 'dynamic_pr_debug'
599 | dynamic_pr_debug(fmt, ##__VA_ARGS__)
| ^~~~~~~~~~~~~~~~
drivers/of/of_reserved_mem.c:640:9: note: in expansion of macro 'pr_debug'
640 | pr_debug("%s, will do devm_memremap_pages, start from %llx, to %llx\n",
| ^~~~~~~~
drivers/of/of_reserved_mem.c:643:17: error: implicit declaration of function 'devm_memremap_pages'; did you mean 'devm_free_pages'? [-Werror=implicit-function-declaration]
643 | vaddr = devm_memremap_pages(dev, pgmap_rmem_dio);
| ^~~~~~~~~~~~~~~~~~~
| devm_free_pages
>> drivers/of/of_reserved_mem.c:643:15: warning: assignment to 'void *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
643 | vaddr = devm_memremap_pages(dev, pgmap_rmem_dio);
| ^
cc1: some warnings being treated as errors


vim +643 drivers/of/of_reserved_mem.c

610
611 /**
612 * reserved_mem_memremap_pages() - build struct pages for reserved mem
613 * @dev: device pointer
614 * @rmem: reserved memory region from dts, which can be get by
615 * get_reserved_mem_from_dev(dev)
616 *
617 * Returns: 0 on success or a negative error-code on failure.
618 */
619 void *reserved_mem_memremap_pages(struct device *dev, struct reserved_mem *rmem)
620 {
621 struct dev_pagemap *pgmap_rmem_dio;
622 void *vaddr;
623 struct page **pages;
624 int i;
625 unsigned long offset = 0;
626 struct page *page;
627
628 rmem->nr_pages = DIV_ROUND_UP(rmem->size, PAGE_SIZE);
629 pages = kvmalloc_array(rmem->nr_pages, sizeof(*pages), GFP_KERNEL);
630 if (!pages)
631 return ERR_PTR(-ENOMEM);
632
633 pgmap_rmem_dio = devm_kzalloc(dev, sizeof(*pgmap_rmem_dio), GFP_KERNEL);
634
635 pgmap_rmem_dio->range.start = rmem->base;
636 pgmap_rmem_dio->range.end = rmem->base + rmem->size - 1;
637 pgmap_rmem_dio->nr_range = 1;
638 pgmap_rmem_dio->type = MEMORY_DEVICE_GENERIC;
639
640 pr_debug("%s, will do devm_memremap_pages, start from %llx, to %llx\n",
641 __func__, pgmap_rmem_dio->range.start, pgmap_rmem_dio->range.end);
642
> 643 vaddr = devm_memremap_pages(dev, pgmap_rmem_dio);

--
0-DAY CI Kernel Test Service
https://01.org/lkp

2022-07-18 13:41:42

by Dan Carpenter

[permalink] [raw]
Subject: Re: [PATCH 1/4] of: add struct page support to rmem

Hi Li,

https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Li-Chen/add-struct-page-and-Direct-I-O-support-to-reserved-memory/20220711-202957
base: https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
config: nios2-randconfig-m031-20220717 (https://download.01.org/0day-ci/archive/20220718/[email protected]/config)
compiler: nios2-linux-gcc (GCC) 12.1.0

If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <[email protected]>
Reported-by: Dan Carpenter <[email protected]>

smatch warnings:
drivers/of/of_reserved_mem.c:472 get_reserved_mem_from_dev() error: passing non negative 22 to ERR_PTR

vim +472 drivers/of/of_reserved_mem.c

8b66b4b9614f1c7 Li Chen 2022-07-11 457 struct reserved_mem *get_reserved_mem_from_dev(struct device *dev)
8b66b4b9614f1c7 Li Chen 2022-07-11 458 {
8b66b4b9614f1c7 Li Chen 2022-07-11 459 struct device_node *np = dev_of_node(dev);
8b66b4b9614f1c7 Li Chen 2022-07-11 460 struct device_node *rmem_np;
8b66b4b9614f1c7 Li Chen 2022-07-11 461 struct reserved_mem *rmem = NULL;
8b66b4b9614f1c7 Li Chen 2022-07-11 462
8b66b4b9614f1c7 Li Chen 2022-07-11 463 rmem_np = of_parse_phandle(np, "memory-region", 0);
8b66b4b9614f1c7 Li Chen 2022-07-11 464 if (!rmem_np) {
8b66b4b9614f1c7 Li Chen 2022-07-11 465 dev_err(dev, "failed to get memory region node\n");
8b66b4b9614f1c7 Li Chen 2022-07-11 466 return ERR_PTR(-ENODEV);
8b66b4b9614f1c7 Li Chen 2022-07-11 467 }
8b66b4b9614f1c7 Li Chen 2022-07-11 468
8b66b4b9614f1c7 Li Chen 2022-07-11 469 rmem = of_reserved_mem_lookup(rmem_np);
8b66b4b9614f1c7 Li Chen 2022-07-11 470 if (!rmem) {
8b66b4b9614f1c7 Li Chen 2022-07-11 471 dev_err(dev, "Failed to lookup reserved memory\n");
8b66b4b9614f1c7 Li Chen 2022-07-11 @472 return ERR_PTR(EINVAL);

Missing - character on -EINVAL.

8b66b4b9614f1c7 Li Chen 2022-07-11 473 }
8b66b4b9614f1c7 Li Chen 2022-07-11 474 return rmem;
8b66b4b9614f1c7 Li Chen 2022-07-11 475 }

--
0-DAY CI Kernel Test Service
https://01.org/lkp