From nobody@FreeBSD.org Tue Aug 8 18:31:13 2006 Return-Path: Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id A14CB16A4DE for ; Tue, 8 Aug 2006 18:31:13 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (www.freebsd.org [216.136.204.117]) by mx1.FreeBSD.org (Postfix) with ESMTP id A424343D6D for ; Tue, 8 Aug 2006 18:31:10 +0000 (GMT) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (localhost [127.0.0.1]) by www.freebsd.org (8.13.1/8.13.1) with ESMTP id k78IVASF048519 for ; Tue, 8 Aug 2006 18:31:10 GMT (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.13.1/8.13.1/Submit) id k78IVA1q048517; Tue, 8 Aug 2006 18:31:10 GMT (envelope-from nobody) Message-Id: <200608081831.k78IVA1q048517@www.freebsd.org> Date: Tue, 8 Aug 2006 18:31:10 GMT From: Michael Plass To: freebsd-gnats-submit@FreeBSD.org Subject: [patch] Some failed calls to contigmalloc(9) cause panic X-Send-Pr-Version: www-2.3 >Number: 101668 >Category: kern >Synopsis: [vm] [patch] Some failed calls to contigmalloc(9) cause panic >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: closed >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Tue Aug 08 18:40:14 GMT 2006 >Closed-Date: Tue Sep 05 23:19:24 GMT 2006 >Last-Modified: Tue Sep 05 23:19:24 GMT 2006 >Originator: Michael Plass >Release: 6.1-RELEASE >Organization: >Environment: FreeBSD froghorn 6.1-RELEASE FreeBSD 6.1-RELEASE #0: Sun May 7 04:42:56 UTC 2006 root@opus.cse.buffalo.edu:/usr/obj/usr/src/sys/SMP i386 >Description: When contigmalloc(9) is used to request a contiguous physical memory area, a panic can result. This is most likely to happen in the case of a failed request. >How-To-Repeat: A call to contigmalloc that asks for more physical memory than the machine has will cause this panic. Calls of considerably smaller size can also provoke the problem. >Fix: The bug is in vm_page_alloc_contig; the retry logic allows the start value to go negative, so the test (i == -1) in line 437 is incorrect. The test should be (i < 0): 63 __FBSDID("$FreeBSD: src/sys/vm/vm_contig.c,v 1.43.2.3.2.1 2006/04/25 15:29:50 scottl Exp $"); 390 391 vm_page_t 392 vm_page_alloc_contig(vm_pindex_t npages, vm_paddr_t low, vm_paddr_t high, 393 vm_offset_t alignment, vm_offset_t boundary) 394 { 395 vm_object_t object; 396 vm_offset_t size; 397 vm_paddr_t phys; 398 vm_page_t pga = vm_page_array; 399 int i, pass, pqtype, start; 400 401 size = npages << PAGE_SHIFT; 402 if (size == 0) 403 panic("vm_page_alloc_contig: size must not be 0"); 404 if ((alignment & (alignment - 1)) != 0) 405 panic("vm_page_alloc_contig: alignment must be a power of 2"); 406 if ((boundary & (boundary - 1)) != 0) 407 panic("vm_page_alloc_contig: boundary must be a power of 2"); 408 409 for (pass = 0; pass < 2; pass++) { 410 if (atop(high) < vm_page_array_size) 411 start = atop(high) - npages + 1; 412 else 413 start = vm_page_array_size - npages + 1; 414 vm_page_lock_queues(); 415 retry: 416 start--; 417 /* 418 * Find last page in array that is free, within range, 419 * aligned, and such that the boundary won't be crossed. 420 */ 421 for (i = start; i >= 0; i--) { 422 phys = VM_PAGE_TO_PHYS(&pga[i]); 423 pqtype = pga[i].queue - pga[i].pc; 424 if (pass == 0) { 425 if (pqtype != PQ_FREE && pqtype != PQ_CACHE) 426 continue; 427 } else if (pqtype != PQ_FREE && pqtype != PQ_CACHE && 428 pga[i].queue != PQ_ACTIVE && 429 pga[i].queue != PQ_INACTIVE) 430 continue; 431 if (phys >= low && phys + size <= high && 432 ((phys & (alignment - 1)) == 0) && 433 ((phys ^ (phys + size - 1)) & ~(boundary - 1)) == 0) 434 break; 435 } 436 /* There are no candidates at all. */ ****437 if (i < 0) { 438 vm_page_unlock_queues(); 439 continue; 440 } 441 start = i; Here is a patch against -CURRENT: Index: vm_contig.c =================================================================== RCS file: /home/ncvs/src/sys/vm/vm_contig.c,v retrieving revision 1.51 diff -u -r1.51 vm_contig.c --- vm_contig.c 8 Mar 2006 00:51:00 -0000 1.51 +++ vm_contig.c 8 Aug 2006 18:10:33 -0000 @@ -447,7 +447,7 @@ break; } /* There are no candidates at all. */ - if (i == -1) { + if (i < 0) { vm_page_unlock_queues(); continue; } >Release-Note: >Audit-Trail: State-Changed-From-To: open->patched State-Changed-By: alc State-Changed-When: Sat Aug 26 02:45:40 UTC 2006 State-Changed-Why: Patch applied to HEAD. http://www.freebsd.org/cgi/query-pr.cgi?pr=101668 State-Changed-From-To: patched->closed State-Changed-By: alc State-Changed-When: Tue Sep 5 23:18:20 UTC 2006 State-Changed-Why: Patch applied to RELENG_6. http://www.freebsd.org/cgi/query-pr.cgi?pr=101668 >Unformatted: