[PATCH] osmocom-bb[master]: trxcon/scheduler: use linuxlist API for lchan management

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Harald Welte gerrit-no-reply at lists.osmocom.org
Thu Feb 22 15:33:37 UTC 2018


Review at  https://gerrit.osmocom.org/6817

trxcon/scheduler: use linuxlist API for lchan management

As there is no any order relation between logical channels, it's
better to use the linuxlist API instead of talloc array.

Change-Id: I5a78582c77ed1ab33817d240e065dc4cd4708199
---
M src/host/trxcon/l1ctl.c
M src/host/trxcon/sched_trx.c
M src/host/trxcon/sched_trx.h
3 files changed, 65 insertions(+), 56 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/17/6817/1

diff --git a/src/host/trxcon/l1ctl.c b/src/host/trxcon/l1ctl.c
index 070ee56..dd75af9 100644
--- a/src/host/trxcon/l1ctl.c
+++ b/src/host/trxcon/l1ctl.c
@@ -700,8 +700,9 @@
 static int l1ctl_rx_tch_mode_req(struct l1ctl_link *l1l, struct msgb *msg)
 {
 	struct l1ctl_tch_mode_req *req;
+	struct trx_lchan_state *lchan;
 	struct trx_ts *ts;
-	int len, i, j;
+	int i;
 
 	req = (struct l1ctl_tch_mode_req *) msg->l1h;
 
@@ -720,9 +721,14 @@
 			continue;
 
 		/* Iterate over all allocated lchans */
-		len = talloc_array_length(ts->lchans);
-		for (j = 0; j < len; j++)
-			ts->lchans[j].tch_mode = req->tch_mode;
+		llist_for_each_entry(lchan, &ts->lchans, list) {
+			/* Omit inactive channels */
+			if (!lchan->active)
+				continue;
+
+			/* Set TCH mode */
+			lchan->tch_mode = req->tch_mode;
+		}
 	}
 
 	/* TODO: do we need to care about audio_mode? */
diff --git a/src/host/trxcon/sched_trx.c b/src/host/trxcon/sched_trx.c
index 9567844..0a9b7f7 100644
--- a/src/host/trxcon/sched_trx.c
+++ b/src/host/trxcon/sched_trx.c
@@ -185,6 +185,7 @@
 
 void sched_trx_del_ts(struct trx_instance *trx, int tn)
 {
+	struct trx_lchan_state *lchan;
 	struct trx_ts *ts;
 
 	/* Find ts in list */
@@ -198,7 +199,8 @@
 	sched_trx_deactivate_all_lchans(ts);
 
 	/* Free channel states */
-	talloc_free(ts->lchans);
+	llist_for_each_entry(lchan, &ts->lchans, list)
+		talloc_free(lchan);
 
 	/* Flush queue primitives for TX */
 	sched_prim_flush_queue(&ts->tx_prims);
@@ -211,10 +213,14 @@
 	trx_if_cmd_setslot(trx, tn, 0);
 }
 
+#define LAYOUT_HAS_LCHAN(layout, lchan) \
+	(layout->lchan_mask & ((uint64_t) 0x01 << lchan))
+
 int sched_trx_configure_ts(struct trx_instance *trx, int tn,
 	enum gsm_phys_chan_config config)
 {
-	int i, type, lchan_cnt = 0;
+	struct trx_lchan_state *lchan;
+	enum trx_lchan_type type;
 	struct trx_ts *ts;
 
 	/* Try to find specified ts */
@@ -229,9 +235,6 @@
 			return -ENOMEM;
 	}
 
-	/* Init queue primitives for TX */
-	INIT_LLIST_HEAD(&ts->tx_prims);
-
 	/* Choose proper multiframe layout */
 	ts->mf_layout = sched_mframe_layout(config, tn);
 	if (ts->mf_layout->chan_config != config)
@@ -240,29 +243,30 @@
 	LOGP(DSCH, LOGL_NOTICE, "(Re)configure TDMA timeslot #%u as %s\n",
 		tn, ts->mf_layout->name);
 
-	/* Count channel states */
-	for (type = 0; type < _TRX_CHAN_MAX; type++)
-		if (ts->mf_layout->lchan_mask & ((uint64_t) 0x01 << type))
-			lchan_cnt++;
-
-	if (!lchan_cnt)
-		return 0;
+	/* Init queue primitives for TX */
+	INIT_LLIST_HEAD(&ts->tx_prims);
+	/* Init logical channels list */
+	INIT_LLIST_HEAD(&ts->lchans);
 
 	/* Allocate channel states */
-	ts->lchans = talloc_zero_array(ts, struct trx_lchan_state, lchan_cnt);
-	if (ts->lchans == NULL)
-		return -ENOMEM;
+	for (type = 0; type < _TRX_CHAN_MAX; type++) {
+		if (!LAYOUT_HAS_LCHAN(ts->mf_layout, type))
+			continue;
 
-	/* Init channel states */
-	for (type = 0, i = 0; type < _TRX_CHAN_MAX; type++) {
-		if (ts->mf_layout->lchan_mask & ((uint64_t) 0x01 << type)) {
-			/* Set proper channel type */
-			ts->lchans[i++].type = type;
+		/* Allocate a channel state */
+		lchan = talloc_zero(ts, struct trx_lchan_state);
+		if (!lchan)
+			return -ENOMEM;
 
-			/* Enable channel automatically if required */
-			if (trx_lchan_desc[type].flags & TRX_CH_FLAG_AUTO)
-				sched_trx_activate_lchan(ts, type);
-		}
+		/* Set channel type */
+		lchan->type = type;
+
+		/* Add to the list of channel states */
+		llist_add_tail(&lchan->list, &ts->lchans);
+
+		/* Enable channel automatically if required */
+		if (trx_lchan_desc[type].flags & TRX_CH_FLAG_AUTO)
+			sched_trx_activate_lchan(ts, type);
 	}
 
 	/* Notify transceiver about TS activation */
@@ -274,6 +278,7 @@
 
 int sched_trx_reset_ts(struct trx_instance *trx, int tn)
 {
+	struct trx_lchan_state *lchan, *lchan_next;
 	struct trx_ts *ts;
 
 	/* Try to find specified ts */
@@ -294,7 +299,10 @@
 	sched_trx_deactivate_all_lchans(ts);
 
 	/* Free channel states */
-	talloc_free(ts->lchans);
+	llist_for_each_entry_safe(lchan, lchan_next, &ts->lchans, list) {
+		llist_del(&lchan->list);
+		talloc_free(lchan);
+	}
 
 	/* Notify transceiver about that */
 	trx_if_cmd_setslot(trx, tn, 0);
@@ -305,9 +313,7 @@
 int sched_trx_start_ciphering(struct trx_ts *ts, uint8_t algo,
 	uint8_t *key, uint8_t key_len)
 {
-	struct trx_lchan_state *state;
-	size_t len;
-	int i;
+	struct trx_lchan_state *lchan;
 
 	/* Prevent NULL-pointer deference */
 	if (!ts)
@@ -318,16 +324,18 @@
 		return -ERANGE;
 
 	/* Iterate over all allocated logical channels */
-	len = talloc_array_length(ts->lchans);
-	for (i = 0; i < len; i++) {
+	llist_for_each_entry(lchan, &ts->lchans, list) {
+		/* Omit inactive channels */
+		if (!lchan->active)
+			continue;
+
 		/* Set key length and algorithm */
-		state = ts->lchans + i;
-		state->a5.key_len = key_len;
-		state->a5.algo = algo;
+		lchan->a5.key_len = key_len;
+		lchan->a5.algo = algo;
 
 		/* Copy requested key */
 		if (key_len)
-			memcpy(state->a5.key, key, key_len);
+			memcpy(lchan->a5.key, key, key_len);
 	}
 
 	return 0;
@@ -336,12 +344,11 @@
 struct trx_lchan_state *sched_trx_find_lchan(struct trx_ts *ts,
 	enum trx_lchan_type chan)
 {
-	int i, len;
+	struct trx_lchan_state *lchan;
 
-	len = talloc_array_length(ts->lchans);
-	for (i = 0; i < len; i++)
-		if (ts->lchans[i].type == chan)
-			return ts->lchans + i;
+	llist_for_each_entry(lchan, &ts->lchans, list)
+		if (lchan->type == chan)
+			return lchan;
 
 	return NULL;
 }
@@ -350,18 +357,16 @@
 {
 	const struct trx_lchan_desc *lchan_desc;
 	struct trx_lchan_state *lchan;
-	int len, i, rc = 0;
+	int rc = 0;
 
 	/* Prevent NULL-pointer deference */
-	if (ts == NULL || ts->lchans == NULL) {
+	if (ts == NULL) {
 		LOGP(DSCH, LOGL_ERROR, "Timeslot isn't configured\n");
 		return -EINVAL;
 	}
 
 	/* Iterate over all allocated lchans */
-	len = talloc_array_length(ts->lchans);
-	for (i = 0; i < len; i++) {
-		lchan = ts->lchans + i;
+	llist_for_each_entry(lchan, &ts->lchans, list) {
 		lchan_desc = &trx_lchan_desc[lchan->type];
 
 		if (lchan_desc->chan_nr == (chan_nr & 0xf8)) {
@@ -396,14 +401,14 @@
 
 	/* Conditionally allocate memory for bursts */
 	if (lchan_desc->rx_fn && lchan_desc->burst_buf_size > 0) {
-		lchan->rx_bursts = talloc_zero_size(ts->lchans,
+		lchan->rx_bursts = talloc_zero_size(lchan,
 			lchan_desc->burst_buf_size);
 		if (lchan->rx_bursts == NULL)
 			return -ENOMEM;
 	}
 
 	if (lchan_desc->tx_fn && lchan_desc->burst_buf_size > 0) {
-		lchan->tx_bursts = talloc_zero_size(ts->lchans,
+		lchan->tx_bursts = talloc_zero_size(lchan,
 			lchan_desc->burst_buf_size);
 		if (lchan->tx_bursts == NULL)
 			return -ENOMEM;
@@ -481,15 +486,11 @@
 void sched_trx_deactivate_all_lchans(struct trx_ts *ts)
 {
 	struct trx_lchan_state *lchan;
-	int i, len;
 
 	LOGP(DSCH, LOGL_DEBUG, "Deactivating all logical channels "
 		"on ts=%d\n", ts->index);
 
-	len = talloc_array_length(ts->lchans);
-	for (i = 0; i < len; i++) {
-		lchan = ts->lchans + i;
-
+	llist_for_each_entry(lchan, &ts->lchans, list) {
 		/* Omit inactive channels */
 		if (!lchan->active)
 			continue;
diff --git a/src/host/trxcon/sched_trx.h b/src/host/trxcon/sched_trx.h
index b93011c..7ee1d47 100644
--- a/src/host/trxcon/sched_trx.h
+++ b/src/host/trxcon/sched_trx.h
@@ -146,6 +146,8 @@
 	enum trx_lchan_type type;
 	/*! \brief Channel status */
 	uint8_t active;
+	/*! \brief Link to a list of channels */
+	struct llist_head list;
 
 	/*! \brief Burst type: GMSK or 8PSK */
 	enum trx_burst_type burst_type;
@@ -221,7 +223,7 @@
 	/*! \brief Pointer to multiframe layout */
 	const struct trx_multiframe *mf_layout;
 	/*! \brief Channel states for logical channels */
-	struct trx_lchan_state *lchans;
+	struct llist_head lchans;
 	/*! \brief Queue primitives for TX */
 	struct llist_head tx_prims;
 };

-- 
To view, visit https://gerrit.osmocom.org/6817
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I5a78582c77ed1ab33817d240e065dc4cd4708199
Gerrit-PatchSet: 1
Gerrit-Project: osmocom-bb
Gerrit-Branch: master
Gerrit-Owner: Harald Welte <laforge at gnumonks.org>



More information about the gerrit-log mailing list