From patchwork Thu Apr 21 21:33:00 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Saeed Mahameed X-Patchwork-Id: 613315 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3qrX8f5S3pz9t4Z for ; Fri, 22 Apr 2016 07:34:58 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753301AbcDUVes (ORCPT ); Thu, 21 Apr 2016 17:34:48 -0400 Received: from [193.47.165.129] ([193.47.165.129]:60170 "EHLO mellanox.co.il" rhost-flags-FAIL-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1752215AbcDUVeD (ORCPT ); Thu, 21 Apr 2016 17:34:03 -0400 Received: from Internal Mail-Server by MTLPINE1 (envelope-from saeedm@mellanox.com) with ESMTPS (AES256-SHA encrypted); 22 Apr 2016 00:33:33 +0300 Received: from reg-l-vrt-045-010.mtl.labs.mlnx. (reg-l-vrt-045-010.mtl.labs.mlnx [10.135.45.10]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id u3LLXWat026877; Fri, 22 Apr 2016 00:33:33 +0300 From: Saeed Mahameed To: "David S. Miller" Cc: netdev@vger.kernel.org, Or Gerlitz , Tal Alon , Eran Ben Elisha , Maor Gottlieb , Saeed Mahameed Subject: [PATCH net V1 1/8] net/mlx5_core: Fix soft lockup in steering error flow Date: Fri, 22 Apr 2016 00:33:00 +0300 Message-Id: <1461274387-10653-2-git-send-email-saeedm@mellanox.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1461274387-10653-1-git-send-email-saeedm@mellanox.com> References: <1461274387-10653-1-git-send-email-saeedm@mellanox.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Maor Gottlieb In the error flow of adding flow rule to auto-grouped flow table, we call to tree_remove_node. tree_remove_node locks the node's parent, however the node's parent is already locked by mlx5_add_flow_rule and this causes a deadlock. After this patch, if we failed to add the flow rule, we unlock the flow table before calling to tree_remove_node. fixes: f0d22d187473 ('net/mlx5_core: Introduce flow steering autogrouped flow table') Signed-off-by: Maor Gottlieb Reported-by: Amir Vadai Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 46 ++++++++------------- 1 files changed, 17 insertions(+), 29 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c index 5121be4..3c7e3e5 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c @@ -1065,33 +1065,6 @@ unlock_fg: return rule; } -static struct mlx5_flow_rule *add_rule_to_auto_fg(struct mlx5_flow_table *ft, - u8 match_criteria_enable, - u32 *match_criteria, - u32 *match_value, - u8 action, - u32 flow_tag, - struct mlx5_flow_destination *dest) -{ - struct mlx5_flow_rule *rule; - struct mlx5_flow_group *g; - - g = create_autogroup(ft, match_criteria_enable, match_criteria); - if (IS_ERR(g)) - return (void *)g; - - rule = add_rule_fg(g, match_value, - action, flow_tag, dest); - if (IS_ERR(rule)) { - /* Remove assumes refcount > 0 and autogroup creates a group - * with a refcount = 0. - */ - tree_get_node(&g->node); - tree_remove_node(&g->node); - } - return rule; -} - static struct mlx5_flow_rule * _mlx5_add_flow_rule(struct mlx5_flow_table *ft, u8 match_criteria_enable, @@ -1119,8 +1092,23 @@ _mlx5_add_flow_rule(struct mlx5_flow_table *ft, goto unlock; } - rule = add_rule_to_auto_fg(ft, match_criteria_enable, match_criteria, - match_value, action, flow_tag, dest); + g = create_autogroup(ft, match_criteria_enable, match_criteria); + if (IS_ERR(g)) { + rule = (void *)g; + goto unlock; + } + + rule = add_rule_fg(g, match_value, + action, flow_tag, dest); + if (IS_ERR(rule)) { + /* Remove assumes refcount > 0 and autogroup creates a group + * with a refcount = 0. + */ + unlock_ref_node(&ft->node); + tree_get_node(&g->node); + tree_remove_node(&g->node); + return rule; + } unlock: unlock_ref_node(&ft->node); return rule;