Hi Suanming, PSB, Best, Ori
> -----Original Message----- > From: Suanming Mou <suanmi...@nvidia.com> > Subject: [PATCH v2 2/2] ethdev: make rte_flow API thread safe > > Currently, the rte_flow functions are not defined as thread safe. > DPDK applications either call the functions in single thread or add > locks around the functions for the critical section. > [Snip ...] > diff --git a/lib/librte_ethdev/rte_flow.c b/lib/librte_ethdev/rte_flow.c > index f8fdd68..2ac966d 100644 > --- a/lib/librte_ethdev/rte_flow.c > +++ b/lib/librte_ethdev/rte_flow.c > @@ -207,6 +207,20 @@ struct rte_flow_desc_data { > return -rte_errno; > } > > +static inline void > +flow_lock(struct rte_eth_dev *dev) Maybe change the name to flow_safe_enter Since this function doesn't always lock. > +{ > + if (!(dev->data->dev_flags & > RTE_ETH_DEV_FLOW_OPS_THREAD_SAFE)) > + pthread_mutex_lock(&dev->data->fts_mutex); > +} > + > +static inline void > +flow_unlock(struct rte_eth_dev *dev) Maybe change the name flow_safe_leave Same reason as above. > +{ > + if (!(dev->data->dev_flags & > RTE_ETH_DEV_FLOW_OPS_THREAD_SAFE)) > + pthread_mutex_unlock(&dev->data->fts_mutex); > +} > + > static int > flow_err(uint16_t port_id, int ret, struct rte_flow_error *error) > { > @@ -346,12 +360,16 @@ struct rte_flow_desc_data { > { > const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error); > struct rte_eth_dev *dev = &rte_eth_devices[port_id]; > + int ret; > > if (unlikely(!ops)) > return -rte_errno; > - if (likely(!!ops->validate)) > - return flow_err(port_id, ops->validate(dev, attr, pattern, > - actions, error), error); > + if (likely(!!ops->validate)) { > + flow_lock(dev); > + ret = ops->validate(dev, attr, pattern, actions, error); > + flow_unlock(dev); > + return flow_err(port_id, ret, error); > + } > return rte_flow_error_set(error, ENOSYS, > RTE_FLOW_ERROR_TYPE_UNSPECIFIED, > NULL, rte_strerror(ENOSYS)); > @@ -372,7 +390,9 @@ struct rte_flow * > if (unlikely(!ops)) > return NULL; > if (likely(!!ops->create)) { > + flow_lock(dev); > flow = ops->create(dev, attr, pattern, actions, error); > + flow_unlock(dev); > if (flow == NULL) > flow_err(port_id, -rte_errno, error); > return flow; > @@ -390,12 +410,16 @@ struct rte_flow * > { > struct rte_eth_dev *dev = &rte_eth_devices[port_id]; > const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error); > + int ret; > > if (unlikely(!ops)) > return -rte_errno; > - if (likely(!!ops->destroy)) > - return flow_err(port_id, ops->destroy(dev, flow, error), > - error); > + if (likely(!!ops->destroy)) { > + flow_lock(dev); > + ret = ops->destroy(dev, flow, error); > + flow_unlock(dev); > + return flow_err(port_id, ret, error); > + } > return rte_flow_error_set(error, ENOSYS, > RTE_FLOW_ERROR_TYPE_UNSPECIFIED, > NULL, rte_strerror(ENOSYS)); > @@ -408,11 +432,16 @@ struct rte_flow * > { > struct rte_eth_dev *dev = &rte_eth_devices[port_id]; > const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error); > + int ret; > > if (unlikely(!ops)) > return -rte_errno; > - if (likely(!!ops->flush)) > - return flow_err(port_id, ops->flush(dev, error), error); > + if (likely(!!ops->flush)) { > + flow_lock(dev); > + ret = ops->flush(dev, error); > + flow_unlock(dev); > + return flow_err(port_id, ret, error); > + } > return rte_flow_error_set(error, ENOSYS, > RTE_FLOW_ERROR_TYPE_UNSPECIFIED, > NULL, rte_strerror(ENOSYS)); > @@ -428,12 +457,16 @@ struct rte_flow * > { > struct rte_eth_dev *dev = &rte_eth_devices[port_id]; > const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error); > + int ret; > > if (!ops) > return -rte_errno; > - if (likely(!!ops->query)) > - return flow_err(port_id, ops->query(dev, flow, action, data, > - error), error); > + if (likely(!!ops->query)) { > + flow_lock(dev); > + ret = ops->query(dev, flow, action, data, error); > + flow_unlock(dev); > + return flow_err(port_id, ret, error); > + } > return rte_flow_error_set(error, ENOSYS, > RTE_FLOW_ERROR_TYPE_UNSPECIFIED, > NULL, rte_strerror(ENOSYS)); > @@ -447,11 +480,16 @@ struct rte_flow * > { > struct rte_eth_dev *dev = &rte_eth_devices[port_id]; > const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error); > + int ret; > > if (!ops) > return -rte_errno; > - if (likely(!!ops->isolate)) > - return flow_err(port_id, ops->isolate(dev, set, error), error); > + if (likely(!!ops->isolate)) { > + flow_lock(dev); > + ret = ops->isolate(dev, set, error); > + flow_unlock(dev); > + return flow_err(port_id, ret, error); > + } > return rte_flow_error_set(error, ENOSYS, > RTE_FLOW_ERROR_TYPE_UNSPECIFIED, > NULL, rte_strerror(ENOSYS)); > @@ -1224,12 +1262,16 @@ enum rte_flow_conv_item_spec_type { > { > struct rte_eth_dev *dev = &rte_eth_devices[port_id]; > const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error); > + int ret; > > if (unlikely(!ops)) > return -rte_errno; > - if (likely(!!ops->dev_dump)) > - return flow_err(port_id, ops->dev_dump(dev, file, error), > - error); > + if (likely(!!ops->dev_dump)) { > + flow_lock(dev); > + ret = ops->dev_dump(dev, file, error); > + flow_unlock(dev); > + return flow_err(port_id, ret, error); > + } > return rte_flow_error_set(error, ENOSYS, > RTE_FLOW_ERROR_TYPE_UNSPECIFIED, > NULL, rte_strerror(ENOSYS)); > @@ -1241,12 +1283,16 @@ enum rte_flow_conv_item_spec_type { > { > struct rte_eth_dev *dev = &rte_eth_devices[port_id]; > const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error); > + int ret; > > if (unlikely(!ops)) > return -rte_errno; > - if (likely(!!ops->get_aged_flows)) > - return flow_err(port_id, ops->get_aged_flows(dev, contexts, > - nb_contexts, error), error); > + if (likely(!!ops->get_aged_flows)) { > + flow_lock(dev); > + ret = ops->get_aged_flows(dev, contexts, nb_contexts, error); > + flow_unlock(dev); > + return flow_err(port_id, ret, error); > + } > return rte_flow_error_set(error, ENOTSUP, > RTE_FLOW_ERROR_TYPE_UNSPECIFIED, > NULL, rte_strerror(ENOTSUP)); > -- > 1.8.3.1