Commit a7ab1828 authored by Cedric Roux's avatar Cedric Roux

nr rlc: don't drop packets if pdcp is in charge of dropping

Memory usage may grow in which case some warnings will be printed.
parent a63f1704
......@@ -63,7 +63,8 @@ nr_rlc_entity_t *new_nr_rlc_entity_am(
int poll_pdu,
int poll_byte,
int max_retx_threshold,
int sn_field_length)
int sn_field_length,
bool do_drop)
{
nr_rlc_entity_am_t *ret;
......@@ -117,6 +118,8 @@ nr_rlc_entity_t *new_nr_rlc_entity_am(
*/
ret->common.txsdu_avg_time_to_tx = time_average_new(100 * 1000, 1024);
ret->common.do_drop = do_drop;
return (nr_rlc_entity_t *)ret;
}
......@@ -127,7 +130,8 @@ nr_rlc_entity_t *new_nr_rlc_entity_um(
char *buf, int size),
void *deliver_sdu_data,
int t_reassembly,
int sn_field_length)
int sn_field_length,
bool do_drop)
{
nr_rlc_entity_um_t *ret;
......@@ -172,6 +176,8 @@ nr_rlc_entity_t *new_nr_rlc_entity_um(
*/
ret->common.txsdu_avg_time_to_tx = time_average_new(100 * 1000, 1024);
ret->common.do_drop = do_drop;
return (nr_rlc_entity_t *)ret;
}
......@@ -179,7 +185,8 @@ nr_rlc_entity_t *new_nr_rlc_entity_tm(
int tx_maxsize,
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity,
char *buf, int size),
void *deliver_sdu_data)
void *deliver_sdu_data,
bool do_drop)
{
nr_rlc_entity_tm_t *ret;
......@@ -212,5 +219,7 @@ nr_rlc_entity_t *new_nr_rlc_entity_tm(
*/
ret->common.txsdu_avg_time_to_tx = time_average_new(100 * 1000, 1024);
ret->common.do_drop = do_drop;
return (nr_rlc_entity_t *)ret;
}
......@@ -23,6 +23,7 @@
#define _NR_RLC_ENTITY_H_
#include <stdint.h>
#include <stdbool.h>
#include "common/utils/time_stat.h"
......@@ -144,6 +145,8 @@ typedef struct nr_rlc_entity_t {
nr_rlc_statistics_t stats;
time_average_t *txsdu_avg_time_to_tx;
int avg_time_is_on;
bool do_drop;
} nr_rlc_entity_t;
nr_rlc_entity_t *new_nr_rlc_entity_am(
......@@ -165,7 +168,8 @@ nr_rlc_entity_t *new_nr_rlc_entity_am(
int poll_pdu,
int poll_byte,
int max_retx_threshold,
int sn_field_length);
int sn_field_length,
bool do_drop);
nr_rlc_entity_t *new_nr_rlc_entity_um(
int rx_maxsize,
......@@ -174,12 +178,14 @@ nr_rlc_entity_t *new_nr_rlc_entity_um(
char *buf, int size),
void *deliver_sdu_data,
int t_reassembly,
int sn_field_length);
int sn_field_length,
bool do_drop);
nr_rlc_entity_t *new_nr_rlc_entity_tm(
int tx_maxsize,
void (*deliver_sdu)(void *deliver_sdu_data, struct nr_rlc_entity_t *entity,
char *buf, int size),
void *deliver_sdu_data);
void *deliver_sdu_data,
bool do_drop);
#endif /* _NR_RLC_ENTITY_H_ */
......@@ -1699,13 +1699,26 @@ void nr_rlc_entity_am_recv_sdu(nr_rlc_entity_t *_entity,
entity->t_log_buffer_full = entity->t_current;
}
if (entity->tx_size + size > entity->tx_maxsize) {
if (entity->common.do_drop && entity->tx_size + size > entity->tx_maxsize) {
entity->sdu_rejected++;
return;
}
entity->tx_size += size;
/* warn about excessive memory usage every tx_maxsize MB
* (might happen when RLC doesn't drop packets but PDCP does)
*/
if (entity->tx_size > entity->tx_last_warning_size &&
entity->tx_size - entity->tx_last_warning_size > entity->tx_maxsize) {
entity->tx_last_warning_size += entity->tx_maxsize;
LOG_W(RLC, "TX list memory usage is over %dMB\n",
entity->tx_last_warning_size / 1000000);
} else if (entity->tx_size < entity->tx_last_warning_size &&
entity->tx_last_warning_size - entity->tx_size > entity->tx_maxsize) {
entity->tx_last_warning_size = (entity->tx_size / entity->tx_maxsize) * entity->tx_maxsize;
}
sdu = nr_rlc_new_sdu(buffer, size, sdu_id);
LOG_D(RLC, "Created new RLC SDU and append it to the RLC list \n");
......@@ -1966,5 +1979,5 @@ void nr_rlc_entity_am_delete(nr_rlc_entity_t *_entity)
int nr_rlc_entity_am_available_tx_space(nr_rlc_entity_t *_entity)
{
nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity;
return entity->tx_maxsize - entity->tx_size;
return entity->tx_size > entity->tx_maxsize ? 0 : entity->tx_maxsize - entity->tx_size;
}
......@@ -79,6 +79,7 @@ typedef struct {
nr_rlc_sdu_segment_t *tx_end;
int tx_size;
int tx_maxsize;
int tx_last_warning_size;
nr_rlc_sdu_segment_t *wait_list;
nr_rlc_sdu_segment_t *wait_end;
......
......@@ -136,7 +136,7 @@ void nr_rlc_entity_tm_recv_sdu(nr_rlc_entity_t *_entity,
exit(1);
}
if (entity->tx_size + size > entity->tx_maxsize) {
if (entity->common.do_drop && entity->tx_size + size > entity->tx_maxsize) {
LOG_D(RLC, "%s:%d:%s: warning: SDU rejected, SDU buffer full\n",
__FILE__, __LINE__, __FUNCTION__);
......@@ -148,6 +148,19 @@ void nr_rlc_entity_tm_recv_sdu(nr_rlc_entity_t *_entity,
entity->tx_size += size;
/* warn about excessive memory usage every tx_maxsize MB
* (might happen when RLC doesn't drop packets but PDCP does)
*/
if (entity->tx_size > entity->tx_last_warning_size &&
entity->tx_size - entity->tx_last_warning_size > entity->tx_maxsize) {
entity->tx_last_warning_size += entity->tx_maxsize;
LOG_W(RLC, "TX list memory usage is over %dMB\n",
entity->tx_last_warning_size / 1000000);
} else if (entity->tx_size < entity->tx_last_warning_size &&
entity->tx_last_warning_size - entity->tx_size > entity->tx_maxsize) {
entity->tx_last_warning_size = (entity->tx_size / entity->tx_maxsize) * entity->tx_maxsize;
}
sdu = nr_rlc_new_sdu(buffer, size, sdu_id);
nr_rlc_sdu_segment_list_append(&entity->tx_list, &entity->tx_end, sdu);
......@@ -207,5 +220,5 @@ void nr_rlc_entity_tm_delete(nr_rlc_entity_t *_entity)
int nr_rlc_entity_tm_available_tx_space(nr_rlc_entity_t *_entity)
{
nr_rlc_entity_tm_t *entity = (nr_rlc_entity_tm_t *)_entity;
return entity->tx_maxsize - entity->tx_size;
return entity->tx_size > entity->tx_maxsize ? 0 : entity->tx_maxsize - entity->tx_size;
}
......@@ -36,6 +36,7 @@ typedef struct {
nr_rlc_sdu_segment_t *tx_end;
int tx_size;
int tx_maxsize;
int tx_last_warning_size;
} nr_rlc_entity_tm_t;
void nr_rlc_entity_tm_recv_sdu(nr_rlc_entity_t *entity,
......
......@@ -575,7 +575,7 @@ void nr_rlc_entity_um_recv_sdu(nr_rlc_entity_t *_entity,
exit(1);
}
if (entity->tx_size + size > entity->tx_maxsize) {
if (entity->common.do_drop && entity->tx_size + size > entity->tx_maxsize) {
LOG_W(RLC, "%s:%d:%s: warning: SDU rejected, SDU buffer full\n",
__FILE__, __LINE__, __FUNCTION__);
......@@ -587,6 +587,19 @@ void nr_rlc_entity_um_recv_sdu(nr_rlc_entity_t *_entity,
entity->tx_size += size;
/* warn about excessive memory usage every tx_maxsize MB
* (might happen when RLC doesn't drop packets but PDCP does)
*/
if (entity->tx_size > entity->tx_last_warning_size &&
entity->tx_size - entity->tx_last_warning_size > entity->tx_maxsize) {
entity->tx_last_warning_size += entity->tx_maxsize;
LOG_W(RLC, "TX list memory usage is over %dMB\n",
entity->tx_last_warning_size / 1000000);
} else if (entity->tx_size < entity->tx_last_warning_size &&
entity->tx_last_warning_size - entity->tx_size > entity->tx_maxsize) {
entity->tx_last_warning_size = (entity->tx_size / entity->tx_maxsize) * entity->tx_maxsize;
}
sdu = nr_rlc_new_sdu(buffer, size, sdu_id);
nr_rlc_sdu_segment_list_append(&entity->tx_list, &entity->tx_end, sdu);
......@@ -754,5 +767,5 @@ void nr_rlc_entity_um_delete(nr_rlc_entity_t *_entity)
int nr_rlc_entity_um_available_tx_space(nr_rlc_entity_t *_entity)
{
nr_rlc_entity_um_t *entity = (nr_rlc_entity_um_t *)_entity;
return entity->tx_maxsize - entity->tx_size;
return entity->tx_size > entity->tx_maxsize ? 0 : entity->tx_maxsize - entity->tx_size;
}
......@@ -60,6 +60,7 @@ typedef struct {
nr_rlc_sdu_segment_t *tx_end;
int tx_size;
int tx_maxsize;
int tx_last_warning_size;
} nr_rlc_entity_um_t;
void nr_rlc_entity_um_recv_sdu(nr_rlc_entity_t *entity,
......
......@@ -697,7 +697,9 @@ void nr_rlc_add_srb(int rnti, int srb_id, const NR_RLC_BearerConfig_t *rlc_Beare
t_poll_retransmit,
t_reassembly, t_status_prohibit,
poll_pdu, poll_byte, max_retx_threshold,
sn_field_length);
sn_field_length,
/* we drop in RLC if we don't drop in PDCP */
!get_softmodem_params()->pdcp_drop);
nr_rlc_ue_add_srb_rlc_entity(ue, srb_id, nr_rlc_am);
LOG_I(RLC, "%s:%d:%s: added srb %d to UE with RNTI 0x%x\n", __FILE__, __LINE__, __FUNCTION__, srb_id, rnti);
......@@ -778,7 +780,9 @@ static void add_drb_am(int rnti, int drb_id, const NR_RLC_BearerConfig_t *rlc_Be
t_poll_retransmit,
t_reassembly, t_status_prohibit,
poll_pdu, poll_byte, max_retx_threshold,
sn_field_length);
sn_field_length,
/* we drop in RLC if we don't drop in PDCP */
!get_softmodem_params()->pdcp_drop);
nr_rlc_ue_add_drb_rlc_entity(ue, drb_id, nr_rlc_am);
LOG_I(RLC, "%s:%d:%s: added drb %d to UE with RNTI 0x%x\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
......@@ -845,7 +849,9 @@ static void add_drb_um(int rnti, int drb_id, const NR_RLC_BearerConfig_t *rlc_Be
RLC_TX_MAXSIZE,
deliver_sdu, ue,
t_reassembly,
sn_field_length);
sn_field_length,
/* we drop in RLC if we don't drop in PDCP */
!get_softmodem_params()->pdcp_drop);
nr_rlc_ue_add_drb_rlc_entity(ue, drb_id, nr_rlc_um);
LOG_D(RLC, "%s:%d:%s: added drb %d to UE with RNTI 0x%x\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti);
......@@ -931,7 +937,9 @@ void nr_rlc_activate_srb0(int rnti, struct gNB_MAC_INST_s *mac, void *rawUE,
}
nr_rlc_tm = new_nr_rlc_entity_tm(10000,
deliver_sdu_srb0, srb0_data);
deliver_sdu_srb0, srb0_data,
/* we drop in RLC if we don't drop in PDCP */
!get_softmodem_params()->pdcp_drop);
nr_rlc_ue_add_srb_rlc_entity(ue, 0, nr_rlc_tm);
LOG_I(RLC, "activated srb0 for UE with RNTI 0x%x\n", rnti);
......
#include "nr_rlc_entity.h"
#include <stdio.h>
int main(void)
{
char out[32768];
nr_rlc_entity_t *am;
int sdu_id = 0;
int size;
int i;
am = new_nr_rlc_entity_am(100000, 100000,
0, 0,
0, 0,
0, 0,
45, 35, 0,
-1, -1, 8,
12);
char data[8] = { 1, 2, 3, 4, 8, 7, 6, 5 };
am->recv_sdu(am, data, sizeof(data), sdu_id++);
size = am->generate_pdu(am, out, 32768);
printf("generate_pdu[%d]:", size);
for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)out[i]);
printf("\n");
return 0;
}
......@@ -262,7 +262,8 @@ int test_main(void)
max_retx_reached_gnb, NULL,
test[pos+3], test[pos+4], test[pos+5],
test[pos+6], test[pos+7], test[pos+8],
test[pos+9]);
test[pos+9],
true);
pos += 10;
break;
case UE_AM:
......@@ -272,27 +273,30 @@ int test_main(void)
max_retx_reached_ue, NULL,
test[pos+3], test[pos+4], test[pos+5],
test[pos+6], test[pos+7], test[pos+8],
test[pos+9]);
test[pos+9],
true);
pos += 10;
break;
case GNB_UM:
gnb = new_nr_rlc_entity_um(test[pos+1], test[pos+2],
deliver_sdu_gnb_um, NULL,
test[pos+3], test[pos+4]);
test[pos+3], test[pos+4],
true);
pos += 5;
break;
case UE_UM:
ue = new_nr_rlc_entity_um(test[pos+1], test[pos+2],
deliver_sdu_ue_um, NULL,
test[pos+3], test[pos+4]);
test[pos+3], test[pos+4],
true);
pos += 5;
break;
case GNB_TM:
gnb = new_nr_rlc_entity_tm(test[pos+1], deliver_sdu_gnb_tm, NULL);
gnb = new_nr_rlc_entity_tm(test[pos+1], deliver_sdu_gnb_tm, NULL, true);
pos += 2;
break;
case UE_TM:
ue = new_nr_rlc_entity_tm(test[pos+1], deliver_sdu_ue_tm, NULL);
ue = new_nr_rlc_entity_tm(test[pos+1], deliver_sdu_ue_tm, NULL, true);
pos += 2;
break;
case GNB_SDU:
......
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