vfs_bio.c (38299) | vfs_bio.c (38517) |
---|---|
1/* 2 * Copyright (c) 1994,1997 John S. Dyson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice immediately at the beginning of the file, without modification, 10 * this list of conditions, and the following disclaimer. 11 * 2. Absolutely no warranty of function or purpose is made by the author 12 * John S. Dyson. 13 * | 1/* 2 * Copyright (c) 1994,1997 John S. Dyson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice immediately at the beginning of the file, without modification, 10 * this list of conditions, and the following disclaimer. 11 * 2. Absolutely no warranty of function or purpose is made by the author 12 * John S. Dyson. 13 * |
14 * $Id: vfs_bio.c,v 1.168 1998/08/06 08:33:18 dfr Exp $ | 14 * $Id: vfs_bio.c,v 1.169 1998/08/13 08:09:07 dfr Exp $ |
15 */ 16 17/* 18 * this file contains a new buffer I/O scheme implementing a coherent 19 * VM object and buffer cache scheme. Pains have been taken to make 20 * sure that the performance degradation associated with schemes such 21 * as this is not realized. 22 * --- 620 unchanged lines hidden (view full) --- 643 644 vp = bp->b_vp; 645 646 resid = bp->b_bufsize; 647 foff = bp->b_offset; 648 649 for (i = 0; i < bp->b_npages; i++) { 650 m = bp->b_pages[i]; | 15 */ 16 17/* 18 * this file contains a new buffer I/O scheme implementing a coherent 19 * VM object and buffer cache scheme. Pains have been taken to make 20 * sure that the performance degradation associated with schemes such 21 * as this is not realized. 22 * --- 620 unchanged lines hidden (view full) --- 643 644 vp = bp->b_vp; 645 646 resid = bp->b_bufsize; 647 foff = bp->b_offset; 648 649 for (i = 0; i < bp->b_npages; i++) { 650 m = bp->b_pages[i]; |
651 m->flags &= ~PG_ZERO; | 651 PAGE_CLEAR_FLAG(m, PG_ZERO); |
652 if (m == bogus_page) { 653 654 obj = (vm_object_t) vp->v_object; 655 poff = OFF_TO_IDX(bp->b_offset); 656 657 for (j = i; j < bp->b_npages; j++) { 658 m = bp->b_pages[j]; 659 if (m == bogus_page) { --- 170 unchanged lines hidden (view full) --- 830 vm_page_test_dirty(m); 831 /* 832 * this keeps pressure off of the process memory 833 */ 834 if (m->dirty == 0 && m->hold_count == 0) 835 vm_page_cache(m); 836 else 837 vm_page_deactivate(m); | 652 if (m == bogus_page) { 653 654 obj = (vm_object_t) vp->v_object; 655 poff = OFF_TO_IDX(bp->b_offset); 656 657 for (j = i; j < bp->b_npages; j++) { 658 m = bp->b_pages[j]; 659 if (m == bogus_page) { --- 170 unchanged lines hidden (view full) --- 830 vm_page_test_dirty(m); 831 /* 832 * this keeps pressure off of the process memory 833 */ 834 if (m->dirty == 0 && m->hold_count == 0) 835 vm_page_cache(m); 836 else 837 vm_page_deactivate(m); |
838 m->flags &= ~PG_ZERO; | 838 PAGE_CLEAR_FLAG(m, PG_ZERO); |
839 } else if (m->hold_count == 0) { | 839 } else if (m->hold_count == 0) { |
840 m->flags |= PG_BUSY; | 840 PAGE_SET_FLAG(m, PG_BUSY); |
841 vm_page_protect(m, VM_PROT_NONE); 842 vm_page_free(m); 843 } 844 } else { 845 /* 846 * If async, then at least we clear the 847 * act_count. 848 */ 849 m->act_count = 0; | 841 vm_page_protect(m, VM_PROT_NONE); 842 vm_page_free(m); 843 } 844 } else { 845 /* 846 * If async, then at least we clear the 847 * act_count. 848 */ 849 m->act_count = 0; |
850 m->flags &= ~PG_ZERO; | 850 PAGE_CLEAR_FLAG(m, PG_ZERO); |
851 } 852 } 853 } 854 bufspace -= bp->b_bufsize; 855 vmiospace -= bp->b_bufsize; 856 pmap_qremove(trunc_page((vm_offset_t) bp->b_data), bp->b_npages); 857 bp->b_npages = 0; 858 bp->b_bufsize = 0; --- 493 unchanged lines hidden (view full) --- 1352 */ 1353 if ((bp->b_flags & B_VMIO) && 1354 ((object = bp->b_pages[0]->object)->flags & (OBJ_WRITEABLE|OBJ_CLEANING))) { 1355 /* 1356 * test the pages to see if they have been modified directly 1357 * by users through the VM system. 1358 */ 1359 for (i = 0; i < bp->b_npages; i++) { | 851 } 852 } 853 } 854 bufspace -= bp->b_bufsize; 855 vmiospace -= bp->b_bufsize; 856 pmap_qremove(trunc_page((vm_offset_t) bp->b_data), bp->b_npages); 857 bp->b_npages = 0; 858 bp->b_bufsize = 0; --- 493 unchanged lines hidden (view full) --- 1352 */ 1353 if ((bp->b_flags & B_VMIO) && 1354 ((object = bp->b_pages[0]->object)->flags & (OBJ_WRITEABLE|OBJ_CLEANING))) { 1355 /* 1356 * test the pages to see if they have been modified directly 1357 * by users through the VM system. 1358 */ 1359 for (i = 0; i < bp->b_npages; i++) { |
1360 bp->b_pages[i]->flags &= ~PG_ZERO; | 1360 PAGE_CLEAR_FLAG(bp->b_pages[i], PG_ZERO); |
1361 vm_page_test_dirty(bp->b_pages[i]); 1362 } 1363 1364 /* 1365 * scan forwards for the first page modified 1366 */ 1367 for (i = 0; i < bp->b_npages; i++) { 1368 if (bp->b_pages[i]->dirty) { --- 415 unchanged lines hidden (view full) --- 1784 m = vm_page_alloc(obj, objoff, VM_ALLOC_NORMAL); 1785 if (!m) { 1786 VM_WAIT; 1787 vm_pageout_deficit += (desiredpages - bp->b_npages); 1788 goto doretry; 1789 } 1790 1791 vm_page_wire(m); | 1361 vm_page_test_dirty(bp->b_pages[i]); 1362 } 1363 1364 /* 1365 * scan forwards for the first page modified 1366 */ 1367 for (i = 0; i < bp->b_npages; i++) { 1368 if (bp->b_pages[i]->dirty) { --- 415 unchanged lines hidden (view full) --- 1784 m = vm_page_alloc(obj, objoff, VM_ALLOC_NORMAL); 1785 if (!m) { 1786 VM_WAIT; 1787 vm_pageout_deficit += (desiredpages - bp->b_npages); 1788 goto doretry; 1789 } 1790 1791 vm_page_wire(m); |
1792 m->flags &= ~PG_BUSY; | 1792 PAGE_CLEAR_FLAG(m, PG_BUSY); |
1793 bp->b_flags &= ~B_CACHE; 1794 1795 } else if (m->flags & PG_BUSY) { 1796 s = splvm(); 1797 if (m->flags & PG_BUSY) { | 1793 bp->b_flags &= ~B_CACHE; 1794 1795 } else if (m->flags & PG_BUSY) { 1796 s = splvm(); 1797 if (m->flags & PG_BUSY) { |
1798 m->flags |= PG_WANTED; | 1798 PAGE_SET_FLAG(m, PG_WANTED); |
1799 tsleep(m, PVM, "pgtblk", 0); 1800 } 1801 splx(s); 1802 goto doretry; 1803 } else { 1804 if ((curproc != pageproc) && 1805 ((m->queue - m->pc) == PQ_CACHE) && 1806 ((cnt.v_free_count + cnt.v_cache_count) < 1807 (cnt.v_free_min + cnt.v_cache_min))) { 1808 pagedaemon_wakeup(); 1809 } 1810 bytesinpage = tinc; 1811 if (tinc > (newbsize - toff)) 1812 bytesinpage = newbsize - toff; 1813 if (bp->b_flags & B_CACHE) 1814 vfs_buf_set_valid(bp, off, toff, bytesinpage, m); | 1799 tsleep(m, PVM, "pgtblk", 0); 1800 } 1801 splx(s); 1802 goto doretry; 1803 } else { 1804 if ((curproc != pageproc) && 1805 ((m->queue - m->pc) == PQ_CACHE) && 1806 ((cnt.v_free_count + cnt.v_cache_count) < 1807 (cnt.v_free_min + cnt.v_cache_min))) { 1808 pagedaemon_wakeup(); 1809 } 1810 bytesinpage = tinc; 1811 if (tinc > (newbsize - toff)) 1812 bytesinpage = newbsize - toff; 1813 if (bp->b_flags & B_CACHE) 1814 vfs_buf_set_valid(bp, off, toff, bytesinpage, m); |
1815 m->flags &= ~PG_ZERO; | 1815 PAGE_CLEAR_FLAG(m, PG_ZERO); |
1816 vm_page_wire(m); 1817 } 1818 bp->b_pages[pageindex] = m; 1819 curbpnpages = pageindex + 1; 1820 } 1821 if (vp->v_tag == VT_NFS && 1822 vp->v_type != VBLK) { 1823 if (bp->b_dirtyend > 0) { --- 142 unchanged lines hidden (view full) --- 1966 m = bp->b_pages[i]; 1967 if (m == bogus_page) { 1968 bogusflag = 1; 1969 m = vm_page_lookup(obj, OFF_TO_IDX(foff)); 1970 if (!m) { 1971#if defined(VFS_BIO_DEBUG) 1972 printf("biodone: page disappeared\n"); 1973#endif | 1816 vm_page_wire(m); 1817 } 1818 bp->b_pages[pageindex] = m; 1819 curbpnpages = pageindex + 1; 1820 } 1821 if (vp->v_tag == VT_NFS && 1822 vp->v_type != VBLK) { 1823 if (bp->b_dirtyend > 0) { --- 142 unchanged lines hidden (view full) --- 1966 m = bp->b_pages[i]; 1967 if (m == bogus_page) { 1968 bogusflag = 1; 1969 m = vm_page_lookup(obj, OFF_TO_IDX(foff)); 1970 if (!m) { 1971#if defined(VFS_BIO_DEBUG) 1972 printf("biodone: page disappeared\n"); 1973#endif |
1974 --obj->paging_in_progress; | 1974 vm_object_pip_subtract(obj, 1); |
1975 continue; 1976 } 1977 bp->b_pages[i] = m; 1978 pmap_qenter(trunc_page(bp->b_data), bp->b_pages, bp->b_npages); 1979 } 1980#if defined(VFS_BIO_DEBUG) 1981 if (OFF_TO_IDX(foff) != m->pindex) { 1982 printf("biodone: foff(%d)/m->pindex(%d) mismatch\n", foff, m->pindex); --- 6 unchanged lines hidden (view full) --- 1989 /* 1990 * In the write case, the valid and clean bits are 1991 * already changed correctly, so we only need to do this 1992 * here in the read case. 1993 */ 1994 if ((bp->b_flags & B_READ) && !bogusflag && resid > 0) { 1995 vfs_page_set_valid(bp, foff, i, m); 1996 } | 1975 continue; 1976 } 1977 bp->b_pages[i] = m; 1978 pmap_qenter(trunc_page(bp->b_data), bp->b_pages, bp->b_npages); 1979 } 1980#if defined(VFS_BIO_DEBUG) 1981 if (OFF_TO_IDX(foff) != m->pindex) { 1982 printf("biodone: foff(%d)/m->pindex(%d) mismatch\n", foff, m->pindex); --- 6 unchanged lines hidden (view full) --- 1989 /* 1990 * In the write case, the valid and clean bits are 1991 * already changed correctly, so we only need to do this 1992 * here in the read case. 1993 */ 1994 if ((bp->b_flags & B_READ) && !bogusflag && resid > 0) { 1995 vfs_page_set_valid(bp, foff, i, m); 1996 } |
1997 m->flags &= ~PG_ZERO; | 1997 PAGE_CLEAR_FLAG(m, PG_ZERO); |
1998 1999 /* 2000 * when debugging new filesystems or buffer I/O methods, this 2001 * is the most common error that pops up. if you see this, you 2002 * have not set the page busy flag correctly!!! 2003 */ 2004 if (m->busy == 0) { 2005#if !defined(MAX_PERF) --- 14 unchanged lines hidden (view full) --- 2020 (int) bp->b_lblkno, 2021 bp->b_flags, bp->b_npages); 2022 printf(" valid: 0x%x, dirty: 0x%x, wired: %d\n", 2023 m->valid, m->dirty, m->wire_count); 2024#endif 2025 panic("biodone: page busy < 0\n"); 2026 } 2027 PAGE_BWAKEUP(m); | 1998 1999 /* 2000 * when debugging new filesystems or buffer I/O methods, this 2001 * is the most common error that pops up. if you see this, you 2002 * have not set the page busy flag correctly!!! 2003 */ 2004 if (m->busy == 0) { 2005#if !defined(MAX_PERF) --- 14 unchanged lines hidden (view full) --- 2020 (int) bp->b_lblkno, 2021 bp->b_flags, bp->b_npages); 2022 printf(" valid: 0x%x, dirty: 0x%x, wired: %d\n", 2023 m->valid, m->dirty, m->wire_count); 2024#endif 2025 panic("biodone: page busy < 0\n"); 2026 } 2027 PAGE_BWAKEUP(m); |
2028 --obj->paging_in_progress; | 2028 vm_object_pip_subtract(obj, 1); |
2029 foff += resid; 2030 iosize -= resid; 2031 } 2032 if (obj && 2033 (obj->paging_in_progress == 0) && 2034 (obj->flags & OBJ_PIPWNT)) { | 2029 foff += resid; 2030 iosize -= resid; 2031 } 2032 if (obj && 2033 (obj->paging_in_progress == 0) && 2034 (obj->flags & OBJ_PIPWNT)) { |
2035 obj->flags &= ~OBJ_PIPWNT; | 2035 vm_object_clear_flag(obj, OBJ_PIPWNT); |
2036 wakeup(obj); 2037 } 2038 } 2039 /* 2040 * For asynchronous completions, release the buffer now. The brelse 2041 * checks for B_WANTED and will do the wakeup there if necessary - so 2042 * no need to do a wakeup here in the async case. 2043 */ --- 76 unchanged lines hidden (view full) --- 2120#if !defined(MAX_PERF) 2121 if (!m) { 2122 panic("vfs_unbusy_pages: page missing\n"); 2123 } 2124#endif 2125 bp->b_pages[i] = m; 2126 pmap_qenter(trunc_page(bp->b_data), bp->b_pages, bp->b_npages); 2127 } | 2036 wakeup(obj); 2037 } 2038 } 2039 /* 2040 * For asynchronous completions, release the buffer now. The brelse 2041 * checks for B_WANTED and will do the wakeup there if necessary - so 2042 * no need to do a wakeup here in the async case. 2043 */ --- 76 unchanged lines hidden (view full) --- 2120#if !defined(MAX_PERF) 2121 if (!m) { 2122 panic("vfs_unbusy_pages: page missing\n"); 2123 } 2124#endif 2125 bp->b_pages[i] = m; 2126 pmap_qenter(trunc_page(bp->b_data), bp->b_pages, bp->b_npages); 2127 } |
2128 s = splvm(); 2129 --obj->paging_in_progress; 2130 splx(s); 2131 m->flags &= ~PG_ZERO; | 2128 vm_object_pip_subtract(obj, 1); 2129 PAGE_CLEAR_FLAG(m, PG_ZERO); |
2132 PAGE_BWAKEUP(m); 2133 } 2134 if (obj->paging_in_progress == 0 && 2135 (obj->flags & OBJ_PIPWNT)) { | 2130 PAGE_BWAKEUP(m); 2131 } 2132 if (obj->paging_in_progress == 0 && 2133 (obj->flags & OBJ_PIPWNT)) { |
2136 obj->flags &= ~OBJ_PIPWNT; | 2134 vm_object_clear_flag(obj, OBJ_PIPWNT); |
2137 wakeup(obj); 2138 } 2139 } 2140} 2141 2142/* 2143 * Set NFS' b_validoff and b_validend fields from the valid bits 2144 * of a page. If the consumer is not NFS, and the page is not --- 100 unchanged lines hidden (view full) --- 2245 vm_page_t m = bp->b_pages[i]; 2246 if (vm_page_sleep(m, "vbpage", NULL)) 2247 goto retry; 2248 } 2249 2250 for (i = 0; i < bp->b_npages; i++, foff += PAGE_SIZE) { 2251 vm_page_t m = bp->b_pages[i]; 2252 | 2135 wakeup(obj); 2136 } 2137 } 2138} 2139 2140/* 2141 * Set NFS' b_validoff and b_validend fields from the valid bits 2142 * of a page. If the consumer is not NFS, and the page is not --- 100 unchanged lines hidden (view full) --- 2243 vm_page_t m = bp->b_pages[i]; 2244 if (vm_page_sleep(m, "vbpage", NULL)) 2245 goto retry; 2246 } 2247 2248 for (i = 0; i < bp->b_npages; i++, foff += PAGE_SIZE) { 2249 vm_page_t m = bp->b_pages[i]; 2250 |
2253 m->flags &= ~PG_ZERO; | 2251 PAGE_CLEAR_FLAG(m, PG_ZERO); |
2254 if ((bp->b_flags & B_CLUSTER) == 0) { | 2252 if ((bp->b_flags & B_CLUSTER) == 0) { |
2255 s = splvm(); 2256 obj->paging_in_progress++; 2257 splx(s); 2258 m->busy++; | 2253 vm_object_pip_add(obj, 1); 2254 PAGE_BUSY(m); |
2259 } 2260 2261 vm_page_protect(m, VM_PROT_NONE); 2262 if (clear_modify) 2263 vfs_page_set_valid(bp, foff, i, m); 2264 else if (bp->b_bcount >= PAGE_SIZE) { 2265 if (m->valid && (bp->b_flags & B_CACHE) == 0) { 2266 bp->b_pages[i] = bogus_page; --- 59 unchanged lines hidden (view full) --- 2326 int j; 2327 for(j=0;j<PAGE_SIZE/DEV_BSIZE;j++) { 2328 if (((bp->b_pages[i]->flags & PG_ZERO) == 0) && 2329 (bp->b_pages[i]->valid & (1<<j)) == 0) 2330 bzero(bp->b_data + (i << PAGE_SHIFT) + j * DEV_BSIZE, DEV_BSIZE); 2331 } 2332 } 2333 bp->b_pages[i]->valid = VM_PAGE_BITS_ALL; | 2255 } 2256 2257 vm_page_protect(m, VM_PROT_NONE); 2258 if (clear_modify) 2259 vfs_page_set_valid(bp, foff, i, m); 2260 else if (bp->b_bcount >= PAGE_SIZE) { 2261 if (m->valid && (bp->b_flags & B_CACHE) == 0) { 2262 bp->b_pages[i] = bogus_page; --- 59 unchanged lines hidden (view full) --- 2322 int j; 2323 for(j=0;j<PAGE_SIZE/DEV_BSIZE;j++) { 2324 if (((bp->b_pages[i]->flags & PG_ZERO) == 0) && 2325 (bp->b_pages[i]->valid & (1<<j)) == 0) 2326 bzero(bp->b_data + (i << PAGE_SHIFT) + j * DEV_BSIZE, DEV_BSIZE); 2327 } 2328 } 2329 bp->b_pages[i]->valid = VM_PAGE_BITS_ALL; |
2334 bp->b_pages[i]->flags &= ~PG_ZERO; | 2330 PAGE_CLEAR_FLAG(bp->b_pages[i], PG_ZERO); |
2335 } 2336 bp->b_resid = 0; 2337 } else { 2338 clrbuf(bp); 2339 } 2340} 2341 2342/* --- 21 unchanged lines hidden (view full) --- 2364 VM_ALLOC_NORMAL); 2365 if (!p) { 2366 vm_pageout_deficit += (to - from) >> PAGE_SHIFT; 2367 VM_WAIT; 2368 goto tryagain; 2369 } 2370 vm_page_wire(p); 2371 p->valid = VM_PAGE_BITS_ALL; | 2331 } 2332 bp->b_resid = 0; 2333 } else { 2334 clrbuf(bp); 2335 } 2336} 2337 2338/* --- 21 unchanged lines hidden (view full) --- 2360 VM_ALLOC_NORMAL); 2361 if (!p) { 2362 vm_pageout_deficit += (to - from) >> PAGE_SHIFT; 2363 VM_WAIT; 2364 goto tryagain; 2365 } 2366 vm_page_wire(p); 2367 p->valid = VM_PAGE_BITS_ALL; |
2372 p->flags &= ~PG_ZERO; | 2368 PAGE_CLEAR_FLAG(p, PG_ZERO); |
2373 pmap_kenter(pg, VM_PAGE_TO_PHYS(p)); 2374 bp->b_pages[index] = p; 2375 PAGE_WAKEUP(p); 2376 } 2377 bp->b_npages = index; 2378} 2379 2380void --- 13 unchanged lines hidden (view full) --- 2394#if !defined(MAX_PERF) 2395 if (p->busy) { 2396 printf("vm_hold_free_pages: blkno: %d, lblkno: %d\n", 2397 bp->b_blkno, bp->b_lblkno); 2398 } 2399#endif 2400 bp->b_pages[index] = NULL; 2401 pmap_kremove(pg); | 2369 pmap_kenter(pg, VM_PAGE_TO_PHYS(p)); 2370 bp->b_pages[index] = p; 2371 PAGE_WAKEUP(p); 2372 } 2373 bp->b_npages = index; 2374} 2375 2376void --- 13 unchanged lines hidden (view full) --- 2390#if !defined(MAX_PERF) 2391 if (p->busy) { 2392 printf("vm_hold_free_pages: blkno: %d, lblkno: %d\n", 2393 bp->b_blkno, bp->b_lblkno); 2394 } 2395#endif 2396 bp->b_pages[index] = NULL; 2397 pmap_kremove(pg); |
2402 p->flags |= PG_BUSY; | 2398 PAGE_SET_FLAG(p, PG_BUSY); |
2403 vm_page_unwire(p); 2404 vm_page_free(p); 2405 } 2406 } 2407 bp->b_npages = newnpages; 2408} 2409 2410 --- 41 unchanged lines hidden --- | 2399 vm_page_unwire(p); 2400 vm_page_free(p); 2401 } 2402 } 2403 bp->b_npages = newnpages; 2404} 2405 2406 --- 41 unchanged lines hidden --- |