Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-RAN
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lizhongxiao
OpenXG-RAN
Commits
3317f276
Commit
3317f276
authored
Dec 13, 2023
by
Sakthivel Velumani
Committed by
Chieh-Chun Chen
Feb 16, 2024
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add support for multiple slices per UE
parent
bdaff4aa
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
211 additions
and
53 deletions
+211
-53
common/utils/nr/nr_common.h
common/utils/nr/nr_common.h
+1
-0
openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
+23
-16
openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
+54
-0
openair2/LAYER2/NR_MAC_gNB/mac_proto.h
openair2/LAYER2/NR_MAC_gNB/mac_proto.h
+2
-0
openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c
openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c
+34
-4
openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
+18
-1
openair2/LAYER2/NR_MAC_gNB/slicing/nr_slicing.c
openair2/LAYER2/NR_MAC_gNB/slicing/nr_slicing.c
+78
-31
openair2/LAYER2/NR_MAC_gNB/slicing/nr_slicing.h
openair2/LAYER2/NR_MAC_gNB/slicing/nr_slicing.h
+1
-1
No files found.
common/utils/nr/nr_common.h
View file @
3317f276
...
@@ -44,6 +44,7 @@
...
@@ -44,6 +44,7 @@
#define NR_NB_SC_PER_RB 12
#define NR_NB_SC_PER_RB 12
#define NR_MAX_NUM_LCID 32
#define NR_MAX_NUM_LCID 32
#define NR_MAX_NUM_QFI 64
#define NR_MAX_NUM_QFI 64
#define NR_MAX_NUM_SLICES 10
#define RNTI_NAMES
/* see 38.321 Table 7.1-2 RNTI usage */
\
#define RNTI_NAMES
/* see 38.321 Table 7.1-2 RNTI usage */
\
R(TYPE_C_RNTI_)
/* Cell RNTI */
\
R(TYPE_C_RNTI_)
/* Cell RNTI */
\
R(TYPE_CS_RNTI_)
/* Configured Scheduling RNTI */
\
R(TYPE_CS_RNTI_)
/* Configured Scheduling RNTI */
\
...
...
openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
View file @
3317f276
...
@@ -317,12 +317,15 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP,
...
@@ -317,12 +317,15 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP,
return
offset
;
return
offset
;
}
}
void
nr_store_dlsch_buffer
(
module_id_t
module_id
,
frame_t
frame
,
sub_frame_t
slot
)
static
void
nr_store_dlsch_buffer
(
module_id_t
module_id
,
frame_t
frame
,
sub_frame_t
slot
)
{
{
UE_iterator
(
RC
.
nrmac
[
module_id
]
->
UE_info
.
list
,
UE
)
{
UE_iterator
(
RC
.
nrmac
[
module_id
]
->
UE_info
.
list
,
UE
)
{
NR_UE_sched_ctrl_t
*
sched_ctrl
=
&
UE
->
UE_sched_ctrl
;
NR_UE_sched_ctrl_t
*
sched_ctrl
=
&
UE
->
UE_sched_ctrl
;
sched_ctrl
->
num_total_bytes
=
0
;
/* add all LCID to fist slice. This is to have a common post-processor function for both slicing and non-slicing scheduler */
sched_ctrl
->
dl_pdus_total
=
0
;
sched_ctrl
->
last_sched_slice
=
0
;
sched_ctrl
->
sliceInfo
[
sched_ctrl
->
last_sched_slice
].
num_total_bytes
=
0
;
sched_ctrl
->
sliceInfo
[
sched_ctrl
->
last_sched_slice
].
dl_pdus_total
=
0
;
reset_nr_list
(
&
sched_ctrl
->
sliceInfo
[
sched_ctrl
->
last_sched_slice
].
lcid
);
/* loop over all activated logical channels */
/* loop over all activated logical channels */
// Note: DL_SCH_LCID_DCCH, DL_SCH_LCID_DCCH1, DL_SCH_LCID_DTCH
// Note: DL_SCH_LCID_DCCH, DL_SCH_LCID_DCCH1, DL_SCH_LCID_DTCH
...
@@ -349,20 +352,22 @@ void nr_store_dlsch_buffer(module_id_t module_id, frame_t frame, sub_frame_t slo
...
@@ -349,20 +352,22 @@ void nr_store_dlsch_buffer(module_id_t module_id, frame_t frame, sub_frame_t slo
if
(
sched_ctrl
->
rlc_status
[
lcid
].
bytes_in_buffer
==
0
)
if
(
sched_ctrl
->
rlc_status
[
lcid
].
bytes_in_buffer
==
0
)
continue
;
continue
;
sched_ctrl
->
dl_pdus_total
+=
sched_ctrl
->
rlc_status
[
lcid
].
pdus_in_buffer
;
sched_ctrl
->
sliceInfo
[
sched_ctrl
->
last_sched_slice
].
dl_pdus_total
+=
sched_ctrl
->
rlc_status
[
lcid
].
pdus_in_buffer
;
sched_ctrl
->
num_total_bytes
+=
sched_ctrl
->
rlc_status
[
lcid
].
bytes_in_buffer
;
sched_ctrl
->
sliceInfo
[
sched_ctrl
->
last_sched_slice
].
num_total_bytes
+=
sched_ctrl
->
rlc_status
[
lcid
].
bytes_in_buffer
;
add_nr_list
(
&
sched_ctrl
->
sliceInfo
[
sched_ctrl
->
last_sched_slice
].
lcid
,
lcid
);
LOG_D
(
MAC
,
LOG_D
(
MAC
,
"[gNB %d][%4d.%2d] %s%d->DLSCH, RLC status for UE %d: %d bytes in buffer, total DL buffer size = %d bytes, %d total PDU bytes, %s TA command
\n
"
,
"[gNB %d][%4d.%2d] %s%d->DLSCH, RLC status for UE %d: %d bytes in buffer, total DL buffer size = %d bytes, %d total "
"PDU bytes, %s TA command
\n
"
,
module_id
,
module_id
,
frame
,
frame
,
slot
,
slot
,
lcid
<
4
?
"DCCH"
:
"DTCH"
,
lcid
<
4
?
"DCCH"
:
"DTCH"
,
lcid
,
lcid
,
UE
->
rnti
,
UE
->
rnti
,
sched_ctrl
->
rlc_status
[
lcid
].
bytes_in_buffer
,
sched_ctrl
->
rlc_status
[
lcid
].
bytes_in_buffer
,
sched_ctrl
->
num_total_bytes
,
sched_ctrl
->
sliceInfo
[
sched_ctrl
->
last_sched_slice
].
num_total_bytes
,
sched_ctrl
->
dl_pdus_total
,
sched_ctrl
->
sliceInfo
[
sched_ctrl
->
last_sched_slice
].
dl_pdus_total
,
sched_ctrl
->
ta_apply
?
"send"
:
"do not send"
);
sched_ctrl
->
ta_apply
?
"send"
:
"do not send"
);
}
}
}
}
}
}
...
@@ -673,7 +678,7 @@ static int nr_pf_dl(module_id_t module_id,
...
@@ -673,7 +678,7 @@ static int nr_pf_dl(module_id_t module_id,
}
}
/* Check DL buffer and skip this UE if no bytes and no TA necessary */
/* Check DL buffer and skip this UE if no bytes and no TA necessary */
if
(
sched_ctrl
->
num_total_bytes
==
0
&&
frame
!=
(
sched_ctrl
->
ta_frame
+
10
)
%
1024
)
if
(
sched_ctrl
->
sliceInfo
[
sched_ctrl
->
last_sched_slice
].
num_total_bytes
==
0
&&
frame
!=
(
sched_ctrl
->
ta_frame
+
10
)
%
1024
)
continue
;
continue
;
/* Calculate coeff */
/* Calculate coeff */
...
@@ -826,7 +831,7 @@ static int nr_pf_dl(module_id_t module_id,
...
@@ -826,7 +831,7 @@ static int nr_pf_dl(module_id_t module_id,
sched_pdsch
->
nrOfLayers
,
sched_pdsch
->
nrOfLayers
,
tda_info
->
nrOfSymbols
,
tda_info
->
nrOfSymbols
,
sched_pdsch
->
dmrs_parms
.
N_PRB_DMRS
*
sched_pdsch
->
dmrs_parms
.
N_DMRS_SLOT
,
sched_pdsch
->
dmrs_parms
.
N_PRB_DMRS
*
sched_pdsch
->
dmrs_parms
.
N_DMRS_SLOT
,
sched_ctrl
->
num_total_bytes
+
oh
,
sched_ctrl
->
sliceInfo
[
sched_ctrl
->
last_sched_slice
].
num_total_bytes
+
oh
,
min_rbSize
,
min_rbSize
,
max_rbSize
,
max_rbSize
,
&
TBS
,
&
TBS
,
...
@@ -1288,10 +1293,11 @@ void nr_schedule_ue_spec(module_id_t module_id,
...
@@ -1288,10 +1293,11 @@ void nr_schedule_ue_spec(module_id_t module_id,
start_meas
(
&
gNB_mac
->
rlc_data_req
);
start_meas
(
&
gNB_mac
->
rlc_data_req
);
int
sdus
=
0
;
int
sdus
=
0
;
if
(
sched_ctrl
->
num_total_bytes
>
0
)
{
if
(
sched_ctrl
->
sliceInfo
[
sched_ctrl
->
last_sched_slice
].
num_total_bytes
>
0
)
{
/* loop over all activated logical channels */
/* loop over all activated logical channels in this slice */
for
(
int
i
=
0
;
i
<
sched_ctrl
->
dl_lc_num
;
++
i
)
{
NR_List_Iterator
(
&
sched_ctrl
->
sliceInfo
[
sched_ctrl
->
last_sched_slice
].
lcid
,
lcidP
)
const
int
lcid
=
sched_ctrl
->
dl_lc_ids
[
i
];
{
const
int
lcid
=
*
lcidP
;
if
(
sched_ctrl
->
rlc_status
[
lcid
].
bytes_in_buffer
==
0
)
if
(
sched_ctrl
->
rlc_status
[
lcid
].
bytes_in_buffer
==
0
)
continue
;
// no data for this LC tbs_size_t len = 0;
continue
;
// no data for this LC tbs_size_t len = 0;
...
@@ -1343,6 +1349,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
...
@@ -1343,6 +1349,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
UE
->
mac_stats
.
dl
.
lc_bytes
[
lcid
]
+=
lcid_bytes
;
UE
->
mac_stats
.
dl
.
lc_bytes
[
lcid
]
+=
lcid_bytes
;
}
}
sched_ctrl
->
harq_slice_map
[
sched_ctrl
->
sched_pdsch
.
dl_harq_pid
]
=
sched_ctrl
->
last_sched_slice
;
}
else
if
(
get_softmodem_params
()
->
phy_test
||
get_softmodem_params
()
->
do_ra
)
{
}
else
if
(
get_softmodem_params
()
->
phy_test
||
get_softmodem_params
()
->
do_ra
)
{
/* we will need the large header, phy-test typically allocates all
/* we will need the large header, phy-test typically allocates all
* resources and fills to the last byte below */
* resources and fills to the last byte below */
...
...
openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
View file @
3317f276
...
@@ -57,6 +57,7 @@
...
@@ -57,6 +57,7 @@
#define DEBUG_gNB_SCHEDULER 1
#define DEBUG_gNB_SCHEDULER 1
#include "common/ran_context.h"
#include "common/ran_context.h"
#include "NR_MAC_gNB/slicing/nr_slicing.h"
//#define DEBUG_DCI
//#define DEBUG_DCI
...
@@ -1842,6 +1843,30 @@ void create_nr_list(NR_list_t *list, int len)
...
@@ -1842,6 +1843,30 @@ void create_nr_list(NR_list_t *list, int len)
list
->
len
=
len
;
list
->
len
=
len
;
}
}
/*
* Reset NR_list
*/
void
reset_nr_list
(
NR_list_t
*
list
)
{
list
->
head
=
-
1
;
memset
(
list
->
next
,
-
1
,
list
->
len
);
list
->
tail
=
-
1
;
}
/*
* Check if id is in the list
*/
bool
check_nr_list
(
const
NR_list_t
*
listP
,
int
id
)
{
const
int
*
cur
=
&
listP
->
head
;
while
(
*
cur
>=
0
)
{
if
(
*
cur
==
id
)
return
true
;
cur
=
&
listP
->
next
[
*
cur
];
}
return
false
;
}
/*
/*
* Resize an NR_list
* Resize an NR_list
*/
*/
...
@@ -2018,6 +2043,10 @@ void delete_nr_ue_data(NR_UE_info_t *UE, NR_COMMON_channels_t *ccPtr, uid_alloca
...
@@ -2018,6 +2043,10 @@ void delete_nr_ue_data(NR_UE_info_t *UE, NR_COMMON_channels_t *ccPtr, uid_alloca
destroy_nr_list
(
&
sched_ctrl
->
retrans_ul_harq
);
destroy_nr_list
(
&
sched_ctrl
->
retrans_ul_harq
);
free_sched_pucch_list
(
sched_ctrl
);
free_sched_pucch_list
(
sched_ctrl
);
uid_linear_allocator_free
(
uia
,
UE
->
uid
);
uid_linear_allocator_free
(
uia
,
UE
->
uid
);
for
(
int
slice
=
0
;
slice
<
NR_MAX_NUM_SLICES
;
slice
++
)
{
destroy_nr_list
(
&
sched_ctrl
->
sliceInfo
[
slice
].
lcid
);
}
destroy_nr_list
(
&
UE
->
dl_id
);
LOG_I
(
NR_MAC
,
"Remove NR rnti 0x%04x
\n
"
,
UE
->
rnti
);
LOG_I
(
NR_MAC
,
"Remove NR rnti 0x%04x
\n
"
,
UE
->
rnti
);
free
(
UE
);
free
(
UE
);
}
}
...
@@ -2430,6 +2459,12 @@ NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConf
...
@@ -2430,6 +2459,12 @@ NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConf
reset_srs_stats
(
UE
);
reset_srs_stats
(
UE
);
/* prepare LC list for all slices in this UE */
for
(
int
slice
=
0
;
slice
<
NR_MAX_NUM_SLICES
;
slice
++
)
{
create_nr_list
(
&
sched_ctrl
->
sliceInfo
[
slice
].
lcid
,
NR_MAX_NUM_LCID
);
}
create_nr_list
(
&
UE
->
dl_id
,
NR_MAX_NUM_SLICES
);
// associate UEs to the first slice if slice exists (there is no DRB setup in this stage)
// associate UEs to the first slice if slice exists (there is no DRB setup in this stage)
nr_pp_impl_param_dl_t
*
dl
=
&
RC
.
nrmac
[
0
]
->
pre_processor_dl
;
nr_pp_impl_param_dl_t
*
dl
=
&
RC
.
nrmac
[
0
]
->
pre_processor_dl
;
if
(
dl
->
slices
)
if
(
dl
->
slices
)
...
@@ -2573,6 +2608,14 @@ void mac_remove_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rnti)
...
@@ -2573,6 +2608,14 @@ void mac_remove_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rnti)
return
;
return
;
}
}
/* Dissociate UE from all corresponding slice*/
nr_pp_impl_param_dl_t
*
dl
=
&
nr_mac
->
pre_processor_dl
;
if
(
dl
->
slices
)
{
for
(
int
i
=
0
;
i
<
dl
->
slices
->
num
;
i
++
)
{
dl
->
remove_UE
(
dl
->
slices
,
UE
,
i
);
}
}
NR_UE_info_t
*
newUEs
[
MAX_MOBILES_PER_GNB
+
1
]
=
{
0
};
NR_UE_info_t
*
newUEs
[
MAX_MOBILES_PER_GNB
+
1
]
=
{
0
};
int
newListIdx
=
0
;
int
newListIdx
=
0
;
for
(
int
i
=
0
;
i
<
MAX_MOBILES_PER_GNB
;
i
++
)
for
(
int
i
=
0
;
i
<
MAX_MOBILES_PER_GNB
;
i
++
)
...
@@ -3044,6 +3087,17 @@ void prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE)
...
@@ -3044,6 +3087,17 @@ void prepare_initial_ul_rrc_message(gNB_MAC_INST *mac, NR_UE_info_t *UE)
UE
->
CellGroup
=
cellGroupConfig
;
UE
->
CellGroup
=
cellGroupConfig
;
process_CellGroup
(
cellGroupConfig
,
UE
);
process_CellGroup
(
cellGroupConfig
,
UE
);
/* Assign SRB1 to default slice */
const
long
lcid
=
1
;
nr_pp_impl_param_dl_t
*
dl
=
&
mac
->
pre_processor_dl
;
if
(
dl
->
slices
)
{
nssai_t
*
default_nssai
=
&
dl
->
slices
->
s
[
0
]
->
nssai
;
UE
->
UE_sched_ctrl
.
dl_lc_nssai
[
lcid
]
=
*
default_nssai
;
LOG_I
(
NR_MAC
,
"Setting NSSAI sst: %d, sd: %d for SRB: %ld
\n
"
,
default_nssai
->
sst
,
default_nssai
->
sd
,
lcid
);
dl
->
add_UE
(
dl
->
slices
,
UE
);
}
/* activate SRB0 */
/* activate SRB0 */
nr_rlc_activate_srb0
(
UE
->
rnti
,
UE
,
send_initial_ul_rrc_message
);
nr_rlc_activate_srb0
(
UE
->
rnti
,
UE
,
send_initial_ul_rrc_message
);
...
...
openair2/LAYER2/NR_MAC_gNB/mac_proto.h
View file @
3317f276
...
@@ -298,6 +298,8 @@ void remove_nr_list(NR_list_t *listP, int id);
...
@@ -298,6 +298,8 @@ void remove_nr_list(NR_list_t *listP, int id);
void
add_tail_nr_list
(
NR_list_t
*
listP
,
int
id
);
void
add_tail_nr_list
(
NR_list_t
*
listP
,
int
id
);
void
add_front_nr_list
(
NR_list_t
*
listP
,
int
id
);
void
add_front_nr_list
(
NR_list_t
*
listP
,
int
id
);
void
remove_front_nr_list
(
NR_list_t
*
listP
);
void
remove_front_nr_list
(
NR_list_t
*
listP
);
void
reset_nr_list
(
NR_list_t
*
listP
);
bool
check_nr_list
(
const
NR_list_t
*
listP
,
int
id
);
NR_UE_info_t
*
find_nr_UE
(
NR_UEs_t
*
UEs
,
rnti_t
rntiP
);
NR_UE_info_t
*
find_nr_UE
(
NR_UEs_t
*
UEs
,
rnti_t
rntiP
);
...
...
openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c
View file @
3317f276
...
@@ -25,6 +25,7 @@
...
@@ -25,6 +25,7 @@
#include "openair2/F1AP/f1ap_ids.h"
#include "openair2/F1AP/f1ap_ids.h"
#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h"
#include "openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h"
#include "F1AP_CauseRadioNetwork.h"
#include "F1AP_CauseRadioNetwork.h"
#include "NR_MAC_gNB/slicing/nr_slicing.h"
#include "uper_decoder.h"
#include "uper_decoder.h"
#include "uper_encoder.h"
#include "uper_encoder.h"
...
@@ -237,8 +238,25 @@ NR_CellGroupConfig_t *clone_CellGroupConfig(const NR_CellGroupConfig_t *orig)
...
@@ -237,8 +238,25 @@ NR_CellGroupConfig_t *clone_CellGroupConfig(const NR_CellGroupConfig_t *orig)
return
cloned
;
return
cloned
;
}
}
static
void
set_nssaiConfig
(
const
int
drb_len
,
const
f1ap_drb_to_be_setup_t
*
req_drbs
,
NR_UE_sched_ctrl_t
*
sched_ctrl
)
static
void
set_nssaiConfig
(
const
int
srb_len
,
const
f1ap_srb_to_be_setup_t
*
req_srbs
,
const
int
drb_len
,
const
f1ap_drb_to_be_setup_t
*
req_drbs
,
NR_UE_sched_ctrl_t
*
sched_ctrl
)
{
{
gNB_MAC_INST
*
mac
=
RC
.
nrmac
[
0
];
for
(
int
i
=
0
;
i
<
srb_len
;
i
++
)
{
const
f1ap_srb_to_be_setup_t
*
srb
=
&
req_srbs
[
i
];
const
long
lcid
=
get_lcid_from_srbid
(
srb
->
srb_id
);
/* consider first slice as default slice and assign it for SRBs */
nr_pp_impl_param_dl_t
*
dl
=
&
mac
->
pre_processor_dl
;
if
(
dl
->
slices
)
{
nssai_t
*
default_nssai
=
&
dl
->
slices
->
s
[
0
]
->
nssai
;
sched_ctrl
->
dl_lc_nssai
[
lcid
]
=
*
default_nssai
;
LOG_I
(
NR_MAC
,
"Setting NSSAI sst: %d, sd: %d for SRB: %ld
\n
"
,
default_nssai
->
sst
,
default_nssai
->
sd
,
srb
->
srb_id
);
}
}
for
(
int
i
=
0
;
i
<
drb_len
;
i
++
)
{
for
(
int
i
=
0
;
i
<
drb_len
;
i
++
)
{
const
f1ap_drb_to_be_setup_t
*
drb
=
&
req_drbs
[
i
];
const
f1ap_drb_to_be_setup_t
*
drb
=
&
req_drbs
[
i
];
...
@@ -358,8 +376,16 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req)
...
@@ -358,8 +376,16 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req)
set_QoSConfig
(
req
,
&
UE
->
UE_sched_ctrl
);
set_QoSConfig
(
req
,
&
UE
->
UE_sched_ctrl
);
/* Set NSSAI config in MAC for each active DRB */
/* Set NSSAI config in MAC for each active DRB */
set_nssaiConfig
(
req
->
drbs_to_be_setup_length
,
req
->
drbs_to_be_setup
,
&
UE
->
UE_sched_ctrl
);
set_nssaiConfig
(
req
->
srbs_to_be_setup_length
,
req
->
srbs_to_be_setup
,
req
->
drbs_to_be_setup_length
,
req
->
drbs_to_be_setup
,
&
UE
->
UE_sched_ctrl
);
/* Associate UE to the corresponding slice*/
nr_pp_impl_param_dl_t
*
dl
=
&
mac
->
pre_processor_dl
;
if
(
dl
->
slices
)
dl
->
add_UE
(
dl
->
slices
,
UE
);
NR_SCHED_UNLOCK
(
&
mac
->
sched_lock
);
NR_SCHED_UNLOCK
(
&
mac
->
sched_lock
);
/* some sanity checks, since we use the same type for request and response */
/* some sanity checks, since we use the same type for request and response */
...
@@ -461,7 +487,11 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req)
...
@@ -461,7 +487,11 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req)
set_QoSConfig
(
req
,
&
UE
->
UE_sched_ctrl
);
set_QoSConfig
(
req
,
&
UE
->
UE_sched_ctrl
);
/* Set NSSAI config in MAC for each active DRB */
/* Set NSSAI config in MAC for each active DRB */
set_nssaiConfig
(
req
->
drbs_to_be_setup_length
,
req
->
drbs_to_be_setup
,
&
UE
->
UE_sched_ctrl
);
set_nssaiConfig
(
req
->
srbs_to_be_setup_length
,
req
->
srbs_to_be_setup
,
req
->
drbs_to_be_setup_length
,
req
->
drbs_to_be_setup
,
&
UE
->
UE_sched_ctrl
);
/* Associate UE to the corresponding slice*/
/* Associate UE to the corresponding slice*/
nr_pp_impl_param_dl_t
*
dl
=
&
mac
->
pre_processor_dl
;
nr_pp_impl_param_dl_t
*
dl
=
&
mac
->
pre_processor_dl
;
...
...
openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h
View file @
3317f276
...
@@ -111,6 +111,8 @@ typedef struct {
...
@@ -111,6 +111,8 @@ typedef struct {
int
len
;
int
len
;
}
NR_list_t
;
}
NR_list_t
;
#define NR_List_Iterator(BaSe, CuR) for (int *CuR = &(BaSe)->head, *nxt = (BaSe)->next; *CuR >= 0; CuR = &nxt[*CuR])
typedef
enum
{
typedef
enum
{
RA_IDLE
=
0
,
RA_IDLE
=
0
,
Msg2
=
1
,
Msg2
=
1
,
...
@@ -543,6 +545,14 @@ typedef struct NR_QoS_config_s {
...
@@ -543,6 +545,14 @@ typedef struct NR_QoS_config_s {
uint64_t
priority
;
uint64_t
priority
;
}
NR_QoS_config_t
;
}
NR_QoS_config_t
;
typedef
struct
{
/// LCs in this slice
NR_list_t
lcid
;
/// total amount of data awaiting for this UE
uint32_t
num_total_bytes
;
uint16_t
dl_pdus_total
;
}
NR_UE_slice_info_t
;
/*! \brief scheduling control information set through an API */
/*! \brief scheduling control information set through an API */
#define MAX_CSI_REPORTS 48
#define MAX_CSI_REPORTS 48
typedef
struct
{
typedef
struct
{
...
@@ -643,6 +653,13 @@ typedef struct {
...
@@ -643,6 +653,13 @@ typedef struct {
nr_srs_feedback_t
srs_feedback
;
nr_srs_feedback_t
srs_feedback
;
nssai_t
dl_lc_nssai
[
NR_MAX_NUM_LCID
];
nssai_t
dl_lc_nssai
[
NR_MAX_NUM_LCID
];
/// last scheduled slice index
int
last_sched_slice
;
/// hold information of slices
NR_UE_slice_info_t
sliceInfo
[
NR_MAX_NUM_SLICES
];
/// DL harq to slice map
int
harq_slice_map
[
NR_MAX_HARQ_PROCESSES
];
// Information about the QoS configuration for each LCID/DRB
// Information about the QoS configuration for each LCID/DRB
NR_QoS_config_t
qos_config
[
NR_MAX_NUM_LCID
-
4
][
NR_MAX_NUM_QFI
];
// 0 -CCCH and 1- 3 SRBs(0,1,2)
NR_QoS_config_t
qos_config
[
NR_MAX_NUM_LCID
-
4
][
NR_MAX_NUM_QFI
];
// 0 -CCCH and 1- 3 SRBs(0,1,2)
}
NR_UE_sched_ctrl_t
;
}
NR_UE_sched_ctrl_t
;
...
@@ -717,7 +734,7 @@ typedef struct {
...
@@ -717,7 +734,7 @@ typedef struct {
float
dl_thr_ue
;
float
dl_thr_ue
;
long
pdsch_HARQ_ACK_Codebook
;
long
pdsch_HARQ_ACK_Codebook
;
/// Assoc slice
/// Assoc slice
slice_id
_t
dl_id
;
NR_list
_t
dl_id
;
}
NR_UE_info_t
;
}
NR_UE_info_t
;
typedef
struct
{
typedef
struct
{
...
...
openair2/LAYER2/NR_MAC_gNB/slicing/nr_slicing.c
View file @
3317f276
...
@@ -92,36 +92,36 @@ void nr_slicing_add_UE(nr_slice_info_t *si, NR_UE_info_t *new_ue)
...
@@ -92,36 +92,36 @@ void nr_slicing_add_UE(nr_slice_info_t *si, NR_UE_info_t *new_ue)
{
{
AssertFatal
(
si
->
num
>
0
&&
si
->
s
!=
NULL
,
"no slices exists, cannot add UEs
\n
"
);
AssertFatal
(
si
->
num
>
0
&&
si
->
s
!=
NULL
,
"no slices exists, cannot add UEs
\n
"
);
NR_UE_sched_ctrl_t
*
sched_ctrl
=
&
new_ue
->
UE_sched_ctrl
;
NR_UE_sched_ctrl_t
*
sched_ctrl
=
&
new_ue
->
UE_sched_ctrl
;
bool
matched_ue
=
0
;
long
lcid
=
0
;
long
lcid
=
0
;
int
slice_idx
=
0
;
reset_nr_list
(
&
new_ue
->
dl_id
)
;
for
(
int
i
=
0
;
i
<
si
->
num
;
++
i
)
{
for
(
int
i
=
0
;
i
<
si
->
num
;
++
i
)
{
reset_nr_list
(
&
new_ue
->
UE_sched_ctrl
.
sliceInfo
[
i
].
lcid
);
bool
matched_ue
=
false
;
for
(
int
l
=
0
;
l
<
sched_ctrl
->
dl_lc_num
;
++
l
)
{
for
(
int
l
=
0
;
l
<
sched_ctrl
->
dl_lc_num
;
++
l
)
{
lcid
=
sched_ctrl
->
dl_lc_ids
[
l
];
lcid
=
sched_ctrl
->
dl_lc_ids
[
l
];
LOG_D
(
NR_MAC
,
"l %d, lcid %ld, sst %d, sd %d
\n
"
,
l
,
lcid
,
sched_ctrl
->
dl_lc_nssai
[
lcid
].
sst
,
sched_ctrl
->
dl_lc_nssai
[
lcid
].
sd
);
LOG_D
(
NR_MAC
,
"l %d, lcid %ld, sst %d, sd %d
\n
"
,
l
,
lcid
,
sched_ctrl
->
dl_lc_nssai
[
lcid
].
sst
,
sched_ctrl
->
dl_lc_nssai
[
lcid
].
sd
);
if
(
nssai_matches
(
sched_ctrl
->
dl_lc_nssai
[
lcid
],
si
->
s
[
i
]
->
nssai
.
sst
,
&
si
->
s
[
i
]
->
nssai
.
sd
))
{
if
(
nssai_matches
(
sched_ctrl
->
dl_lc_nssai
[
lcid
],
si
->
s
[
i
]
->
nssai
.
sst
,
&
si
->
s
[
i
]
->
nssai
.
sd
))
{
matched_ue
=
1
;
// assume UE only associates to one slice
add_nr_list
(
&
new_ue
->
UE_sched_ctrl
.
sliceInfo
[
i
].
lcid
,
lcid
);
break
;
matched_ue
=
true
;
}
}
}
}
if
(
matched_ue
)
{
if
(
matched_ue
)
{
slice_idx
=
i
;
add_nr_list
(
&
new_ue
->
dl_id
,
si
->
s
[
i
]
->
id
);
break
;
int
num_UEs
=
si
->
s
[
i
]
->
num_UEs
;
}
else
{
if
(
si
->
s
[
i
]
->
UE_list
[
num_UEs
]
==
NULL
)
{
LOG_W
(
NR_MAC
,
"cannot find lcid for UE rnti 0x%04x, associate UE at the first slice
\n
"
,
new_ue
->
rnti
);
si
->
s
[
i
]
->
UE_list
[
num_UEs
]
=
new_ue
;
si
->
s
[
i
]
->
num_UEs
+=
1
;
}
else
{
LOG_E
(
NR_MAC
,
"cannot add new UE rnti 0x%04x to slice idx %d, num_UEs %d
\n
"
,
new_ue
->
rnti
,
i
,
si
->
s
[
i
]
->
num_UEs
);
}
LOG_W
(
NR_MAC
,
"Add UE rnti 0x%04x to slice idx %d, sst %d, sd %d
\n
"
,
new_ue
->
rnti
,
i
,
si
->
s
[
i
]
->
nssai
.
sst
,
si
->
s
[
i
]
->
nssai
.
sd
);
}
}
}
}
new_ue
->
dl_id
=
si
->
s
[
slice_idx
]
->
id
;
int
num_UEs
=
si
->
s
[
slice_idx
]
->
num_UEs
;
if
(
si
->
s
[
slice_idx
]
->
UE_list
[
num_UEs
]
==
NULL
)
{
si
->
s
[
slice_idx
]
->
UE_list
[
num_UEs
]
=
new_ue
;
si
->
s
[
slice_idx
]
->
num_UEs
+=
1
;
}
else
{
LOG_E
(
NR_MAC
,
"cannot add new UE rnti 0x%04x to slice idx %d, num_UEs %d
\n
"
,
new_ue
->
rnti
,
slice_idx
,
si
->
s
[
slice_idx
]
->
num_UEs
);
}
LOG_W
(
NR_MAC
,
"Add UE rnti 0x%04x to slice idx %d, sst %d, sd %d
\n
"
,
new_ue
->
rnti
,
slice_idx
,
si
->
s
[
slice_idx
]
->
nssai
.
sst
,
si
->
s
[
slice_idx
]
->
nssai
.
sd
);
}
}
void
nr_slicing_remove_UE
(
nr_slice_info_t
*
si
,
NR_UE_info_t
*
rm_ue
,
int
idx
)
void
nr_slicing_remove_UE
(
nr_slice_info_t
*
si
,
NR_UE_info_t
*
rm_ue
,
int
idx
)
...
@@ -131,7 +131,7 @@ void nr_slicing_remove_UE(nr_slice_info_t *si, NR_UE_info_t* rm_ue, int idx)
...
@@ -131,7 +131,7 @@ void nr_slicing_remove_UE(nr_slice_info_t *si, NR_UE_info_t* rm_ue, int idx)
if
(
si
->
s
[
idx
]
->
UE_list
[
i
]
->
rnti
==
rm_ue
->
rnti
)
{
if
(
si
->
s
[
idx
]
->
UE_list
[
i
]
->
rnti
==
rm_ue
->
rnti
)
{
si
->
s
[
idx
]
->
UE_list
[
i
]
=
NULL
;
si
->
s
[
idx
]
->
UE_list
[
i
]
=
NULL
;
si
->
s
[
idx
]
->
num_UEs
-=
1
;
si
->
s
[
idx
]
->
num_UEs
-=
1
;
r
m_ue
->
dl_id
=
-
1
;
r
emove_nr_list
(
&
rm_ue
->
dl_id
,
si
->
s
[
idx
]
->
id
)
;
break
;
break
;
}
}
}
}
...
@@ -144,7 +144,8 @@ void nr_slicing_move_UE(nr_slice_info_t *si, NR_UE_info_t* assoc_ue, int old_idx
...
@@ -144,7 +144,8 @@ void nr_slicing_move_UE(nr_slice_info_t *si, NR_UE_info_t* assoc_ue, int old_idx
DevAssert
(
old_idx
>=
-
1
&&
old_idx
<
si
->
num
);
DevAssert
(
old_idx
>=
-
1
&&
old_idx
<
si
->
num
);
// add UE to new slice
// add UE to new slice
assoc_ue
->
dl_id
=
si
->
s
[
new_idx
]
->
id
;
remove_nr_list
(
&
assoc_ue
->
dl_id
,
si
->
s
[
old_idx
]
->
id
);
add_nr_list
(
&
assoc_ue
->
dl_id
,
si
->
s
[
new_idx
]
->
id
);
int
cur_idx
=
si
->
s
[
new_idx
]
->
num_UEs
;
int
cur_idx
=
si
->
s
[
new_idx
]
->
num_UEs
;
si
->
s
[
new_idx
]
->
UE_list
[
cur_idx
]
=
assoc_ue
;
si
->
s
[
new_idx
]
->
UE_list
[
cur_idx
]
=
assoc_ue
;
si
->
s
[
new_idx
]
->
num_UEs
+=
1
;
si
->
s
[
new_idx
]
->
num_UEs
+=
1
;
...
@@ -339,7 +340,7 @@ int remove_nvs_nr_slice_dl(nr_slice_info_t *si, uint8_t slice_idx)
...
@@ -339,7 +340,7 @@ int remove_nvs_nr_slice_dl(nr_slice_info_t *si, uint8_t slice_idx)
return
0
;
return
0
;
UE_iterator
(
si
->
s
[
slice_idx
]
->
UE_list
,
rm_ue
)
{
UE_iterator
(
si
->
s
[
slice_idx
]
->
UE_list
,
rm_ue
)
{
nr_slicing_remove_UE
(
si
,
rm_ue
,
slice_idx
);
nr_slicing_remove_UE
(
si
,
rm_ue
,
slice_idx
);
r
m_ue
->
dl_id
=
si
->
s
[
0
]
->
id
;
r
emove_nr_list
(
&
rm_ue
->
dl_id
,
si
->
s
[
slice_idx
]
->
id
)
;
LOG_D
(
NR_MAC
,
"%s(), move UE rnti 0x%04x in slice ID %d idx %d to slice ID %d idx %d
\n
"
,
LOG_D
(
NR_MAC
,
"%s(), move UE rnti 0x%04x in slice ID %d idx %d to slice ID %d idx %d
\n
"
,
__func__
,
rm_ue
->
rnti
,
si
->
s
[
slice_idx
]
->
id
,
slice_idx
,
si
->
s
[
0
]
->
id
,
0
);
__func__
,
rm_ue
->
rnti
,
si
->
s
[
slice_idx
]
->
id
,
slice_idx
,
si
->
s
[
0
]
->
id
,
0
);
for
(
int
i
=
0
;
i
<
MAX_MOBILES_PER_GNB
;
i
++
)
{
for
(
int
i
=
0
;
i
<
MAX_MOBILES_PER_GNB
;
i
++
)
{
...
@@ -360,7 +361,50 @@ int remove_nvs_nr_slice_dl(nr_slice_info_t *si, uint8_t slice_idx)
...
@@ -360,7 +361,50 @@ int remove_nvs_nr_slice_dl(nr_slice_info_t *si, uint8_t slice_idx)
return
1
;
return
1
;
}
}
extern
void
nr_store_dlsch_buffer
(
module_id_t
,
frame_t
,
sub_frame_t
);
static
void
nr_store_dlsch_buffer
(
module_id_t
module_id
,
frame_t
frame
,
sub_frame_t
slot
)
{
nr_slice_info_t
*
si
=
RC
.
nrmac
[
module_id
]
->
pre_processor_dl
.
slices
;
for
(
int
s
=
0
;
s
<
si
->
num
;
s
++
)
{
UE_iterator
(
si
->
s
[
s
]
->
UE_list
,
UE
)
{
NR_UE_sched_ctrl_t
*
sched_ctrl
=
&
UE
->
UE_sched_ctrl
;
sched_ctrl
->
sliceInfo
[
s
].
num_total_bytes
=
0
;
sched_ctrl
->
sliceInfo
[
s
].
dl_pdus_total
=
0
;
NR_List_Iterator
(
&
UE
->
UE_sched_ctrl
.
sliceInfo
[
s
].
lcid
,
lcidP
)
{
const
int
lcid
=
*
lcidP
;
const
uint16_t
rnti
=
UE
->
rnti
;
LOG_D
(
NR_MAC
,
"In %s: UE %x: LCID %d
\n
"
,
__FUNCTION__
,
rnti
,
lcid
);
if
(
lcid
==
DL_SCH_LCID_DTCH
&&
sched_ctrl
->
rrc_processing_timer
>
0
)
{
continue
;
}
start_meas
(
&
RC
.
nrmac
[
module_id
]
->
rlc_status_ind
);
sched_ctrl
->
rlc_status
[
lcid
]
=
mac_rlc_status_ind
(
module_id
,
rnti
,
module_id
,
frame
,
slot
,
ENB_FLAG_YES
,
MBMS_FLAG_NO
,
lcid
,
0
,
0
);
stop_meas
(
&
RC
.
nrmac
[
module_id
]
->
rlc_status_ind
);
if
(
sched_ctrl
->
rlc_status
[
lcid
].
bytes_in_buffer
==
0
)
continue
;
sched_ctrl
->
sliceInfo
[
s
].
dl_pdus_total
+=
sched_ctrl
->
rlc_status
[
lcid
].
pdus_in_buffer
;
sched_ctrl
->
sliceInfo
[
s
].
num_total_bytes
+=
sched_ctrl
->
rlc_status
[
lcid
].
bytes_in_buffer
;
LOG_D
(
MAC
,
"[gNB %d][%4d.%2d] %s%d->DLSCH, RLC status for UE %d, slice %d: %d bytes in buffer, total DL buffer size = %d bytes, "
"%d total PDU bytes, %s TA command
\n
"
,
module_id
,
frame
,
slot
,
lcid
<
4
?
"DCCH"
:
"DTCH"
,
lcid
,
UE
->
rnti
,
s
,
sched_ctrl
->
rlc_status
[
lcid
].
bytes_in_buffer
,
sched_ctrl
->
sliceInfo
[
s
].
num_total_bytes
,
sched_ctrl
->
sliceInfo
[
s
].
dl_pdus_total
,
sched_ctrl
->
ta_apply
?
"send"
:
"do not send"
);
}
}
}
}
void
nvs_nr_dl
(
module_id_t
mod_id
,
void
nvs_nr_dl
(
module_id_t
mod_id
,
frame_t
frame
,
frame_t
frame
,
...
@@ -416,16 +460,15 @@ void nvs_nr_dl(module_id_t mod_id,
...
@@ -416,16 +460,15 @@ void nvs_nr_dl(module_id_t mod_id,
nr_slice_info_t
*
si
=
RC
.
nrmac
[
mod_id
]
->
pre_processor_dl
.
slices
;
nr_slice_info_t
*
si
=
RC
.
nrmac
[
mod_id
]
->
pre_processor_dl
.
slices
;
int
bytes_last_round
[
MAX_NVS_SLICES
]
=
{
0
};
int
bytes_last_round
[
MAX_NVS_SLICES
]
=
{
0
};
for
(
int
s_idx
=
0
;
s_idx
<
si
->
num
;
++
s_idx
)
{
for
(
int
s_idx
=
0
;
s_idx
<
si
->
num
;
++
s_idx
)
{
UE_iterator
(
UE_info
->
list
,
UE
)
{
UE_iterator
(
si
->
s
[
s_idx
]
->
UE_
list
,
UE
)
{
const
NR_UE_sched_ctrl_t
*
sched_ctrl
=
&
UE
->
UE_sched_ctrl
;
const
NR_UE_sched_ctrl_t
*
sched_ctrl
=
&
UE
->
UE_sched_ctrl
;
if
(
si
->
s
[
s_idx
]
->
id
==
UE
->
dl_id
)
{
bytes_last_round
[
s_idx
]
+=
UE
->
mac_stats
.
dl
.
current_bytes
;
bytes_last_round
[
s_idx
]
+=
UE
->
mac_stats
.
dl
.
current_bytes
;
/* if UE has data or retransmission, mark respective slice as active */
/* if UE has data or retransmission, mark respective slice as active */
const
int
retx_pid
=
sched_ctrl
->
retrans_dl_harq
.
head
;
const
int
retx_pid
=
sched_ctrl
->
retrans_dl_harq
.
head
;
const
bool
active
=
sched_ctrl
->
num_total_bytes
>
0
||
retx_pid
>=
0
;
const
int
retx_slice
=
sched_ctrl
->
harq_slice_map
[
retx_pid
]
;
((
_nvs_int_t
*
)
si
->
s
[
s_idx
]
->
int_data
)
->
active
|=
active
;
const
bool
active
=
sched_ctrl
->
sliceInfo
[
s_idx
].
num_total_bytes
>
0
||
retx_slice
==
s_idx
;
}
((
_nvs_int_t
*
)
si
->
s
[
s_idx
]
->
int_data
)
->
active
|=
active
;
}
}
}
}
...
@@ -471,6 +514,10 @@ void nvs_nr_dl(module_id_t mod_id,
...
@@ -471,6 +514,10 @@ void nvs_nr_dl(module_id_t mod_id,
((
_nvs_int_t
*
)
si
->
s
[
maxidx
]
->
int_data
)
->
rb
=
n_rb_sched
;
((
_nvs_int_t
*
)
si
->
s
[
maxidx
]
->
int_data
)
->
rb
=
n_rb_sched
;
UE_iterator
(
si
->
s
[
maxidx
]
->
UE_list
,
UE
)
{
UE
->
UE_sched_ctrl
.
last_sched_slice
=
maxidx
;
}
/* proportional fair scheduling algorithm */
/* proportional fair scheduling algorithm */
int
rb_rem
=
si
->
s
[
maxidx
]
->
dl_algo
.
run
(
mod_id
,
int
rb_rem
=
si
->
s
[
maxidx
]
->
dl_algo
.
run
(
mod_id
,
frame
,
frame
,
...
...
openair2/LAYER2/NR_MAC_gNB/slicing/nr_slicing.h
View file @
3317f276
...
@@ -60,7 +60,7 @@ typedef struct nr_slice_info_s {
...
@@ -60,7 +60,7 @@ typedef struct nr_slice_info_s {
#define NVS_SLICING 20
#define NVS_SLICING 20
/* arbitrary upper limit, increase if you want to instantiate more slices */
/* arbitrary upper limit, increase if you want to instantiate more slices */
#define MAX_NVS_SLICES
10
#define MAX_NVS_SLICES
NR_MAX_NUM_SLICES
/* window for slice weight averaging -> 1s for fine granularity */
/* window for slice weight averaging -> 1s for fine granularity */
#define BETA 0.001f
#define BETA 0.001f
typedef
struct
{
typedef
struct
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment