The dpdk_list serves different usecases: - maintaining all DPDK ports link status (dpdk_watchdog), - looking up a DPDK port id for checking which netdevice uses a DPDK port (if any), - looking up a vhost_id for checking which netdevice uses a vHost port (if any), - running some command on all DPDK and vHost backed ports,
Have a separate list (and mutex) for vHost ports objects. Thanks to this, specialised usecases don't need to care about the device type. Signed-off-by: David Marchand <[email protected]> --- lib/netdev-dpdk-common.c | 3 +- lib/netdev-dpdk-common.h | 6 +- lib/netdev-dpdk.c | 159 ++++++++++++++++++--------------------- 3 files changed, 79 insertions(+), 89 deletions(-) diff --git a/lib/netdev-dpdk-common.c b/lib/netdev-dpdk-common.c index 5ae5da091..2de5af7ac 100644 --- a/lib/netdev-dpdk-common.c +++ b/lib/netdev-dpdk-common.c @@ -97,7 +97,8 @@ BUILD_ASSERT_DECL(MAX_NB_MBUF % ROUND_DOWN_POW2(MAX_NB_MBUF / MIN_NB_MBUF) BUILD_ASSERT_DECL((MAX_NB_MBUF / ROUND_DOWN_POW2(MAX_NB_MBUF / MIN_NB_MBUF)) % MP_CACHE_SZ == 0); -struct ovs_mutex dpdk_mp_mutex OVS_ACQ_AFTER(dpdk_mutex) +struct ovs_mutex dpdk_mp_mutex + OVS_ACQ_AFTER(dpdk_eth_mutex, dpdk_vhost_mutex) = OVS_MUTEX_INITIALIZER; /* Contains all 'struct dpdk_mp's. */ diff --git a/lib/netdev-dpdk-common.h b/lib/netdev-dpdk-common.h index 989853b2f..8d4d8b0d1 100644 --- a/lib/netdev-dpdk-common.h +++ b/lib/netdev-dpdk-common.h @@ -42,8 +42,10 @@ struct smap; #define SOCKET0 0 -extern struct ovs_mutex dpdk_mutex; -extern struct ovs_mutex dpdk_mp_mutex OVS_ACQ_AFTER(dpdk_mutex); +extern struct ovs_mutex dpdk_eth_mutex; +extern struct ovs_mutex dpdk_vhost_mutex; +extern struct ovs_mutex dpdk_mp_mutex + OVS_ACQ_AFTER(dpdk_eth_mutex, dpdk_vhost_mutex); /* Need to reserve tons of extra space in the mbufs so we can align the * DMA addresses to 4KB. diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index f07216560..2f6c40fba 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -155,11 +155,17 @@ static const struct rte_vhost_device_ops virtio_net_device_ops = .destroy_connection = destroy_connection, }; -struct ovs_mutex dpdk_mutex = OVS_MUTEX_INITIALIZER; +struct ovs_mutex dpdk_eth_mutex = OVS_MUTEX_INITIALIZER; -/* Contains all 'struct dpdk_dev's. */ -static struct ovs_list dpdk_list OVS_GUARDED_BY(dpdk_mutex) - = OVS_LIST_INITIALIZER(&dpdk_list); +/* Contains all ethernet ports. */ +static struct ovs_list dpdk_eth_list OVS_GUARDED_BY(dpdk_eth_mutex) + = OVS_LIST_INITIALIZER(&dpdk_eth_list); + +struct ovs_mutex dpdk_vhost_mutex = OVS_MUTEX_INITIALIZER; + +/* Contains all vhost ports. */ +static struct ovs_list dpdk_vhost_list OVS_GUARDED_BY(dpdk_vhost_mutex) + = OVS_LIST_INITIALIZER(&dpdk_vhost_list); /* There should be one 'struct dpdk_tx_queue' created for * each netdev tx queue. */ @@ -239,7 +245,7 @@ struct netdev_dpdk { ); PADDED_MEMBERS_CACHELINE_MARKER(CACHE_LINE_SIZE, cacheline1, - struct ovs_mutex mutex OVS_ACQ_AFTER(dpdk_mutex); + struct ovs_mutex mutex OVS_ACQ_AFTER(dpdk_eth_mutex, dpdk_vhost_mutex); struct dpdk_mp *dpdk_mp; /* virtio identifier for vhost devices */ @@ -258,8 +264,8 @@ struct netdev_dpdk { PADDED_MEMBERS(CACHE_LINE_SIZE, struct netdev up; - /* In dpdk_list. */ - struct ovs_list list_node OVS_GUARDED_BY(dpdk_mutex); + /* In dpdk_eth_list or dpdk_vhost_list. */ + struct ovs_list list_node; /* QoS configuration and lock for the device */ OVSRCU_TYPE(struct dpdk_qos_conf *) qos_conf; @@ -475,15 +481,13 @@ dpdk_watchdog(void *dummy OVS_UNUSED) pthread_detach(pthread_self()); for (;;) { - ovs_mutex_lock(&dpdk_mutex); - LIST_FOR_EACH (dev, list_node, &dpdk_list) { + ovs_mutex_lock(&dpdk_eth_mutex); + LIST_FOR_EACH (dev, list_node, &dpdk_eth_list) { ovs_mutex_lock(&dev->mutex); - if (is_eth_class(dev->up.netdev_class)) { - check_link_status(dev); - } + check_link_status(dev); ovs_mutex_unlock(&dev->mutex); } - ovs_mutex_unlock(&dpdk_mutex); + ovs_mutex_unlock(&dpdk_eth_mutex); xsleep(DPDK_PORT_WATCHDOG_INTERVAL); } @@ -999,16 +1003,16 @@ netdev_dpdk_vhost_construct(struct netdev *netdev) goto out; } - ovs_mutex_lock(&dpdk_mutex); + ovs_mutex_lock(&dpdk_vhost_mutex); err = rte_vhost_driver_start(dev->vhost_id); if (!err) { - ovs_list_push_back(&dpdk_list, &dev->list_node); + ovs_list_push_back(&dpdk_vhost_list, &dev->list_node); netdev_request_reconfigure(netdev); } else { VLOG_ERR("rte_vhost_driver_start failed for vhost user " "port: %s\n", name); } - ovs_mutex_unlock(&dpdk_mutex); + ovs_mutex_unlock(&dpdk_vhost_mutex); out: if (err) { @@ -1033,10 +1037,10 @@ netdev_dpdk_vhost_client_construct(struct netdev *netdev) "port: %s\n", netdev->name); return err; } else { - ovs_mutex_lock(&dpdk_mutex); - ovs_list_push_back(&dpdk_list, &dev->list_node); + ovs_mutex_lock(&dpdk_vhost_mutex); + ovs_list_push_back(&dpdk_vhost_list, &dev->list_node); netdev_request_reconfigure(netdev); - ovs_mutex_unlock(&dpdk_mutex); + ovs_mutex_unlock(&dpdk_vhost_mutex); } return err; @@ -1070,10 +1074,10 @@ netdev_dpdk_eth_construct(struct netdev *netdev) dev->rte_xstats_ids_size = 0; common->sw_stats->tx_retries = UINT64_MAX; - ovs_mutex_lock(&dpdk_mutex); - ovs_list_push_back(&dpdk_list, &dev->list_node); + ovs_mutex_lock(&dpdk_eth_mutex); + ovs_list_push_back(&dpdk_eth_list, &dev->list_node); netdev_request_reconfigure(netdev); - ovs_mutex_unlock(&dpdk_mutex); + ovs_mutex_unlock(&dpdk_eth_mutex); return 0; } @@ -1085,7 +1089,7 @@ netdev_dpdk_eth_destruct(struct netdev *netdev) struct netdev_dpdk_common *common = netdev_dpdk_common_cast(netdev); struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); - ovs_mutex_lock(&dpdk_mutex); + ovs_mutex_lock(&dpdk_eth_mutex); ovs_list_remove(&dev->list_node); /* Destroy any rx-steering flows to allow RXQs to be removed. */ @@ -1110,10 +1114,7 @@ netdev_dpdk_eth_destruct(struct netdev *netdev) if (sibling_port_id == dev->port_id) { continue; } - LIST_FOR_EACH (sibling, list_node, &dpdk_list) { - if (!is_eth_class(sibling->up.netdev_class)) { - continue; - } + LIST_FOR_EACH (sibling, list_node, &dpdk_eth_list) { if (sibling->port_id != sibling_port_id) { continue; } @@ -1152,7 +1153,7 @@ netdev_dpdk_eth_destruct(struct netdev *netdev) VLOG_INFO("Device '%s' has been removed", dev->devargs); } } - ovs_mutex_unlock(&dpdk_mutex); + ovs_mutex_unlock(&dpdk_eth_mutex); netdev_dpdk_clear_xstats(dev); free(dev->devargs); @@ -1180,12 +1181,12 @@ vhost_common_destruct(struct netdev_dpdk *dev) } /* rte_vhost_driver_unregister() can call back destroy_device(), which will - * try to acquire 'dpdk_mutex' and possibly 'dev->mutex'. To avoid a + * try to acquire 'dpdk_vhost_mutex' and possibly 'dev->mutex'. To avoid a * deadlock, none of the mutexes must be held while calling this function. */ static int dpdk_vhost_driver_unregister(struct netdev_dpdk *dev OVS_UNUSED, char *vhost_id) - OVS_EXCLUDED(dpdk_mutex) + OVS_EXCLUDED(dpdk_vhost_mutex) OVS_EXCLUDED(dev->mutex) { return rte_vhost_driver_unregister(vhost_id); @@ -1198,7 +1199,7 @@ netdev_dpdk_vhost_destruct(struct netdev *netdev) bool is_client_mode; char *vhost_id; - ovs_mutex_lock(&dpdk_mutex); + ovs_mutex_lock(&dpdk_vhost_mutex); /* Guest becomes an orphan if still attached. */ if (netdev_dpdk_get_vid(dev) >= 0 @@ -1210,7 +1211,7 @@ netdev_dpdk_vhost_destruct(struct netdev *netdev) } ovs_list_remove(&dev->list_node); - ovs_mutex_unlock(&dpdk_mutex); + ovs_mutex_unlock(&dpdk_vhost_mutex); vhost_id = dev->vhost_id; is_client_mode = dev->vhost_driver_flags & RTE_VHOST_USER_CLIENT; @@ -1388,14 +1389,11 @@ netdev_dpdk_eth_get_config(const struct netdev *netdev, struct smap *args) static struct netdev_dpdk * netdev_dpdk_lookup_by_port_id(dpdk_port_t port_id) - OVS_REQUIRES(dpdk_mutex) + OVS_REQUIRES(dpdk_eth_mutex) { struct netdev_dpdk *dev; - LIST_FOR_EACH (dev, list_node, &dpdk_list) { - if (!is_eth_class(dev->up.netdev_class)) { - continue; - } + LIST_FOR_EACH (dev, list_node, &dpdk_eth_list) { if (dev->port_id == port_id) { return dev; } @@ -1433,7 +1431,7 @@ netdev_dpdk_get_port_by_mac(const char *mac_str, char const **extra_err) /* Return the first DPDK port id matching the devargs pattern. */ static dpdk_port_t netdev_dpdk_get_port_by_devargs(const char *devargs) - OVS_REQUIRES(dpdk_mutex) + OVS_REQUIRES(dpdk_eth_mutex) { dpdk_port_t port_id; struct rte_dev_iterator iterator; @@ -1461,7 +1459,7 @@ static dpdk_port_t netdev_dpdk_get_port_by_devargs(const char *devargs) static dpdk_port_t netdev_dpdk_process_devargs(struct netdev_dpdk *dev, const char *devargs, char **errp) - OVS_REQUIRES(dpdk_mutex) + OVS_REQUIRES(dpdk_eth_mutex) { dpdk_port_t new_port_id; char const *extra_err = NULL; @@ -1537,7 +1535,7 @@ netdev_dpdk_eth_run(const struct netdev_class *netdev_class OVS_UNUSED) continue; } - ovs_mutex_lock(&dpdk_mutex); + ovs_mutex_lock(&dpdk_eth_mutex); dev = netdev_dpdk_lookup_by_port_id(port_id); if (dev) { struct netdev *netdev = &dev->up; @@ -1548,7 +1546,7 @@ netdev_dpdk_eth_run(const struct netdev_class *netdev_class OVS_UNUSED) netdev_get_name(netdev)); ovs_mutex_unlock(&dev->mutex); } - ovs_mutex_unlock(&dpdk_mutex); + ovs_mutex_unlock(&dpdk_eth_mutex); } } } @@ -1680,7 +1678,7 @@ netdev_dpdk_eth_set_config(struct netdev *netdev, const struct smap *args, const char *vf_mac; int err = 0; - ovs_mutex_lock(&dpdk_mutex); + ovs_mutex_lock(&dpdk_eth_mutex); ovs_mutex_lock(&dev->mutex); dpdk_set_rx_steer_config(netdev, dev, args); @@ -1828,7 +1826,7 @@ netdev_dpdk_eth_set_config(struct netdev *netdev, const struct smap *args, out: ovs_mutex_unlock(&dev->mutex); - ovs_mutex_unlock(&dpdk_mutex); + ovs_mutex_unlock(&dpdk_eth_mutex); return err; } @@ -3424,7 +3422,7 @@ netdev_dpdk_eth_get_status(const struct netdev *netdev, struct smap *args) return ENODEV; } - ovs_mutex_lock(&dpdk_mutex); + ovs_mutex_lock(&dpdk_eth_mutex); ovs_mutex_lock(&dev->mutex); diag = rte_eth_dev_info_get(dev->port_id, &dev_info); link_speed = dev->link.link_speed; @@ -3432,7 +3430,7 @@ netdev_dpdk_eth_get_status(const struct netdev *netdev, struct smap *args) rx_steer_flows_num = dev->rx_steer_flows_num; n_rxq = netdev->n_rxq; ovs_mutex_unlock(&dev->mutex); - ovs_mutex_unlock(&dpdk_mutex); + ovs_mutex_unlock(&dpdk_eth_mutex); smap_add_format(args, "port_no", DPDK_PORT_ID_FMT, dev->port_id); smap_add_format(args, "numa_id", "%d", @@ -3570,19 +3568,24 @@ netdev_dpdk_set_admin_state(struct unixctl_conn *conn, int argc, return; } } else { + struct netdev_dpdk *vhost_dev; struct netdev_dpdk *dev; - ovs_mutex_lock(&dpdk_mutex); - LIST_FOR_EACH (dev, list_node, &dpdk_list) { + ovs_mutex_lock(&dpdk_eth_mutex); + LIST_FOR_EACH (dev, list_node, &dpdk_eth_list) { ovs_mutex_lock(&dev->mutex); - if (is_eth_class(dev->up.netdev_class)) { - netdev_dpdk_eth_set_admin_state__(dev, up); - } else { - netdev_dpdk_vhost_set_admin_state__(dev, up); - } + netdev_dpdk_eth_set_admin_state__(dev, up); ovs_mutex_unlock(&dev->mutex); } - ovs_mutex_unlock(&dpdk_mutex); + ovs_mutex_unlock(&dpdk_eth_mutex); + + ovs_mutex_lock(&dpdk_vhost_mutex); + LIST_FOR_EACH (vhost_dev, list_node, &dpdk_vhost_list) { + ovs_mutex_lock(&vhost_dev->mutex); + netdev_dpdk_vhost_set_admin_state__(vhost_dev, up); + ovs_mutex_unlock(&vhost_dev->mutex); + } + ovs_mutex_unlock(&dpdk_vhost_mutex); } unixctl_command_reply(conn, "OK"); } @@ -3599,7 +3602,7 @@ netdev_dpdk_detach(struct unixctl_conn *conn, int argc OVS_UNUSED, char *response; int diag; - ovs_mutex_lock(&dpdk_mutex); + ovs_mutex_lock(&dpdk_eth_mutex); port_id = netdev_dpdk_get_port_by_devargs(argv[1]); if (!rte_eth_dev_is_valid_port(port_id)) { @@ -3614,10 +3617,7 @@ netdev_dpdk_detach(struct unixctl_conn *conn, int argc OVS_UNUSED, RTE_ETH_FOREACH_DEV_SIBLING (sibling_port_id, port_id) { struct netdev_dpdk *dev; - LIST_FOR_EACH (dev, list_node, &dpdk_list) { - if (!is_eth_class(dev->up.netdev_class)) { - continue; - } + LIST_FOR_EACH (dev, list_node, &dpdk_eth_list) { if (dev->port_id != sibling_port_id) { continue; } @@ -3646,13 +3646,13 @@ netdev_dpdk_detach(struct unixctl_conn *conn, int argc OVS_UNUSED, response = xasprintf("All devices shared with device '%s' " "have been detached", argv[1]); - ovs_mutex_unlock(&dpdk_mutex); + ovs_mutex_unlock(&dpdk_eth_mutex); unixctl_command_reply(conn, response); free(response); return; error: - ovs_mutex_unlock(&dpdk_mutex); + ovs_mutex_unlock(&dpdk_eth_mutex); unixctl_command_reply_error(conn, response); free(response); } @@ -3788,15 +3788,12 @@ new_device(int vid) rte_vhost_get_ifname(vid, ifname, sizeof ifname); - ovs_mutex_lock(&dpdk_mutex); + ovs_mutex_lock(&dpdk_vhost_mutex); /* Add device to the vhost port with the same name as that passed down. */ - LIST_FOR_EACH(dev, list_node, &dpdk_list) { + LIST_FOR_EACH (dev, list_node, &dpdk_vhost_list) { struct netdev_dpdk_common *common = netdev_dpdk_common_cast(&dev->up); struct netdev *netdev = &common->up; - if (!is_vhost_class(netdev->netdev_class)) { - continue; - } ovs_mutex_lock(&dev->mutex); if (nullable_string_is_equal(ifname, dev->vhost_id)) { uint32_t qp_num = rte_vhost_get_vring_num(vid) / VIRTIO_QNUM; @@ -3870,7 +3867,7 @@ new_device(int vid) } ovs_mutex_unlock(&dev->mutex); } - ovs_mutex_unlock(&dpdk_mutex); + ovs_mutex_unlock(&dpdk_vhost_mutex); if (!exists) { VLOG_INFO("vHost Device '%s' can't be added - name not found", ifname); @@ -3912,14 +3909,11 @@ destroy_device(int vid) rte_vhost_get_ifname(vid, ifname, sizeof ifname); - ovs_mutex_lock(&dpdk_mutex); - LIST_FOR_EACH (dev, list_node, &dpdk_list) { + ovs_mutex_lock(&dpdk_vhost_mutex); + LIST_FOR_EACH (dev, list_node, &dpdk_vhost_list) { struct netdev_dpdk_common *common = netdev_dpdk_common_cast(&dev->up); struct netdev *netdev = &common->up; - if (!is_vhost_class(netdev->netdev_class)) { - continue; - } if (netdev_dpdk_get_vid(dev) == vid) { ovs_mutex_lock(&dev->mutex); @@ -3940,7 +3934,7 @@ destroy_device(int vid) } } - ovs_mutex_unlock(&dpdk_mutex); + ovs_mutex_unlock(&dpdk_vhost_mutex); if (exists) { /* @@ -3978,14 +3972,10 @@ vring_state_changed__(struct vhost_state_change *sc) int qid = sc->queue_id / VIRTIO_QNUM; bool is_rx = (sc->queue_id % VIRTIO_QNUM) == VIRTIO_TXQ; - ovs_mutex_lock(&dpdk_mutex); - LIST_FOR_EACH (dev, list_node, &dpdk_list) { + ovs_mutex_lock(&dpdk_vhost_mutex); + LIST_FOR_EACH (dev, list_node, &dpdk_vhost_list) { struct netdev_dpdk_common *common = netdev_dpdk_common_cast(&dev->up); - struct netdev *netdev = &common->up; - if (!is_vhost_class(netdev->netdev_class)) { - continue; - } ovs_mutex_lock(&dev->mutex); if (nullable_string_is_equal(sc->ifname, dev->vhost_id)) { if (is_rx) { @@ -3993,7 +3983,7 @@ vring_state_changed__(struct vhost_state_change *sc) dev->vhost_rxq_enabled[qid] = sc->enable != 0; if (old_state != dev->vhost_rxq_enabled[qid]) { - netdev_change_seq_changed(netdev); + netdev_change_seq_changed(&common->up); } } else { if (sc->enable) { @@ -4009,7 +3999,7 @@ vring_state_changed__(struct vhost_state_change *sc) } ovs_mutex_unlock(&dev->mutex); } - ovs_mutex_unlock(&dpdk_mutex); + ovs_mutex_unlock(&dpdk_vhost_mutex); if (exists) { VLOG_INFO("State of queue %d ( %s_qid %d ) of vhost device '%s' " @@ -4090,14 +4080,11 @@ destroy_connection(int vid) rte_vhost_get_ifname(vid, ifname, sizeof ifname); - ovs_mutex_lock(&dpdk_mutex); - LIST_FOR_EACH (dev, list_node, &dpdk_list) { + ovs_mutex_lock(&dpdk_vhost_mutex); + LIST_FOR_EACH (dev, list_node, &dpdk_vhost_list) { struct netdev_dpdk_common *common = netdev_dpdk_common_cast(&dev->up); struct netdev *netdev = &common->up; - if (!is_vhost_class(netdev->netdev_class)) { - continue; - } ovs_mutex_lock(&dev->mutex); if (nullable_string_is_equal(ifname, dev->vhost_id)) { uint32_t qp_num = NR_QUEUE; @@ -4159,7 +4146,7 @@ destroy_connection(int vid) } ovs_mutex_unlock(&dev->mutex); } - ovs_mutex_unlock(&dpdk_mutex); + ovs_mutex_unlock(&dpdk_vhost_mutex); if (exists) { VLOG_INFO("vHost Device '%s' connection has been destroyed", ifname); -- 2.56.0 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
