It seems to be a problem in vm/vm_fault() and 
vnode_pager_generic_putpages() in FreeBSD 3.x & 4.0.

The following code illustrates the problem:

#include <sys/types.h>
#include <sys/mman.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>

#define COUNT   1024
#define SIZE    10*1024*1024

int main () {
    int i,j,fd;
    char *fptr, fname [16];
    
    for (i=0;i<COUNT;i++) {
        sprintf (fname, "%d", i);
        printf ("DEBUG: fname: %s\n", fname);
        
        fd=open (fname, O_RDWR|O_CREAT, 644);
        lseek (fd, SIZE, SEEK_SET);
        write (fd, "-", 1);
        
        if ((fptr=mmap (NULL, SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 
0))==MAP_FAILED) {
            printf ("mmap() failed !\n");
            return 0;
        }
        
        for (j=0;j<SIZE;j++)
            fptr[j]='o';
    }
    
    return 0;
}

So, if we haven't required disk space on partition with mmap'ed files,
system deadlock in vm_fault() appears.

This is part of vnode_pager.c/vnode_pager_generic_putpages() :

        aiov.iov_base = (caddr_t) 0;
        aiov.iov_len = maxsize;
        auio.uio_iov = &aiov;
        auio.uio_iovcnt = 1;
        auio.uio_offset = poffset;
        auio.uio_segflg = UIO_NOCOPY;
        auio.uio_rw = UIO_WRITE;
        auio.uio_resid = maxsize;
        auio.uio_procp = (struct proc *) 0;
        error = VOP_WRITE(vp, &auio, ioflags, curproc->p_ucred);
        cnt.v_vnodeout++;
        cnt.v_vnodepgsout += ncount;

        if (error) {
                printf("vnode_pager_putpages: I/O error %d\n", error);
        }
        if (auio.uio_resid) {
                printf("vnode_pager_putpages: residual I/O %d at %lu\n",
                    auio.uio_resid, (u_long)m[0]->pindex);
        }
        for (i = 0; i < ncount; i++) {
                rtvals[i] = VM_PAGER_OK;                /* ???? */
        }
        return rtvals[0];                               /* ???? */

So, such errors as I/O errors, are not handled there.

This seems to be a serious problem in FreeBSD VM subsystem, isn't it ?



To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message

Reply via email to