pdch: Move enable/disable into the PDCH code
When a PDCH is disabled all resources should be freed. This is currently not possible as the PDCH does not know where it belongs to. On top of that the list (and other resources) should be properly initialized on construction so that disable() is idempotent and does not check if it was disabled. During the re-factoring I noticed that during a sysmobts re-start some resources are not freed. I left a warning in the code to resolve this issue later.
This commit is contained in:
parent
ba5543fbf3
commit
17b0d83a1f
4
TODO
4
TODO
|
@ -4,4 +4,6 @@
|
||||||
* Group more into in classes.. remove bts pointers.
|
* Group more into in classes.. remove bts pointers.
|
||||||
* Change functions with 100 parameters to get a struct as param
|
* Change functions with 100 parameters to get a struct as param
|
||||||
* Move move into the TBF class
|
* Move move into the TBF class
|
||||||
* Replace trx/ts with
|
* Replace trx/ts with pointers. E.g. a PDCH should know the trx
|
||||||
|
it is on... then we can omit trx, ts and parameters and just pass
|
||||||
|
the pdch.
|
||||||
|
|
44
src/bts.cpp
44
src/bts.cpp
|
@ -20,6 +20,13 @@
|
||||||
|
|
||||||
#include <bts.h>
|
#include <bts.h>
|
||||||
#include <poll_controller.h>
|
#include <poll_controller.h>
|
||||||
|
#include <tbf.h>
|
||||||
|
|
||||||
|
#include <gprs_rlcmac.h>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <osmocom/core/talloc.h>
|
||||||
|
}
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
@ -53,3 +60,40 @@ void BTS::set_current_frame_number(int fn)
|
||||||
m_cur_fn = fn;
|
m_cur_fn = fn;
|
||||||
m_pollController.expireTimedout(m_cur_fn);
|
m_pollController.expireTimedout(m_cur_fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gprs_rlcmac_pdch::enable()
|
||||||
|
{
|
||||||
|
/* TODO: Check if there are still allocated resources.. */
|
||||||
|
INIT_LLIST_HEAD(&paging_list);
|
||||||
|
m_is_enabled = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gprs_rlcmac_pdch::disable()
|
||||||
|
{
|
||||||
|
/* TODO.. kick free_resources once we know the TRX/TS we are on */
|
||||||
|
m_is_enabled = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gprs_rlcmac_pdch::free_resources(uint8_t trx, uint8_t ts)
|
||||||
|
{
|
||||||
|
struct gprs_rlcmac_paging *pag;
|
||||||
|
struct gprs_rlcmac_sba *sba, *sba2;
|
||||||
|
|
||||||
|
/* we are not enabled. there should be no resources */
|
||||||
|
if (!is_enabled())
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* kick all TBF on slot */
|
||||||
|
gprs_rlcmac_tbf::free_all(this);
|
||||||
|
|
||||||
|
/* flush all pending paging messages */
|
||||||
|
while ((pag = gprs_rlcmac_dequeue_paging(this)))
|
||||||
|
talloc_free(pag);
|
||||||
|
|
||||||
|
llist_for_each_entry_safe(sba, sba2, &gprs_rlcmac_sbas, list) {
|
||||||
|
if (sba->trx == trx && sba->ts == ts) {
|
||||||
|
llist_del(&sba->list);
|
||||||
|
talloc_free(sba);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
17
src/bts.h
17
src/bts.h
|
@ -39,7 +39,17 @@ struct BTS;
|
||||||
* PDCH instance
|
* PDCH instance
|
||||||
*/
|
*/
|
||||||
struct gprs_rlcmac_pdch {
|
struct gprs_rlcmac_pdch {
|
||||||
uint8_t enable; /* TS is enabled */
|
#ifdef __cplusplus
|
||||||
|
/* TODO: the PDCH should know the trx/ts it belongs to */
|
||||||
|
void free_resources(uint8_t trx, uint8_t ts);
|
||||||
|
|
||||||
|
bool is_enabled() const;
|
||||||
|
|
||||||
|
void enable();
|
||||||
|
void disable();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint8_t m_is_enabled; /* TS is enabled */
|
||||||
uint8_t tsc; /* TSC of this slot */
|
uint8_t tsc; /* TSC of this slot */
|
||||||
uint8_t next_ul_tfi; /* next uplink TBF/TFI to schedule (0..31) */
|
uint8_t next_ul_tfi; /* next uplink TBF/TFI to schedule (0..31) */
|
||||||
uint8_t next_dl_tfi; /* next downlink TBF/TFI to schedule (0..31) */
|
uint8_t next_dl_tfi; /* next downlink TBF/TFI to schedule (0..31) */
|
||||||
|
@ -135,4 +145,9 @@ extern "C" {
|
||||||
struct gprs_rlcmac_bts *bts_main_data();
|
struct gprs_rlcmac_bts *bts_main_data();
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool gprs_rlcmac_pdch::is_enabled() const
|
||||||
|
{
|
||||||
|
return m_is_enabled;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -149,7 +149,7 @@ int tfi_find_free(struct gprs_rlcmac_bts *bts, enum gprs_rlcmac_tbf_direction di
|
||||||
for (trx = trx_from; trx <= trx_to; trx++) {
|
for (trx = trx_from; trx <= trx_to; trx++) {
|
||||||
for (ts = 0; ts < 8; ts++) {
|
for (ts = 0; ts < 8; ts++) {
|
||||||
pdch = &bts->trx[trx].pdch[ts];
|
pdch = &bts->trx[trx].pdch[ts];
|
||||||
if (!pdch->enable)
|
if (!pdch->is_enabled())
|
||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -205,7 +205,7 @@ int sba_alloc(struct gprs_rlcmac_bts *bts,
|
||||||
for (trx = 0; trx < 8; trx++) {
|
for (trx = 0; trx < 8; trx++) {
|
||||||
for (ts = 0; ts < 8; ts++) {
|
for (ts = 0; ts < 8; ts++) {
|
||||||
pdch = &bts->trx[trx].pdch[ts];
|
pdch = &bts->trx[trx].pdch[ts];
|
||||||
if (!pdch->enable)
|
if (!pdch->is_enabled())
|
||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -241,7 +241,7 @@ int gprs_rlcmac_rcv_rts_block(struct gprs_rlcmac_bts *bts,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
pdch = &bts->trx[trx].pdch[ts];
|
pdch = &bts->trx[trx].pdch[ts];
|
||||||
|
|
||||||
if (!pdch->enable) {
|
if (!pdch->is_enabled()) {
|
||||||
LOGP(DRLCMACSCHED, LOGL_ERROR, "Received RTS on disabled PDCH: "
|
LOGP(DRLCMACSCHED, LOGL_ERROR, "Received RTS on disabled PDCH: "
|
||||||
"TRX=%d TS=%d\n", trx, ts);
|
"TRX=%d TS=%d\n", trx, ts);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
|
@ -104,7 +104,7 @@ static int find_enabled_pdch(struct gprs_rlcmac_trx *trx, const uint8_t start_ts
|
||||||
struct gprs_rlcmac_pdch *pdch;
|
struct gprs_rlcmac_pdch *pdch;
|
||||||
|
|
||||||
pdch = &trx->pdch[ts];
|
pdch = &trx->pdch[ts];
|
||||||
if (!pdch->enable) {
|
if (!pdch->is_enabled()) {
|
||||||
LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, because "
|
LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, because "
|
||||||
"not enabled\n", ts);
|
"not enabled\n", ts);
|
||||||
continue;
|
continue;
|
||||||
|
@ -265,7 +265,7 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts,
|
||||||
for (ts = 0, i = 0; ts < 8; ts++) {
|
for (ts = 0, i = 0; ts < 8; ts++) {
|
||||||
pdch = &tbf->trx->pdch[ts];
|
pdch = &tbf->trx->pdch[ts];
|
||||||
/* check if enabled */
|
/* check if enabled */
|
||||||
if (!pdch->enable) {
|
if (!pdch->is_enabled()) {
|
||||||
LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, because "
|
LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, because "
|
||||||
"not enabled\n", ts);
|
"not enabled\n", ts);
|
||||||
/* increase window for Type 1 */
|
/* increase window for Type 1 */
|
||||||
|
@ -421,7 +421,7 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts,
|
||||||
for (ts = tx_win_min, i = 0; i < tx_range; ts = (ts + 1) & 7) {
|
for (ts = tx_win_min, i = 0; i < tx_range; ts = (ts + 1) & 7) {
|
||||||
pdch = &tbf->trx->pdch[ts];
|
pdch = &tbf->trx->pdch[ts];
|
||||||
/* check if enabled */
|
/* check if enabled */
|
||||||
if (!pdch->enable) {
|
if (!pdch->is_enabled()) {
|
||||||
LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, "
|
LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, "
|
||||||
"because not enabled\n", ts);
|
"because not enabled\n", ts);
|
||||||
continue;
|
continue;
|
||||||
|
@ -493,7 +493,7 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts,
|
||||||
for (ts = tx_win_min, i = 0; i < tx_range; ts = (ts + 1) & 7) {
|
for (ts = tx_win_min, i = 0; i < tx_range; ts = (ts + 1) & 7) {
|
||||||
pdch = &tbf->trx->pdch[ts];
|
pdch = &tbf->trx->pdch[ts];
|
||||||
/* check if enabled */
|
/* check if enabled */
|
||||||
if (!pdch->enable) {
|
if (!pdch->is_enabled()) {
|
||||||
LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, "
|
LOGP(DRLCMAC, LOGL_DEBUG, "- Skipping TS %d, "
|
||||||
"because not enabled\n", ts);
|
"because not enabled\n", ts);
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -295,28 +295,6 @@ static int pcu_rx_rach_ind(struct gsm_pcu_if_rach_ind *rach_ind)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int flush_pdch(struct gprs_rlcmac_pdch *pdch, uint8_t trx, uint8_t ts)
|
|
||||||
{
|
|
||||||
struct gprs_rlcmac_paging *pag;
|
|
||||||
struct gprs_rlcmac_sba *sba, *sba2;
|
|
||||||
|
|
||||||
/* kick all TBF on slot */
|
|
||||||
gprs_rlcmac_tbf::free_all(pdch);
|
|
||||||
|
|
||||||
/* flush all pending paging messages */
|
|
||||||
while ((pag = gprs_rlcmac_dequeue_paging(pdch)))
|
|
||||||
talloc_free(pag);
|
|
||||||
|
|
||||||
llist_for_each_entry_safe(sba, sba2, &gprs_rlcmac_sbas, list) {
|
|
||||||
if (sba->trx == trx && sba->ts == ts) {
|
|
||||||
llist_del(&sba->list);
|
|
||||||
talloc_free(sba);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pcu_rx_info_ind(struct gsm_pcu_if_info_ind *info_ind)
|
static int pcu_rx_info_ind(struct gsm_pcu_if_info_ind *info_ind)
|
||||||
{
|
{
|
||||||
struct gprs_rlcmac_bts *bts = bts_main_data();
|
struct gprs_rlcmac_bts *bts = bts_main_data();
|
||||||
|
@ -342,11 +320,8 @@ bssgp_failed:
|
||||||
/* free all TBF */
|
/* free all TBF */
|
||||||
for (trx = 0; trx < 8; trx++) {
|
for (trx = 0; trx < 8; trx++) {
|
||||||
bts->trx[trx].arfcn = info_ind->trx[trx].arfcn;
|
bts->trx[trx].arfcn = info_ind->trx[trx].arfcn;
|
||||||
for (ts = 0; ts < 8; ts++) {
|
for (ts = 0; ts < 8; ts++)
|
||||||
if (bts->trx[trx].pdch[ts].enable)
|
bts->trx[trx].pdch[ts].free_resources(trx, ts);
|
||||||
flush_pdch(&bts->trx[trx].pdch[ts],
|
|
||||||
trx, ts);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
gprs_bssgp_destroy_or_exit();
|
gprs_bssgp_destroy_or_exit();
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -465,7 +440,7 @@ bssgp_failed:
|
||||||
pdch = &bts->trx[trx].pdch[ts];
|
pdch = &bts->trx[trx].pdch[ts];
|
||||||
if ((info_ind->trx[trx].pdch_mask & (1 << ts))) {
|
if ((info_ind->trx[trx].pdch_mask & (1 << ts))) {
|
||||||
/* FIXME: activate dynamically at RLCMAC */
|
/* FIXME: activate dynamically at RLCMAC */
|
||||||
if (!pdch->enable) {
|
if (!pdch->is_enabled()) {
|
||||||
#ifdef ENABLE_SYSMODSP
|
#ifdef ENABLE_SYSMODSP
|
||||||
if ((info_ind->flags &
|
if ((info_ind->flags &
|
||||||
PCU_IF_FLAG_SYSMO))
|
PCU_IF_FLAG_SYSMO))
|
||||||
|
@ -473,17 +448,16 @@ bssgp_failed:
|
||||||
bts->trx[trx].fl1h, ts);
|
bts->trx[trx].fl1h, ts);
|
||||||
#endif
|
#endif
|
||||||
pcu_tx_act_req(trx, ts, 1);
|
pcu_tx_act_req(trx, ts, 1);
|
||||||
INIT_LLIST_HEAD(&pdch->paging_list);
|
pdch->enable();
|
||||||
pdch->enable = 1;
|
|
||||||
}
|
}
|
||||||
pdch->tsc = info_ind->trx[trx].tsc[ts];
|
pdch->tsc = info_ind->trx[trx].tsc[ts];
|
||||||
LOGP(DL1IF, LOGL_INFO, "PDCH: trx=%d ts=%d\n",
|
LOGP(DL1IF, LOGL_INFO, "PDCH: trx=%d ts=%d\n",
|
||||||
trx, ts);
|
trx, ts);
|
||||||
} else {
|
} else {
|
||||||
if (pdch->enable) {
|
if (pdch->is_enabled()) {
|
||||||
pcu_tx_act_req(trx, ts, 0);
|
pcu_tx_act_req(trx, ts, 0);
|
||||||
pdch->enable = 0;
|
pdch->free_resources(trx, ts);
|
||||||
flush_pdch(pdch, trx, ts);
|
pdch->disable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,8 @@ static void pcu_sock_close(struct pcu_sock_state *state, int lost)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
for (ts = 0; ts < 8; ts++)
|
for (ts = 0; ts < 8; ts++)
|
||||||
bts->trx[trx].pdch[ts].enable = 0;
|
bts->trx[trx].pdch[ts].disable();
|
||||||
|
#warning "NOT ALL RESOURCES are freed in this case... inconsistent with the other code. Share the code with pcu_l1if.c for the reset."
|
||||||
gprs_rlcmac_tbf::free_all(&bts->trx[trx]);
|
gprs_rlcmac_tbf::free_all(&bts->trx[trx]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,8 +48,8 @@ static void test_alloc_a(gprs_rlcmac_tbf_direction dir, const int count)
|
||||||
bts.alloc_algorithm = alloc_algorithm_a;
|
bts.alloc_algorithm = alloc_algorithm_a;
|
||||||
|
|
||||||
struct gprs_rlcmac_trx *trx = &bts.trx[0];
|
struct gprs_rlcmac_trx *trx = &bts.trx[0];
|
||||||
trx->pdch[2].enable = 1;
|
trx->pdch[2].enable();
|
||||||
trx->pdch[3].enable = 1;
|
trx->pdch[3].enable();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Currently alloc_a will only allocate from the first
|
* Currently alloc_a will only allocate from the first
|
||||||
|
|
Loading…
Reference in New Issue