[ovs-dev] [PATCH v2] lib/dpif-netdev: Remove recursive use of emc_mutex.
Jarno Rajahalme
jrajahalme at nicira.com
Tue Sep 9 15:20:58 UTC 2014
Here’s the updated description:
lib/dpif-netdev: Make emc_mutex recursive.
dpif_netdev_execute may be called while doing upcall processing.
Since the context of the input port is not tracked upto this point, we
use the shared dp->emc_cache for packet execution, where the emc_cache
is needed for recirculation.
While recursive mutexes can make thread safety analysis hard, for now
we change emc_mutex to be recursive. Forthcoming new unit tests will
fail with the current non-recursive mutex. Later improvements may
remove the need for this recursion.
Signed-off-by: Jarno Rajahalme <jrajahalme at nicira.com>
On Sep 8, 2014, at 4:06 PM, Jarno Rajahalme <jrajahalme at nicira.com> wrote:
> Forgot to update the description,
>
> Jarno
>
>> On Sep 8, 2014, at 3:37 PM, Jarno Rajahalme <jrajahalme at nicira.com> wrote:
>>
>> dpif_netdev_execute may be called while doing upcall processing.
>> Since the context of the input port is not tracked upto this point, we
>> used the chared dp->emc_cache for packet execution. Execution needs
>> to be able to pass the cache to recirculation code.
>>
>> Typically the pmd threads use their own emc_cache, so there is little
>> value in using the shared emc_cache while processing recirculation
>> during packet execution. Also, whenever the shared emc_cache was
>> already used while doing the upcall, the emc_mutex is already held,
>> and would be locked recursively in dpif_netdev_execute(). Rather than
>> changing the mutex to a recursive type, it seems more proper to not
>> use any emc_cache in dpif_netdev_execute.
>>
>> Forthcoming new unit tests will fail with the current lock recursion.
>>
>> Signed-off-by: Jarno Rajahalme <jrajahalme at nicira.com>
>> ---
>> lib/dpif-netdev.c | 32 ++++++++++----------------------
>> 1 file changed, 10 insertions(+), 22 deletions(-)
>>
>> diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
>> index 409c9bf..072ed5d 100644
>> --- a/lib/dpif-netdev.c
>> +++ b/lib/dpif-netdev.c
>> @@ -380,10 +380,9 @@ static void dp_netdev_execute_actions(struct dp_netdev *dp,
>> struct emc_cache *flow_cache,
>> const struct nlattr *actions,
>> size_t actions_len);
>> -static void dp_netdev_port_input(struct dp_netdev *dp,
>> - struct emc_cache *flow_cache,
>> - struct dpif_packet **packets, int cnt,
>> - odp_port_t port_no);
>> +static void dp_netdev_input(struct dp_netdev *, struct emc_cache *,
>> + struct dpif_packet **, int cnt,
>> + struct pkt_metadata *);
>>
>> static void dp_netdev_set_pmd_threads(struct dp_netdev *, int n);
>> static void dp_netdev_disable_upcall(struct dp_netdev *);
>> @@ -560,7 +559,7 @@ create_dp_netdev(const char *name, const struct dpif_class *class,
>> return error;
>> }
>>
>> - ovs_mutex_init(&dp->emc_mutex);
>> + ovs_mutex_init_recursive(&dp->emc_mutex);
>> emc_cache_init(&dp->flow_cache);
>>
>> *dpp = dp;
>> @@ -1799,14 +1798,15 @@ dp_netdev_process_rxq_port(struct dp_netdev *dp,
>>
>> error = netdev_rxq_recv(rxq, packets, &cnt);
>> if (!error) {
>> - dp_netdev_port_input(dp, flow_cache, packets, cnt, port->port_no);
>> + struct pkt_metadata md = PKT_METADATA_INITIALIZER(port->port_no);
>> +
>> + *recirc_depth_get() = 0;
>> + dp_netdev_input(dp, flow_cache, packets, cnt, &md);
>> } else if (error != EAGAIN && error != EOPNOTSUPP) {
>> - static struct vlog_rate_limit rl
>> - = VLOG_RATE_LIMIT_INIT(1, 5);
>> + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
>>
>> VLOG_ERR_RL(&rl, "error receiving data from %s: %s",
>> - netdev_get_name(port->netdev),
>> - ovs_strerror(error));
>> + netdev_get_name(port->netdev), ovs_strerror(error));
>> }
>> }
>>
>> @@ -2404,18 +2404,6 @@ dp_netdev_input(struct dp_netdev *dp, struct emc_cache *flow_cache,
>> }
>> }
>>
>> -
>> -static void
>> -dp_netdev_port_input(struct dp_netdev *dp, struct emc_cache *flow_cache,
>> - struct dpif_packet **packets, int cnt, odp_port_t port_no)
>> -{
>> - uint32_t *recirc_depth = recirc_depth_get();
>> - struct pkt_metadata md = PKT_METADATA_INITIALIZER(port_no);
>> -
>> - *recirc_depth = 0;
>> - dp_netdev_input(dp, flow_cache, packets, cnt, &md);
>> -}
>> -
>> struct dp_netdev_execute_aux {
>> struct dp_netdev *dp;
>> struct emc_cache *flow_cache;
>> --
>> 1.7.10.4
>>
More information about the dev
mailing list