Most recent kernel where this bug did not occur: Distribution: Hardware Environment: Software Environment: glibc-2.5 gcc-4.1.2 Problem Description: bus error when trying to access page created by mremap() Steps to reproduce: In the code below, I mmap() a single page of 4096 and simply mremap() the same page to 2*4096 which is 8192. Then when I try to write anywhere after 4096 bytes, in the newly expanded area. I get Bus error. Can somebody please help me? #define _GNU_SOURCE #include <sys/mman.h> #include <unistd.h> #include <stdio.h> main() { void *ptr; if ((ptr=mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_SHARED|MAP_GROWSDOWN, 0, 0)) == -1) { printf("failed to mmap\n"); return; } if ((ptr=mremap(ptr, 4096, 8192, MREMAP_MAYMOVE)) == -1) { printf("failed to mremap\n"); return; } //why does this failed. I am well in the interval [4096, 8192] *(unsigned int *)(ptr + 4096 + 8)= 10; }
Subject: Re: New: bus error when trying to access page created by mremap() I don't mean to press anybody, but please, can somebody help to find a work around if there is not immediate solutions. Sincerely, William Tambe bugme-daemon@bugzilla.kernel.org wrote: > http://bugzilla.kernel.org/show_bug.cgi?id=8691 > > Summary: bus error when trying to access page created by mremap() > Product: Memory Management > Version: 2.5 > KernelVersion: 2.6.21.5 > Platform: All > OS/Version: Linux > Tree: Mainline > Status: NEW > Severity: blocking > Priority: P1 > Component: Page Allocator > AssignedTo: akpm@osdl.org > ReportedBy: tambewilliam@gmail.com > > > Most recent kernel where this bug did not occur: > Distribution: > Hardware Environment: > Software Environment: glibc-2.5 gcc-4.1.2 > > Problem Description: > bus error when trying to access page created by mremap() > > Steps to reproduce: > In the code below, I mmap() a single page of 4096 and simply mremap() the > same > page to 2*4096 which is 8192. > > Then when I try to write anywhere after 4096 bytes, in the newly expanded > area. > I get Bus error. > > Can somebody please help me? > > > #define _GNU_SOURCE > #include <sys/mman.h> > #include <unistd.h> > > #include <stdio.h> > > main() { > void *ptr; > if ((ptr=mmap(0, 4096, PROT_READ|PROT_WRITE, > MAP_ANONYMOUS|MAP_SHARED|MAP_GROWSDOWN, 0, 0)) == -1) { > printf("failed to mmap\n"); > return; > } > > if ((ptr=mremap(ptr, 4096, 8192, MREMAP_MAYMOVE)) == -1) { > printf("failed to mremap\n"); > return; > } > > //why does this failed. I am well in the interval [4096, 8192] > *(unsigned int *)(ptr + 4096 + 8)= 10; > } > >
Subject: Re: bus error when trying to access page created by mremap() On Sun, 1 Jul 2007 19:43:25 -0700 (PDT) bugme-daemon@bugzilla.kernel.org wrote: > http://bugzilla.kernel.org/show_bug.cgi?id=8691 > > > > > > ------- Comment #1 from tambewilliam@gmail.com 2007-07-01 19:47 ------- > Subject: Re: New: bus error when trying to access page created > by mremap() > > I don't mean to press anybody, but please, can somebody help to find a > work around if there is not immediate solutions. > > Sincerely, > William Tambe > > bugme-daemon@bugzilla.kernel.org wrote: > > http://bugzilla.kernel.org/show_bug.cgi?id=8691 > > > > Summary: bus error when trying to access page created by > mremap() > > Product: Memory Management > > Version: 2.5 > > KernelVersion: 2.6.21.5 > > Platform: All > > OS/Version: Linux > > Tree: Mainline > > Status: NEW > > Severity: blocking > > Priority: P1 > > Component: Page Allocator > > AssignedTo: akpm@osdl.org > > ReportedBy: tambewilliam@gmail.com > > > > > > Most recent kernel where this bug did not occur: > > Distribution: > > Hardware Environment: > > Software Environment: glibc-2.5 gcc-4.1.2 > > > > Problem Description: > > bus error when trying to access page created by mremap() > > > > Steps to reproduce: > > In the code below, I mmap() a single page of 4096 and simply mremap() the > same > > page to 2*4096 which is 8192. > > > > Then when I try to write anywhere after 4096 bytes, in the newly expanded > area. > > I get Bus error. > > > > Can somebody please help me? > > > > > > #define _GNU_SOURCE > > #include <sys/mman.h> > > #include <unistd.h> > > > > #include <stdio.h> > > > > main() { > > void *ptr; > > if ((ptr=mmap(0, 4096, PROT_READ|PROT_WRITE, > > MAP_ANONYMOUS|MAP_SHARED|MAP_GROWSDOWN, 0, 0)) == -1) { > > printf("failed to mmap\n"); > > return; > > } > > > > if ((ptr=mremap(ptr, 4096, 8192, MREMAP_MAYMOVE)) == -1) { > > printf("failed to mremap\n"); > > return; > > } > > > > //why does this failed. I am well in the interval [4096, 8192] > > *(unsigned int *)(ptr + 4096 + 8)= 10; > > } > > > > maybe mremap() failed and your (incorrect) comparison with -1 didn't detect it. Try using MAP_FAILED as the manpage says.
Subject: Re: bus error when trying to access page created by mremap() I did replace -1 with MAP_FAILED but it does the same thing: Bus error. Even if mremap() had failed while I using -1, I would have gotten instead a segmentation fault. But I get a Bus error. I am guessing that the new expended memory area, is not backed by any kind of actual memory (shared memory or file) I am not a kernel expert, I am just guessing. Please I need help. Sincerely, William Tambe bugme-daemon@bugzilla.kernel.org wrote: > http://bugzilla.kernel.org/show_bug.cgi?id=8691 > > > > > > ------- Comment #2 from akpm@osdl.org 2007-07-01 21:30 ------- > Subject: Re: bus error when trying to access page created by > mremap() > > On Sun, 1 Jul 2007 19:43:25 -0700 (PDT) bugme-daemon@bugzilla.kernel.org > wrote: > >> http://bugzilla.kernel.org/show_bug.cgi?id=8691 >> >> >> >> >> >> ------- Comment #1 from tambewilliam@gmail.com 2007-07-01 19:47 ------- >> Subject: Re: New: bus error when trying to access page created >> by mremap() >> >> I don't mean to press anybody, but please, can somebody help to find a >> work around if there is not immediate solutions. >> >> Sincerely, >> William Tambe >> >> bugme-daemon@bugzilla.kernel.org wrote: >>> http://bugzilla.kernel.org/show_bug.cgi?id=8691 >>> >>> Summary: bus error when trying to access page created by >>> mremap() >>> Product: Memory Management >>> Version: 2.5 >>> KernelVersion: 2.6.21.5 >>> Platform: All >>> OS/Version: Linux >>> Tree: Mainline >>> Status: NEW >>> Severity: blocking >>> Priority: P1 >>> Component: Page Allocator >>> AssignedTo: akpm@osdl.org >>> ReportedBy: tambewilliam@gmail.com >>> >>> >>> Most recent kernel where this bug did not occur: >>> Distribution: >>> Hardware Environment: >>> Software Environment: glibc-2.5 gcc-4.1.2 >>> >>> Problem Description: >>> bus error when trying to access page created by mremap() >>> >>> Steps to reproduce: >>> In the code below, I mmap() a single page of 4096 and simply mremap() the >>> same >>> page to 2*4096 which is 8192. >>> >>> Then when I try to write anywhere after 4096 bytes, in the newly expanded >>> area. >>> I get Bus error. >>> >>> Can somebody please help me? >>> >>> >>> #define _GNU_SOURCE >>> #include <sys/mman.h> >>> #include <unistd.h> >>> >>> #include <stdio.h> >>> >>> main() { >>> void *ptr; >>> if ((ptr=mmap(0, 4096, PROT_READ|PROT_WRITE, >>> MAP_ANONYMOUS|MAP_SHARED|MAP_GROWSDOWN, 0, 0)) == -1) { >>> printf("failed to mmap\n"); >>> return; >>> } >>> >>> if ((ptr=mremap(ptr, 4096, 8192, MREMAP_MAYMOVE)) == -1) { >>> printf("failed to mremap\n"); >>> return; >>> } >>> >>> //why does this failed. I am well in the interval [4096, 8192] >>> *(unsigned int *)(ptr + 4096 + 8)= 10; >>> } >>> >>> > > maybe mremap() failed and your (incorrect) comparison with -1 didn't > detect it. Try using MAP_FAILED as the manpage says. > >
Verified - critical element is that MAP_SHARED is set
Yes, the file in shmemfs is not being grown along with the vm_area_struct. As a result, we fail the check at shmem_fault ( http://lxr.linux.no/linux+v2.6.27/mm/shmem.c#L1441 ) The question I have is, what is right behavior when one grows a shared mapping with mremap? If it is to grow the shmemfs file backing the vm_area_struct, then: How about invoking shmem_file_setup with size=SHMEM_MAX_BYTES or some such when initially creating the file at shmem_zero_setup? ( http://lxr.linux.no/linux+v2.6.27/mm/shmem.c#L2595 ). That way, the file will grow by itself whenever someone mremaps it (and then accesses any address from the new page frames). I would be interested in implementing this fix or any other, if there is something better. Please let me know if the above sounds like a good idea.
Creating the shmem segment with SMEM_MAX_BYTES is not going to work, due to the call to shmem_acct_size in shmem_file_setup. I suspect we will have to teach mremap to resize the shmem segment. Refusing to grow a MAP_ANONYMOUS|MAP_SHARED region through mremap might break applications (I'm not sure that it will, though).
> I suspect we will have to teach mremap to resize the shmem segment. I guess we could do this by checking for a shmem backing file for the vma in do_mremap and then truncating the file to the new size. But then, what if one of the processes sharing the shmem segment shrinks it? Now the other processes will start getting bus errors when they try to access the now-truncated-out part of the the shmem file.
If anyone can tell me what the right behavior is supposed to be, I will be happy to try and write a fix
If we decrease the shmem backing file size and some other process gets a bus error then isnt it a programming error.