>-----Original Message----- >From: Ananyev, Konstantin <konstantin.anan...@intel.com> >Sent: Monday, January 6, 2020 5:43 PM >To: Pavan Nikhilesh Bhagavatula <pbhagavat...@marvell.com>; Jerin >Jacob Kollanukkaran <jer...@marvell.com>; Kovacevic, Marko ><marko.kovace...@intel.com>; Ori Kam <or...@mellanox.com>; >Richardson, Bruce <bruce.richard...@intel.com>; Nicolau, Radu ><radu.nico...@intel.com>; Akhil Goyal <akhil.go...@nxp.com>; >Kantecki, Tomasz <tomasz.kante...@intel.com>; Sunil Kumar Kori ><sk...@marvell.com> >Cc: dev@dpdk.org >Subject: [EXT] RE: [dpdk-dev] [PATCH v2 10/11] examples/l3fwd: add >graceful teardown for eventdevice > >External Email > >---------------------------------------------------------------------- > >> >> Add graceful teardown that addresses both event mode and poll >> >mode. >> >> >> >> Signed-off-by: Pavan Nikhilesh <pbhagavat...@marvell.com> >> >> --- >> >> examples/l3fwd/main.c | 49 >++++++++++++++++++++++++++++++- >> >------------ >> >> 1 file changed, 34 insertions(+), 15 deletions(-) >> >> >> >> diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c >> >> index 0ae64dd41..68998f42c 100644 >> >> --- a/examples/l3fwd/main.c >> >> +++ b/examples/l3fwd/main.c >> >> @@ -920,7 +920,7 @@ main(int argc, char **argv) >> >> struct lcore_conf *qconf; >> >> struct rte_eth_dev_info dev_info; >> >> struct rte_eth_txconf *txconf; >> >> - int ret; >> >> + int i, ret; >> >> unsigned nb_ports; >> >> uint16_t queueid, portid; >> >> unsigned lcore_id; >> >> @@ -1195,27 +1195,46 @@ main(int argc, char **argv) >> >> } >> >> } >> >> >> >> - >> >> check_all_ports_link_status(enabled_port_mask); >> >> >> >> ret = 0; >> >> /* launch per-lcore init on every lcore */ >> >> rte_eal_mp_remote_launch(l3fwd_lkp.main_loop, NULL, >> >CALL_MASTER); >> >> - RTE_LCORE_FOREACH_SLAVE(lcore_id) { >> >> - if (rte_eal_wait_lcore(lcore_id) < 0) { >> >> - ret = -1; >> >> - break; >> >> + if (evt_rsrc->enabled) { >> >> + for (i = 0; i < evt_rsrc->rx_adptr.nb_rx_adptr; i++) >> >> + rte_event_eth_rx_adapter_stop( >> >> + evt_rsrc->rx_adptr.rx_adptr[i]); >> >> + for (i = 0; i < evt_rsrc->tx_adptr.nb_tx_adptr; i++) >> >> + rte_event_eth_tx_adapter_stop( >> >> + evt_rsrc->tx_adptr.tx_adptr[i]); >> >> + >> >> + RTE_ETH_FOREACH_DEV(portid) { >> >> + if ((enabled_port_mask & (1 << portid)) == 0) >> >> + continue; >> >> + rte_eth_dev_stop(portid); >> >> } >> >> - } >> >> >> >> - /* stop ports */ >> >> - RTE_ETH_FOREACH_DEV(portid) { >> >> - if ((enabled_port_mask & (1 << portid)) == 0) >> >> - continue; >> >> - printf("Closing port %d...", portid); >> >> - rte_eth_dev_stop(portid); >> >> - rte_eth_dev_close(portid); >> >> - printf(" Done\n"); >> > >> >Why to stop ports *before* making sure all lcores are stopped? >> >Shouldn't that peace of code be identical for both poll and event >mode? >> >Something like: >> >rte_eal_mp_wait_lcore(); >> > >> > RTE_ETH_FOREACH_DEV(portid) { >> > if ((enabled_port_mask & (1 << portid)) == 0) >> > continue; >> > rte_eth_dev_stop(portid); >> > rte_eth_dev_close(portid); >> > } >> >? >> > >> >> Event dev spec requires stopping producers before consumers else >we might run into >> deadlock in some cases. > >Ok... but for TX path wouldn't core be a producer?
Not in all cases, true in case of SW event device and implementation defined in HW event devices. Also both the cases of Tx poll on force_quit in case Tx path fails so that cores can exit. if (flags & L3FWD_EVENT_TX_ENQ) { ev.queue_id = tx_q_id; ev.op = RTE_EVENT_OP_FORWARD; while (rte_event_enqueue_burst(event_d_id, event_p_id, &ev, 1) && !force_quit) ; } if (flags & L3FWD_EVENT_TX_DIRECT) { rte_event_eth_tx_adapter_txq_set(mbuf, 0); while (!rte_event_eth_tx_adapter_enqueue(event_d_id, event_p_id, &ev, 1, 0) && !force_quit) ; } >Also for that wouldn't rte_event_eth_(rx|tx)_adapter_stop(0 be >enough? In case of HW event devices the above might be nop as control lies with driver/net. And since anyway we need to stop ethernet device we might as well do it here. >I am not familiar with event-dev spec at all, so forgive for possibly dumb >questions 😉 😊 > >> >> >> + rte_eal_mp_wait_lcore(); >> >> + RTE_ETH_FOREACH_DEV(portid) { >> >> + if ((enabled_port_mask & (1 << portid)) == 0) >> >> + continue; >> >> + rte_eth_dev_close(portid); >> >> + } >> >> + >> >> + rte_event_dev_stop(evt_rsrc->event_d_id); >> >> + rte_event_dev_close(evt_rsrc->event_d_id); >> >> + >> >> + } else { >> >> + rte_eal_mp_wait_lcore(); >> >> + >> >> + RTE_ETH_FOREACH_DEV(portid) { >> >> + if ((enabled_port_mask & (1 << portid)) == 0) >> >> + continue; >> >> + printf("Closing port %d...", portid); >> >> + rte_eth_dev_stop(portid); >> >> + rte_eth_dev_close(portid); >> >> + printf(" Done\n"); >> >> + } >> >> } >> >> printf("Bye...\n"); >> >> >> >> -- >> >> 2.17.1