Skip to content

Commit ba8e062

Browse files
committed
Fix: protect shared port access with proper sync
Signed-off-by: Kasiewicz, Marek <marek.kasiewicz@intel.com>
1 parent 44e9bd4 commit ba8e062

File tree

7 files changed

+136
-27
lines changed

7 files changed

+136
-27
lines changed

lib/src/datapath/mt_queue.c

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,20 @@ static uint16_t rx_csq_burst(struct mt_rxq_entry* entry, struct rte_mbuf** rx_pk
4545

4646
static uint16_t rx_dpdk_burst(struct mt_rxq_entry* entry, struct rte_mbuf** rx_pkts,
4747
const uint16_t nb_pkts) {
48-
return mt_dpdk_rx_burst(entry->rxq, rx_pkts, nb_pkts);
48+
enum mtl_port port_id = entry->rxq->port;
49+
struct mt_interface* inf = mt_if(entry->parent, port_id);
50+
int ret;
51+
52+
/* Trylock as we should not block in tasklates */
53+
ret = mt_pthread_rwlock_tryrdlock(&inf->rl_rwlock);
54+
if (ret) {
55+
dbg("%s(%d), try lock fail %d\n", __func__, port_id, ret);
56+
return 0;
57+
}
58+
ret = mt_dpdk_rx_burst(entry->rxq, rx_pkts, nb_pkts);
59+
mt_pthread_rwlock_unlock(&inf->rl_rwlock);
60+
61+
return ret;
4962
}
5063

5164
struct mt_rxq_entry* mt_rxq_get(struct mtl_main_impl* impl, enum mtl_port port,
@@ -163,7 +176,20 @@ static uint16_t tx_tsq_burst(struct mt_txq_entry* entry, struct rte_mbuf** tx_pk
163176

164177
static uint16_t tx_dpdk_burst(struct mt_txq_entry* entry, struct rte_mbuf** tx_pkts,
165178
uint16_t nb_pkts) {
166-
return mt_dpdk_tx_burst(entry->txq, tx_pkts, nb_pkts);
179+
enum mtl_port port_id = entry->txq->port;
180+
struct mt_interface* inf = mt_if(entry->parent, port_id);
181+
uint16_t ret;
182+
183+
/* Trylock as we should not block in tasklates */
184+
ret = mt_pthread_rwlock_tryrdlock(&inf->rl_rwlock);
185+
if (ret) {
186+
dbg("%s(%d), try lock fail %d\n", __func__, port_id, ret);
187+
return 0;
188+
}
189+
ret = mt_dpdk_tx_burst(entry->txq, tx_pkts, nb_pkts);
190+
mt_pthread_rwlock_unlock(&inf->rl_rwlock);
191+
192+
return ret;
167193
}
168194

169195
struct mt_txq_entry* mt_txq_get(struct mtl_main_impl* impl, enum mtl_port port,

lib/src/dev/mt_dev.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -707,8 +707,11 @@ static int dev_tx_queue_set_rl_rate(struct mt_interface* inf, uint16_t queue,
707707
/* not changed */
708708
if (bps == tx_queue->bps) return 0;
709709

710-
rte_atomic32_set(&inf->resetting, true);
711-
mt_pthread_mutex_lock(&inf->vf_cmd_mutex);
710+
ret = mt_pthread_rwlock_wrlock(&inf->rl_rwlock);
711+
if (ret) {
712+
err("%s(%d), failed to acquire write lock, ret %d\n", __func__, port, ret);
713+
return ret;
714+
}
712715

713716
ret = rte_eth_dev_stop(port_id);
714717
if (ret) {
@@ -800,8 +803,9 @@ static int dev_tx_queue_set_rl_rate(struct mt_interface* inf, uint16_t queue,
800803
tx_queue->bps = bps;
801804

802805
exit:
803-
mt_pthread_mutex_unlock(&inf->vf_cmd_mutex);
804-
rte_atomic32_set(&inf->resetting, false);
806+
ret = mt_pthread_rwlock_unlock(&inf->rl_rwlock);
807+
if (ret) err("%s(%d), failed to release write lock, ret %d\n", __func__, port, ret);
808+
805809
return ret;
806810
}
807811

@@ -2115,7 +2119,7 @@ int mt_dev_if_uinit(struct mtl_main_impl* impl) {
21152119

21162120
mt_pthread_mutex_destroy(&inf->tx_queues_mutex);
21172121
mt_pthread_mutex_destroy(&inf->rx_queues_mutex);
2118-
mt_pthread_mutex_destroy(&inf->vf_cmd_mutex);
2122+
mt_pthread_rwlock_destroy(&inf->rl_rwlock);
21192123

21202124
dev_close_port(inf);
21212125
}
@@ -2181,7 +2185,7 @@ int mt_dev_if_init(struct mtl_main_impl* impl) {
21812185
inf->tx_pacing_way = p->pacing;
21822186
mt_pthread_mutex_init(&inf->tx_queues_mutex, NULL);
21832187
mt_pthread_mutex_init(&inf->rx_queues_mutex, NULL);
2184-
mt_pthread_mutex_init(&inf->vf_cmd_mutex, NULL);
2188+
mt_pthread_rwlock_pref_wr_init(&inf->rl_rwlock);
21852189
rte_spinlock_init(&inf->stats_lock);
21862190

21872191
if (mt_user_ptp_tsc_source(impl)) {

lib/src/mt_cni.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,6 @@ static int cni_traffic(struct mtl_main_impl* impl) {
344344
for (int i = 0; i < num_ports; i++) {
345345
cni = cni_get_entry(impl, i);
346346
if (!cni->rxq) continue;
347-
if (rte_atomic32_read(&impl->inf[i].resetting)) continue;
348347

349348
struct mt_rx_pcap* pcap = &cni->pcap;
350349
/* if any pcap progress */

lib/src/mt_flow.c

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ static struct rte_flow* rte_rx_flow_create_raw(struct mt_interface* inf, uint16_
2727
struct rte_flow_item_raw spec = {0};
2828
struct rte_flow_item_raw mask = {0};
2929
struct rte_flow_action_queue to_queue = {0};
30+
int ret;
3031

3132
uint16_t port_id = inf->port_id;
3233
char pkt_buf[] =
@@ -58,9 +59,17 @@ static struct rte_flow* rte_rx_flow_create_raw(struct mt_interface* inf, uint16_
5859
action[0].conf = &to_queue;
5960
action[1].type = RTE_FLOW_ACTION_TYPE_END;
6061

61-
mt_pthread_mutex_lock(&inf->vf_cmd_mutex);
62+
ret = mt_pthread_rwlock_wrlock(&inf->rl_rwlock);
63+
if (ret) {
64+
err("%s(%d), failed to acquire write lock, ret %d\n", __func__, port_id, ret);
65+
return NULL;
66+
}
6267
r_flow = rte_flow_create(port_id, &attr, pattern, action, &error);
63-
mt_pthread_mutex_unlock(&inf->vf_cmd_mutex);
68+
ret = mt_pthread_rwlock_unlock(&inf->rl_rwlock);
69+
if (ret) {
70+
err("%s(%d), failed to release write lock, ret %d\n", __func__, port_id, ret);
71+
return NULL;
72+
}
6473
if (!r_flow) {
6574
err("%s(%d), rte_flow_create fail for queue %d, %s\n", __func__, port_id, q,
6675
mt_string_safe(error.message));
@@ -175,9 +184,17 @@ static struct rte_flow* rte_rx_flow_create(struct mt_interface* inf, uint16_t q,
175184
return NULL;
176185
}
177186

178-
mt_pthread_mutex_lock(&inf->vf_cmd_mutex);
187+
ret = mt_pthread_rwlock_wrlock(&inf->rl_rwlock);
188+
if (ret) {
189+
err("%s(%d), failed to acquire write lock, ret %d\n", __func__, port_id, ret);
190+
return NULL;
191+
}
179192
r_flow = rte_flow_create(port_id, &attr, pattern, action, &error);
180-
mt_pthread_mutex_unlock(&inf->vf_cmd_mutex);
193+
ret = mt_pthread_rwlock_unlock(&inf->rl_rwlock);
194+
if (ret) {
195+
err("%s(%d), failed to release write lock, ret %d\n", __func__, port_id, ret);
196+
return NULL;
197+
}
181198

182199
/* WA specific for e810 for PF interfaces */
183200
if (!has_ip_flow && !r_flow) {
@@ -192,9 +209,17 @@ static struct rte_flow* rte_rx_flow_create(struct mt_interface* inf, uint16_t q,
192209
return NULL;
193210
}
194211

195-
mt_pthread_mutex_lock(&inf->vf_cmd_mutex);
212+
ret = mt_pthread_rwlock_wrlock(&inf->rl_rwlock);
213+
if (ret) {
214+
err("%s(%d), failed to acquire write lock, ret %d\n", __func__, port_id, ret);
215+
return NULL;
216+
}
196217
r_flow = rte_flow_create(port_id, &attr, pattern, action, &error);
197-
mt_pthread_mutex_unlock(&inf->vf_cmd_mutex);
218+
ret = mt_pthread_rwlock_unlock(&inf->rl_rwlock);
219+
if (ret) {
220+
err("%s(%d), failed to release write lock, ret %d\n", __func__, port_id, ret);
221+
return NULL;
222+
}
198223
}
199224

200225
if (!r_flow) {
@@ -264,6 +289,7 @@ static int rx_flow_free(struct mt_interface* inf, struct mt_rx_flow_rsp* rsp) {
264289
enum mtl_port port = inf->port;
265290
struct rte_flow_error error;
266291
int ret;
292+
int rwlock_ret;
267293
int max_retry = 5;
268294
int retry = 0;
269295

@@ -273,9 +299,18 @@ static int rx_flow_free(struct mt_interface* inf, struct mt_rx_flow_rsp* rsp) {
273299
rsp->flow_id = -1;
274300
}
275301
if (rsp->flow) {
276-
mt_pthread_mutex_lock(&inf->vf_cmd_mutex);
302+
rwlock_ret = mt_pthread_rwlock_wrlock(&inf->rl_rwlock);
303+
if (rwlock_ret) {
304+
err("%s(%d), failed to acquire write lock, ret %d\n", __func__, port, rwlock_ret);
305+
return rwlock_ret;
306+
}
277307
ret = rte_flow_destroy(inf->port_id, rsp->flow, &error);
278-
mt_pthread_mutex_unlock(&inf->vf_cmd_mutex);
308+
rwlock_ret = mt_pthread_rwlock_unlock(&inf->rl_rwlock);
309+
if (rwlock_ret) {
310+
err("%s(%d), failed to release write lock, ret %d\n", __func__, port, rwlock_ret);
311+
return rwlock_ret;
312+
}
313+
279314
if (ret < 0) {
280315
err("%s(%d), flow destroy fail, queue %d, retry %d\n", __func__, port,
281316
rsp->queue_id, retry);

lib/src/mt_main.h

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -704,8 +704,6 @@ struct mt_interface {
704704
struct rte_ether_addr* mcast_mac_lists; /* pool of multicast mac addrs */
705705
uint32_t mcast_nb; /* number of address */
706706
uint32_t status; /* MT_IF_STAT_* */
707-
/* The port is temporarily off, e.g. during rte_tm_hierarchy_commit */
708-
rte_atomic32_t resetting;
709707

710708
/* default tx mbuf_pool */
711709
struct rte_mempool* tx_mbuf_pool;
@@ -715,11 +713,9 @@ struct mt_interface {
715713
uint16_t nb_rx_desc;
716714

717715
struct rte_mbuf* pad;
718-
/*
719-
* protect rl and fdir for vf.
720-
* _atomic_set_cmd(): There is incomplete cmd 112
721-
*/
722-
pthread_mutex_t vf_cmd_mutex;
716+
717+
/* protect port during reset when changing RL speed */
718+
pthread_rwlock_t rl_rwlock;
723719

724720
/* tx queue resources */
725721
uint16_t nb_tx_q;

lib/src/mt_platform.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,55 @@ static inline int mt_pthread_mutex_destroy(pthread_mutex_t* mutex) {
9393
return pthread_mutex_destroy(mutex);
9494
}
9595

96+
static inline int mt_pthread_rwlock_init(pthread_rwlock_t* rwlock,
97+
pthread_rwlockattr_t* attr) {
98+
return pthread_rwlock_init(rwlock, attr);
99+
}
100+
101+
static inline int mt_pthread_rwlock_pref_wr_init(pthread_rwlock_t* rwlock) {
102+
pthread_rwlockattr_t rwlock_attr;
103+
int ret;
104+
105+
ret = pthread_rwlockattr_init(&rwlock_attr);
106+
if (ret) return ret;
107+
108+
ret = pthread_rwlockattr_setkind_np(&rwlock_attr,
109+
PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
110+
if (ret) {
111+
pthread_rwlockattr_destroy(&rwlock_attr);
112+
return ret;
113+
}
114+
115+
ret = pthread_rwlock_init(rwlock, &rwlock_attr);
116+
pthread_rwlockattr_destroy(&rwlock_attr);
117+
118+
return ret;
119+
}
120+
121+
static inline int mt_pthread_rwlock_rdlock(pthread_rwlock_t* rwlock) {
122+
return pthread_rwlock_rdlock(rwlock);
123+
}
124+
125+
static inline int mt_pthread_rwlock_tryrdlock(pthread_rwlock_t* rwlock) {
126+
return pthread_rwlock_tryrdlock(rwlock);
127+
}
128+
129+
static inline int mt_pthread_rwlock_wrlock(pthread_rwlock_t* rwlock) {
130+
return pthread_rwlock_wrlock(rwlock);
131+
}
132+
133+
static inline int mt_pthread_rwlock_trywrlock(pthread_rwlock_t* rwlock) {
134+
return pthread_rwlock_trywrlock(rwlock);
135+
}
136+
137+
static inline int mt_pthread_rwlock_unlock(pthread_rwlock_t* rwlock) {
138+
return pthread_rwlock_unlock(rwlock);
139+
}
140+
141+
static inline int mt_pthread_rwlock_destroy(pthread_rwlock_t* rwlock) {
142+
return pthread_rwlock_destroy(rwlock);
143+
}
144+
96145
static inline int mt_pthread_cond_init(pthread_cond_t* cond,
97146
pthread_condattr_t* cond_attr) {
98147
return pthread_cond_init(cond, cond_attr);

lib/src/st2110/st_tx_video_session.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -430,15 +430,15 @@ static int tv_train_pacing(struct mtl_main_impl* impl, struct st_tx_video_sessio
430430
/* If the measured speed is lower than expected. Set higher bps and retrain to add
431431
* padding */
432432
if (measured_bps < rl_bps) {
433-
info("%s(%d), measured bps %"PRIu64" is lower then set bps %"PRIu64"\n",
434-
__func__, idx, (uint64_t)measured_bps, rl_bps);
433+
info("%s(%d), measured bps %" PRIu64 " is lower than set bps %" PRIu64 "\n", __func__,
434+
idx, (uint64_t)measured_bps, rl_bps);
435435
if (!mt_pacing_train_bps_result_search(impl, port, rl_bps, &bps_to_set)) {
436436
err("%s(%d), measured speed is too low on already trained bps\n", __func__, idx);
437437
return -EINVAL;
438438
}
439439

440440
bps_to_set = (rl_bps * rl_bps) / measured_bps;
441-
info("%s(%d), increase bps to %"PRIu64"\n", __func__, idx, bps_to_set);
441+
info("%s(%d), increase bps to %" PRIu64 "\n", __func__, idx, bps_to_set);
442442
mt_pacing_train_bps_result_add(impl, port, rl_bps, bps_to_set);
443443
mt_txq_set_tx_bps(queue, bps_to_set);
444444
ret = tv_train_pacing(impl, s, s_port);

0 commit comments

Comments
 (0)