23 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_BE 224 static const char *zone_names[] = {
231 return zone_names[
type];
257 .bas_print_index = 0,
283 if (
alloc && failed) {
297 #define P_ACS(acs) (acs)->bcs_nr, (acs)->bcs_size 299 "free=(%lu, %" PRIu64 "), alloc_failure=(%lu, %" PRIu64 ")", descr,
308 "print_interval=%lu print_index=%lu",
310 stats->bas_print_interval,
stats->bas_print_index);
312 stats->bas_chunks_nr,
stats->bas_free_chunks_nr);
323 unsigned long space_change;
328 multiplier = failed ? 0 :
alloc ? 1 : -1;
329 space_change =
size +
stats->bas_chunk_overhead;
330 stats->bas_space_used += multiplier * space_change;
331 stats->bas_space_free -= multiplier * space_change;
336 if (
stats->bas_print_index++ ==
stats->bas_print_interval) {
338 stats->bas_print_index = 0;
417 cprev = chunks_all_be_list_prev(&h->
bah_chunks,
c);
418 cnext = chunks_all_be_list_next(&h->
bah_chunks,
c);
446 chunks_all_be_tlink_create(
c, tx);
469 chunks_all_be_tlink_destroy(
c, tx);
535 (uintptr_t) &
c->bac_mem[
c->bac_size];
552 M0_PRE(size_total >
sizeof *
new);
562 chunks_all_be_list_add_after(&h->
bah_chunks, tx,
c,
new);
564 chunks_all_be_list_add(&h->
bah_chunks, tx,
new);
586 c->bac_size = new_size;
600 if (size_total <=
sizeof *
c) {
603 c->bac_size + size_total);
608 offset, size_total,
true);
625 uintptr_t start_next;
638 start1 = start_new +
sizeof *
new + size_min_aligned;
640 chunk0_size = start_new - start0;
641 chunk1_size = start_next - start1;
652 prev ==
NULL ? chunk0_size : 0,
653 sizeof *
new + size_min_aligned,
false);
671 uintptr_t alignment = 1UL << shift;
673 uintptr_t addr_start;
679 addr_start = (uintptr_t)
c;
680 addr_end = (uintptr_t) &
c->bac_mem[
c->bac_size];
682 addr_mem = addr_start +
sizeof *
c + alignment - 1;
683 addr_mem &= ~(alignment - 1);
685 result = addr_mem +
size <= addr_end ?
700 bool chunks_were_merged =
false;
706 if (
x !=
NULL && y !=
NULL &&
x->bac_free && y->bac_free) {
707 y_size_total =
sizeof *y + y->bac_size;
710 x->bac_size + y_size_total);
711 chunks_were_merged =
true;
716 return chunks_were_merged;
787 chunks_all_be_list_create(&h->
bah_chunks, tx);
818 chunks_all_be_list_destroy(&h->
bah_chunks, tx);
823 uint32_t *zone_percent,
837 M0_PRE(m0_reduce(
i, zones_nr, 0ULL, + zone_percent[
i]) == 100);
846 for (
i = 0;
i < zones_nr; ++
i) {
847 if (
i < zones_nr - 1) {
848 size = free_space * zone_percent[
i] / 100;
855 for (z = 0; z <
i; ++z)
872 for (
i = 0;
i < zones_nr; ++
i)
943 chunks_all_be_list_credit(
M0_BLO_CREATE, 1, &cred_list_create);
949 chunks_all_be_list_credit(
M0_BLO_ADD, 1, &tmp);
951 chunk_add_after_credit = tmp;
954 chunks_all_be_list_credit(
M0_BLO_DEL, 1, &tmp);
957 chunk_del_fini_credit = tmp;
967 &chunk_resize_credit,
968 &chunk_add_after_credit);
1046 if ((zonemask &
M0_BITS(z)) != 0)
1057 memset(&
c->bac_mem, 0,
size);
1067 "c=%p c->bac_size=%" PRIu64 " ptr=%p", a,
size, shift,
c,
1110 bool chunks_were_merged;
1124 ztype =
c->bac_zone;
1126 "data=%p", a,
c,
c->bac_size,
c->bac_zone, &
c->bac_mem);
1131 c->bac_size,
false,
false);
1136 if (chunks_were_merged)
1185 #undef M0_TRACE_SUBSYSTEM
static void ptr(struct m0_addb2__context *ctx, const uint64_t *v, char *buf)
#define M0_BE_TX_CREDIT_PTR(ptr)
static struct be_alloc_chunk * be_alloc_chunk_next(struct m0_be_allocator *a, enum m0_be_alloc_zone_type ztype, struct be_alloc_chunk *c)
static void be_alloc_chunk_mark_free(struct m0_be_allocator *a, enum m0_be_alloc_zone_type ztype, struct m0_be_tx *tx, struct be_alloc_chunk *c)
M0_INTERNAL void m0_mutex_unlock(struct m0_mutex *mutex)
static struct be_alloc_chunk * be_alloc_chunk_trysplit(struct m0_be_allocator *a, enum m0_be_alloc_zone_type ztype, struct m0_be_tx *tx, struct be_alloc_chunk *c, m0_bcount_t size, unsigned shift)
M0_INTERNAL void m0_be_fl_destroy(struct m0_be_fl *fl, struct m0_be_tx *tx)
static bool m0_addr_is_aligned(const void *addr, unsigned shift)
m0_bcount_t bas_stat0_boundary
static bool be_alloc_chunk_is_in(const struct m0_be_allocator *a, enum m0_be_alloc_zone_type ztype, const struct be_alloc_chunk *c)
#define M0_LOG(level,...)
M0_INTERNAL void m0_be_alloc_stats_capture(struct m0_be_allocator *a, struct m0_be_tx *tx)
static struct be_alloc_chunk * be_alloc_chunk_prev(struct m0_be_allocator *a, enum m0_be_alloc_zone_type ztype, struct be_alloc_chunk *c)
#define M0_BE_REG_PTR(seg, ptr)
static void be_allocator_call_stats_init(struct m0_be_allocator_call_stats *cs)
static void be_alloc_free_flag_capture(const struct m0_be_allocator *a, struct m0_be_tx *tx, struct be_alloc_chunk *c)
static void be_allocator_call_stat_update(struct m0_be_allocator_call_stat *cstat, unsigned long nr, m0_bcount_t size)
M0_INTERNAL void m0_be_alloc_stats(struct m0_be_allocator *a, struct m0_be_allocator_stats *out)
#define M0_BE_TX_CAPTURE_PTR(seg, tx, ptr)
M0_INTERNAL bool m0_be_seg__invariant(const struct m0_be_seg *seg)
#define container_of(ptr, type, member)
#define M0_BE_TX_CREDIT_TYPE(type)
M0_INTERNAL void m0_mutex_lock(struct m0_mutex *mutex)
M0_INTERNAL void m0_be_alloc_aligned(struct m0_be_allocator *a, struct m0_be_tx *tx, struct m0_be_op *op, void **ptr, m0_bcount_t size, unsigned shift, uint64_t zonemask)
#define M0_BE_REG(seg, size, addr)
static void be_allocator_stats_print(struct m0_be_allocator_stats *stats)
static void be_allocator_header_destroy(struct m0_be_allocator *a, enum m0_be_alloc_zone_type ztype, struct m0_be_tx *tx)
M0_INTERNAL void m0_be_fl_create(struct m0_be_fl *fl, struct m0_be_tx *tx, struct m0_be_seg *seg)
#define M0_BE_TX_CREDIT(nr, size)
#define M0_ASSERT_EX(cond)
static const char * be_alloc_zone_name(enum m0_be_alloc_zone_type type)
M0_INTERNAL m0_bcount_t m0_be_seg_reserved(const struct m0_be_seg *seg)
M0_BE_LIST_DEFINE(chunks_all, static, struct be_alloc_chunk)
M0_INTERNAL void m0_be_alloc_stats_credit(struct m0_be_allocator *a, struct m0_be_tx_credit *accum)
return M0_ERR(-EOPNOTSUPP)
struct m0_be_allocator_call_stat bacs_free
M0_INTERNAL void m0_be_fl_credit(struct m0_be_fl *fl, enum m0_be_fl_op fl_op, struct m0_be_tx_credit *accum)
static void be_allocator_call_stats_update(struct m0_be_allocator_call_stats *cs, m0_bcount_t size, bool alloc, bool failed)
M0_INTERNAL void m0_be_tx_credit_mac(struct m0_be_tx_credit *c, const struct m0_be_tx_credit *c1, m0_bcount_t k)
M0_INTERNAL bool m0_mutex_is_locked(const struct m0_mutex *mutex)
struct m0_be_allocator_header * ba_h[M0_BAP_NR]
struct m0_be_list_link bac_linkage
static struct m0_addb2_callback c
struct m0_be_allocator_header bh_alloc[M0_BAP_NR]
M0_INTERNAL void m0_be_tx_credit_add(struct m0_be_tx_credit *c0, const struct m0_be_tx_credit *c1)
static bool be_alloc_chunk_is_not_overlapping(const struct be_alloc_chunk *a, const struct be_alloc_chunk *b)
M0_INTERNAL void m0_be_alloc(struct m0_be_allocator *a, struct m0_be_tx *tx, struct m0_be_op *op, void **ptr, m0_bcount_t size)
M0_INTERNAL bool m0_be_allocator__invariant(struct m0_be_allocator *a)
static struct ff2c_term * alloc(void)
static void be_alloc_chunk_resize(struct m0_be_allocator *a, enum m0_be_alloc_zone_type ztype, struct m0_be_tx *tx, struct be_alloc_chunk *c, m0_bcount_t new_size)
struct m0_be_allocator_call_stat bacs_alloc_failure
static void be_alloc_size_capture(const struct m0_be_allocator *a, struct m0_be_tx *tx, struct be_alloc_chunk *c)
M0_INTERNAL void m0_mutex_init(struct m0_mutex *mutex)
static bool be_alloc_mem_is_in(const struct m0_be_allocator *a, enum m0_be_alloc_zone_type ztype, const void *ptr, m0_bcount_t size)
M0_INTERNAL void m0_be_op_done(struct m0_be_op *op)
static m0_bindex_t offset
M0_INTERNAL void m0_be_allocator_destroy(struct m0_be_allocator *a, struct m0_be_tx *tx)
M0_INTERNAL struct be_alloc_chunk * m0_be_fl_pick(struct m0_be_fl *fl, m0_bcount_t size)
static void be_allocator_stats_capture(struct m0_be_allocator *a, enum m0_be_alloc_zone_type ztype, struct m0_be_tx *tx)
#define m0_forall(var, nr,...)
m0_bcount_t bas_stat0_boundary
struct m0_be_seg * ba_seg
static int be_allocator_header_create(struct m0_be_allocator *a, enum m0_be_alloc_zone_type ztype, struct m0_be_tx *tx, uintptr_t offset, m0_bcount_t size)
static void be_alloc_chunk_init(struct m0_be_allocator *a, enum m0_be_alloc_zone_type ztype, struct m0_be_tx *tx, struct be_alloc_chunk *c, m0_bcount_t size, bool free)
M0_INTERNAL void m0_be_op_active(struct m0_be_op *op)
M0_BE_LIST_DESCR_DEFINE(chunks_all, "list of all chunks in m0_be_allocator", static, struct be_alloc_chunk, bac_linkage, bac_magic, M0_BE_ALLOC_ALL_LINK_MAGIC, M0_BE_ALLOC_ALL_MAGIC)
M0_INTERNAL void m0_be_free(struct m0_be_allocator *a, struct m0_be_tx *tx, struct m0_be_op *op, void *ptr)
static struct be_alloc_chunk * be_alloc_chunk_addr(void *ptr)
static void be_allocator_call_stat_init(struct m0_be_allocator_call_stat *cstat)
M0_INTERNAL void m0_be_fl_add(struct m0_be_fl *fl, struct m0_be_tx *tx, struct be_alloc_chunk *chunk)
static bool be_alloc_chunk_trymerge(struct m0_be_allocator *a, enum m0_be_alloc_zone_type ztype, struct m0_be_tx *tx, struct be_alloc_chunk *x, struct be_alloc_chunk *y)
struct m0_be_allocator_call_stat bacs_alloc_success
static bool be_alloc_chunk_invariant(struct m0_be_allocator *a, const struct be_alloc_chunk *c)
M0_INTERNAL void m0_mutex_fini(struct m0_mutex *mutex)
static void be_allocator_call_stats_print(struct m0_be_allocator_call_stats *cs, const char *descr)
M0_INTERNAL void m0_be_free_aligned(struct m0_be_allocator *a, struct m0_be_tx *tx, struct m0_be_op *op, void *ptr)
static void be_alloc_chunk_capture(struct m0_be_allocator *a, struct m0_be_tx *tx, struct be_alloc_chunk *c)
#define m0_be_list_forall(name, var, head,...)
static struct m0_be_seg * seg
#define M0_ASSERT_INFO(cond, fmt,...)
static struct be_alloc_chunk * be_alloc_chunk_split(struct m0_be_allocator *a, enum m0_be_alloc_zone_type ztype, struct m0_be_tx *tx, struct be_alloc_chunk *c, uintptr_t start_new, m0_bcount_t size)
M0_INTERNAL int m0_be_allocator_create(struct m0_be_allocator *a, struct m0_be_tx *tx, uint32_t *zone_percent, uint32_t zones_nr)
M0_INTERNAL void m0_be_tx_capture(struct m0_be_tx *tx, const struct m0_be_reg *reg)
M0_INTERNAL void m0_be_fl_del(struct m0_be_fl *fl, struct m0_be_tx *tx, struct be_alloc_chunk *chunk)
M0_INTERNAL int m0_be_allocator_init(struct m0_be_allocator *a, struct m0_be_seg *seg)
static uintptr_t be_alloc_chunk_after(struct m0_be_allocator *a, enum m0_be_alloc_zone_type ztype, struct be_alloc_chunk *c)
static void be_allocator_stats_init(struct m0_be_allocator_stats *stats, struct m0_be_allocator_header *h)
M0_INTERNAL void m0_be_allocator_credit(struct m0_be_allocator *a, enum m0_be_allocator_op optype, m0_bcount_t size, unsigned shift, struct m0_be_tx_credit *accum)
M0_INTERNAL void m0_be_tx_credit_max(struct m0_be_tx_credit *c, const struct m0_be_tx_credit *c0, const struct m0_be_tx_credit *c1)
static struct be_alloc_chunk * be_alloc_chunk_add_after(struct m0_be_allocator *a, enum m0_be_alloc_zone_type ztype, struct m0_be_tx *tx, struct be_alloc_chunk *c, uintptr_t offset, m0_bcount_t size_total, bool free)
static void be_alloc_chunk_del_fini(struct m0_be_allocator *a, enum m0_be_alloc_zone_type ztype, struct m0_be_tx *tx, struct be_alloc_chunk *c)
static struct be_alloc_chunk * be_alloc_chunk_tryadd_free_after(struct m0_be_allocator *a, enum m0_be_alloc_zone_type ztype, struct m0_be_tx *tx, struct be_alloc_chunk *c, uintptr_t offset, m0_bcount_t size_total)
static uint64_t m0_align(uint64_t val, uint64_t alignment)
M0_INTERNAL void m0_be_allocator_fini(struct m0_be_allocator *a)
static void be_allocator_stats_update(struct m0_be_allocator_stats *stats, m0_bcount_t size, bool alloc, bool failed)
#define M0_IMPOSSIBLE(fmt,...)