Commit 2cecffb0 authored by Robert Schmidt's avatar Robert Schmidt

Merge remote-tracking branch 'origin/fix-huge-malloc' into integration_2025_w04 (!3211)

Avoid huge calloc by alloc'ing TBs independently

Fix real-time problems on smaller machines due to big calloc(). See the
commit(s) for more details.
parents f3e5ab10 84c69e50
......@@ -72,3 +72,17 @@ byte_array_t cp_str_to_ba(const char* str)
return dst;
}
char* cp_ba_to_str(const byte_array_t ba)
{
assert(ba.len > 0);
const size_t sz = ba.len;
char* str = calloc(sz+1, sizeof(char));
assert(str != NULL && "Memory exhausted");
memcpy(str, ba.buf, sz);
str[sz] = '\0';
return str;
}
......@@ -42,5 +42,6 @@ void free_byte_array(byte_array_t ba);
bool eq_byte_array(const byte_array_t* m0, const byte_array_t* m1);
byte_array_t cp_str_to_ba(const char* str);
char* cp_ba_to_str(const byte_array_t ba);
#endif
......@@ -12,7 +12,7 @@ add_library(e2_ran_func_cuup STATIC
../flexric/test/rnd/fill_rnd_data_tc.c
)
target_link_libraries(e2_ran_func_cuup PUBLIC asn1_nr_rrc nr_rrc asn1_nr_rrc_hdrs e2_time_obj kpm_ric_info_common_obj 3gpp_derived_ie_obj sm_common_ie_obj)
target_link_libraries(e2_ran_func_cuup PUBLIC asn1_nr_rrc nr_rrc asn1_nr_rrc_hdrs e2_time_obj kpm_ric_info_common_obj 3gpp_derived_ie_obj sm_common_ie_obj ds)
target_compile_definitions(e2_ran_func_cuup PUBLIC ${E2AP_VERSION} ${KPM_VERSION} NGRAN_GNB_CUUP)
......@@ -35,7 +35,7 @@ add_library(e2_ran_func_du_cucp_cuup STATIC
../flexric/test/rnd/fill_rnd_data_tc.c
)
target_link_libraries(e2_ran_func_du_cucp_cuup PUBLIC asn1_nr_rrc nr_rrc asn1_nr_rrc_hdrs e2_time_obj kpm_ric_info_common_obj 3gpp_derived_ie_obj e2sm_rc_ir_obj sm_common_ie_obj)
target_link_libraries(e2_ran_func_du_cucp_cuup PUBLIC asn1_nr_rrc nr_rrc asn1_nr_rrc_hdrs e2_time_obj kpm_ric_info_common_obj 3gpp_derived_ie_obj e2sm_rc_ir_obj sm_common_ie_obj ds)
target_compile_definitions(e2_ran_func_du_cucp_cuup PUBLIC ${E2AP_VERSION} ${KPM_VERSION} NGRAN_GNB_DU NGRAN_GNB_CUCP NGRAN_GNB_CUUP)
# Current implementation:
......
......@@ -23,6 +23,7 @@
#include "ran_func_kpm_subs.h"
#include "ran_e2sm_ue_id.h"
#include "common/utils/ds/byte_array.h"
#include "openair2/E1AP/e1ap_common.h"
#include "openair2/E2AP/flexric/src/util/time_now_us.h"
#include "openair2/F1AP/f1ap_ids.h"
......
......@@ -2126,7 +2126,7 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP,
harq->tb_size = tb_size;
uint8_t *buf = (uint8_t *) harq->transportBlock;
uint8_t *buf = allocate_transportBlock_buffer(&harq->transportBlock, tb_size);
// Bytes to be transmitted
if (harq->round == 0) {
uint16_t mac_pdu_length = 0;
......@@ -2206,11 +2206,11 @@ static void nr_generate_Msg4_MsgB(module_id_t module_idP,
}
T(T_GNB_MAC_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(ra->rnti),
T_INT(frameP), T_INT(slotP), T_INT(current_harq_pid), T_BUFFER(harq->transportBlock, harq->tb_size));
T_INT(frameP), T_INT(slotP), T_INT(current_harq_pid), T_BUFFER(harq->transportBlock.buf, harq->tb_size));
// DL TX request
nfapi_nr_pdu_t *tx_req = &TX_req->pdu_list[TX_req->Number_of_PDUs];
memcpy(tx_req->TLVs[0].value.direct, harq->transportBlock, sizeof(uint8_t) * harq->tb_size);
memcpy(tx_req->TLVs[0].value.direct, harq->transportBlock.buf, sizeof(uint8_t) * harq->tb_size);
tx_req->PDU_index = pduindex;
tx_req->num_TLV = 1;
tx_req->TLVs[0].length = harq->tb_size;
......
......@@ -1280,12 +1280,12 @@ void nr_schedule_ue_spec(module_id_t module_id,
UE->rnti,
current_harq_pid);
T(T_GNB_MAC_RETRANSMISSION_DL_PDU_WITH_DATA, T_INT(module_id), T_INT(CC_id), T_INT(rnti),
T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_INT(harq->round), T_BUFFER(harq->transportBlock, TBS));
T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_INT(harq->round), T_BUFFER(harq->transportBlock.buf, TBS));
UE->mac_stats.dl.total_rbs_retx += sched_pdsch->rbSize;
gNB_mac->mac_stats.used_prb_aggregate += sched_pdsch->rbSize;
} else { /* initial transmission */
LOG_D(NR_MAC, "Initial HARQ transmission in %d.%d\n", frame, slot);
uint8_t *buf = (uint8_t *) harq->transportBlock;
uint8_t *buf = allocate_transportBlock_buffer(&harq->transportBlock, TBS);
/* first, write all CEs that might be there */
int written = nr_write_ce_dlsch_pdu(module_id,
sched_ctrl,
......@@ -1420,7 +1420,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
}
T(T_GNB_MAC_DL_PDU_WITH_DATA, T_INT(module_id), T_INT(CC_id), T_INT(rnti),
T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_BUFFER(harq->transportBlock, TBS));
T_INT(frame), T_INT(slot), T_INT(current_harq_pid), T_BUFFER(harq->transportBlock.buf, TBS));
}
const int ntx_req = TX_req->Number_of_PDUs;
......@@ -1429,7 +1429,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
tx_req->num_TLV = 1;
tx_req->TLVs[0].length = TBS;
tx_req->PDU_length = compute_PDU_length(tx_req->num_TLV, tx_req->TLVs[0].length);
memcpy(tx_req->TLVs[0].value.direct, harq->transportBlock, TBS);
memcpy(tx_req->TLVs[0].value.direct, harq->transportBlock.buf, TBS);
TX_req->Number_of_PDUs++;
TX_req->SFN = frame;
TX_req->Slot = slot;
......
......@@ -2079,12 +2079,35 @@ void delete_nr_ue_data(NR_UE_info_t *UE, NR_COMMON_channels_t *ccPtr, uid_alloca
destroy_nr_list(&sched_ctrl->available_ul_harq);
destroy_nr_list(&sched_ctrl->feedback_ul_harq);
destroy_nr_list(&sched_ctrl->retrans_ul_harq);
for (int i = 0; i < NR_MAX_HARQ_PROCESSES; ++i)
free_transportBlock_buffer(&sched_ctrl->harq_processes[i].transportBlock);
free_sched_pucch_list(sched_ctrl);
uid_linear_allocator_free(uia, UE->uid);
LOG_I(NR_MAC, "Remove NR rnti 0x%04x\n", UE->rnti);
free(UE);
}
#define TB_SINGLE_LAYER (32 * 1024)
uint8_t *allocate_transportBlock_buffer(byte_array_t *tb, uint32_t needed)
{
DevAssert(needed > 0);
if (tb->buf != NULL && needed <= tb->len)
return tb->buf; // nothing to do, current is enough
uint32_t size = TB_SINGLE_LAYER;
while (needed > size)
size *= 2;
LOG_D(NR_MAC, "allocating new TB block of size %d\n", size);
free(tb->buf);
tb->buf = malloc_or_fail(size);
tb->len = size;
return tb->buf;
}
void free_transportBlock_buffer(byte_array_t *tb)
{
free_byte_array(*tb);
}
void set_max_fb_time(NR_UE_UL_BWP_t *UL_BWP, const NR_UE_DL_BWP_t *DL_BWP)
{
......
......@@ -381,6 +381,9 @@ void handle_nr_ul_harq(const int CC_idP,
sub_frame_t slot,
const nfapi_nr_crc_t *crc_pdu);
uint8_t *allocate_transportBlock_buffer(byte_array_t *tb, uint32_t needed);
void free_transportBlock_buffer(byte_array_t *tb);
void handle_nr_srs_measurements(const module_id_t module_id,
const frame_t frame,
const sub_frame_t slot,
......
......@@ -44,6 +44,7 @@
#include <pthread.h>
#include "common/utils/ds/seq_arr.h"
#include "common/utils/nr/nr_common.h"
#include "common/utils/ds/byte_array.h"
#define NR_SCHED_LOCK(lock) \
do { \
......@@ -481,10 +482,9 @@ typedef struct NR_UE_harq {
uint16_t feedback_frame;
uint16_t feedback_slot;
/* Transport block to be sent using this HARQ process, its size is in
* sched_pdsch */
uint32_t transportBlock[38016]; // valid up to 4 layers
uint32_t tb_size;
/* Transport block to be sent using this HARQ process */
byte_array_t transportBlock;
uint32_t tb_size; // size of currently stored TB
/// sched_pdsch keeps information on MCS etc used for the initial transmission
NR_sched_pdsch_t sched_pdsch;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment