Date: Fri, 29 Mar 2002 11:57:42 -0800 (PST) From: "Dorr H. Clark" <dclark@applmath.scu.edu> To: freebsd-gnats-submit@FreeBSD.org Subject: kern/36504: crash/panic vm_object_allocate under file system code w/fix Message-ID: <200203291957.g2TJvg114596@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 36504 >Category: kern >Synopsis: crash/panic vm_object_allocate under file system code w/fix >Confidential: no >Severity: critical >Priority: high >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Fri Mar 29 12:00:10 PST 2002 >Closed-Date: >Last-Modified: >Originator: Dorr H. Clark >Release: 4.4 >Organization: Santa Clara University >Environment: FreeBSD 4.4 on i386, also 4.5 & current have same issue >Description: The problem is that unlike other parts of the kernel, vnode_pager_alloc assumes that the call to vm_object_allocate will succeed. If the allocation fails, the kernel crashes immediately. I have put in a defensive check for this, and also changed the error handling in the calling routine to account for the allocation failure. >How-To-Repeat: hard to do - it's intermittent under heavy load w/almost no memory >Fix: My fix touches two files, vm/vnode_pager.c and kern/vfs_default.c, I chose to minimize code changes but I think vfs_default.c could be favorably restructured a little in this area. Sorry for the grody diff but I'm on HPUX here. First file change vm/vnode_pager.c: *** 143,149 **** * And an object of the appropriate size */ object = vm_object_allocate(OBJT_VNODE, OFF_TO_IDX(round_page(s ize))); + if (object) { object->flags = 0; object->un_pager.vnp.vnp_size = size; --- 143,148 ---- *************** *** 151,157 **** object->handle = handle; vp->v_object = object; vp->v_usecount++; + } } else { object->ref_count++; vp->v_usecount++; --- 150,155 ---- Second file change kern/vfs_default.c: *************** *** 516,524 **** retry: if ((object = vp->v_object) == NULL) { if (vp->v_type == VREG || vp->v_type == VDIR) { ! if (((error = VOP_GETATTR(vp, &vat, cred, p)) != 0) || ! (!(object = vnode_pager_alloc(vp, vat.va_size, 0, 0)))) goto retn; } else if (devsw(vp->v_rdev) != NULL) { /* * This simply allocates the biggest object possible --- 518,526 ---- retry: if ((object = vp->v_object) == NULL) { if (vp->v_type == VREG || vp->v_type == VDIR) { ! if ((error = VOP_GETATTR(vp, &vat, cred, p)) != 0) goto retn; + object = vnode_pager_alloc(vp, vat.va_size, 0, 0); } else if (devsw(vp->v_rdev) != NULL) { /* * This simply allocates the biggest object possible *************** *** 525,532 **** * for a disk vnode. This should be fixed, but doesn't * cause any problems (yet). */ ! if (!(object = vnode_pager_alloc(vp, IDX_TO_OFF(INT_MAX ), 0, 0))) ! goto retn; } else { goto retn; } --- 527,533 ---- * for a disk vnode. This should be fixed, but doesn 't * cause any problems (yet). */ ! object = vnode_pager_alloc(vp, IDX_TO_OFF(INT_MAX), 0 , 0); } else { goto retn; } *************** >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200203291957.g2TJvg114596>