Skip to content

Commit

Permalink
app/testpmd: add attach and detach port for multiple process
Browse files Browse the repository at this point in the history
The port information needs to be updated due to attaching and detaching
port. Currently, it is done in the same thread as removing or probing
device, which doesn't satisfy the operation of attaching and detaching
device in multiple process.

If this operation is performed in one process, the other process can
receive 'new' or 'destroy' event. So we can move updating port information
to event callback to support attaching and detaching port in primary and
secondary process.

Note: the reason for adding an alarm callback in 'destroy' event is that
the ethdev state is changed from 'ATTACHED' to 'UNUSED' only after the
event callback finished. But the remove_invalid_ports() function removes
invalid port only if ethdev state is 'UNUSED'. If we don't add alarm
callback, this detached port information can not be removed.

Signed-off-by: Huisong Li <[email protected]>
Signed-off-by: Dongdong Liu <[email protected]>
Acked-by: Chengwen Feng <[email protected]>
  • Loading branch information
LiHuiSong1 authored and shemminger committed Feb 7, 2025
1 parent a1b1974 commit 94a0607
Showing 1 changed file with 51 additions and 17 deletions.
68 changes: 51 additions & 17 deletions app/test-pmd/testpmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -2905,6 +2905,9 @@ start_port(portid_t pid)
at_least_one_port_exist = true;

port = &ports[pi];
if (port->need_setup)
setup_attached_port(pi);

if (port->port_status == RTE_PORT_STOPPED) {
port->port_status = RTE_PORT_HANDLING;
all_ports_already_started = false;
Expand Down Expand Up @@ -3252,6 +3255,7 @@ remove_invalid_ports(void)
remove_invalid_ports_in(ports_ids, &nb_ports);
remove_invalid_ports_in(fwd_ports_ids, &nb_fwd_ports);
nb_cfg_ports = nb_fwd_ports;
printf("Now total ports is %d\n", nb_ports);
}

static void
Expand Down Expand Up @@ -3424,14 +3428,11 @@ attach_port(char *identifier)
return;
}

/* first attach mode: event */
/* First attach mode: event
* New port flag is updated on RTE_ETH_EVENT_NEW event
*/
if (setup_on_probe_event) {
/* new ports are detected on RTE_ETH_EVENT_NEW event */
for (pi = 0; pi < RTE_MAX_ETHPORTS; pi++)
if (ports[pi].port_status == RTE_PORT_HANDLING &&
ports[pi].need_setup != 0)
setup_attached_port(pi);
return;
goto out;
}

/* second attach mode: iterator */
Expand All @@ -3441,6 +3442,9 @@ attach_port(char *identifier)
continue; /* port was already attached before */
setup_attached_port(pi);
}
out:
printf("Port %s is attached.\n", identifier);
printf("Done\n");
}

static void
Expand All @@ -3460,14 +3464,8 @@ setup_attached_port(portid_t pi)
"Error during enabling promiscuous mode for port %u: %s - ignore\n",
pi, rte_strerror(-ret));

ports_ids[nb_ports++] = pi;
fwd_ports_ids[nb_fwd_ports++] = pi;
nb_cfg_ports = nb_fwd_ports;
ports[pi].need_setup = 0;
ports[pi].port_status = RTE_PORT_STOPPED;

printf("Port %d is attached. Now total ports is %d\n", pi, nb_ports);
printf("Done\n");
}

static void
Expand Down Expand Up @@ -3497,10 +3495,8 @@ detach_device(struct rte_device *dev)
TESTPMD_LOG(ERR, "Failed to detach device %s\n", rte_dev_name(dev));
return;
}
remove_invalid_ports();

printf("Device is detached\n");
printf("Now total ports is %d\n", nb_ports);
printf("Done\n");
return;
}
Expand Down Expand Up @@ -3732,7 +3728,25 @@ rmv_port_callback(void *arg)
struct rte_device *device = dev_info.device;
close_port(port_id);
detach_device(device); /* might be already removed or have more ports */
remove_invalid_ports();
}
if (need_to_start)
start_packet_forwarding(0);
}

static void
remove_invalid_ports_callback(void *arg)
{
portid_t port_id = (intptr_t)arg;
int need_to_start = 0;

if (!test_done && port_is_forwarding(port_id)) {
need_to_start = 1;
stop_packet_forwarding();
}

remove_invalid_ports();

if (need_to_start)
start_packet_forwarding(0);
}
Expand All @@ -3758,8 +3772,19 @@ eth_event_callback(portid_t port_id, enum rte_eth_event_type type, void *param,

switch (type) {
case RTE_ETH_EVENT_NEW:
ports[port_id].need_setup = 1;
ports[port_id].port_status = RTE_PORT_HANDLING;
/* The port in ports_id and fwd_ports_ids is always valid
* from index 0 ~ (nb_ports - 1) due to updating their
* position when one port is detached or removed.
*/
ports_ids[nb_ports++] = port_id;
fwd_ports_ids[nb_fwd_ports++] = port_id;
nb_cfg_ports = nb_fwd_ports;
printf("Port %d is probed. Now total ports is %d\n", port_id, nb_ports);

if (setup_on_probe_event) {
ports[port_id].need_setup = 1;
ports[port_id].port_status = RTE_PORT_HANDLING;
}
break;
case RTE_ETH_EVENT_INTR_RMV:
if (port_id_is_invalid(port_id, DISABLED_WARN))
Expand All @@ -3772,6 +3797,15 @@ eth_event_callback(portid_t port_id, enum rte_eth_event_type type, void *param,
case RTE_ETH_EVENT_DESTROY:
ports[port_id].port_status = RTE_PORT_CLOSED;
printf("Port %u is closed\n", port_id);
/*
* Defer to remove port id due to the reason that the ethdev
* state is changed from 'ATTACHED' to 'UNUSED' only after the
* event callback finished. Otherwise this port id can not be
* removed.
*/
if (rte_eal_alarm_set(100000, remove_invalid_ports_callback,
(void *)(intptr_t)port_id))
fprintf(stderr, "Could not set up deferred task to remove this port id.\n");
break;
case RTE_ETH_EVENT_RX_AVAIL_THRESH: {
uint16_t rxq_id;
Expand Down

0 comments on commit 94a0607

Please sign in to comment.