diff mbox series

[SRU,EOAN,1/1] UBUNTU: SAUCE: i40e Fix GPF when deleting VMs

Message ID 20191115035403.20173-2-gerald.yang@canonical.com
State New
Headers show
Series Fix for LP:#1852663 | expand

Commit Message

Gerald Yang Nov. 15, 2019, 3:54 a.m. UTC
BugLink: https://bugs.launchpad.net/bugs/1852663

Fix a general protection in i40e_config_vf_promiscuous_mode

When deleting VMs with VFs created by i40e, a general protection
fault occurs in i40e_config_vf_promiscuous_mode due to race
condition for vsi->mac_filter_hash
And it also happens when deleteing pod with VFs

This issue was reported in e1000-devel mailling list
https://sourceforge.net/p/e1000/mailman/message/36766306/

Suggested-by: Billy McFall <bmcfall@redhat.com>
Signed-off-by: Gerald Yang <gerald.yang@canonical.com>
---
 drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

Comments

Sultan Alsawaf Nov. 20, 2019, 5:44 p.m. UTC | #1
Acked-by: Sultan Alsawaf <sultan.alsawaf@canonical.com>

On Thu, Nov 14, 2019, 7:54 PM Gerald Yang <gerald.yang@canonical.com> wrote:

> BugLink: https://bugs.launchpad.net/bugs/1852663
>
> Fix a general protection in i40e_config_vf_promiscuous_mode
>
> When deleting VMs with VFs created by i40e, a general protection
> fault occurs in i40e_config_vf_promiscuous_mode due to race
> condition for vsi->mac_filter_hash
> And it also happens when deleteing pod with VFs
>
> This issue was reported in e1000-devel mailling list
> https://sourceforge.net/p/e1000/mailman/message/36766306/
>
> Suggested-by: Billy McFall <bmcfall@redhat.com>
> Signed-off-by: Gerald Yang <gerald.yang@canonical.com>
> ---
>  drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
> b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
> index 02b09a8ad54c..6f78db626031 100644
> --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
> +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
> @@ -1121,6 +1121,7 @@ static i40e_status
> i40e_config_vf_promiscuous_mode(struct i40e_vf *vf,
>         struct i40e_pf *pf = vf->pf;
>         struct i40e_hw *hw = &pf->hw;
>         struct i40e_mac_filter *f;
> +       struct hlist_node *h;
>         i40e_status aq_ret = 0;
>         struct i40e_vsi *vsi;
>         int bkt;
> @@ -1160,7 +1161,8 @@ static i40e_status
> i40e_config_vf_promiscuous_mode(struct i40e_vf *vf,
>                 }
>                 return aq_ret;
>         } else if (i40e_getnum_vf_vsi_vlan_filters(vsi)) {
> -               hash_for_each(vsi->mac_filter_hash, bkt, f, hlist) {
> +               spin_lock_bh(&vsi->mac_filter_hash_lock);
> +               hash_for_each_safe(vsi->mac_filter_hash, bkt, h, f, hlist)
> {
>                         if (f->vlan < 0 || f->vlan > I40E_MAX_VLANID)
>                                 continue;
>                         aq_ret = i40e_aq_set_vsi_mc_promisc_on_vlan(hw,
> @@ -1193,6 +1195,7 @@ static i40e_status
> i40e_config_vf_promiscuous_mode(struct i40e_vf *vf,
>                                         i40e_aq_str(&pf->hw, aq_err));
>                         }
>                 }
> +               spin_unlock_bh(&vsi->mac_filter_hash_lock);
>                 return aq_ret;
>         }
>         aq_ret = i40e_aq_set_vsi_multicast_promiscuous(hw, vsi->seid,
> allmulti,
> --
> 2.17.1
>
>
> --
> kernel-team mailing list
> kernel-team@lists.ubuntu.com
> https://lists.ubuntu.com/mailman/listinfo/kernel-team
>
Connor Kuehl Nov. 20, 2019, 6:41 p.m. UTC | #2
On 11/14/19 7:54 PM, Gerald Yang wrote:
> BugLink: https://bugs.launchpad.net/bugs/1852663
> 
> Fix a general protection in i40e_config_vf_promiscuous_mode
> 
> When deleting VMs with VFs created by i40e, a general protection
> fault occurs in i40e_config_vf_promiscuous_mode due to race
> condition for vsi->mac_filter_hash
> And it also happens when deleteing pod with VFs
> 
> This issue was reported in e1000-devel mailling list
> https://sourceforge.net/p/e1000/mailman/message/36766306/
> 
> Suggested-by: Billy McFall <bmcfall@redhat.com>
> Signed-off-by: Gerald Yang <gerald.yang@canonical.com>

This seems reasonable to me, it looks like the lock is well-managed. It 
doesn't look like there's been much discussion in the mailing list it 
was submitted to regarding acceptance, so it would be good to keep an 
eye on that.

Acked-by: Connor Kuehl <connor.kuehl@canonical.com>

> ---
>   drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 5 ++++-
>   1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
> index 02b09a8ad54c..6f78db626031 100644
> --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
> +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
> @@ -1121,6 +1121,7 @@ static i40e_status i40e_config_vf_promiscuous_mode(struct i40e_vf *vf,
>   	struct i40e_pf *pf = vf->pf;
>   	struct i40e_hw *hw = &pf->hw;
>   	struct i40e_mac_filter *f;
> +	struct hlist_node *h;
>   	i40e_status aq_ret = 0;
>   	struct i40e_vsi *vsi;
>   	int bkt;
> @@ -1160,7 +1161,8 @@ static i40e_status i40e_config_vf_promiscuous_mode(struct i40e_vf *vf,
>   		}
>   		return aq_ret;
>   	} else if (i40e_getnum_vf_vsi_vlan_filters(vsi)) {
> -		hash_for_each(vsi->mac_filter_hash, bkt, f, hlist) {
> +		spin_lock_bh(&vsi->mac_filter_hash_lock);
> +		hash_for_each_safe(vsi->mac_filter_hash, bkt, h, f, hlist) {
>   			if (f->vlan < 0 || f->vlan > I40E_MAX_VLANID)
>   				continue;
>   			aq_ret = i40e_aq_set_vsi_mc_promisc_on_vlan(hw,
> @@ -1193,6 +1195,7 @@ static i40e_status i40e_config_vf_promiscuous_mode(struct i40e_vf *vf,
>   					i40e_aq_str(&pf->hw, aq_err));
>   			}
>   		}
> +		spin_unlock_bh(&vsi->mac_filter_hash_lock);
>   		return aq_ret;
>   	}
>   	aq_ret = i40e_aq_set_vsi_multicast_promiscuous(hw, vsi->seid, allmulti,
>
diff mbox series

Patch

diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
index 02b09a8ad54c..6f78db626031 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
@@ -1121,6 +1121,7 @@  static i40e_status i40e_config_vf_promiscuous_mode(struct i40e_vf *vf,
 	struct i40e_pf *pf = vf->pf;
 	struct i40e_hw *hw = &pf->hw;
 	struct i40e_mac_filter *f;
+	struct hlist_node *h;
 	i40e_status aq_ret = 0;
 	struct i40e_vsi *vsi;
 	int bkt;
@@ -1160,7 +1161,8 @@  static i40e_status i40e_config_vf_promiscuous_mode(struct i40e_vf *vf,
 		}
 		return aq_ret;
 	} else if (i40e_getnum_vf_vsi_vlan_filters(vsi)) {
-		hash_for_each(vsi->mac_filter_hash, bkt, f, hlist) {
+		spin_lock_bh(&vsi->mac_filter_hash_lock);
+		hash_for_each_safe(vsi->mac_filter_hash, bkt, h, f, hlist) {
 			if (f->vlan < 0 || f->vlan > I40E_MAX_VLANID)
 				continue;
 			aq_ret = i40e_aq_set_vsi_mc_promisc_on_vlan(hw,
@@ -1193,6 +1195,7 @@  static i40e_status i40e_config_vf_promiscuous_mode(struct i40e_vf *vf,
 					i40e_aq_str(&pf->hw, aq_err));
 			}
 		}
+		spin_unlock_bh(&vsi->mac_filter_hash_lock);
 		return aq_ret;
 	}
 	aq_ret = i40e_aq_set_vsi_multicast_promiscuous(hw, vsi->seid, allmulti,