F1AP IDs: Allow AddMod, fix concurrency bug
Modify xu_add_f1_ue_data() to be xu_addmod_f1_ue_data(), i.e., "addmod" behavior in which it is possible to also update f1_ue_data. I do it this way since an xu_updade_f1_ue_data() function would be almost the same as the add function (only deleting existing data, whereas the original add() was asserting in that case). Modify tests to test for this behavior. This fixes a concurrency bug. For instance, during reestablishment, the CU needs to update the DU UE ID under which the UE is identified in the DU. Previously, the CU would remove, then add the DU UE ID info. At the same time, the PDCP thread might look up the information. This can lead to asserts. Use the above addmod functionality to do the remove-add under a mutex.
This commit is contained in:
@@ -60,14 +60,14 @@ void cu_init_f1_ue_data(void)
|
||||
pthread_mutex_unlock(&cu2du_mutex);
|
||||
}
|
||||
|
||||
bool cu_add_f1_ue_data(uint32_t ue_id, const f1_ue_data_t *data)
|
||||
bool cu_addmod_f1_ue_data(uint32_t ue_id, const f1_ue_data_t *data)
|
||||
{
|
||||
pthread_mutex_lock(&cu2du_mutex);
|
||||
DevAssert(cu2du_ue_mapping != NULL);
|
||||
uint64_t key = ue_id;
|
||||
if (hashtable_is_key_exists(cu2du_ue_mapping, key) == HASH_TABLE_OK) {
|
||||
pthread_mutex_unlock(&cu2du_mutex);
|
||||
return false;
|
||||
hashtable_rc_t ret = hashtable_remove(cu2du_ue_mapping, key);
|
||||
DevAssert(ret == HASH_TABLE_OK);
|
||||
}
|
||||
bool ret = add_hashtable_data(cu2du_ue_mapping, key, data);
|
||||
pthread_mutex_unlock(&cu2du_mutex);
|
||||
@@ -116,14 +116,14 @@ void du_init_f1_ue_data(void)
|
||||
pthread_mutex_unlock(&du2cu_mutex);
|
||||
}
|
||||
|
||||
bool du_add_f1_ue_data(uint32_t ue_id, const f1_ue_data_t *data)
|
||||
bool du_addmod_f1_ue_data(uint32_t ue_id, const f1_ue_data_t *data)
|
||||
{
|
||||
pthread_mutex_lock(&du2cu_mutex);
|
||||
DevAssert(du2cu_ue_mapping != NULL);
|
||||
uint64_t key = ue_id;
|
||||
if (hashtable_is_key_exists(du2cu_ue_mapping, key) == HASH_TABLE_OK) {
|
||||
pthread_mutex_unlock(&du2cu_mutex);
|
||||
return false;
|
||||
hashtable_rc_t ret = hashtable_remove(du2cu_ue_mapping, key);
|
||||
DevAssert(ret == HASH_TABLE_OK);
|
||||
}
|
||||
bool ret = add_hashtable_data(du2cu_ue_mapping, key, data);
|
||||
pthread_mutex_unlock(&du2cu_mutex);
|
||||
|
||||
@@ -38,13 +38,13 @@ typedef struct f1_ue_data_t {
|
||||
} f1_ue_data_t;
|
||||
|
||||
void cu_init_f1_ue_data(void);
|
||||
bool cu_add_f1_ue_data(uint32_t ue_id, const f1_ue_data_t *data);
|
||||
bool cu_addmod_f1_ue_data(uint32_t ue_id, const f1_ue_data_t *data);
|
||||
bool cu_exists_f1_ue_data(uint32_t ue_id);
|
||||
f1_ue_data_t cu_get_f1_ue_data(uint32_t ue_id);
|
||||
bool cu_remove_f1_ue_data(uint32_t ue_id);
|
||||
|
||||
void du_init_f1_ue_data(void);
|
||||
bool du_add_f1_ue_data(uint32_t ue_id, const f1_ue_data_t *data);
|
||||
bool du_addmod_f1_ue_data(uint32_t ue_id, const f1_ue_data_t *data);
|
||||
bool du_exists_f1_ue_data(uint32_t ue_id);
|
||||
f1_ue_data_t du_get_f1_ue_data(uint32_t ue_id);
|
||||
bool du_remove_f1_ue_data(uint32_t ue_id);
|
||||
|
||||
@@ -30,10 +30,11 @@ void du_data_test()
|
||||
du_init_f1_ue_data();
|
||||
int rnti = 13;
|
||||
f1_ue_data_t data = {.secondary_ue = 1};
|
||||
bool ret = du_add_f1_ue_data(rnti, &data);
|
||||
bool ret = du_addmod_f1_ue_data(rnti, &data);
|
||||
DevAssert(ret);
|
||||
// we can overwrite, no problem
|
||||
ret = du_addmod_f1_ue_data(rnti, &data);
|
||||
DevAssert(ret);
|
||||
ret = du_add_f1_ue_data(rnti, &data);
|
||||
DevAssert(!ret);
|
||||
bool exists = du_exists_f1_ue_data(rnti);
|
||||
DevAssert(exists);
|
||||
f1_ue_data_t rdata = du_get_f1_ue_data(rnti);
|
||||
@@ -45,14 +46,25 @@ void cu_data_test()
|
||||
cu_init_f1_ue_data();
|
||||
int ue_id = 13;
|
||||
f1_ue_data_t data = {.secondary_ue = 1};
|
||||
bool ret = cu_add_f1_ue_data(ue_id, &data);
|
||||
bool ret = cu_addmod_f1_ue_data(ue_id, &data);
|
||||
DevAssert(ret);
|
||||
// we can overwrite, no problem
|
||||
data.secondary_ue = 2;
|
||||
ret = cu_addmod_f1_ue_data(ue_id, &data);
|
||||
DevAssert(ret);
|
||||
ret = cu_add_f1_ue_data(ue_id, &data);
|
||||
DevAssert(!ret);
|
||||
bool exists = cu_exists_f1_ue_data(ue_id);
|
||||
DevAssert(exists);
|
||||
f1_ue_data_t rdata = cu_get_f1_ue_data(ue_id);
|
||||
DevAssert(rdata.secondary_ue == data.secondary_ue);
|
||||
|
||||
rdata.secondary_ue = 3;
|
||||
// overwrite once more
|
||||
ret = cu_addmod_f1_ue_data(ue_id, &rdata);
|
||||
DevAssert(ret);
|
||||
exists = cu_exists_f1_ue_data(ue_id);
|
||||
DevAssert(exists);
|
||||
f1_ue_data_t r2data = cu_get_f1_ue_data(ue_id);
|
||||
DevAssert(r2data.secondary_ue == rdata.secondary_ue);
|
||||
}
|
||||
|
||||
int main()
|
||||
|
||||
Reference in New Issue
Block a user