提交 4b7b805c 编写于 作者: I iveresov

6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.

Summary: Don't move tops of the chunks in ensure_parsibility(). Handle the situation with Solaris when a machine has a locality group with no memory.
Reviewed-by: apetrusenko, jcoomes, ysr
上级 9d3cf533
...@@ -122,6 +122,13 @@ struct memcntl_mha { ...@@ -122,6 +122,13 @@ struct memcntl_mha {
# define MADV_ACCESS_MANY 8 /* many processes to access heavily */ # define MADV_ACCESS_MANY 8 /* many processes to access heavily */
#endif #endif
#ifndef LGRP_RSRC_CPU
# define LGRP_RSRC_CPU 0 /* CPU resources */
#endif
#ifndef LGRP_RSRC_MEM
# define LGRP_RSRC_MEM 1 /* memory resources */
#endif
// Some more macros from sys/mman.h that are not present in Solaris 8. // Some more macros from sys/mman.h that are not present in Solaris 8.
#ifndef MAX_MEMINFO_CNT #ifndef MAX_MEMINFO_CNT
...@@ -2640,9 +2647,14 @@ size_t os::numa_get_leaf_groups(int *ids, size_t size) { ...@@ -2640,9 +2647,14 @@ size_t os::numa_get_leaf_groups(int *ids, size_t size) {
return 1; return 1;
} }
if (!r) { if (!r) {
// That's a leaf node.
assert (bottom <= cur, "Sanity check"); assert (bottom <= cur, "Sanity check");
// Check if the node has memory
if (Solaris::lgrp_resources(Solaris::lgrp_cookie(), ids[cur],
NULL, 0, LGRP_RSRC_MEM) > 0) {
ids[bottom++] = ids[cur]; ids[bottom++] = ids[cur];
} }
}
top += r; top += r;
cur++; cur++;
} }
...@@ -2664,11 +2676,20 @@ bool os::numa_topology_changed() { ...@@ -2664,11 +2676,20 @@ bool os::numa_topology_changed() {
// Get the group id of the current LWP. // Get the group id of the current LWP.
int os::numa_get_group_id() { int os::numa_get_group_id() {
int lgrp_id = os::Solaris::lgrp_home(P_LWPID, P_MYID); int lgrp_id = Solaris::lgrp_home(P_LWPID, P_MYID);
if (lgrp_id == -1) { if (lgrp_id == -1) {
return 0; return 0;
} }
return lgrp_id; const int size = os::numa_get_groups_num();
int *ids = (int*)alloca(size * sizeof(int));
// Get the ids of all lgroups with memory; r is the count.
int r = Solaris::lgrp_resources(Solaris::lgrp_cookie(), lgrp_id,
(Solaris::lgrp_id_t*)ids, size, LGRP_RSRC_MEM);
if (r <= 0) {
return 0;
}
return ids[os::random() % r];
} }
// Request information about the page. // Request information about the page.
...@@ -4353,6 +4374,7 @@ os::Solaris::lgrp_init_func_t os::Solaris::_lgrp_init; ...@@ -4353,6 +4374,7 @@ os::Solaris::lgrp_init_func_t os::Solaris::_lgrp_init;
os::Solaris::lgrp_fini_func_t os::Solaris::_lgrp_fini; os::Solaris::lgrp_fini_func_t os::Solaris::_lgrp_fini;
os::Solaris::lgrp_root_func_t os::Solaris::_lgrp_root; os::Solaris::lgrp_root_func_t os::Solaris::_lgrp_root;
os::Solaris::lgrp_children_func_t os::Solaris::_lgrp_children; os::Solaris::lgrp_children_func_t os::Solaris::_lgrp_children;
os::Solaris::lgrp_resources_func_t os::Solaris::_lgrp_resources;
os::Solaris::lgrp_nlgrps_func_t os::Solaris::_lgrp_nlgrps; os::Solaris::lgrp_nlgrps_func_t os::Solaris::_lgrp_nlgrps;
os::Solaris::lgrp_cookie_stale_func_t os::Solaris::_lgrp_cookie_stale; os::Solaris::lgrp_cookie_stale_func_t os::Solaris::_lgrp_cookie_stale;
os::Solaris::lgrp_cookie_t os::Solaris::_lgrp_cookie = 0; os::Solaris::lgrp_cookie_t os::Solaris::_lgrp_cookie = 0;
...@@ -4555,6 +4577,7 @@ void os::Solaris::liblgrp_init() { ...@@ -4555,6 +4577,7 @@ void os::Solaris::liblgrp_init() {
os::Solaris::set_lgrp_fini(CAST_TO_FN_PTR(lgrp_fini_func_t, dlsym(handle, "lgrp_fini"))); os::Solaris::set_lgrp_fini(CAST_TO_FN_PTR(lgrp_fini_func_t, dlsym(handle, "lgrp_fini")));
os::Solaris::set_lgrp_root(CAST_TO_FN_PTR(lgrp_root_func_t, dlsym(handle, "lgrp_root"))); os::Solaris::set_lgrp_root(CAST_TO_FN_PTR(lgrp_root_func_t, dlsym(handle, "lgrp_root")));
os::Solaris::set_lgrp_children(CAST_TO_FN_PTR(lgrp_children_func_t, dlsym(handle, "lgrp_children"))); os::Solaris::set_lgrp_children(CAST_TO_FN_PTR(lgrp_children_func_t, dlsym(handle, "lgrp_children")));
os::Solaris::set_lgrp_resources(CAST_TO_FN_PTR(lgrp_resources_func_t, dlsym(handle, "lgrp_resources")));
os::Solaris::set_lgrp_nlgrps(CAST_TO_FN_PTR(lgrp_nlgrps_func_t, dlsym(handle, "lgrp_nlgrps"))); os::Solaris::set_lgrp_nlgrps(CAST_TO_FN_PTR(lgrp_nlgrps_func_t, dlsym(handle, "lgrp_nlgrps")));
os::Solaris::set_lgrp_cookie_stale(CAST_TO_FN_PTR(lgrp_cookie_stale_func_t, os::Solaris::set_lgrp_cookie_stale(CAST_TO_FN_PTR(lgrp_cookie_stale_func_t,
dlsym(handle, "lgrp_cookie_stale"))); dlsym(handle, "lgrp_cookie_stale")));
......
...@@ -66,6 +66,7 @@ class Solaris { ...@@ -66,6 +66,7 @@ class Solaris {
typedef uintptr_t lgrp_cookie_t; typedef uintptr_t lgrp_cookie_t;
typedef id_t lgrp_id_t; typedef id_t lgrp_id_t;
typedef int lgrp_rsrc_t;
typedef enum lgrp_view { typedef enum lgrp_view {
LGRP_VIEW_CALLER, /* what's available to the caller */ LGRP_VIEW_CALLER, /* what's available to the caller */
LGRP_VIEW_OS /* what's available to operating system */ LGRP_VIEW_OS /* what's available to operating system */
...@@ -77,6 +78,9 @@ class Solaris { ...@@ -77,6 +78,9 @@ class Solaris {
typedef lgrp_id_t (*lgrp_root_func_t)(lgrp_cookie_t cookie); typedef lgrp_id_t (*lgrp_root_func_t)(lgrp_cookie_t cookie);
typedef int (*lgrp_children_func_t)(lgrp_cookie_t cookie, lgrp_id_t parent, typedef int (*lgrp_children_func_t)(lgrp_cookie_t cookie, lgrp_id_t parent,
lgrp_id_t *lgrp_array, uint_t lgrp_array_size); lgrp_id_t *lgrp_array, uint_t lgrp_array_size);
typedef int (*lgrp_resources_func_t)(lgrp_cookie_t cookie, lgrp_id_t lgrp,
lgrp_id_t *lgrp_array, uint_t lgrp_array_size,
lgrp_rsrc_t type);
typedef int (*lgrp_nlgrps_func_t)(lgrp_cookie_t cookie); typedef int (*lgrp_nlgrps_func_t)(lgrp_cookie_t cookie);
typedef int (*lgrp_cookie_stale_func_t)(lgrp_cookie_t cookie); typedef int (*lgrp_cookie_stale_func_t)(lgrp_cookie_t cookie);
typedef int (*meminfo_func_t)(const uint64_t inaddr[], int addr_count, typedef int (*meminfo_func_t)(const uint64_t inaddr[], int addr_count,
...@@ -88,6 +92,7 @@ class Solaris { ...@@ -88,6 +92,7 @@ class Solaris {
static lgrp_fini_func_t _lgrp_fini; static lgrp_fini_func_t _lgrp_fini;
static lgrp_root_func_t _lgrp_root; static lgrp_root_func_t _lgrp_root;
static lgrp_children_func_t _lgrp_children; static lgrp_children_func_t _lgrp_children;
static lgrp_resources_func_t _lgrp_resources;
static lgrp_nlgrps_func_t _lgrp_nlgrps; static lgrp_nlgrps_func_t _lgrp_nlgrps;
static lgrp_cookie_stale_func_t _lgrp_cookie_stale; static lgrp_cookie_stale_func_t _lgrp_cookie_stale;
static lgrp_cookie_t _lgrp_cookie; static lgrp_cookie_t _lgrp_cookie;
...@@ -109,7 +114,6 @@ class Solaris { ...@@ -109,7 +114,6 @@ class Solaris {
static int (*get_libjsig_version)(); static int (*get_libjsig_version)();
static void save_preinstalled_handler(int, struct sigaction&); static void save_preinstalled_handler(int, struct sigaction&);
static void check_signal_handler(int sig); static void check_signal_handler(int sig);
// For overridable signals // For overridable signals
static int _SIGinterrupt; // user-overridable INTERRUPT_SIGNAL static int _SIGinterrupt; // user-overridable INTERRUPT_SIGNAL
static int _SIGasync; // user-overridable ASYNC_SIGNAL static int _SIGasync; // user-overridable ASYNC_SIGNAL
...@@ -254,6 +258,7 @@ class Solaris { ...@@ -254,6 +258,7 @@ class Solaris {
static void set_lgrp_fini(lgrp_fini_func_t func) { _lgrp_fini = func; } static void set_lgrp_fini(lgrp_fini_func_t func) { _lgrp_fini = func; }
static void set_lgrp_root(lgrp_root_func_t func) { _lgrp_root = func; } static void set_lgrp_root(lgrp_root_func_t func) { _lgrp_root = func; }
static void set_lgrp_children(lgrp_children_func_t func) { _lgrp_children = func; } static void set_lgrp_children(lgrp_children_func_t func) { _lgrp_children = func; }
static void set_lgrp_resources(lgrp_resources_func_t func) { _lgrp_resources = func; }
static void set_lgrp_nlgrps(lgrp_nlgrps_func_t func) { _lgrp_nlgrps = func; } static void set_lgrp_nlgrps(lgrp_nlgrps_func_t func) { _lgrp_nlgrps = func; }
static void set_lgrp_cookie_stale(lgrp_cookie_stale_func_t func) { _lgrp_cookie_stale = func; } static void set_lgrp_cookie_stale(lgrp_cookie_stale_func_t func) { _lgrp_cookie_stale = func; }
static void set_lgrp_cookie(lgrp_cookie_t cookie) { _lgrp_cookie = cookie; } static void set_lgrp_cookie(lgrp_cookie_t cookie) { _lgrp_cookie = cookie; }
...@@ -266,6 +271,12 @@ class Solaris { ...@@ -266,6 +271,12 @@ class Solaris {
lgrp_id_t *lgrp_array, uint_t lgrp_array_size) { lgrp_id_t *lgrp_array, uint_t lgrp_array_size) {
return _lgrp_children != NULL ? _lgrp_children(cookie, parent, lgrp_array, lgrp_array_size) : -1; return _lgrp_children != NULL ? _lgrp_children(cookie, parent, lgrp_array, lgrp_array_size) : -1;
} }
static int lgrp_resources(lgrp_cookie_t cookie, lgrp_id_t lgrp,
lgrp_id_t *lgrp_array, uint_t lgrp_array_size,
lgrp_rsrc_t type) {
return _lgrp_resources != NULL ? _lgrp_resources(cookie, lgrp, lgrp_array, lgrp_array_size, type) : -1;
}
static int lgrp_nlgrps(lgrp_cookie_t cookie) { return _lgrp_nlgrps != NULL ? _lgrp_nlgrps(cookie) : -1; } static int lgrp_nlgrps(lgrp_cookie_t cookie) { return _lgrp_nlgrps != NULL ? _lgrp_nlgrps(cookie) : -1; }
static int lgrp_cookie_stale(lgrp_cookie_t cookie) { static int lgrp_cookie_stale(lgrp_cookie_t cookie) {
return _lgrp_cookie_stale != NULL ? _lgrp_cookie_stale(cookie) : -1; return _lgrp_cookie_stale != NULL ? _lgrp_cookie_stale(cookie) : -1;
......
...@@ -62,10 +62,10 @@ void MutableNUMASpace::ensure_parsability() { ...@@ -62,10 +62,10 @@ void MutableNUMASpace::ensure_parsability() {
for (int i = 0; i < lgrp_spaces()->length(); i++) { for (int i = 0; i < lgrp_spaces()->length(); i++) {
LGRPSpace *ls = lgrp_spaces()->at(i); LGRPSpace *ls = lgrp_spaces()->at(i);
MutableSpace *s = ls->space(); MutableSpace *s = ls->space();
if (!s->contains(top())) { if (s->top() < top()) { // For all spaces preceeding the one containing top()
if (s->free_in_words() > 0) { if (s->free_in_words() > 0) {
SharedHeap::fill_region_with_object(MemRegion(s->top(), s->end())); SharedHeap::fill_region_with_object(MemRegion(s->top(), s->end()));
size_t area_touched_words = pointer_delta(s->end(), s->top(), sizeof(HeapWordSize)); size_t area_touched_words = pointer_delta(s->end(), s->top());
#ifndef ASSERT #ifndef ASSERT
if (!ZapUnusedHeapArea) { if (!ZapUnusedHeapArea) {
area_touched_words = MIN2((size_t)align_object_size(typeArrayOopDesc::header_size(T_INT)), area_touched_words = MIN2((size_t)align_object_size(typeArrayOopDesc::header_size(T_INT)),
...@@ -88,7 +88,6 @@ void MutableNUMASpace::ensure_parsability() { ...@@ -88,7 +88,6 @@ void MutableNUMASpace::ensure_parsability() {
ls->add_invalid_region(invalid); ls->add_invalid_region(invalid);
} }
s->set_top(s->end());
} }
} else { } else {
if (!os::numa_has_static_binding()) { if (!os::numa_has_static_binding()) {
...@@ -99,8 +98,12 @@ void MutableNUMASpace::ensure_parsability() { ...@@ -99,8 +98,12 @@ void MutableNUMASpace::ensure_parsability() {
if (ZapUnusedHeapArea) { if (ZapUnusedHeapArea) {
MemRegion invalid(s->top(), s->end()); MemRegion invalid(s->top(), s->end());
ls->add_invalid_region(invalid); ls->add_invalid_region(invalid);
} else break; } else {
return;
}
#endif #endif
} else {
return;
} }
} }
} }
...@@ -658,10 +661,13 @@ HeapWord* MutableNUMASpace::allocate(size_t size) { ...@@ -658,10 +661,13 @@ HeapWord* MutableNUMASpace::allocate(size_t size) {
MutableSpace *s = lgrp_spaces()->at(i)->space(); MutableSpace *s = lgrp_spaces()->at(i)->space();
HeapWord *p = s->allocate(size); HeapWord *p = s->allocate(size);
if (p != NULL && s->free_in_words() < (size_t)oopDesc::header_size()) { if (p != NULL) {
size_t remainder = s->free_in_words();
if (remainder < (size_t)oopDesc::header_size() && remainder > 0) {
s->set_top(s->top() - size); s->set_top(s->top() - size);
p = NULL; p = NULL;
} }
}
if (p != NULL) { if (p != NULL) {
if (top() < s->top()) { // Keep _top updated. if (top() < s->top()) { // Keep _top updated.
MutableSpace::set_top(s->top()); MutableSpace::set_top(s->top());
...@@ -693,13 +699,16 @@ HeapWord* MutableNUMASpace::cas_allocate(size_t size) { ...@@ -693,13 +699,16 @@ HeapWord* MutableNUMASpace::cas_allocate(size_t size) {
} }
MutableSpace *s = lgrp_spaces()->at(i)->space(); MutableSpace *s = lgrp_spaces()->at(i)->space();
HeapWord *p = s->cas_allocate(size); HeapWord *p = s->cas_allocate(size);
if (p != NULL && s->free_in_words() < (size_t)oopDesc::header_size()) { if (p != NULL) {
size_t remainder = pointer_delta(s->end(), p);
if (remainder < (size_t)oopDesc::header_size() && remainder > 0) {
if (s->cas_deallocate(p, size)) { if (s->cas_deallocate(p, size)) {
// We were the last to allocate and created a fragment less than // We were the last to allocate and created a fragment less than
// a minimal object. // a minimal object.
p = NULL; p = NULL;
} }
} }
}
if (p != NULL) { if (p != NULL) {
HeapWord* cur_top, *cur_chunk_top = p + size; HeapWord* cur_top, *cur_chunk_top = p + size;
while ((cur_top = top()) < cur_chunk_top) { // Keep _top updated. while ((cur_top = top()) < cur_chunk_top) { // Keep _top updated.
...@@ -738,6 +747,9 @@ void MutableNUMASpace::print_on(outputStream* st) const { ...@@ -738,6 +747,9 @@ void MutableNUMASpace::print_on(outputStream* st) const {
st->print(" lgrp %d", ls->lgrp_id()); st->print(" lgrp %d", ls->lgrp_id());
ls->space()->print_on(st); ls->space()->print_on(st);
if (NUMAStats) { if (NUMAStats) {
for (int i = 0; i < lgrp_spaces()->length(); i++) {
lgrp_spaces()->at(i)->accumulate_statistics(page_size());
}
st->print(" local/remote/unbiased/uncommitted: %dK/%dK/%dK/%dK, large/small pages: %d/%d\n", st->print(" local/remote/unbiased/uncommitted: %dK/%dK/%dK/%dK, large/small pages: %d/%d\n",
ls->space_stats()->_local_space / K, ls->space_stats()->_local_space / K,
ls->space_stats()->_remote_space / K, ls->space_stats()->_remote_space / K,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册