|
Link Here
|
| 792 |
} |
879 |
} |
| 793 |
|
880 |
|
| 794 |
/* |
881 |
/* |
|
|
882 |
* SWP_FIND_CONTINUOUS_REGION() - find a continuous region of swap blocks |
| 883 |
* |
| 884 |
* Given the "start" entry is not SWAPBLK_NONE, it searches a range |
| 885 |
* if SWAPBLK to be up to including "last" element. |
| 886 |
* |
| 887 |
* The return value indicates the number of blocks freed. |
| 888 |
* |
| 889 |
* An example of good case is when swblk holds [2, 3, 4, 5, 6, 7, 8, 9], |
| 890 |
* caller passes (&d[0], and &[7]) as arguments and 8 is returned. |
| 891 |
* |
| 892 |
* Another example is with [NONE, 3, NONE, 11, 12, 13, 4, NONE], |
| 893 |
* caller wants to skip d[0] and passes (&d[1], &d[7]) which |
| 894 |
* returns 1 block. Then, caller skips d[2] and pass (&d[3], &d[7]) which |
| 895 |
* returns 3 blocks as 4 is not a number fater 13 and not continous. |
| 896 |
* Then callers get 1 block back for &d[6] and won't want to call |
| 897 |
* for &d[7] as it is NONE. |
| 898 |
*/ |
| 899 |
static int |
| 900 |
swp_find_continuous_region(const daddr_t *start, const daddr_t *last) |
| 901 |
{ |
| 902 |
const daddr_t *next; |
| 903 |
daddr_t expected; |
| 904 |
|
| 905 |
if (*start == SWAPBLK_NONE) |
| 906 |
return 0; |
| 907 |
|
| 908 |
next = start + 1; |
| 909 |
expected = *start + 1; |
| 910 |
while (next <= last && (expected == *next)) |
| 911 |
{ |
| 912 |
next++; |
| 913 |
expected++; |
| 914 |
} |
| 915 |
return npages = next - start; |
| 916 |
} |
| 917 |
|
| 918 |
/* |
| 795 |
* SYSCTL_SWAP_FRAGMENTATION() - produce raw swap space stats |
919 |
* SYSCTL_SWAP_FRAGMENTATION() - produce raw swap space stats |
| 796 |
*/ |
920 |
*/ |
| 797 |
static int |
921 |
static int |
|
Link Here
|
| 1888 |
static void |
2047 |
static void |
| 1889 |
swp_pager_meta_free(vm_object_t object, vm_pindex_t pindex, vm_pindex_t count) |
2048 |
swp_pager_meta_free(vm_object_t object, vm_pindex_t pindex, vm_pindex_t count) |
| 1890 |
{ |
2049 |
{ |
|
|
2050 |
int offset, npages; |
| 1891 |
struct swblk *sb; |
2051 |
struct swblk *sb; |
| 1892 |
vm_pindex_t last; |
2052 |
vm_pindex_t last; |
| 1893 |
int i; |
2053 |
int i; |
|
Link Here
|
| 1908 |
if (sb->d[i] == SWAPBLK_NONE) |
2072 |
if (sb->d[i] == SWAPBLK_NONE) |
| 1909 |
continue; |
2073 |
continue; |
| 1910 |
if (pindex <= sb->p + i && sb->p + i <= last) { |
2074 |
if (pindex <= sb->p + i && sb->p + i <= last) { |
| 1911 |
swp_pager_freeswapspace(sb->d[i], 1); |
2075 |
offset = last - (sb->p + i); |
|
|
2076 |
if (offset == 0) { |
| 2077 |
npages = 1; |
| 2078 |
} else { |
| 2079 |
offset = min(offset, (SWAP_META_PAGES - 1 - i)); |
| 2080 |
npages = swp_find_continuous_region(&sb->d[i], &sb->d[i + offset]); |
| 2081 |
printf("swp_find_continuous_region:start %lld@d[%d] offset=%d %lld->%d\n", |
| 2082 |
sb->d[i], i, offset, sb->d[i], npages); |
| 2083 |
} |
| 2084 |
swp_pager_freeswapspace(sb->d[i], npages); |
| 2085 |
while( npages-- > 1 ) |
| 2086 |
sb->d[i++] = SWAPBLK_NONE; |
| 1912 |
sb->d[i] = SWAPBLK_NONE; |
2087 |
sb->d[i] = SWAPBLK_NONE; |
| 1913 |
} else |
2088 |
} else |
| 1914 |
empty = false; |
2089 |
empty = false; |
|
Link Here
|
| 1933 |
{ |
2108 |
{ |
| 1934 |
struct swblk *sb; |
2109 |
struct swblk *sb; |
| 1935 |
vm_pindex_t pindex; |
2110 |
vm_pindex_t pindex; |
| 1936 |
int i; |
2111 |
int i, npages; |
| 1937 |
|
2112 |
|
| 1938 |
VM_OBJECT_ASSERT_WLOCKED(object); |
2113 |
VM_OBJECT_ASSERT_WLOCKED(object); |
| 1939 |
if (object->type != OBJT_SWAP) |
2114 |
if (object->type != OBJT_SWAP) |
|
Link Here
|
| 1942 |
for (pindex = 0; (sb = SWAP_PCTRIE_LOOKUP_GE( |
2117 |
for (pindex = 0; (sb = SWAP_PCTRIE_LOOKUP_GE( |
| 1943 |
&object->un_pager.swp.swp_blks, pindex)) != NULL;) { |
2118 |
&object->un_pager.swp.swp_blks, pindex)) != NULL;) { |
| 1944 |
pindex = sb->p + SWAP_META_PAGES; |
2119 |
pindex = sb->p + SWAP_META_PAGES; |
| 1945 |
for (i = 0; i < SWAP_META_PAGES; i++) { |
2120 |
for (i = 0; i < SWAP_META_PAGES;) { |
| 1946 |
if (sb->d[i] != SWAPBLK_NONE) |
2121 |
if (sb->d[i] != SWAPBLK_NONE) { |
| 1947 |
swp_pager_freeswapspace(sb->d[i], 1); |
2122 |
npages = swp_find_continuous_region(&sb->d[i], &sb->d[SWAP_META_PAGES - 1]); |
|
|
2123 |
swp_pager_freeswapspace(sb->d[i], npages); |
| 2124 |
i += npages; |
| 2125 |
} else |
| 2126 |
i++; |
| 2127 |
|
| 1948 |
} |
2128 |
} |
| 1949 |
SWAP_PCTRIE_REMOVE(&object->un_pager.swp.swp_blks, sb->p); |
2129 |
SWAP_PCTRIE_REMOVE(&object->un_pager.swp.swp_blks, sb->p); |
| 1950 |
uma_zfree(swblk_zone, sb); |
2130 |
uma_zfree(swblk_zone, sb); |