Commit 97c69dc4 authored by Robert Schmidt's avatar Robert Schmidt

Drop traffic in PDCP if RLC buffer is full

If the buffer in the RLC is full, testing the buffer state over and over again
slows the DL traffic down. In order to circumvent this, the PDCP will drop any
data during a configurable time (compile-time) before it delivers data to RLC
again.

To change this, see the constant TM_SKIP_FULL_BUF_MS in pdcp.h.
parent 3b80c73f
...@@ -169,6 +169,11 @@ boolean_t pdcp_data_req( ...@@ -169,6 +169,11 @@ boolean_t pdcp_data_req(
start_meas(&UE_pdcp_stats[ctxt_pP->module_id].data_req); start_meas(&UE_pdcp_stats[ctxt_pP->module_id].data_req);
} }
for (pdcp_uid = 0; pdcp_uid < MAX_MOBILES_PER_ENB; ++pdcp_uid) {
if (pdcp_enb[ctxt_pP->module_id].rnti[pdcp_uid] == ctxt_pP->rnti)
break;
}
// PDCP transparent mode for MBMS traffic // PDCP transparent mode for MBMS traffic
if (modeP == PDCP_TRANSMISSION_MODE_TRANSPARENT) { if (modeP == PDCP_TRANSMISSION_MODE_TRANSPARENT) {
...@@ -366,13 +371,24 @@ boolean_t pdcp_data_req( ...@@ -366,13 +371,24 @@ boolean_t pdcp_data_req(
LOG_DUMPMSG(PDCP,DEBUG_PDCP,(char *)pdcp_pdu_p->data,pdcp_pdu_size, LOG_DUMPMSG(PDCP,DEBUG_PDCP,(char *)pdcp_pdu_p->data,pdcp_pdu_size,
"[MSG] PDCP DL %s PDU on rb_id %d\n",(srb_flagP)? "CONTROL" : "DATA", rb_idP); "[MSG] PDCP DL %s PDU on rb_id %d\n",(srb_flagP)? "CONTROL" : "DATA", rb_idP);
rlc_status = rlc_data_req(ctxt_pP, srb_flagP, MBMS_FLAG_NO, rb_idP, muiP, confirmP, pdcp_pdu_size, pdcp_pdu_p /* if RLC buffer for this UE has been full, we want to skip all subsequent
* traffic for TM_SKIP_FULL_BUF_MS ms. Afterwards, it will be checkd again */
if (pdcp_enb[ctxt_pP->module_id].time_buf_full[pdcp_uid] == 0
|| pdcp_enb[ctxt_pP->module_id].sfn - pdcp_enb[ctxt_pP->module_id].time_buf_full[pdcp_uid] >= TM_SKIP_FULL_BUF_MS) {
pdcp_enb[ctxt_pP->module_id].time_buf_full[pdcp_uid] = 0;
rlc_status = rlc_data_req(ctxt_pP, srb_flagP, MBMS_FLAG_NO, rb_idP, muiP,
confirmP, pdcp_pdu_size, pdcp_pdu_p
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
,sourceL2Id ,sourceL2Id
,destinationL2Id ,destinationL2Id
#endif #endif
); );
} else {
/* RLC would free pdcp_pdu_p, but since we skip it, have to do it
* ourselves and fake normal operation */
free_mem_block(pdcp_pdu_p, __func__);
rlc_status = RLC_OP_SKIPPED_FUL_BUF;
}
} }
switch (rlc_status) { switch (rlc_status) {
...@@ -392,10 +408,19 @@ boolean_t pdcp_data_req( ...@@ -392,10 +408,19 @@ boolean_t pdcp_data_req(
break; break;
case RLC_OP_STATUS_OUT_OF_RESSOURCES: case RLC_OP_STATUS_OUT_OF_RESSOURCES:
pdcp_enb[ctxt_pP->module_id].time_buf_full[pdcp_uid] = pdcp_enb[ctxt_pP->module_id].sfn;
LOG_W(PDCP, "Data sending request over RLC failed with 'Out of Resources' reason!\n"); LOG_W(PDCP, "Data sending request over RLC failed with 'Out of Resources' reason!\n");
int h = TM_SKIP_FULL_BUF_MS;
LOG_W(PDCP, "Blocking incoming traffic for %d ms\n", h);
ret= FALSE; ret= FALSE;
break; break;
case RLC_OP_SKIPPED_FUL_BUF:
LOG_D(PDCP, "Skipping RLC request due to full buffer\n");
/* fake good return so that GTP doesn't spam us */
ret = TRUE;
break;
default: default:
LOG_W(PDCP, "RLC returned an unknown status code after PDCP placed the order to send some data (Status Code:%d)\n", rlc_status); LOG_W(PDCP, "RLC returned an unknown status code after PDCP placed the order to send some data (Status Code:%d)\n", rlc_status);
ret= FALSE; ret= FALSE;
...@@ -408,16 +433,6 @@ boolean_t pdcp_data_req( ...@@ -408,16 +433,6 @@ boolean_t pdcp_data_req(
stop_meas(&UE_pdcp_stats[ctxt_pP->module_id].data_req); stop_meas(&UE_pdcp_stats[ctxt_pP->module_id].data_req);
} }
/*
* Control arrives here only if rlc_data_req() returns RLC_OP_STATUS_OK
* so we return TRUE afterwards
*/
for (pdcp_uid=0; pdcp_uid< MAX_MOBILES_PER_ENB;pdcp_uid++){
if (pdcp_enb[ctxt_pP->module_id].rnti[pdcp_uid] == ctxt_pP->rnti )
break;
}
//LOG_I(PDCP,"ueid %d lcid %d tx seq num %d\n", pdcp_uid, rb_idP+rb_offset, current_sn); //LOG_I(PDCP,"ueid %d lcid %d tx seq num %d\n", pdcp_uid, rb_idP+rb_offset, current_sn);
Pdcp_stats_tx[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; Pdcp_stats_tx[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++;
Pdcp_stats_tx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++; Pdcp_stats_tx_tmp_w[ctxt_pP->module_id][pdcp_uid][rb_idP+rb_offset]++;
...@@ -1066,6 +1081,7 @@ void pdcp_add_UE(const protocol_ctxt_t* const ctxt_pP){ ...@@ -1066,6 +1081,7 @@ void pdcp_add_UE(const protocol_ctxt_t* const ctxt_pP){
if (pdcp_enb[ctxt_pP->module_id].rnti[i] == 0 ){ if (pdcp_enb[ctxt_pP->module_id].rnti[i] == 0 ){
pdcp_enb[ctxt_pP->module_id].rnti[i]=ctxt_pP->rnti; pdcp_enb[ctxt_pP->module_id].rnti[i]=ctxt_pP->rnti;
pdcp_enb[ctxt_pP->module_id].uid[i]=i; pdcp_enb[ctxt_pP->module_id].uid[i]=i;
pdcp_enb[ctxt_pP->module_id].time_buf_full[i] = 0;
pdcp_enb[ctxt_pP->module_id].num_ues++; pdcp_enb[ctxt_pP->module_id].num_ues++;
printf("add new uid is %d %x\n\n", i, ctxt_pP->rnti); printf("add new uid is %d %x\n\n", i, ctxt_pP->rnti);
// ret=1; // ret=1;
......
...@@ -106,6 +106,8 @@ typedef struct pdcp_enb_s { ...@@ -106,6 +106,8 @@ typedef struct pdcp_enb_s {
uint16_t uid[MAX_MOBILES_PER_ENB]; uint16_t uid[MAX_MOBILES_PER_ENB];
rnti_t rnti[MAX_MOBILES_PER_ENB]; rnti_t rnti[MAX_MOBILES_PER_ENB];
uint16_t num_ues; uint16_t num_ues;
#define TM_SKIP_FULL_BUF_MS (500)
uint64_t time_buf_full[MAX_MOBILES_PER_ENB];
uint64_t sfn; uint64_t sfn;
frame_t frame; frame_t frame;
......
...@@ -67,6 +67,7 @@ typedef uint64_t hash_key_t; ...@@ -67,6 +67,7 @@ typedef uint64_t hash_key_t;
#define RLC_OP_STATUS_BAD_PARAMETER 22 #define RLC_OP_STATUS_BAD_PARAMETER 22
#define RLC_OP_STATUS_INTERNAL_ERROR 2 #define RLC_OP_STATUS_INTERNAL_ERROR 2
#define RLC_OP_STATUS_OUT_OF_RESSOURCES 3 #define RLC_OP_STATUS_OUT_OF_RESSOURCES 3
#define RLC_OP_SKIPPED_FUL_BUF 4
#define RLC_MUI_UNDEFINED (mui_t)0 #define RLC_MUI_UNDEFINED (mui_t)0
......
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