app/testpmd: align behaviour of multi-port detach

A port can be closed in multiple situations:
	- close command calling close_port() -> rte_eth_dev_close()
	- exit calling close_port() -> rte_eth_dev_close()
	- hotplug calling close_port() -> rte_eth_dev_close()
	- hotplug calling detach_device() -> rte_dev_remove()
	- port detach command, detach_device() -> rte_dev_remove()
	- device detach command, detach_devargs() -> rte_eal_hotplug_remove()

The flow rules are flushed before each close.
It was already done in close_port(), detach_devargs() and
detach_port_device() which calls detach_device(),
but not in detach_device(). As a consequence, it was missing for siblings
of port detach command and unplugged device.
The check before calling port_flow_flush() is moved inside the function.

The state of the port to close is checked to be stopped.
As above, this check was missing in detach_device(),
impacting the cases of a multi-port device unplugged or detached
with the port detach command.

Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
Acked-by: Stephen Hemminger <stephen@networkplumber.org>
This commit is contained in:
Thomas Monjalon 2020-09-29 01:14:34 +02:00 committed by Ferruh Yigit
parent 85c6571c91
commit 2a449871a1
2 changed files with 17 additions and 14 deletions

View File

@ -1707,9 +1707,12 @@ int
port_flow_flush(portid_t port_id)
{
struct rte_flow_error error;
struct rte_port *port;
struct rte_port *port = &ports[port_id];
int ret = 0;
if (port->flow_list == NULL)
return ret;
/* Poisoning to make sure PMDs update it in case of error. */
memset(&error, 0x44, sizeof(error));
if (rte_flow_flush(port_id, &error)) {
@ -1718,7 +1721,7 @@ port_flow_flush(portid_t port_id)
port_id == (portid_t)RTE_PORT_ALL)
return ret;
}
port = &ports[port_id];
while (port->flow_list) {
struct port_flow *pf = port->flow_list->next;

View File

@ -2695,8 +2695,7 @@ close_port(portid_t pid)
continue;
}
if (port->flow_list)
port_flow_flush(pi);
port_flow_flush(pi);
rte_eth_dev_close(pi);
}
@ -2826,15 +2825,20 @@ detach_device(struct rte_device *dev)
printf("Removing a device...\n");
RTE_ETH_FOREACH_DEV_OF(sibling, dev) {
if (ports[sibling].port_status != RTE_PORT_CLOSED) {
if (ports[sibling].port_status != RTE_PORT_STOPPED) {
printf("Port %u not stopped\n", sibling);
return;
}
port_flow_flush(sibling);
}
}
if (rte_dev_remove(dev) < 0) {
TESTPMD_LOG(ERR, "Failed to detach device %s\n", dev->name);
return;
}
RTE_ETH_FOREACH_DEV_OF(sibling, dev) {
if (ports[sibling].port_status != RTE_PORT_CLOSED) {
}
}
remove_invalid_ports();
printf("Device is detached\n");
@ -2855,8 +2859,6 @@ detach_port_device(portid_t port_id)
return;
}
printf("Port was not closed\n");
if (ports[port_id].flow_list)
port_flow_flush(port_id);
}
detach_device(rte_eth_devices[port_id].device);
@ -2886,9 +2888,7 @@ detach_devargs(char *identifier)
rte_eth_iterator_cleanup(&iterator);
return;
}
if (ports[port_id].flow_list)
port_flow_flush(port_id);
port_flow_flush(port_id);
}
}