linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 1/2] mm, proc: Fix region lost in /proc/self/smaps
@ 2016-10-01  4:42 Robert Ho
  2016-10-01  4:42 ` [PATCH v4 2/2] Dcumentation/filesystems/proc.txt: Add more description for maps/smaps Robert Ho
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Robert Ho @ 2016-10-01  4:42 UTC (permalink / raw)
  To: pbonzini, akpm, mhocko, oleg, dave.hansen, dan.j.williams
  Cc: guangrong.xiao, gleb, mtosatti, kvm, linux-kernel, stefanha,
	yuhuang, linux-mm, ross.zwisler, Robert Ho

Recently, Redhat reported that nvml test suite failed on QEMU/KVM,
more detailed info please refer to:
   https://bugzilla.redhat.com/show_bug.cgi?id=1365721

Actually, this bug is not only for NVDIMM/DAX but also for any other file
systems. This simple test case abstracted from nvml can easily reproduce
this bug in common environment:

-------------------------- testcase.c -----------------------------

int
is_pmem_proc(const void *addr, size_t len)
{
        const char *caddr = addr;

        FILE *fp;
        if ((fp = fopen("/proc/self/smaps", "r")) == NULL) {
                printf("!/proc/self/smaps");
                return 0;
        }

        int retval = 0;         /* assume false until proven otherwise */
        char line[PROCMAXLEN];  /* for fgets() */
        char *lo = NULL;        /* beginning of current range in smaps file */
        char *hi = NULL;        /* end of current range in smaps file */
        int needmm = 0;         /* looking for mm flag for current range */
        while (fgets(line, PROCMAXLEN, fp) != NULL) {
                static const char vmflags[] = "VmFlags:";
                static const char mm[] = " wr";

                /* check for range line */
                if (sscanf(line, "%p-%p", &lo, &hi) == 2) {
                        if (needmm) {
                                /* last range matched, but no mm flag found */
                                printf("never found mm flag.\n");
                                break;
                        } else if (caddr < lo) {
                                /* never found the range for caddr */
                                printf("#######no match for addr %p.\n", caddr);
                                break;
                        } else if (caddr < hi) {
                                /* start address is in this range */
                                size_t rangelen = (size_t)(hi - caddr);

                                /* remember that matching has started */
                                needmm = 1;

                                /* calculate remaining range to search for */
                                if (len > rangelen) {
                                        len -= rangelen;
                                        caddr += rangelen;
                                        printf("matched %zu bytes in range "
                                                "%p-%p, %zu left over.\n",
                                                        rangelen, lo, hi, len);
                                } else {
                                        len = 0;
                                        printf("matched all bytes in range "
                                                        "%p-%p.\n", lo, hi);
                                }
                        }
                } else if (needmm && strncmp(line, vmflags,
                                        sizeof(vmflags) - 1) == 0) {
                        if (strstr(&line[sizeof(vmflags) - 1], mm) != NULL) {
                                printf("mm flag found.\n");
                                if (len == 0) {
                                        /* entire range matched */
                                        retval = 1;
                                        break;
                                }
                                needmm = 0;     /* saw what was needed */
                        } else {
                                /* mm flag not set for some or all of range */
                                printf("range has no mm flag.\n");
                                break;
                        }
                }
        }

        fclose(fp);

        printf("returning %d.\n", retval);
        return retval;
}

void *Addr;
size_t Size;

/*
 * worker -- the work each thread performs
 */
static void *
worker(void *arg)
{
        int *ret = (int *)arg;
        *ret =  is_pmem_proc(Addr, Size);
        return NULL;
}

int main(int argc, char *argv[])
{
        if (argc <  2 || argc > 3) {
                printf("usage: %s file [env].\n", argv[0]);
                return -1;
        }

        int fd = open(argv[1], O_RDWR);

        struct stat stbuf;
        fstat(fd, &stbuf);

        Size = stbuf.st_size;
        Addr = mmap(0, stbuf.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);

        close(fd);

        pthread_t threads[NTHREAD];
        int ret[NTHREAD];

        /* kick off NTHREAD threads */
        for (int i = 0; i < NTHREAD; i++)
                pthread_create(&threads[i], NULL, worker, &ret[i]);

        /* wait for all the threads to complete */
        for (int i = 0; i < NTHREAD; i++)
                pthread_join(threads[i], NULL);

        /* verify that all the threads return the same value */
        for (int i = 1; i < NTHREAD; i++) {
                if (ret[0] != ret[i]) {
                        printf("Error i %d ret[0] = %d ret[i] = %d.\n", i,
                                ret[0], ret[i]);
                }
        }

        printf("%d", ret[0]);
        return 0;
}

It failed as some threads can not find the memory region in
"/proc/self/smaps" which is allocated in the main process

It is caused by proc fs which uses 'file->version' to indicate the VMA that
is the last one has already been handled by read() system call. When the
next read() issues, it uses the 'version' to find the VMA, then the next
VMA is what we want to handle, the related code is as follows:

        if (last_addr) {
                vma = find_vma(mm, last_addr);
                if (vma && (vma = m_next_vma(priv, vma)))
                        return vma;
        }

However, VMA will be lost if the last VMA is gone, e.g:

The process VMA list is A->B->C->D

CPU 0                                  CPU 1
read() system call
   handle VMA B
   version = B
return to userspace

                                   unmap VMA B

issue read() again to continue to get
the region info
   find_vma(version) will get VMA C
   m_next_vma(C) will get VMA D
   handle D
   !!! VMA C is lost !!!

In order to fix this bug, we make 'file->version' indicate the end address
of current VMA

Changelog:
v4:
	Thank Oleg Nesterov <oleg@redhat.com>'s contribution, making the patch
more simplified. We now only need to 1) use vm_end in m->version for remember
last vma 2) in m_start(), by judging the found vma's vm_start, determine
whether use it or its successor.

v3:
	Thank Michal's pointing. Fix the incompletion of v2's fixing:
"/proc/<pid>/smaps will report counters for the full vma range while
the header (aka show_map_vma) will report shorter (non-overlapping) range"
    Add description in Documentation/filesystems/proc.txt, regarding maps,
smaps reading's guaruntees.

v2:
Thanks to Dave Hansen's comments, this version fixes the issue in v1 that
same virtual address range may be outputted twice, e.g:

Take two example VMAs:

	vma-A: (0x1000 -> 0x2000)
	vma-B: (0x2000 -> 0x3000)

read() #1: prints vma-A, sets m->version=0x2000

Now, merge A/B to make C:

	vma-C: (0x1000 -> 0x3000)

read() #2: find_vma(m->version=0x2000), returns vma-C, prints vma-C

The user will see two VMAs in their output:

	A: 0x1000->0x2000
	C: 0x1000->0x3000

Acked-by: Dave Hansen <dave.hansen@intel.com>
Signed-off-by: Xiao Guangrong <guangrong.xiao@linux.intel.com>
Signed-off-by: Robert Hu <robert.hu@intel.com>
---
 fs/proc/task_mmu.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index f6fa99e..45f42c8 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -147,7 +147,7 @@ m_next_vma(struct proc_maps_private *priv, struct vm_area_struct *vma)
 static void m_cache_vma(struct seq_file *m, struct vm_area_struct *vma)
 {
 	if (m->count < m->size)	/* vma is copied successfully */
-		m->version = m_next_vma(m->private, vma) ? vma->vm_start : -1UL;
+		m->version = m_next_vma(m->private, vma) ? vma->vm_end : -1UL;
 }
 
 static void *m_start(struct seq_file *m, loff_t *ppos)
@@ -175,8 +175,10 @@ static void *m_start(struct seq_file *m, loff_t *ppos)
 	priv->tail_vma = get_gate_vma(mm);
 
 	if (last_addr) {
-		vma = find_vma(mm, last_addr);
-		if (vma && (vma = m_next_vma(priv, vma)))
+		vma = find_vma(mm, last_addr - 1);
+		if (vma && vma->vm_start <= last_addr)
+			vma = m_next_vma(priv, vma);
+		if (vma)
 			return vma;
 	}
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v4 2/2] Dcumentation/filesystems/proc.txt: Add more description for maps/smaps
  2016-10-01  4:42 [PATCH v4 1/2] mm, proc: Fix region lost in /proc/self/smaps Robert Ho
@ 2016-10-01  4:42 ` Robert Ho
  2016-10-03 11:53   ` Michal Hocko
  2016-10-03 11:52 ` [PATCH v4 1/2] mm, proc: Fix region lost in /proc/self/smaps Michal Hocko
  2016-10-03 15:51 ` Oleg Nesterov
  2 siblings, 1 reply; 6+ messages in thread
From: Robert Ho @ 2016-10-01  4:42 UTC (permalink / raw)
  To: pbonzini, akpm, mhocko, oleg, dave.hansen, dan.j.williams
  Cc: guangrong.xiao, gleb, mtosatti, kvm, linux-kernel, stefanha,
	yuhuang, linux-mm, ross.zwisler, Robert Ho

Add some more description on the limitations for smaps/maps readings, as well
as some guaruntees we can make.

Changelog:
v2:
	Adopt Dave Hansen's revision from v1 as the description.

Signed-off-by: Robert Ho <robert.hu@intel.com>
---
 Documentation/filesystems/proc.txt | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index 68080ad..daa096f 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -515,6 +515,18 @@ be vanished or the reverse -- new added.
 This file is only present if the CONFIG_MMU kernel configuration option is
 enabled.
 
+Note: reading /proc/PID/maps or /proc/PID/smaps is inherently racy (consistent
+output can be achieved only in the single read call).
+This typically manifests when doing partial reads of these files while the
+memory map is being modified.  Despite the races, we do provide the following
+guarantees:
+
+1) The mapped addresses never go backwards, which implies no two
+   regions will ever overlap.
+2) If there is something at a given vaddr during the entirety of the
+   life of the smaps/maps walk, there will be some output for it.
+
+
 The /proc/PID/clear_refs is used to reset the PG_Referenced and ACCESSED/YOUNG
 bits on both physical and virtual pages associated with a process, and the
 soft-dirty bit on pte (see Documentation/vm/soft-dirty.txt for details).
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v4 1/2] mm, proc: Fix region lost in /proc/self/smaps
  2016-10-01  4:42 [PATCH v4 1/2] mm, proc: Fix region lost in /proc/self/smaps Robert Ho
  2016-10-01  4:42 ` [PATCH v4 2/2] Dcumentation/filesystems/proc.txt: Add more description for maps/smaps Robert Ho
@ 2016-10-03 11:52 ` Michal Hocko
       [not found]   ` <1475806642.6073.10.camel@vmm.sh.intel.com>
  2016-10-03 15:51 ` Oleg Nesterov
  2 siblings, 1 reply; 6+ messages in thread
From: Michal Hocko @ 2016-10-03 11:52 UTC (permalink / raw)
  To: Robert Ho
  Cc: pbonzini, akpm, oleg, dave.hansen, dan.j.williams,
	guangrong.xiao, gleb, mtosatti, kvm, linux-kernel, stefanha,
	yuhuang, linux-mm, ross.zwisler

On Sat 01-10-16 12:42:37, Robert Ho wrote:
> Recently, Redhat reported that nvml test suite failed on QEMU/KVM,
> more detailed info please refer to:
>    https://bugzilla.redhat.com/show_bug.cgi?id=1365721
> 
> Actually, this bug is not only for NVDIMM/DAX but also for any other file
> systems. This simple test case abstracted from nvml can easily reproduce
> this bug in common environment:
> 
> -------------------------- testcase.c -----------------------------
> 
> int
> is_pmem_proc(const void *addr, size_t len)
> {
>         const char *caddr = addr;
> 
>         FILE *fp;
>         if ((fp = fopen("/proc/self/smaps", "r")) == NULL) {
>                 printf("!/proc/self/smaps");
>                 return 0;
>         }
> 
>         int retval = 0;         /* assume false until proven otherwise */
>         char line[PROCMAXLEN];  /* for fgets() */
>         char *lo = NULL;        /* beginning of current range in smaps file */
>         char *hi = NULL;        /* end of current range in smaps file */
>         int needmm = 0;         /* looking for mm flag for current range */
>         while (fgets(line, PROCMAXLEN, fp) != NULL) {
>                 static const char vmflags[] = "VmFlags:";
>                 static const char mm[] = " wr";
> 
>                 /* check for range line */
>                 if (sscanf(line, "%p-%p", &lo, &hi) == 2) {
>                         if (needmm) {
>                                 /* last range matched, but no mm flag found */
>                                 printf("never found mm flag.\n");
>                                 break;
>                         } else if (caddr < lo) {
>                                 /* never found the range for caddr */
>                                 printf("#######no match for addr %p.\n", caddr);
>                                 break;
>                         } else if (caddr < hi) {
>                                 /* start address is in this range */
>                                 size_t rangelen = (size_t)(hi - caddr);
> 
>                                 /* remember that matching has started */
>                                 needmm = 1;
> 
>                                 /* calculate remaining range to search for */
>                                 if (len > rangelen) {
>                                         len -= rangelen;
>                                         caddr += rangelen;
>                                         printf("matched %zu bytes in range "
>                                                 "%p-%p, %zu left over.\n",
>                                                         rangelen, lo, hi, len);
>                                 } else {
>                                         len = 0;
>                                         printf("matched all bytes in range "
>                                                         "%p-%p.\n", lo, hi);
>                                 }
>                         }
>                 } else if (needmm && strncmp(line, vmflags,
>                                         sizeof(vmflags) - 1) == 0) {
>                         if (strstr(&line[sizeof(vmflags) - 1], mm) != NULL) {
>                                 printf("mm flag found.\n");
>                                 if (len == 0) {
>                                         /* entire range matched */
>                                         retval = 1;
>                                         break;
>                                 }
>                                 needmm = 0;     /* saw what was needed */
>                         } else {
>                                 /* mm flag not set for some or all of range */
>                                 printf("range has no mm flag.\n");
>                                 break;
>                         }
>                 }
>         }
> 
>         fclose(fp);
> 
>         printf("returning %d.\n", retval);
>         return retval;
> }
> 
> void *Addr;
> size_t Size;
> 
> /*
>  * worker -- the work each thread performs
>  */
> static void *
> worker(void *arg)
> {
>         int *ret = (int *)arg;
>         *ret =  is_pmem_proc(Addr, Size);
>         return NULL;
> }
> 
> int main(int argc, char *argv[])
> {
>         if (argc <  2 || argc > 3) {
>                 printf("usage: %s file [env].\n", argv[0]);
>                 return -1;
>         }
> 
>         int fd = open(argv[1], O_RDWR);
> 
>         struct stat stbuf;
>         fstat(fd, &stbuf);
> 
>         Size = stbuf.st_size;
>         Addr = mmap(0, stbuf.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
> 
>         close(fd);
> 
>         pthread_t threads[NTHREAD];
>         int ret[NTHREAD];
> 
>         /* kick off NTHREAD threads */
>         for (int i = 0; i < NTHREAD; i++)
>                 pthread_create(&threads[i], NULL, worker, &ret[i]);
> 
>         /* wait for all the threads to complete */
>         for (int i = 0; i < NTHREAD; i++)
>                 pthread_join(threads[i], NULL);
> 
>         /* verify that all the threads return the same value */
>         for (int i = 1; i < NTHREAD; i++) {
>                 if (ret[0] != ret[i]) {
>                         printf("Error i %d ret[0] = %d ret[i] = %d.\n", i,
>                                 ret[0], ret[i]);
>                 }
>         }
> 
>         printf("%d", ret[0]);
>         return 0;
> }
> 
> It failed as some threads can not find the memory region in
> "/proc/self/smaps" which is allocated in the main process
> 
> It is caused by proc fs which uses 'file->version' to indicate the VMA that
> is the last one has already been handled by read() system call. When the
> next read() issues, it uses the 'version' to find the VMA, then the next
> VMA is what we want to handle, the related code is as follows:
> 
>         if (last_addr) {
>                 vma = find_vma(mm, last_addr);
>                 if (vma && (vma = m_next_vma(priv, vma)))
>                         return vma;
>         }
> 
> However, VMA will be lost if the last VMA is gone, e.g:
> 
> The process VMA list is A->B->C->D
> 
> CPU 0                                  CPU 1
> read() system call
>    handle VMA B
>    version = B
> return to userspace
> 
>                                    unmap VMA B
> 
> issue read() again to continue to get
> the region info
>    find_vma(version) will get VMA C
>    m_next_vma(C) will get VMA D
>    handle D
>    !!! VMA C is lost !!!
> 
> In order to fix this bug, we make 'file->version' indicate the end address
> of current VMA

I guess you wanted to finish that sentence, right?
"
m_start will then look up a vma which with vma_start < last_vm_end and
moves on to the next vma if we found the same or an overlapping vma.
This will guarantee that we will not miss an exclusive vma but we can
still miss one if the previous vma was shrunk. This is acceptable
because guaranteeing "never miss a vma" is simply not feasible. User has
to cope with some inconsistencies if the file is not read in one go.
"
 
> Changelog:
> v4:
> 	Thank Oleg Nesterov <oleg@redhat.com>'s contribution, making the patch
> more simplified. We now only need to 1) use vm_end in m->version for remember
> last vma 2) in m_start(), by judging the found vma's vm_start, determine
> whether use it or its successor.
> 
> v3:
> 	Thank Michal's pointing. Fix the incompletion of v2's fixing:
> "/proc/<pid>/smaps will report counters for the full vma range while
> the header (aka show_map_vma) will report shorter (non-overlapping) range"
>     Add description in Documentation/filesystems/proc.txt, regarding maps,
> smaps reading's guaruntees.
> 
> v2:
> Thanks to Dave Hansen's comments, this version fixes the issue in v1 that
> same virtual address range may be outputted twice, e.g:

I am not sure how the two above are helpful as the patch has been
reworked basically.

> Take two example VMAs:
> 
> 	vma-A: (0x1000 -> 0x2000)
> 	vma-B: (0x2000 -> 0x3000)
> 
> read() #1: prints vma-A, sets m->version=0x2000
> 
> Now, merge A/B to make C:
> 
> 	vma-C: (0x1000 -> 0x3000)
> 
> read() #2: find_vma(m->version=0x2000), returns vma-C, prints vma-C
> 
> The user will see two VMAs in their output:
> 
> 	A: 0x1000->0x2000
> 	C: 0x1000->0x3000
> 

{Suggested,Signed-off}-by: Oleg Nesterov <oleg@redhat.com>
?

> Acked-by: Dave Hansen <dave.hansen@intel.com>
> Signed-off-by: Xiao Guangrong <guangrong.xiao@linux.intel.com>
> Signed-off-by: Robert Hu <robert.hu@intel.com>

Anyway this is definitely an improvement!

Acked-by: Michal Hocko <mhocko@suse.com>

> ---
>  fs/proc/task_mmu.c | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)
> 
> diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
> index f6fa99e..45f42c8 100644
> --- a/fs/proc/task_mmu.c
> +++ b/fs/proc/task_mmu.c
> @@ -147,7 +147,7 @@ m_next_vma(struct proc_maps_private *priv, struct vm_area_struct *vma)
>  static void m_cache_vma(struct seq_file *m, struct vm_area_struct *vma)
>  {
>  	if (m->count < m->size)	/* vma is copied successfully */
> -		m->version = m_next_vma(m->private, vma) ? vma->vm_start : -1UL;
> +		m->version = m_next_vma(m->private, vma) ? vma->vm_end : -1UL;
>  }
>  
>  static void *m_start(struct seq_file *m, loff_t *ppos)
> @@ -175,8 +175,10 @@ static void *m_start(struct seq_file *m, loff_t *ppos)
>  	priv->tail_vma = get_gate_vma(mm);
>  
>  	if (last_addr) {
> -		vma = find_vma(mm, last_addr);
> -		if (vma && (vma = m_next_vma(priv, vma)))
> +		vma = find_vma(mm, last_addr - 1);
> +		if (vma && vma->vm_start <= last_addr)
> +			vma = m_next_vma(priv, vma);
> +		if (vma)
>  			return vma;
>  	}
>  
> -- 
> 1.8.3.1
> 

-- 
Michal Hocko
SUSE Labs

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v4 2/2] Dcumentation/filesystems/proc.txt: Add more description for maps/smaps
  2016-10-01  4:42 ` [PATCH v4 2/2] Dcumentation/filesystems/proc.txt: Add more description for maps/smaps Robert Ho
@ 2016-10-03 11:53   ` Michal Hocko
  0 siblings, 0 replies; 6+ messages in thread
From: Michal Hocko @ 2016-10-03 11:53 UTC (permalink / raw)
  To: Robert Ho
  Cc: pbonzini, akpm, oleg, dave.hansen, dan.j.williams,
	guangrong.xiao, gleb, mtosatti, kvm, linux-kernel, stefanha,
	yuhuang, linux-mm, ross.zwisler

On Sat 01-10-16 12:42:38, Robert Ho wrote:
> Add some more description on the limitations for smaps/maps readings, as well
> as some guaruntees we can make.
> 
> Changelog:
> v2:
> 	Adopt Dave Hansen's revision from v1 as the description.
> 
> Signed-off-by: Robert Ho <robert.hu@intel.com>

Acked-by: Michal Hocko <mhocko@suse.com>

> ---
>  Documentation/filesystems/proc.txt | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
> index 68080ad..daa096f 100644
> --- a/Documentation/filesystems/proc.txt
> +++ b/Documentation/filesystems/proc.txt
> @@ -515,6 +515,18 @@ be vanished or the reverse -- new added.
>  This file is only present if the CONFIG_MMU kernel configuration option is
>  enabled.
>  
> +Note: reading /proc/PID/maps or /proc/PID/smaps is inherently racy (consistent
> +output can be achieved only in the single read call).
> +This typically manifests when doing partial reads of these files while the
> +memory map is being modified.  Despite the races, we do provide the following
> +guarantees:
> +
> +1) The mapped addresses never go backwards, which implies no two
> +   regions will ever overlap.
> +2) If there is something at a given vaddr during the entirety of the
> +   life of the smaps/maps walk, there will be some output for it.
> +
> +
>  The /proc/PID/clear_refs is used to reset the PG_Referenced and ACCESSED/YOUNG
>  bits on both physical and virtual pages associated with a process, and the
>  soft-dirty bit on pte (see Documentation/vm/soft-dirty.txt for details).
> -- 
> 1.8.3.1
> 

-- 
Michal Hocko
SUSE Labs

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v4 1/2] mm, proc: Fix region lost in /proc/self/smaps
  2016-10-01  4:42 [PATCH v4 1/2] mm, proc: Fix region lost in /proc/self/smaps Robert Ho
  2016-10-01  4:42 ` [PATCH v4 2/2] Dcumentation/filesystems/proc.txt: Add more description for maps/smaps Robert Ho
  2016-10-03 11:52 ` [PATCH v4 1/2] mm, proc: Fix region lost in /proc/self/smaps Michal Hocko
@ 2016-10-03 15:51 ` Oleg Nesterov
  2 siblings, 0 replies; 6+ messages in thread
From: Oleg Nesterov @ 2016-10-03 15:51 UTC (permalink / raw)
  To: Robert Ho
  Cc: pbonzini, akpm, mhocko, dave.hansen, dan.j.williams,
	guangrong.xiao, gleb, mtosatti, kvm, linux-kernel, stefanha,
	yuhuang, linux-mm, ross.zwisler

On 10/01, Robert Ho wrote:
>
> --- a/fs/proc/task_mmu.c
> +++ b/fs/proc/task_mmu.c
> @@ -147,7 +147,7 @@ m_next_vma(struct proc_maps_private *priv, struct vm_area_struct *vma)
>  static void m_cache_vma(struct seq_file *m, struct vm_area_struct *vma)
>  {
>  	if (m->count < m->size)	/* vma is copied successfully */
> -		m->version = m_next_vma(m->private, vma) ? vma->vm_start : -1UL;
> +		m->version = m_next_vma(m->private, vma) ? vma->vm_end : -1UL;
>  }
>  
>  static void *m_start(struct seq_file *m, loff_t *ppos)
> @@ -175,8 +175,10 @@ static void *m_start(struct seq_file *m, loff_t *ppos)
>  	priv->tail_vma = get_gate_vma(mm);
>  
>  	if (last_addr) {
> -		vma = find_vma(mm, last_addr);
> -		if (vma && (vma = m_next_vma(priv, vma)))
> +		vma = find_vma(mm, last_addr - 1);
> +		if (vma && vma->vm_start <= last_addr)
> +			vma = m_next_vma(priv, vma);
> +		if (vma)
>  			return vma;
>  	}

Acked-by: Oleg Nesterov <oleg@redhat.com>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v4 1/2] mm, proc: Fix region lost in /proc/self/smaps
       [not found]   ` <1475806642.6073.10.camel@vmm.sh.intel.com>
@ 2016-10-07  8:29     ` Michal Hocko
  0 siblings, 0 replies; 6+ messages in thread
From: Michal Hocko @ 2016-10-07  8:29 UTC (permalink / raw)
  To: robert.hu
  Cc: pbonzini, akpm, oleg, dave.hansen, dan.j.williams,
	guangrong.xiao, gleb, mtosatti, kvm, linux-kernel, stefanha,
	yuhuang, linux-mm, ross.zwisler

On Fri 07-10-16 10:17:22, Robert Hu wrote:
> On Mon, 2016-10-03 at 13:52 +0200, Michal Hocko wrote:
> > On Sat 01-10-16 12:42:37, Robert Ho wrote:
> > > Recently, Redhat reported that nvml test suite failed on QEMU/KVM,
> > > more detailed info please refer to:
> > >    https://bugzilla.redhat.com/show_bug.cgi?id=1365721
> > > 
> [trim...]
> > > 
> > > In order to fix this bug, we make 'file->version' indicate the end address
> > > of current VMA
> > 
> > I guess you wanted to finish that sentence, right?
> > "
> > m_start will then look up a vma which with vma_start < last_vm_end and
> > moves on to the next vma if we found the same or an overlapping vma.
> > This will guarantee that we will not miss an exclusive vma but we can
> > still miss one if the previous vma was shrunk. This is acceptable
> > because guaranteeing "never miss a vma" is simply not feasible. User has
> > to cope with some inconsistencies if the file is not read in one go.
> > "
> 
> Yes, you're right. Sorry that I didn't complement that in v4.
> I see the patch is already moved to -mm tree (by you?) with the above
> complemented. So I'm not supposed to work a v5 patch, am I right?

Andrew took the patch and updated the changelog. So there doesn't seem
to be any reason for v5 just for to update changelog. Unless you want to
have a different wording of course.

[...]
> > I am not sure how the two above are helpful as the patch has been
> > reworked basically.
> > 
> I might be wrong, I thought the change log should honestly write each
> version's changes, although it indeed looks confusing if looks at this
> single version only.
> 
> So I learned from you now that change log shall only reflect the final
> adopted changes only, right?

well, I would keep the changelog if it was helpful - aka small changes
along the way between different submissions - but it is much less useful
when the solution changes completely or way to much. Reader would have
a very limited context to understand those changes without reading the
original email threads anyway.

Anyway, thanks for your persistence!
-- 
Michal Hocko
SUSE Labs

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2016-10-07  8:31 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-01  4:42 [PATCH v4 1/2] mm, proc: Fix region lost in /proc/self/smaps Robert Ho
2016-10-01  4:42 ` [PATCH v4 2/2] Dcumentation/filesystems/proc.txt: Add more description for maps/smaps Robert Ho
2016-10-03 11:53   ` Michal Hocko
2016-10-03 11:52 ` [PATCH v4 1/2] mm, proc: Fix region lost in /proc/self/smaps Michal Hocko
     [not found]   ` <1475806642.6073.10.camel@vmm.sh.intel.com>
2016-10-07  8:29     ` Michal Hocko
2016-10-03 15:51 ` Oleg Nesterov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).