modprobe: ERROR: could not insert 'pmem': Invalid argument
diff mbox

Message ID 1423087236.22217.11.camel@theros.lm.intel.com
State New, archived
Headers show

Commit Message

Ross Zwisler Feb. 4, 2015, 10 p.m. UTC
On Wed, 2015-02-04 at 13:45 -0800, Roger C. Pao (Enmotus) wrote:
> [rcpao@test27 pmem]$ sudo modprobe pmem map=4G@18G
> modprobe: ERROR: could not insert 'pmem': Invalid argument
> 
> 
> From dmesg:
> 
> [  125.343206] add_persistent_memory: request_mem_region_exclusive
> phys=0x480000000 size=0x100000000 failed
> 
> 
> occurs even if I add mapmem=4G$18G to the kernel line.  I originally
> tried without it.
> 
> [rcpao@test27 pmem]$ cat /proc/cmdline 
> BOOT_IMAGE=/vmlinuz-3.19.0-rc3+ root=/dev/mapper/fedora-root ro
> rd.lvm.lv=fedora/swap rd.lvm.lv=fedora/root mapmem=4G$18G
> 
> 
> Note: /etc/default/grub requires \\\ to escape \ and $:
> GRUB_CMDLINE_LINUX="rd.lvm.lv=fedora/swap rd.lvm.lv=fedora/root
> mapmem=4G\\\$18G"

Ah, yep, I've seen this issue as well I think.  The
request_mem_region_exclusive() fails when you aren't dealing with kernel
usable memory - and yours isn't because it's marked as type 12 in the e820
table.

Here, try this patch (compile tested only against my tree):

-------------------------

From 9dbd5ae0b7369862e71d28e465372b75cd363e9c Mon Sep 17 00:00:00 2001
From: Ross Zwisler <ross.zwisler@linux.intel.com>
Date: Wed, 4 Feb 2015 14:58:43 -0700
Subject: [PATCH] TEST pmem: Skip memory reservation for PMEM region

Skip the memory reservation step for the memory consumed by PMEM.  This
is a quick workaround for systems that have real NVDIMMs that don't show
up as kernel usable in the e820 table.

Compile tested only.

Signed-off-by: Ross Zwisler <ross.zwisler@linux.intel.com>
---
 drivers/block/pmem.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

Comments

Roger C. Pao (Enmotus) Feb. 4, 2015, 11:02 p.m. UTC | #1
On Wed, Feb 4, 2015 at 2:00 PM, Ross Zwisler <ross.zwisler@linux.intel.com>
wrote:

> On Wed, 2015-02-04 at 13:45 -0800, Roger C. Pao (Enmotus) wrote:
> > [rcpao@test27 pmem]$ sudo modprobe pmem map=4G@18G
> > modprobe: ERROR: could not insert 'pmem': Invalid argument
> >
> >
> > From dmesg:
> >
> > [  125.343206] add_persistent_memory: request_mem_region_exclusive
> > phys=0x480000000 size=0x100000000 failed
> >
> >
> > occurs even if I add mapmem=4G$18G to the kernel line.  I originally
> > tried without it.
> >
> > [rcpao@test27 pmem]$ cat /proc/cmdline
> > BOOT_IMAGE=/vmlinuz-3.19.0-rc3+ root=/dev/mapper/fedora-root ro
> > rd.lvm.lv=fedora/swap rd.lvm.lv=fedora/root mapmem=4G$18G
> >
> >
> > Note: /etc/default/grub requires \\\ to escape \ and $:
> > GRUB_CMDLINE_LINUX="rd.lvm.lv=fedora/swap rd.lvm.lv=fedora/root
> > mapmem=4G\\\$18G"
>
> Ah, yep, I've seen this issue as well I think.  The
> request_mem_region_exclusive() fails when you aren't dealing with kernel
> usable memory - and yours isn't because it's marked as type 12 in the e820
> table.
>
> Here, try this patch (compile tested only against my tree):
>
> -------------------------
>
> From 9dbd5ae0b7369862e71d28e465372b75cd363e9c Mon Sep 17 00:00:00 2001
> From: Ross Zwisler <ross.zwisler@linux.intel.com>
> Date: Wed, 4 Feb 2015 14:58:43 -0700
> Subject: [PATCH] TEST pmem: Skip memory reservation for PMEM region
>
> Skip the memory reservation step for the memory consumed by PMEM.  This
> is a quick workaround for systems that have real NVDIMMs that don't show
> up as kernel usable in the e820 table.
>
> Compile tested only.
>
> Signed-off-by: Ross Zwisler <ross.zwisler@linux.intel.com>
> ---
>  drivers/block/pmem.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/block/pmem.c b/drivers/block/pmem.c
> index 1bd9ab0..078ad09 100644
> --- a/drivers/block/pmem.c
> +++ b/drivers/block/pmem.c
> @@ -238,6 +238,7 @@ int pmem_mapmem(struct pmem_device *pmem)
>         struct resource *res_mem;
>         int err;
>
> +       /*
>         res_mem = request_mem_region_exclusive(pmem->phys_addr, pmem->size,
>                                                "pmem");
>         if (!res_mem) {
> @@ -245,6 +246,7 @@ int pmem_mapmem(struct pmem_device *pmem)
>                            pmem->phys_addr, pmem->size);
>                 return -EINVAL;
>         }
> +       */
>
>         pmem->virt_addr = ioremap_cache(pmem->phys_addr, pmem->size);
>         if (unlikely(!pmem->virt_addr)) {
> @@ -254,7 +256,7 @@ int pmem_mapmem(struct pmem_device *pmem)
>         return 0;
>
>  out_release:
> -       release_mem_region(pmem->phys_addr, pmem->size);
> +//     release_mem_region(pmem->phys_addr, pmem->size);
>         return err;
>  }
>
> @@ -264,7 +266,7 @@ void pmem_unmapmem(struct pmem_device *pmem)
>                 return;
>
>         iounmap(pmem->virt_addr);
> -       release_mem_region(pmem->phys_addr, pmem->size);
> +//     release_mem_region(pmem->phys_addr, pmem->size);
>         pmem->virt_addr = NULL;
>  }
>
> --
> 1.9.3
>
>
Success!  Thank you Ross.  Your patch works with a small compiler warning:

  CC [M]  drivers/block/pmem.o
drivers/block/pmem.c: In function ‘pmem_mapmem’:
drivers/block/pmem.c:238:19: warning: unused variable ‘res_mem’
[-Wunused-variable]
  struct resource *res_mem;
                   ^

...
[rcpao@test27 ~]$ sudo modprobe pmem pmem_start_gb=18 pmem_size_gb=4
pmem_count=1
[rcpao@test27 ~]$ ls -al /dev/pmem0
brw-rw----. 1 root disk 259, 0 Feb  4 14:46 /dev/pmem0

dmesg:
[  135.047433]  pmem0: unknown partition table
[  135.047563] pmem: module loaded


[  135.047433]  pmem0: unknown partition table <<<--- expected at this
point.  I plan on using this directly so I hope nothing attempts to use
it--not sure why anything is even looking for a partition table in it.

At least now I can continue with my NVDIMM testing using your prd tree plus
this patch.  Thank you.

Patch
diff mbox

diff --git a/drivers/block/pmem.c b/drivers/block/pmem.c
index 1bd9ab0..078ad09 100644
--- a/drivers/block/pmem.c
+++ b/drivers/block/pmem.c
@@ -238,6 +238,7 @@  int pmem_mapmem(struct pmem_device *pmem)
 	struct resource *res_mem;
 	int err;
 
+	/*
 	res_mem = request_mem_region_exclusive(pmem->phys_addr, pmem->size,
 					       "pmem");
 	if (!res_mem) {
@@ -245,6 +246,7 @@  int pmem_mapmem(struct pmem_device *pmem)
 			   pmem->phys_addr, pmem->size);
 		return -EINVAL;
 	}
+	*/
 
 	pmem->virt_addr = ioremap_cache(pmem->phys_addr, pmem->size);
 	if (unlikely(!pmem->virt_addr)) {
@@ -254,7 +256,7 @@  int pmem_mapmem(struct pmem_device *pmem)
 	return 0;
 
 out_release:
-	release_mem_region(pmem->phys_addr, pmem->size);
+//	release_mem_region(pmem->phys_addr, pmem->size);
 	return err;
 }
 
@@ -264,7 +266,7 @@  void pmem_unmapmem(struct pmem_device *pmem)
 		return;
 
 	iounmap(pmem->virt_addr);
-	release_mem_region(pmem->phys_addr, pmem->size);
+//	release_mem_region(pmem->phys_addr, pmem->size);
 	pmem->virt_addr = NULL;
 }