@@ -3016,13 +3016,15 @@ static void cu__sort_types_by_offset(struct cu *cu, struct conf_load *conf)
cu__for_all_tags(cu, type__sort_by_offset, conf);
}
-static int cu__finalize(struct cu *cu, struct conf_load *conf, void *thr_data)
+static int cu__finalize(struct cu *cu, struct cus *cus, struct conf_load *conf, void *thr_data)
{
cu__for_all_tags(cu, class_member__cache_byte_size, conf);
if (cu__language_reorders_offsets(cu))
cu__sort_types_by_offset(cu, conf);
+ cus__set_cu_state(cus, cu, CU__LOADED);
+
if (conf && conf->steal) {
return conf->steal(cu, conf, thr_data);
}
@@ -3031,7 +3033,7 @@ static int cu__finalize(struct cu *cu, struct conf_load *conf, void *thr_data)
static int cus__finalize(struct cus *cus, struct cu *cu, struct conf_load *conf, void *thr_data)
{
- int lsk = cu__finalize(cu, conf, thr_data);
+ int lsk = cu__finalize(cu, cus, conf, thr_data);
switch (lsk) {
case LSK__DELETE:
cus__remove(cus, cu);
@@ -3508,7 +3510,7 @@ static int cus__load_module(struct cus *cus, struct conf_load *conf,
}
if (type_cu != NULL) {
- type_lsk = cu__finalize(type_cu, conf, NULL);
+ type_lsk = cu__finalize(type_cu, cus, conf, NULL);
if (type_lsk == LSK__DELETE) {
cus__remove(cus, type_cu);
}
@@ -469,6 +469,44 @@ void cus__unlock(struct cus *cus)
pthread_mutex_unlock(&cus->mutex);
}
+void cus__set_cu_state(struct cus *cus, struct cu *cu, enum cu_state state)
+{
+ cus__lock(cus);
+ cu->state = state;
+ cus__unlock(cus);
+}
+
+// Used only when reproducible builds are desired
+struct cu *cus__get_next_processable_cu(struct cus *cus)
+{
+ struct cu *cu;
+
+ cus__lock(cus);
+
+ list_for_each_entry(cu, &cus->cus, node) {
+ switch (cu->state) {
+ case CU__LOADED:
+ cu->state = CU__PROCESSING;
+ goto found;
+ case CU__PROCESSING:
+ // This will only happen when we get to parallel
+ // reproducible BTF encoding, libbpf dedup work needed here.
+ continue;
+ case CU__UNPROCESSED:
+ // The first entry isn't loaded, signal the
+ // caller to return and try another day, as we
+ // need to respect the original DWARF CU ordering.
+ goto out;
+ }
+ }
+out:
+ cu = NULL;
+found:
+ cus__unlock(cus);
+
+ return cu;
+}
+
bool cus__empty(const struct cus *cus)
{
return list_empty(&cus->cus);
@@ -701,6 +739,8 @@ struct cu *cu__new(const char *name, uint8_t addr_size,
cu->addr_size = addr_size;
cu->extra_dbg_info = 0;
+ cu->state = CU__UNPROCESSED;
+
cu->nr_inline_expansions = 0;
cu->size_inline_expansions = 0;
cu->nr_structures_changed = 0;
@@ -43,6 +43,12 @@ enum load_steal_kind {
LSK__STOP_LOADING,
};
+enum cu_state {
+ CU__UNPROCESSED,
+ CU__LOADED,
+ CU__PROCESSING,
+};
+
/*
* BTF combines all the types into one big CU using btf_dedup(), so for something
* like a allyesconfig vmlinux kernel we can get over 65535 types.
@@ -177,6 +183,10 @@ void cus__add(struct cus *cus, struct cu *cu);
void __cus__remove(struct cus *cus, struct cu *cu);
void cus__remove(struct cus *cus, struct cu *cu);
+struct cu *cus__get_next_processable_cu(struct cus *cus);
+
+void cus__set_cu_state(struct cus *cus, struct cu *cu, enum cu_state state);
+
void cus__print_error_msg(const char *progname, const struct cus *cus,
const char *filename, const int err);
struct cu *cus__find_pair(struct cus *cus, const char *name);
@@ -287,6 +297,7 @@ struct cu {
uint8_t little_endian:1;
uint8_t nr_register_params;
int register_params[ARCH_MAX_REGISTER_PARAMS];
+ enum cu_state state;
uint16_t language;
unsigned long nr_inline_expansions;
size_t size_inline_expansions;