2
0
mirror of https://github.com/openvswitch/ovs synced 2025-09-01 06:45:17 +00:00

netdev-dpdk: Introduce dpdk_mp_mutex.

'dpdk_mutex' protects two independent things: list of dpdk devices
and list of memory pools. Let's spit it in two to avoid global blocking
inside 'netdev_dpdk.*_reconfigure()' as possible.

Signed-off-by: Ilya Maximets <i.maximets@samsung.com>
Signed-off-by: Daniele Di Proietto <diproiettod@vmware.com>
This commit is contained in:
Ilya Maximets
2016-09-23 16:17:58 +03:00
committed by Daniele Di Proietto
parent c90daaca31
commit c2adb102e2

View File

@@ -177,8 +177,6 @@ enum dpdk_dev_type {
static int rte_eal_init_ret = ENODEV; static int rte_eal_init_ret = ENODEV;
static struct ovs_mutex dpdk_mutex = OVS_MUTEX_INITIALIZER;
/* Quality of Service */ /* Quality of Service */
/* An instance of a QoS configuration. Always associated with a particular /* An instance of a QoS configuration. Always associated with a particular
@@ -274,11 +272,16 @@ static const struct dpdk_qos_ops *const qos_confs[] = {
NULL NULL
}; };
static struct ovs_mutex dpdk_mutex = OVS_MUTEX_INITIALIZER;
/* Contains all 'struct dpdk_dev's. */ /* Contains all 'struct dpdk_dev's. */
static struct ovs_list dpdk_list OVS_GUARDED_BY(dpdk_mutex) static struct ovs_list dpdk_list OVS_GUARDED_BY(dpdk_mutex)
= OVS_LIST_INITIALIZER(&dpdk_list); = OVS_LIST_INITIALIZER(&dpdk_list);
static struct ovs_list dpdk_mp_list OVS_GUARDED_BY(dpdk_mutex) static struct ovs_mutex dpdk_mp_mutex OVS_ACQ_AFTER(dpdk_mutex)
= OVS_MUTEX_INITIALIZER;
static struct ovs_list dpdk_mp_list OVS_GUARDED_BY(dpdk_mp_mutex)
= OVS_LIST_INITIALIZER(&dpdk_mp_list); = OVS_LIST_INITIALIZER(&dpdk_mp_list);
/* This mutex must be used by non pmd threads when allocating or freeing /* This mutex must be used by non pmd threads when allocating or freeing
@@ -290,7 +293,7 @@ struct dpdk_mp {
int mtu; int mtu;
int socket_id; int socket_id;
int refcount; int refcount;
struct ovs_list list_node OVS_GUARDED_BY(dpdk_mutex); struct ovs_list list_node OVS_GUARDED_BY(dpdk_mp_mutex);
}; };
/* There should be one 'struct dpdk_tx_queue' created for /* There should be one 'struct dpdk_tx_queue' created for
@@ -463,17 +466,19 @@ ovs_rte_pktmbuf_init(struct rte_mempool *mp,
} }
static struct dpdk_mp * static struct dpdk_mp *
dpdk_mp_get(int socket_id, int mtu) OVS_REQUIRES(dpdk_mutex) dpdk_mp_get(int socket_id, int mtu)
{ {
struct dpdk_mp *dmp = NULL; struct dpdk_mp *dmp = NULL;
char mp_name[RTE_MEMPOOL_NAMESIZE]; char mp_name[RTE_MEMPOOL_NAMESIZE];
unsigned mp_size; unsigned mp_size;
struct rte_pktmbuf_pool_private mbp_priv; struct rte_pktmbuf_pool_private mbp_priv;
bool failed = false;
ovs_mutex_lock(&dpdk_mp_mutex);
LIST_FOR_EACH (dmp, list_node, &dpdk_mp_list) { LIST_FOR_EACH (dmp, list_node, &dpdk_mp_list) {
if (dmp->socket_id == socket_id && dmp->mtu == mtu) { if (dmp->socket_id == socket_id && dmp->mtu == mtu) {
dmp->refcount++; dmp->refcount++;
return dmp; goto out;
} }
} }
@@ -498,7 +503,8 @@ dpdk_mp_get(int socket_id, int mtu) OVS_REQUIRES(dpdk_mutex)
do { do {
if (snprintf(mp_name, RTE_MEMPOOL_NAMESIZE, "ovs_mp_%d_%d_%u", if (snprintf(mp_name, RTE_MEMPOOL_NAMESIZE, "ovs_mp_%d_%d_%u",
dmp->mtu, dmp->socket_id, mp_size) < 0) { dmp->mtu, dmp->socket_id, mp_size) < 0) {
goto fail; failed = true;
goto out;
} }
dmp->mp = rte_mempool_create(mp_name, mp_size, MBUF_SIZE(mtu), dmp->mp = rte_mempool_create(mp_name, mp_size, MBUF_SIZE(mtu),
@@ -510,26 +516,32 @@ dpdk_mp_get(int socket_id, int mtu) OVS_REQUIRES(dpdk_mutex)
} while (!dmp->mp && rte_errno == ENOMEM && (mp_size /= 2) >= MIN_NB_MBUF); } while (!dmp->mp && rte_errno == ENOMEM && (mp_size /= 2) >= MIN_NB_MBUF);
if (dmp->mp == NULL) { if (dmp->mp == NULL) {
goto fail; failed = true;
goto out;
} else { } else {
VLOG_DBG("Allocated \"%s\" mempool with %u mbufs", mp_name, mp_size ); VLOG_DBG("Allocated \"%s\" mempool with %u mbufs", mp_name, mp_size );
} }
ovs_list_push_back(&dpdk_mp_list, &dmp->list_node); ovs_list_push_back(&dpdk_mp_list, &dmp->list_node);
return dmp;
fail: out:
rte_free(dmp); ovs_mutex_unlock(&dpdk_mp_mutex);
return NULL;
if (failed) {
rte_free(dmp);
return NULL;
}
return dmp;
} }
static void static void
dpdk_mp_put(struct dpdk_mp *dmp) OVS_REQUIRES(dpdk_mutex) dpdk_mp_put(struct dpdk_mp *dmp)
{ {
if (!dmp) { if (!dmp) {
return; return;
} }
ovs_mutex_lock(&dpdk_mp_mutex);
ovs_assert(dmp->refcount); ovs_assert(dmp->refcount);
if (!--dmp->refcount) { if (!--dmp->refcount) {
@@ -537,6 +549,7 @@ dpdk_mp_put(struct dpdk_mp *dmp) OVS_REQUIRES(dpdk_mutex)
rte_mempool_free(dmp->mp); rte_mempool_free(dmp->mp);
rte_free(dmp); rte_free(dmp);
} }
ovs_mutex_unlock(&dpdk_mp_mutex);
} }
/* Tries to allocate new mempool on requested_socket_id with /* Tries to allocate new mempool on requested_socket_id with
@@ -545,7 +558,6 @@ dpdk_mp_put(struct dpdk_mp *dmp) OVS_REQUIRES(dpdk_mutex)
* On error, device will be left unchanged. */ * On error, device will be left unchanged. */
static int static int
netdev_dpdk_mempool_configure(struct netdev_dpdk *dev) netdev_dpdk_mempool_configure(struct netdev_dpdk *dev)
OVS_REQUIRES(dpdk_mutex)
OVS_REQUIRES(dev->mutex) OVS_REQUIRES(dev->mutex)
{ {
uint32_t buf_size = dpdk_buf_size(dev->requested_mtu); uint32_t buf_size = dpdk_buf_size(dev->requested_mtu);
@@ -696,7 +708,8 @@ dpdk_eth_flow_ctrl_setup(struct netdev_dpdk *dev) OVS_REQUIRES(dev->mutex)
} }
static int static int
dpdk_eth_dev_init(struct netdev_dpdk *dev) OVS_REQUIRES(dpdk_mutex) dpdk_eth_dev_init(struct netdev_dpdk *dev)
OVS_REQUIRES(dev->mutex)
{ {
struct rte_pktmbuf_pool_private *mbp_priv; struct rte_pktmbuf_pool_private *mbp_priv;
struct rte_eth_dev_info info; struct rte_eth_dev_info info;
@@ -2921,7 +2934,6 @@ netdev_dpdk_reconfigure(struct netdev *netdev)
struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
int err = 0; int err = 0;
ovs_mutex_lock(&dpdk_mutex);
ovs_mutex_lock(&dev->mutex); ovs_mutex_lock(&dev->mutex);
if (netdev->n_txq == dev->requested_n_txq if (netdev->n_txq == dev->requested_n_txq
@@ -2948,16 +2960,12 @@ netdev_dpdk_reconfigure(struct netdev *netdev)
netdev_change_seq_changed(netdev); netdev_change_seq_changed(netdev);
out: out:
ovs_mutex_unlock(&dev->mutex); ovs_mutex_unlock(&dev->mutex);
ovs_mutex_unlock(&dpdk_mutex);
return err; return err;
} }
static void static void
dpdk_vhost_reconfigure_helper(struct netdev_dpdk *dev) dpdk_vhost_reconfigure_helper(struct netdev_dpdk *dev)
OVS_REQUIRES(dpdk_mutex)
OVS_REQUIRES(dev->mutex) OVS_REQUIRES(dev->mutex)
{ {
dev->up.n_txq = dev->requested_n_txq; dev->up.n_txq = dev->requested_n_txq;
@@ -2987,14 +2995,9 @@ netdev_dpdk_vhost_reconfigure(struct netdev *netdev)
{ {
struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
ovs_mutex_lock(&dpdk_mutex);
ovs_mutex_lock(&dev->mutex); ovs_mutex_lock(&dev->mutex);
dpdk_vhost_reconfigure_helper(dev); dpdk_vhost_reconfigure_helper(dev);
ovs_mutex_unlock(&dev->mutex); ovs_mutex_unlock(&dev->mutex);
ovs_mutex_unlock(&dpdk_mutex);
return 0; return 0;
} }
@@ -3004,7 +3007,6 @@ netdev_dpdk_vhost_client_reconfigure(struct netdev *netdev)
struct netdev_dpdk *dev = netdev_dpdk_cast(netdev); struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
int err = 0; int err = 0;
ovs_mutex_lock(&dpdk_mutex);
ovs_mutex_lock(&dev->mutex); ovs_mutex_lock(&dev->mutex);
dpdk_vhost_reconfigure_helper(dev); dpdk_vhost_reconfigure_helper(dev);
@@ -3032,7 +3034,6 @@ netdev_dpdk_vhost_client_reconfigure(struct netdev *netdev)
} }
ovs_mutex_unlock(&dev->mutex); ovs_mutex_unlock(&dev->mutex);
ovs_mutex_unlock(&dpdk_mutex);
return 0; return 0;
} }