Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 03f80da

Browse filesBrowse files
committed
Re-bin segment when memory pages are freed.
It's OK to be lazy about re-binning memory segments when allocating, because that can only leave segments in a bin that's too high. We'll search higher bins if necessary while allocating next time, and also eventually re-bin, so no memory can become unreachable that way. However, when freeing memory, the largest contiguous range of free pages might go up, so we should re-bin eagerly to make sure we don't leave the segment in a bin that is too low for get_best_segment() to find. The re-binning code is moved into a function of its own, so it can be called whenever free pages are returned to the segment's free page map. Back-patch to all supported releases. Author: Dongming Liu <ldming101@gmail.com> Reviewed-by: Robert Haas <robertmhaas@gmail.com> (earlier version) Reviewed-by: Thomas Munro <thomas.munro@gmail.com> Discussion: https://postgr.es/m/CAL1p7e8LzB2LSeAXo2pXCW4%2BRya9s0sJ3G_ReKOU%3DAjSUWjHWQ%40mail.gmail.com
1 parent a8c09da commit 03f80da
Copy full SHA for 03f80da

File tree

1 file changed

+43
-22
lines changed
Filter options
  • src/backend/utils/mmgr

1 file changed

+43
-22
lines changed

‎src/backend/utils/mmgr/dsa.c

Copy file name to clipboardExpand all lines: src/backend/utils/mmgr/dsa.c
+43-22Lines changed: 43 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,7 @@ static dsa_area *attach_internal(void *place, dsm_segment *segment,
418418
dsa_handle handle);
419419
static void check_for_freed_segments(dsa_area *area);
420420
static void check_for_freed_segments_locked(dsa_area *area);
421+
static void rebin_segment(dsa_area *area, dsa_segment_map *segment_map);
421422

422423
/*
423424
* Create a new shared area in a new DSM segment. Further DSM segments will
@@ -869,7 +870,11 @@ dsa_free(dsa_area *area, dsa_pointer dp)
869870
FreePageManagerPut(segment_map->fpm,
870871
DSA_EXTRACT_OFFSET(span->start) / FPM_PAGE_SIZE,
871872
span->npages);
873+
874+
/* Move segment to appropriate bin if necessary. */
875+
rebin_segment(area, segment_map);
872876
LWLockRelease(DSA_AREA_LOCK(area));
877+
873878
/* Unlink span. */
874879
LWLockAcquire(DSA_SCLASS_LOCK(area, DSA_SCLASS_SPAN_LARGE),
875880
LW_EXCLUSIVE);
@@ -1858,6 +1863,11 @@ destroy_superblock(dsa_area *area, dsa_pointer span_pointer)
18581863
segment_map->mapped_address = NULL;
18591864
}
18601865
}
1866+
1867+
/* Move segment to appropriate bin if necessary. */
1868+
if (segment_map->header != NULL)
1869+
rebin_segment(area, segment_map);
1870+
18611871
LWLockRelease(DSA_AREA_LOCK(area));
18621872

18631873
/*
@@ -2021,28 +2031,7 @@ get_best_segment(dsa_area *area, size_t npages)
20212031
/* Re-bin it if it's no longer in the appropriate bin. */
20222032
if (contiguous_pages < threshold)
20232033
{
2024-
size_t new_bin;
2025-
2026-
new_bin = contiguous_pages_to_segment_bin(contiguous_pages);
2027-
2028-
/* Remove it from its current bin. */
2029-
unlink_segment(area, segment_map);
2030-
2031-
/* Push it onto the front of its new bin. */
2032-
segment_map->header->prev = DSA_SEGMENT_INDEX_NONE;
2033-
segment_map->header->next =
2034-
area->control->segment_bins[new_bin];
2035-
segment_map->header->bin = new_bin;
2036-
area->control->segment_bins[new_bin] = segment_index;
2037-
if (segment_map->header->next != DSA_SEGMENT_INDEX_NONE)
2038-
{
2039-
dsa_segment_map *next;
2040-
2041-
next = get_segment_by_index(area,
2042-
segment_map->header->next);
2043-
Assert(next->header->bin == new_bin);
2044-
next->header->prev = segment_index;
2045-
}
2034+
rebin_segment(area, segment_map);
20462035

20472036
/*
20482037
* But fall through to see if it's enough to satisfy this
@@ -2297,3 +2286,35 @@ check_for_freed_segments_locked(dsa_area *area)
22972286
area->freed_segment_counter = freed_segment_counter;
22982287
}
22992288
}
2289+
2290+
/*
2291+
* Re-bin segment if it's no longer in the appropriate bin.
2292+
*/
2293+
static void
2294+
rebin_segment(dsa_area *area, dsa_segment_map *segment_map)
2295+
{
2296+
size_t new_bin;
2297+
dsa_segment_index segment_index;
2298+
2299+
new_bin = contiguous_pages_to_segment_bin(fpm_largest(segment_map->fpm));
2300+
if (segment_map->header->bin == new_bin)
2301+
return;
2302+
2303+
/* Remove it from its current bin. */
2304+
unlink_segment(area, segment_map);
2305+
2306+
/* Push it onto the front of its new bin. */
2307+
segment_index = get_segment_index(area, segment_map);
2308+
segment_map->header->prev = DSA_SEGMENT_INDEX_NONE;
2309+
segment_map->header->next = area->control->segment_bins[new_bin];
2310+
segment_map->header->bin = new_bin;
2311+
area->control->segment_bins[new_bin] = segment_index;
2312+
if (segment_map->header->next != DSA_SEGMENT_INDEX_NONE)
2313+
{
2314+
dsa_segment_map *next;
2315+
2316+
next = get_segment_by_index(area, segment_map->header->next);
2317+
Assert(next->header->bin == new_bin);
2318+
next->header->prev = segment_index;
2319+
}
2320+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.