Fix potential freelist corruption in unified_cache_refill (Class 0) and improve TLS SLL logging/safety
This commit is contained in:
@ -130,7 +130,9 @@ static inline int tiny_front_is_pgo_build(void) {
|
|||||||
|
|
||||||
// Get effective configuration (for diagnostics)
|
// Get effective configuration (for diagnostics)
|
||||||
static inline void tiny_front_config_report(void) {
|
static inline void tiny_front_config_report(void) {
|
||||||
#if !HAKMEM_BUILD_RELEASE
|
#if 0 // !HAKMEM_BUILD_RELEASE
|
||||||
|
// Disabled to avoid circular dependency / implicit declaration issues
|
||||||
|
// re-enable when include order is fixed
|
||||||
fprintf(stderr, "[TINY_FRONT_CONFIG]\n");
|
fprintf(stderr, "[TINY_FRONT_CONFIG]\n");
|
||||||
fprintf(stderr, " PGO Build: %d\n", HAKMEM_TINY_FRONT_PGO);
|
fprintf(stderr, " PGO Build: %d\n", HAKMEM_TINY_FRONT_PGO);
|
||||||
fprintf(stderr, " Ultra SLIM: %d\n", TINY_FRONT_ULTRA_SLIM_ENABLED);
|
fprintf(stderr, " Ultra SLIM: %d\n", TINY_FRONT_ULTRA_SLIM_ENABLED);
|
||||||
|
|||||||
@ -538,8 +538,8 @@ static inline bool tls_sll_pop_impl(int class_idx, hak_base_ptr_t* out, const ch
|
|||||||
uint64_t cnt = atomic_fetch_add_explicit(&g_tls_sll_invalid_head[class_idx], 1, memory_order_relaxed);
|
uint64_t cnt = atomic_fetch_add_explicit(&g_tls_sll_invalid_head[class_idx], 1, memory_order_relaxed);
|
||||||
static __thread uint8_t s_log_limit[TINY_NUM_CLASSES] = {0};
|
static __thread uint8_t s_log_limit[TINY_NUM_CLASSES] = {0};
|
||||||
if (s_log_limit[class_idx] < 4) {
|
if (s_log_limit[class_idx] < 4) {
|
||||||
fprintf(stderr, "[TLS_SLL_POP_INVALID] cls=%d head=%p dropped count=%llu\n",
|
fprintf(stderr, "[TLS_SLL_POP_INVALID] cls=%d head=%p (val=%llx) dropped count=%llu\n",
|
||||||
class_idx, raw_base, (unsigned long long)cnt + 1);
|
class_idx, raw_base, (unsigned long long)base_addr, (unsigned long long)cnt + 1);
|
||||||
s_log_limit[class_idx]++;
|
s_log_limit[class_idx]++;
|
||||||
}
|
}
|
||||||
// Help triage: show last successful push base for this thread/class
|
// Help triage: show last successful push base for this thread/class
|
||||||
|
|||||||
@ -337,18 +337,18 @@ void* unified_cache_refill(int class_idx) {
|
|||||||
if (m->freelist) {
|
if (m->freelist) {
|
||||||
// Freelist pop
|
// Freelist pop
|
||||||
void* p = m->freelist;
|
void* p = m->freelist;
|
||||||
|
void* next_node = tiny_next_read(class_idx, p);
|
||||||
|
|
||||||
// ROOT CAUSE FIX: Write header BEFORE tiny_next_read()
|
// ROOT CAUSE FIX: Write header BEFORE exposing block (but AFTER reading next)
|
||||||
// Without this, compiler can reorder header write after out[] assignment
|
// For Class 0 (offset 0), next overlaps header, so we must read next first.
|
||||||
// causing SEGVAULT in release builds (unified_cache_refill+0x46f)
|
|
||||||
#if HAKMEM_TINY_HEADER_CLASSIDX
|
#if HAKMEM_TINY_HEADER_CLASSIDX
|
||||||
*(uint8_t*)p = (uint8_t)(0xa0 | (class_idx & 0x0f));
|
*(uint8_t*)p = (uint8_t)(0xa0 | (class_idx & 0x0f));
|
||||||
|
|
||||||
// Prevent compiler from reordering operations
|
// Prevent compiler from reordering header write after out[] assignment
|
||||||
__atomic_thread_fence(__ATOMIC_RELEASE);
|
__atomic_thread_fence(__ATOMIC_RELEASE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m->freelist = tiny_next_read(class_idx, p);
|
m->freelist = next_node;
|
||||||
|
|
||||||
unified_refill_validate_base(class_idx, tls, m, p,
|
unified_refill_validate_base(class_idx, tls, m, p,
|
||||||
"unified_refill_freelist");
|
"unified_refill_freelist");
|
||||||
|
|||||||
Reference in New Issue
Block a user