extern int mem_poison_byte;
void *pool_get_from_os(struct pool_head *pool);
+void pool_put_to_os(struct pool_head *pool, void *ptr);
void *pool_alloc_nocache(struct pool_head *pool);
+void pool_free_nocache(struct pool_head *pool, void *ptr);
void dump_pools_to_trash();
void dump_pools(void);
int pool_total_failures();
static inline void pool_put_to_shared_cache(struct pool_head *pool, void *ptr)
{
- _HA_ATOMIC_DEC(&pool->used);
- _HA_ATOMIC_DEC(&pool->allocated);
- swrate_add(&pool->needed_avg, POOL_AVG_SAMPLES, pool->used);
- pool_free_area(ptr, pool->size + POOL_EXTRA);
+ pool_free_nocache(pool, ptr);
}
#elif defined(CONFIG_HAP_LOCKLESS_POOLS)
_HA_ATOMIC_DEC(&pool->used);
if (unlikely(pool_is_crowded(pool))) {
- pool_free_area(ptr, pool->size + POOL_EXTRA);
- _HA_ATOMIC_DEC(&pool->allocated);
+ pool_put_to_os(pool, ptr);
} else {
do {
*POOL_LINK(pool, ptr) = (void *)free_list;
if (ptr) {
/* still not freed */
- pool_free_area(ptr, pool->size + POOL_EXTRA);
- _HA_ATOMIC_DEC(&pool->allocated);
+ pool_put_to_os(pool, ptr);
}
swrate_add(&pool->needed_avg, POOL_AVG_SAMPLES, pool->used);
}
}
+/* Releases a pool item back to the operating system and atomically updates
+ * the allocation counter.
+ */
+void pool_put_to_os(struct pool_head *pool, void *ptr)
+{
+ pool_free_area(ptr, pool->size + POOL_EXTRA);
+ _HA_ATOMIC_DEC(&pool->allocated);
+}
+
#ifdef CONFIG_HAP_POOLS
/* Evicts some of the oldest objects from the local cache, pushing them to the
* global pool.
return ptr;
}
+/* Release a pool item back to the OS and keeps the pool's counters up to date.
+ * This is always defined even when pools are not enabled (their usage stats
+ * are maintained).
+ */
+void pool_free_nocache(struct pool_head *pool, void *ptr)
+{
+ _HA_ATOMIC_DEC(&pool->used);
+ swrate_add(&pool->needed_avg, POOL_AVG_SAMPLES, pool->used);
+ pool_put_to_os(pool, ptr);
+}
+
#if defined(CONFIG_HAP_NO_GLOBAL_POOLS)
while (next) {
temp = next;
next = *POOL_LINK(pool, temp);
- pool_free_area(temp, pool->size + POOL_EXTRA);
- _HA_ATOMIC_DEC(&pool->allocated);
+ pool_put_to_os(pool, temp);
}
pool->free_list = next;
/* here, we should have pool->allocate == pool->used */
new.seq = cmp.seq + 1;
if (HA_ATOMIC_DWCAS(&entry->free_list, &cmp, &new) == 0)
continue;
- pool_free_area(cmp.free_list, entry->size + POOL_EXTRA);
- _HA_ATOMIC_DEC(&entry->allocated);
+ pool_put_to_os(entry, cmp.free_list);
}
}
}
pool->free_list = *POOL_LINK(pool, temp);
HA_SPIN_UNLOCK(POOL_LOCK, &pool->lock);
- pool_free_area(temp, pool->size + POOL_EXTRA);
- _HA_ATOMIC_DEC(&pool->allocated);
+ pool_put_to_os(pool, temp);
}
/* here, we should have pool->allocated == pool->used */
}
(int)(entry->allocated - entry->used) > (int)entry->minavail) {
temp = entry->free_list;
entry->free_list = *POOL_LINK(entry, temp);
- pool_free_area(temp, entry->size + POOL_EXTRA);
- _HA_ATOMIC_DEC(&entry->allocated);
+ pool_put_to_os(entry, temp);
}
}