Skip to content

Commit 3808404

Browse files
Dimon-Zhaotmonjalo
authored andcommitted
net/nbl: fix hardware stats interrupt nesting
The timer interrupt handler periodically queries and updates hw_stats via mailbox. Since mailbox operations rely on interrupts for packet reception, this causes interrupt nesting. To resolve this, trigger a task from the interrupt handler and start a dedicated thread to execute this task, eliminating the nested interrupt scenario. Fixes: c9726a7 ("net/nbl: support dropped packets counter") Cc: stable@dpdk.org Signed-off-by: Dimon Zhao <dimon.zhao@nebula-matrix.com>
1 parent 903bec3 commit 3808404

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

drivers/net/nbl/nbl_dev/nbl_dev.c

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,11 +168,37 @@ static int nbl_dev_update_hw_stats(struct rte_eth_dev *eth_dev)
168168
return ret;
169169
}
170170

171+
static uint32_t nbl_dev_thread_hw_stats_task(void *param)
172+
{
173+
struct rte_eth_dev *eth_dev = param;
174+
struct nbl_adapter *adapter = ETH_DEV_TO_NBL_DEV_PF_PRIV(eth_dev);
175+
struct nbl_dev_mgt *dev_mgt = NBL_ADAPTER_TO_DEV_MGT(adapter);
176+
struct nbl_dev_net_mgt *net_dev = NBL_DEV_MGT_TO_NET_DEV(dev_mgt);
177+
char unused[16];
178+
ssize_t nr;
179+
180+
while (true) {
181+
nr = read(net_dev->fd[0], &unused, sizeof(unused));
182+
if (nr <= 0)
183+
break;
184+
185+
nbl_dev_update_hw_stats(eth_dev);
186+
}
187+
188+
return 0;
189+
}
190+
171191
static void nbl_dev_update_hw_stats_handler(void *param)
172192
{
173193
struct rte_eth_dev *eth_dev = param;
194+
struct nbl_adapter *adapter = ETH_DEV_TO_NBL_DEV_PF_PRIV(eth_dev);
195+
struct nbl_dev_mgt *dev_mgt = NBL_ADAPTER_TO_DEV_MGT(adapter);
196+
struct nbl_dev_net_mgt *net_dev = NBL_DEV_MGT_TO_NET_DEV(dev_mgt);
197+
char notify_byte = 0;
198+
ssize_t nw;
174199

175-
nbl_dev_update_hw_stats(eth_dev);
200+
nw = write(net_dev->fd[1], &notify_byte, 1);
201+
RTE_SET_USED(nw);
176202

177203
rte_eal_alarm_set(NBL_ALARM_INTERNAL, nbl_dev_update_hw_stats_handler, eth_dev);
178204
}
@@ -187,6 +213,23 @@ static int nbl_dev_hw_stats_start(struct rte_eth_dev *eth_dev)
187213
struct nbl_ustore_stats ustore_stats = {0};
188214
int ret;
189215

216+
ret = pipe(net_dev->fd);
217+
if (ret) {
218+
NBL_LOG(ERR, "hw_stats pipe failed, ret %d", ret);
219+
return ret;
220+
}
221+
222+
ret = rte_thread_create_internal_control(&net_dev->tid, "nbl_hw_stats_thread",
223+
nbl_dev_thread_hw_stats_task, eth_dev);
224+
if (ret) {
225+
NBL_LOG(ERR, "create hw_stats thread failed, ret %d", ret);
226+
close(net_dev->fd[0]);
227+
close(net_dev->fd[1]);
228+
net_dev->fd[0] = -1;
229+
net_dev->fd[1] = -1;
230+
return ret;
231+
}
232+
190233
if (!common->is_vf) {
191234
ret = disp_ops->get_ustore_total_pkt_drop_stats(NBL_DEV_MGT_TO_DISP_PRIV(dev_mgt),
192235
common->eth_id, &ustore_stats);
@@ -261,8 +304,19 @@ static void nbl_dev_txrx_stop(struct rte_eth_dev *eth_dev)
261304

262305
static int nbl_dev_hw_stats_stop(struct rte_eth_dev *eth_dev)
263306
{
307+
struct nbl_adapter *adapter = ETH_DEV_TO_NBL_DEV_PF_PRIV(eth_dev);
308+
struct nbl_dev_mgt *dev_mgt = NBL_ADAPTER_TO_DEV_MGT(adapter);
309+
struct nbl_dev_net_mgt *net_dev = NBL_DEV_MGT_TO_NET_DEV(dev_mgt);
310+
264311
rte_eal_alarm_cancel(nbl_dev_update_hw_stats_handler, eth_dev);
265312

313+
/* closing pipe to cause hw_stats thread to exit */
314+
close(net_dev->fd[0]);
315+
close(net_dev->fd[1]);
316+
net_dev->fd[0] = -1;
317+
net_dev->fd[1] = -1;
318+
rte_thread_join(net_dev->tid, NULL);
319+
266320
return 0;
267321
}
268322

drivers/net/nbl/nbl_dev/nbl_dev.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ struct nbl_dev_net_mgt {
6060
u8 rsv:6;
6161
struct nbl_hw_stats hw_stats;
6262
bool hw_stats_inited;
63+
rte_thread_t tid;
64+
int fd[2];
6365
};
6466

6567
struct nbl_dev_mgt {

0 commit comments

Comments
 (0)