Re: page->mapping == NULL recreated without vmware...

From: Petr Vandrovec (VANDROVE@vc.cvut.cz)
Date: Mon Oct 09 2000 - 11:09:14 EST


On 6 Oct 00 at 19:25, Petr Vandrovec wrote:
> Hi,
> month ago I informed here that VMware causes oops on exit.
> After some time, and tons of tweaking I was able to recreate
> it without vmmon... 2.4.0-test9, no special patches, no
> vmware modules loaded...
>
> Machine is dual PIII/450, 256MB RAM, 18GB IDE disk.
>
> Here it is... Adjust MSIZE so that it is almost all of your
> memory, to cause swapping... (0x0E000000 is for mine 256MB).

Hi,
  it looks much worse - no page locking is required - just create
shared mapping, dirty it from someone else, ftruncate() and look how
kernel oopses...

  You do not have to be root, if there is no ulimit on shared memory
for you... Maybe it is severe enough to get listed on 2.4 TODO page?
I received no feedback on this...

  I'd say that vmtruncate does not work at all, but I'm sure that
somebody should notice such problem already... Also note, that
currently all dirtying is done before ftruncate, so it is completely
legal code. It looks like that pagetables of other processes which are
attached to this mapping are not consulted at all... and if they were
dirty, you'll get nice oopses in filemap_write_page - either from
filemap_swap_out, or from filemap_unmap->filemap_sync... (and even
if pages were not marked dirty, it is bug to have lying around
pages which have mapping == NULL, I think)

  Patch for kernel to get text below instead of oopses is still
available at http://platan.vc.cvut.cz/listit (listit without any dot,
yes *.br...).

  Tell me if I should try to cut example down even more...
                                        Best regards,
                                            Petr Vandrovec
                                            vandrove@vc.cvut.cz
                                            
P.S.: And one complaint: If I was dirtying memory with
read(/dev/zero, mma[mmi-1], mml[mmi-1]) (in addition to loop
currently in code), kernel completely STOPPED for up to
40 secs - only console swithching and ping worked, but no schedule() -
- or at least no schedule visible to f.e. TCP inetd/echo, or to mpg123,
or to typing characters on console to bash... As I have 208MB free before
(and after ;-) ) running code below, I do not see any reason for such
strange behavior... It should not take 40 secs to swap out 24MB...

#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/ioctl.h>
#include <sys/raw.h>

unsigned char zero;

#define MSIZE 0x0E000000

void x4768(void) {
    int fd;
    pid_t pid;
    int x4778_1[2];
    int x4778_2[2];
    int x4779_1[2];
    int x4779_2[2];
    int from4778;
    int to4778;
    int from4779;
    int to4779;
    char* mma[65536];
    unsigned int mml[65536];
    unsigned int mmi = 0;
    unsigned int ln = 0;
    unsigned int x;
    
#define MAL2(a,l) ftruncate(fd, ln+l); mml[mmi] = l; mma[mmi++] = mmap(a, l, PROT_READ|PROT_WRITE, MAP_SHARED, fd, ln); ln += l; mma[mmi-1][0] = 99;
#define MAL(l) MAL2(NULL,l)

    fd = open("ram0", O_RDWR | O_CREAT, 0600);
    unlink("ram0");
    MAL(MSIZE);
    pipe(x4778_1);
    pipe(x4778_2);
    pid = fork();
    if (!pid) {
        int from4768 = x4778_1[0];
        int to4768 = x4778_2[1];
        close(x4778_1[1]);
        close(x4778_2[0]);
        close(fd);
        read(from4768, &zero, 1);
        for (x = 0; x < mml[mmi - 1]; x += 4096)
            mma[mmi-1][x] = 98;
        write(to4768, &zero, 1);
        read(from4768, &zero, 1);
#if 0
        printf("1a: %02X\n", mma[mmi-1][0]);
        fflush(stdout);
        mma[mmi-1][0] = 99;
        printf("1b: %02X\n", mma[mmi-1][0]);
#endif
        exit(0);
        
    } else if (pid < 0) {
        perror("fork failed");
        exit(222);
    }
    to4778 = x4778_1[1];
    from4778 = x4778_2[0];
    close(x4778_1[0]);
    close(x4778_2[1]);

#if 0
    pipe(x4779_1);
    pipe(x4779_2);
    pid = fork();
    if (!pid) {
        int from4768 = x4779_1[0];
        int to4768 = x4779_2[1];
        close(x4779_1[1]);
        close(x4779_2[0]);
        close(to4778);
        close(from4778);
        close(fd);
        read(from4768, &zero, 1);
        write(to4768, &zero, 1);
        read(from4768, &zero, 1);
#if 0
        printf("2a: %02X\n", mma[mmi-1][0]);
        fflush(stdout);
        mma[mmi-1][0] = 95;
        printf("2b: %02X\n", mma[mmi-1][0]);
#endif
        exit(0);
        
    } else if (pid < 0) {
        perror("fork failed");
        exit(222);
    }
    to4779 = x4779_1[1];
    from4779 = x4779_2[0];
    close(x4779_1[0]);
    close(x4779_2[1]);
#else
    /* so that read/write to this fails... */
    from4779 = -1;
    to4779 = -1;
#endif
    {
        write(to4778, &zero, 1);
        write(to4779, &zero, 1);
        read(from4778, &zero, 1);
        read(from4779, &zero, 1);

        write(to4778, &zero, 1);
        write(to4779, &zero, 1);
        sleep(5);
        ftruncate(fd, 0);
    }
    close(fd);
    while (mmi--) {
        munmap(mma[mmi], mml[mmi]);
    }
    exit(0);
}

int main(int argc, char* argv[]) {
    printf("Go\n");
    mlockall(MCL_CURRENT);
    
    x4768();
    return 0;
}

part of kernel dump (almost _each_ page listed, these are just last
two...):

page->mapping == NULL
error: -22
ptep: c7a87be8
pteval: 03DEE007
vma: cb631660
  vm_mm: cf502980
  vm_start: 40128000
  vm_end: 4E128000
  vm_next: cb631620
  vm_avl_height: 0
  vm_avl_left: 00000000
  vm_avl_right: 00000000
  vm_next_share: 00000000
  vm_pprev_share: cb631404
  vm_operations_struct: c021dd40
  vm_pgoff: 00000000
  vm_file: c3e8fb00
  vm_raend: 00000000
  vm_private_data: 00000000
address: 422FA000
flags: 00000001
  file: c3e8fb00
    dentry: c1dbbd20
      inode: c3d9c1e0
          num: 848284
          dev: 0x00000302
      path: /usr/src/tst/ram0 (deleted)
    vfsmount: c14b2ac0
    op: c0220760
    count: 5
    flags: 0x00000002
    mode: 0000000003
    pos: 0
    reada: 0
    ramax: 0
    raend: 0
    ralen: 0
    rawin: 0
    owner.pid: 0
    owner.uid: 0
    owner.euid: 0
    owner.signum: 0
    uid: 0
    gid: 0
    error: 0
    version: 210820
    private_data: 00000000
  page: c1107348
    mapping: 00000000
    index: 8658
    nexthash: 00000000
    count: 2
    flags: 0x00000009
    age: 4
    pprevhash: 00000000
    buffers: 00000000
    virtual: c3dee000
    zone: c021e118
pagedump done
page->mapping == NULL
error: -22
ptep: c7a87bec
pteval: 03DED007
vma: cb631660
  vm_mm: cf502980
  vm_start: 40128000
  vm_end: 4E128000
  vm_next: cb631620
  vm_avl_height: 0
  vm_avl_left: 00000000
  vm_avl_right: 00000000
  vm_next_share: 00000000
  vm_pprev_share: cb631404
  vm_operations_struct: c021dd40
  vm_pgoff: 00000000
  vm_file: c3e8fb00
  vm_raend: 00000000
  vm_private_data: 00000000
address: 422FB000
flags: 00000001
  file: c3e8fb00
    dentry: c1dbbd20
      inode: c3d9c1e0
          num: 848284
          dev: 0x00000302
      path: /usr/src/tst/ram0 (deleted)
    vfsmount: c14b2ac0
    op: c0220760
    count: 5
    flags: 0x00000002
    mode: 0000000003
    pos: 0
    reada: 0
    ramax: 0
    raend: 0
    ralen: 0
    rawin: 0
    owner.pid: 0
    owner.uid: 0
    owner.euid: 0
    owner.signum: 0
    uid: 0
    gid: 0
    error: 0
    version: 210820
    private_data: 00000000
  page: c1107304
    mapping: 00000000
    index: 8659
    nexthash: 00000000
    count: 2
    flags: 0x00000009
    age: 4
    pprevhash: 00000000
    buffers: 00000000
    virtual: c3ded000
    zone: c021e118
pagedump done
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sun Oct 15 2000 - 21:00:12 EST