-
Notifications
You must be signed in to change notification settings - Fork 11
Description
In srsRAN, in lib/scheduler/ue_scheduling/ue_event_managr.cpp, we call hook_mac_sched_ul_phr_indication as below.
This in slightkl incorrect .... the for loop walks the "phr" vector, but we pass the higher level phr_ind to to the codelet. Ideally should pass "cell_phr".
void ue_event_manager::handle_ul_phr_indication(const ul_phr_indication_message& phr_ind)
{
auto phr_ind_ptr = ind_pdu_pool->create_pdu(phr_ind);
if (phr_ind_ptr == nullptr) {
return;
}
auto handle_phr_impl = this, phr_ind = std::move(phr_ind_ptr) {
auto& u = ue_db[phr_ind->ue_index];
for (const cell_ph_report& cell_phr : phr_ind->phr.get_phr()) {
srsran_sanity_check(cell_phr.serv_cell_id < u.nof_cells(),
"Invalid serving cell index={}",
fmt::underlying(cell_phr.serv_cell_id));
auto& ue_cc = u.get_cell(cell_phr.serv_cell_id);
ue_cc.get_pusch_power_controller().handle_phr(cell_phr, phr_ind->slot_rx);
#ifdef JBPF_ENABLED
hook_mac_sched_ul_phr_indication(const_cast<void*>(static_cast<const void*>(&cell_phr)),
0, phr_ind->ue_index, ue_cc.cfg().cell_cfg_common.pci, (uint16_t)phr_ind->rnti, sizeof(cell_ph_report));
#endif
The codelet (codelets/mac/mac_sched_phr_stats.cpp) also does the walk of the vector …
auto ph_reports = mac_ctx.phr.get_phr();
for (int i=0; i<srsran::MAX_NOF_DU_CELLS; i++) {
if (i < ph_reports.size()) {
int new_val = 0;
//uint64_t key = ((uint64_t)ph_reports[i].serv_cell_id << 31) << 1 | (uint64_t)ctx->du_ue_index;
uint32_t ind = JBPF_PROTOHASH_LOOKUP_ELEM_64(out, stats, phr_hash, ph_reports[i].serv_cell_id, ctx->du_ue_index, new_val);
if (new_val) {
For some reason , this manifests as an infinite loop in srsRAN_project/external/jbpf/3p/ck/src/ck_epoch.c, function ck_epoch_dispatch …
for (cursor = head; cursor != NULL; cursor = next) {
struct ck_epoch_entry *entry =
ck_epoch_entry_container(cursor);
next = CK_STACK_NEXT(cursor);
if (deferred != NULL)
ck_stack_push_spnc(deferred, &entry->stack_entry);
else
entry->function(entry);
i++;
}
For debug code, I updated this as below. This shows that there are duplicate pointers on the list, which causes the infinite loop.
// Use a simple array to detect cycles (addresses of nodes already seen)
ck_stack_entry_t *seen[1024]; // adjust size if your lists are longer
unsigned int seen_count = 0;
for (cursor = head; cursor != NULL; cursor = next) {
struct ck_epoch_entry *entry =
ck_epoch_entry_container(cursor);
next = CK_STACK_NEXT(cursor);
// Check for self-loop or cycles
for (unsigned int s = 0; s < seen_count; s++) {
if (seen[s] == cursor) {
printf("[ERROR] Detected cycle in pending[%u] at node %p (epoch=%u)\n",
epoch, cursor, epoch);
return i; // stop to prevent infinite loop
}
}
if (seen_count < sizeof(seen)/sizeof(seen[0])) {
seen[seen_count++] = cursor;
}
if (deferred != NULL)
ck_stack_push_spnc(deferred, &entry->stack_entry);
else
entry->function(entry);
i++;
}