mirror of
https://github.com/openvswitch/ovs
synced 2025-08-22 01:51:26 +00:00
netdev-dpdk: add hotplug support
In order to use dpdk ports in ovs they have to be bound to a DPDK compatible driver before ovs is started. This patch adds the possibility to hotplug (or hot-unplug) a device after ovs has been started. The implementation adds two appctl commands: netdev-dpdk/attach and netdev-dpdk/detach After the user attaches a new device, it has to be added to a bridge using the add-port command, similarly, before detaching a device, it has to be removed using the del-port command. Signed-off-by: Mauricio Vasquez B <mauricio.vasquezbernal@studenti.polito.it> Signed-off-by: Ciara Loftus <ciara.loftus@intel.com> Co-authored-by: Ciara Loftus <ciara.loftus@intel.com> Acked-by: Stephen Finucane <stephen@that.guru> # docs only Signed-off-by: Daniele Di Proietto <diproiettod@vmware.com>
This commit is contained in:
parent
0fb03722ff
commit
b8374d0d04
@ -298,6 +298,33 @@ physical ports which in turn effects the non-tunnel traffic performance.
|
||||
So it is advised to turn off the Rx checksum offload for non-tunnel traffic use
|
||||
cases to achieve the best performance.
|
||||
|
||||
.. _port-hotplug:
|
||||
|
||||
Port Hotplug
|
||||
------------
|
||||
|
||||
OVS supports port hotplugging, allowing the use of ports that were not bound
|
||||
to DPDK when vswitchd was started.
|
||||
In order to attach a port, it has to be bound to DPDK using the
|
||||
``dpdk_nic_bind.py`` script::
|
||||
|
||||
$ $DPDK_DIR/tools/dpdk_nic_bind.py --bind=igb_uio 0000:01:00.0
|
||||
|
||||
Then it can be attached to OVS::
|
||||
|
||||
$ ovs-appctl netdev-dpdk/attach 0000:01:00.0
|
||||
|
||||
At this point, the user can create a dpdk port using the ``add-port`` command.
|
||||
|
||||
It is also possible to detach a port from ovs, the user has to remove the
|
||||
port using the del-port command, then it can be detached using::
|
||||
|
||||
$ ovs-appctl netdev-dpdk/detach dpdk0
|
||||
|
||||
This feature is not supported with VFIO and does not work with some NICs.
|
||||
For more information please refer to the `DPDK Port Hotplug Framework
|
||||
<http://dpdk.org/doc/guides/prog_guide/port_hotplug_framework.html#hotplug>`__.
|
||||
|
||||
.. _dpdk-ovs-in-guest:
|
||||
|
||||
OVS with DPDK Inside VMs
|
||||
|
1
NEWS
1
NEWS
@ -55,6 +55,7 @@ Post-v2.6.0
|
||||
which set the number of rx and tx descriptors to use for the given port.
|
||||
* Support for DPDK v16.11.
|
||||
* Support for rx checksum offload. Refer DPDK HOWTO for details.
|
||||
* Port Hotplug is now supported.
|
||||
- Fedora packaging:
|
||||
* A package upgrade does not automatically restart OVS service.
|
||||
- ovs-vswitchd/ovs-vsctl:
|
||||
|
@ -2357,6 +2357,82 @@ netdev_dpdk_set_admin_state(struct unixctl_conn *conn, int argc,
|
||||
unixctl_command_reply(conn, "OK");
|
||||
}
|
||||
|
||||
static void
|
||||
netdev_dpdk_attach(struct unixctl_conn *conn, int argc OVS_UNUSED,
|
||||
const char *argv[], void *aux OVS_UNUSED)
|
||||
{
|
||||
int ret;
|
||||
char *response;
|
||||
uint8_t port_id;
|
||||
|
||||
ovs_mutex_lock(&dpdk_mutex);
|
||||
|
||||
ret = rte_eth_dev_attach(argv[1], &port_id);
|
||||
if (ret < 0) {
|
||||
response = xasprintf("Error attaching device '%s'", argv[1]);
|
||||
ovs_mutex_unlock(&dpdk_mutex);
|
||||
unixctl_command_reply_error(conn, response);
|
||||
free(response);
|
||||
return;
|
||||
}
|
||||
|
||||
response = xasprintf("Device '%s' has been attached as 'dpdk%d'",
|
||||
argv[1], port_id);
|
||||
|
||||
ovs_mutex_unlock(&dpdk_mutex);
|
||||
unixctl_command_reply(conn, response);
|
||||
free(response);
|
||||
}
|
||||
|
||||
static void
|
||||
netdev_dpdk_detach(struct unixctl_conn *conn, int argc OVS_UNUSED,
|
||||
const char *argv[], void *aux OVS_UNUSED)
|
||||
{
|
||||
int ret;
|
||||
char *response;
|
||||
unsigned int parsed_port;
|
||||
uint8_t port_id;
|
||||
char devname[RTE_ETH_NAME_MAX_LEN];
|
||||
|
||||
ovs_mutex_lock(&dpdk_mutex);
|
||||
|
||||
ret = dpdk_dev_parse_name(argv[1], "dpdk", &parsed_port);
|
||||
if (ret) {
|
||||
response = xasprintf("'%s' is not a valid port", argv[1]);
|
||||
goto error;
|
||||
}
|
||||
|
||||
port_id = parsed_port;
|
||||
|
||||
struct netdev *netdev = netdev_from_name(argv[1]);
|
||||
if (netdev) {
|
||||
netdev_close(netdev);
|
||||
response = xasprintf("Port '%s' is being used. Remove it before"
|
||||
"detaching", argv[1]);
|
||||
goto error;
|
||||
}
|
||||
|
||||
rte_eth_dev_close(port_id);
|
||||
|
||||
ret = rte_eth_dev_detach(port_id, devname);
|
||||
if (ret < 0) {
|
||||
response = xasprintf("Port '%s' can not be detached", argv[1]);
|
||||
goto error;
|
||||
}
|
||||
|
||||
response = xasprintf("Port '%s' has been detached", argv[1]);
|
||||
|
||||
ovs_mutex_unlock(&dpdk_mutex);
|
||||
unixctl_command_reply(conn, response);
|
||||
free(response);
|
||||
return;
|
||||
|
||||
error:
|
||||
ovs_mutex_unlock(&dpdk_mutex);
|
||||
unixctl_command_reply_error(conn, response);
|
||||
free(response);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set virtqueue flags so that we do not receive interrupts.
|
||||
*/
|
||||
@ -2632,6 +2708,12 @@ netdev_dpdk_class_init(void)
|
||||
unixctl_command_register("netdev-dpdk/set-admin-state",
|
||||
"[netdev] up|down", 1, 2,
|
||||
netdev_dpdk_set_admin_state, NULL);
|
||||
unixctl_command_register("netdev-dpdk/attach",
|
||||
"pci address of device", 1, 1,
|
||||
netdev_dpdk_attach, NULL);
|
||||
unixctl_command_register("netdev-dpdk/detach",
|
||||
"port", 1, 1,
|
||||
netdev_dpdk_detach, NULL);
|
||||
|
||||
ovsthread_once_done(&once);
|
||||
}
|
||||
@ -2668,7 +2750,7 @@ dpdk_ring_create(const char dev_name[], unsigned int port_no,
|
||||
{
|
||||
struct dpdk_ring *ring_pair;
|
||||
char *ring_name;
|
||||
int err;
|
||||
int port_id;
|
||||
|
||||
ring_pair = dpdk_rte_mzalloc(sizeof *ring_pair);
|
||||
if (!ring_pair) {
|
||||
@ -2698,19 +2780,20 @@ dpdk_ring_create(const char dev_name[], unsigned int port_no,
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
err = rte_eth_from_rings(dev_name, &ring_pair->cring_rx, 1,
|
||||
&ring_pair->cring_tx, 1, SOCKET0);
|
||||
port_id = rte_eth_from_rings(dev_name, &ring_pair->cring_rx, 1,
|
||||
&ring_pair->cring_tx, 1, SOCKET0);
|
||||
|
||||
if (err < 0) {
|
||||
if (port_id < 0) {
|
||||
rte_free(ring_pair);
|
||||
return ENODEV;
|
||||
}
|
||||
|
||||
ring_pair->user_port_id = port_no;
|
||||
ring_pair->eth_port_id = rte_eth_dev_count() - 1;
|
||||
ring_pair->eth_port_id = port_id;
|
||||
*eth_port_id = port_id;
|
||||
|
||||
ovs_list_push_back(&dpdk_ring_list, &ring_pair->list_node);
|
||||
|
||||
*eth_port_id = ring_pair->eth_port_id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user