mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-17 06:30:31 +00:00
RLC data req: Add API to fill multiple RLC PDUs in one TB, use at gNB
Adds the API, which will always prepend a 3 byte header before writing a PDU. This can be used to call less often into RLC, and avoid potential locking. The API is used at the gNB DLSCH scheduler. Also, this removes the "overhead" calculation: since we fill the entire TB at once, RLC will leave space for headers as necessary.
This commit is contained in:
@@ -50,6 +50,8 @@
|
||||
#define WORD 32
|
||||
//#define SIZE_OF_POINTER sizeof (void *)
|
||||
|
||||
#define MAX_NUM_DATA_REQ 1024
|
||||
|
||||
int get_dl_tda(const gNB_MAC_INST *nrmac, int slot)
|
||||
{
|
||||
/* we assume that this function is mutex-protected from outside */
|
||||
@@ -1298,47 +1300,25 @@ void post_process_dlsch(gNB_MAC_INST *nr_mac, post_process_pdsch_t *pdsch, NR_UE
|
||||
if (sched_ctrl->rlc_status[lcid].bytes_in_buffer == 0)
|
||||
continue; // no data for this LC tbs_size_t len = 0;
|
||||
|
||||
int lcid_bytes=0;
|
||||
while (bufEnd-buf > sizeof(NR_MAC_SUBHEADER_LONG) + 1 ) {
|
||||
// we do not know how much data we will get from RLC, i.e., whether it
|
||||
// will be longer than 256B or not. Therefore, reserve space for long header, then
|
||||
// fetch data, then fill real length
|
||||
|
||||
tb_size_t pdu_siz[MAX_NUM_DATA_REQ];
|
||||
int num = nr_mac_rlc_multi_data_req(module_id, rnti, true, lcid, bufEnd - buf, (char *)buf, pdu_siz, sizeofArray(pdu_siz));
|
||||
DevAssert(num <= sizeofArray(pdu_siz));
|
||||
|
||||
sdus += num;
|
||||
int lcid_bytes = 0;
|
||||
for (int j = 0; j < num; ++j) {
|
||||
NR_MAC_SUBHEADER_LONG *header = (NR_MAC_SUBHEADER_LONG *) buf;
|
||||
/* limit requested number of bytes to what preprocessor specified, or
|
||||
* such that TBS is full */
|
||||
const rlc_buffer_occupancy_t ndata = min(sched_ctrl->rlc_status[lcid].bytes_in_buffer,
|
||||
bufEnd-buf-sizeof(NR_MAC_SUBHEADER_LONG));
|
||||
tbs_size_t len = nr_mac_rlc_data_req(module_id,
|
||||
rnti,
|
||||
true,
|
||||
lcid,
|
||||
ndata,
|
||||
(char *)buf+sizeof(NR_MAC_SUBHEADER_LONG));
|
||||
LOG_D(NR_MAC,
|
||||
"%4d.%2d RNTI %04x: %d bytes from %s %d (ndata %d, remaining size %ld)\n",
|
||||
frame,
|
||||
slot,
|
||||
rnti,
|
||||
len,
|
||||
lcid < 4 ? "DCCH" : "DTCH",
|
||||
lcid,
|
||||
ndata,
|
||||
bufEnd-buf-sizeof(NR_MAC_SUBHEADER_LONG));
|
||||
|
||||
if (len == 0)
|
||||
break;
|
||||
|
||||
T(T_GNB_MAC_LCID_DL, T_INT(rnti), T_INT(frame), T_INT(slot), T_INT(lcid), T_INT(len * 8), T_INT(nr_rlc_tx_list_occupancy(rnti, lcid)));
|
||||
header->R = 0;
|
||||
header->F = 1;
|
||||
header->LCID = lcid;
|
||||
header->L = htons(len);
|
||||
buf += len+sizeof(NR_MAC_SUBHEADER_LONG);
|
||||
dlsch_total_bytes += len;
|
||||
lcid_bytes += len;
|
||||
sdus += 1;
|
||||
header->L = htons(pdu_siz[j]);
|
||||
buf += pdu_siz[j] + sizeof(NR_MAC_SUBHEADER_LONG);
|
||||
dlsch_total_bytes += pdu_siz[j];
|
||||
lcid_bytes += pdu_siz[j];
|
||||
}
|
||||
|
||||
T(T_GNB_MAC_LCID_DL, T_INT(rnti), T_INT(frame), T_INT(slot), T_INT(lcid), T_INT(lcid_bytes), T_INT(nr_rlc_tx_list_occupancy(rnti, lcid)));
|
||||
UE->mac_stats.dl.lc_bytes[lcid] += lcid_bytes;
|
||||
}
|
||||
} else if (get_softmodem_params()->phy_test || get_softmodem_params()->do_ra) {
|
||||
|
||||
@@ -191,6 +191,50 @@ void nr_mac_rlc_data_ind(const module_id_t module_idP,
|
||||
nr_rlc_manager_unlock(nr_rlc_ue_manager);
|
||||
}
|
||||
|
||||
int nr_mac_rlc_multi_data_req(const module_id_t module_idP,
|
||||
const uint16_t ue_id,
|
||||
const bool gnb_flagP,
|
||||
const logical_chan_id_t channel_idP,
|
||||
tb_size_t tb_sizeP,
|
||||
char *buffer_pP,
|
||||
tb_size_t *pdu_siz,
|
||||
int pdu_siz_len)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
nr_rlc_manager_lock(nr_rlc_ue_manager);
|
||||
nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, ue_id);
|
||||
nr_rlc_entity_t *rb = get_rlc_entity_from_lcid(ue, channel_idP);
|
||||
|
||||
if (rb != NULL) {
|
||||
rb->set_time(rb, get_nr_rlc_current_time());
|
||||
while (tb_sizeP - 3 > 0 && pdu_siz_len > 0) {
|
||||
// fill PDU in buffer, store size of PDU
|
||||
pdu_siz[0] = rb->generate_pdu(rb, buffer_pP + 3, tb_sizeP - 3);
|
||||
if (pdu_siz[0] == 0)
|
||||
break;
|
||||
LOG_D(RLC, "MAC PDU created: channel_idP %d len %d\n", channel_idP, pdu_siz[0]);
|
||||
// reserve header
|
||||
tb_sizeP -= 3 + pdu_siz[0];
|
||||
buffer_pP += 3 + pdu_siz[0];
|
||||
pdu_siz++;
|
||||
pdu_siz_len--;
|
||||
ret++;
|
||||
}
|
||||
} else {
|
||||
LOG_D(RLC, "MAC PDU failed to get created for channel_idP:%d \n", channel_idP);
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
nr_rlc_manager_unlock(nr_rlc_ue_manager);
|
||||
|
||||
if (gnb_flagP)
|
||||
T(T_ENB_RLC_MAC_DL, T_INT(module_idP), T_INT(ue_id),
|
||||
T_INT(channel_idP), T_INT(ret));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
tbs_size_t nr_mac_rlc_data_req(const module_id_t module_idP,
|
||||
const uint16_t ue_id,
|
||||
const bool gnb_flagP,
|
||||
|
||||
@@ -51,6 +51,22 @@ void nr_mac_rlc_data_ind(const module_id_t module_idP,
|
||||
const bool gnb_flagP,
|
||||
const nr_rlc_data_ind_t *data,
|
||||
int num_data);
|
||||
/* \brief Fill up to pdu_siz_len RLC PDUs into buffer pointed to by buffer_pP,
|
||||
* or until tb_sizeP is reached. Each PDU is preceded by 3 bytes (nothing is
|
||||
* written) that have to be filled by the consumer (with a MAC sub-PDU
|
||||
* subheader). This function fills up to an entire TB in a single call, unlike
|
||||
* nr_mac_rlc_data_req() that fills only one RLC PDU in one step. */
|
||||
int nr_mac_rlc_multi_data_req(const module_id_t module_idP,
|
||||
const uint16_t ue_id,
|
||||
const bool gnb_flagP,
|
||||
const logical_chan_id_t channel_idP,
|
||||
const tb_size_t tb_sizeP,
|
||||
char *buffer_pP,
|
||||
tb_size_t *pdu_siz,
|
||||
int pdu_siz_len);
|
||||
/* \brief Fill one RLC PDU into buffer pointed to by buffer_pP, or until
|
||||
* tb_sizeP is reached. Note that NO header is prepended (for a MAC sub-PDU
|
||||
* subheader), and the user of the API has to fill the necessary data. */
|
||||
tbs_size_t nr_mac_rlc_data_req(const module_id_t module_idP,
|
||||
const uint16_t ue_id,
|
||||
const bool gnb_flagP,
|
||||
|
||||
Reference in New Issue
Block a user