diff options
author | David S. Miller <davem@davemloft.net> | 2016-07-15 17:27:44 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-07-15 17:27:44 -0400 |
commit | dd79cf7dd10028d00f99d332d5a0d04734908282 (patch) | |
tree | 9fd2d30d1c5b5ffd7b2258678212fbd35d5bb3bc | |
parent | c961e877cff4b669788900a7e12386f67efbe2d3 (diff) | |
parent | 7f6c553902bfa1c4e3f6cfa955c5ea036c7fe8e4 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-queue
Jeff Kirsher says:
====================
Intel Wired LAN Driver Updates 2016-07-14
This series contains fixes to i40e and ixgbe.
Alex fixes issues found in i40e_rx_checksum() which was broken, where the
checksum was being returned valid when it was not.
Kiran fixes a bug which was found when we abruptly remove a cable which
caused a panic. Set the VSI broadcast promiscuous mode during VSI add
sequence and prevents adding MAC filter if specified MAC address is
broadcast.
Paolo Abeni fixes a bug by returning the actual work done, capped to
weight - 1, since the core doesn't allow to return the full budget when
the driver modifies the NAPI status.
Guilherme Piccoli fixes an issue where the q_vector initialization
routine sets the affinity _mask of a q_vector based on v_idx value.
This means a loop iterates on v_idx, which is an incremental value, and
the cpumask is created based on this value. This is a problem in
systems with multiple logical CPUs per core (like in SMT scenarios).
Changed the way q_vector's affinity_mask is created to resolve the issue.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/intel/i40e/i40e_main.c | 48 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/i40e/i40e_txrx.c | 30 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 30 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 2 |
4 files changed, 66 insertions, 44 deletions
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 5ea22008d721..501f15d9f4d6 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c | |||
@@ -1344,6 +1344,13 @@ struct i40e_mac_filter *i40e_add_filter(struct i40e_vsi *vsi, | |||
1344 | if (!vsi || !macaddr) | 1344 | if (!vsi || !macaddr) |
1345 | return NULL; | 1345 | return NULL; |
1346 | 1346 | ||
1347 | /* Do not allow broadcast filter to be added since broadcast filter | ||
1348 | * is added as part of add VSI for any newly created VSI except | ||
1349 | * FDIR VSI | ||
1350 | */ | ||
1351 | if (is_broadcast_ether_addr(macaddr)) | ||
1352 | return NULL; | ||
1353 | |||
1347 | f = i40e_find_filter(vsi, macaddr, vlan, is_vf, is_netdev); | 1354 | f = i40e_find_filter(vsi, macaddr, vlan, is_vf, is_netdev); |
1348 | if (!f) { | 1355 | if (!f) { |
1349 | f = kzalloc(sizeof(*f), GFP_ATOMIC); | 1356 | f = kzalloc(sizeof(*f), GFP_ATOMIC); |
@@ -2151,18 +2158,6 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi) | |||
2151 | aq_ret, pf->hw.aq.asq_last_status); | 2158 | aq_ret, pf->hw.aq.asq_last_status); |
2152 | } | 2159 | } |
2153 | } | 2160 | } |
2154 | aq_ret = i40e_aq_set_vsi_broadcast(&vsi->back->hw, | ||
2155 | vsi->seid, | ||
2156 | cur_promisc, NULL); | ||
2157 | if (aq_ret) { | ||
2158 | retval = i40e_aq_rc_to_posix(aq_ret, | ||
2159 | pf->hw.aq.asq_last_status); | ||
2160 | dev_info(&pf->pdev->dev, | ||
2161 | "set brdcast promisc failed, err %s, aq_err %s\n", | ||
2162 | i40e_stat_str(&pf->hw, aq_ret), | ||
2163 | i40e_aq_str(&pf->hw, | ||
2164 | pf->hw.aq.asq_last_status)); | ||
2165 | } | ||
2166 | } | 2161 | } |
2167 | out: | 2162 | out: |
2168 | /* if something went wrong then set the changed flag so we try again */ | 2163 | /* if something went wrong then set the changed flag so we try again */ |
@@ -7726,10 +7721,11 @@ static int i40e_init_msix(struct i40e_pf *pf) | |||
7726 | * i40e_vsi_alloc_q_vector - Allocate memory for a single interrupt vector | 7721 | * i40e_vsi_alloc_q_vector - Allocate memory for a single interrupt vector |
7727 | * @vsi: the VSI being configured | 7722 | * @vsi: the VSI being configured |
7728 | * @v_idx: index of the vector in the vsi struct | 7723 | * @v_idx: index of the vector in the vsi struct |
7724 | * @cpu: cpu to be used on affinity_mask | ||
7729 | * | 7725 | * |
7730 | * We allocate one q_vector. If allocation fails we return -ENOMEM. | 7726 | * We allocate one q_vector. If allocation fails we return -ENOMEM. |
7731 | **/ | 7727 | **/ |
7732 | static int i40e_vsi_alloc_q_vector(struct i40e_vsi *vsi, int v_idx) | 7728 | static int i40e_vsi_alloc_q_vector(struct i40e_vsi *vsi, int v_idx, int cpu) |
7733 | { | 7729 | { |
7734 | struct i40e_q_vector *q_vector; | 7730 | struct i40e_q_vector *q_vector; |
7735 | 7731 | ||
@@ -7740,7 +7736,8 @@ static int i40e_vsi_alloc_q_vector(struct i40e_vsi *vsi, int v_idx) | |||
7740 | 7736 | ||
7741 | q_vector->vsi = vsi; | 7737 | q_vector->vsi = vsi; |
7742 | q_vector->v_idx = v_idx; | 7738 | q_vector->v_idx = v_idx; |
7743 | cpumask_set_cpu(v_idx, &q_vector->affinity_mask); | 7739 | cpumask_set_cpu(cpu, &q_vector->affinity_mask); |
7740 | |||
7744 | if (vsi->netdev) | 7741 | if (vsi->netdev) |
7745 | netif_napi_add(vsi->netdev, &q_vector->napi, | 7742 | netif_napi_add(vsi->netdev, &q_vector->napi, |
7746 | i40e_napi_poll, NAPI_POLL_WEIGHT); | 7743 | i40e_napi_poll, NAPI_POLL_WEIGHT); |
@@ -7764,8 +7761,7 @@ static int i40e_vsi_alloc_q_vector(struct i40e_vsi *vsi, int v_idx) | |||
7764 | static int i40e_vsi_alloc_q_vectors(struct i40e_vsi *vsi) | 7761 | static int i40e_vsi_alloc_q_vectors(struct i40e_vsi *vsi) |
7765 | { | 7762 | { |
7766 | struct i40e_pf *pf = vsi->back; | 7763 | struct i40e_pf *pf = vsi->back; |
7767 | int v_idx, num_q_vectors; | 7764 | int err, v_idx, num_q_vectors, current_cpu; |
7768 | int err; | ||
7769 | 7765 | ||
7770 | /* if not MSIX, give the one vector only to the LAN VSI */ | 7766 | /* if not MSIX, give the one vector only to the LAN VSI */ |
7771 | if (pf->flags & I40E_FLAG_MSIX_ENABLED) | 7767 | if (pf->flags & I40E_FLAG_MSIX_ENABLED) |
@@ -7775,10 +7771,15 @@ static int i40e_vsi_alloc_q_vectors(struct i40e_vsi *vsi) | |||
7775 | else | 7771 | else |
7776 | return -EINVAL; | 7772 | return -EINVAL; |
7777 | 7773 | ||
7774 | current_cpu = cpumask_first(cpu_online_mask); | ||
7775 | |||
7778 | for (v_idx = 0; v_idx < num_q_vectors; v_idx++) { | 7776 | for (v_idx = 0; v_idx < num_q_vectors; v_idx++) { |
7779 | err = i40e_vsi_alloc_q_vector(vsi, v_idx); | 7777 | err = i40e_vsi_alloc_q_vector(vsi, v_idx, current_cpu); |
7780 | if (err) | 7778 | if (err) |
7781 | goto err_out; | 7779 | goto err_out; |
7780 | current_cpu = cpumask_next(current_cpu, cpu_online_mask); | ||
7781 | if (unlikely(current_cpu >= nr_cpu_ids)) | ||
7782 | current_cpu = cpumask_first(cpu_online_mask); | ||
7782 | } | 7783 | } |
7783 | 7784 | ||
7784 | return 0; | 7785 | return 0; |
@@ -9224,6 +9225,7 @@ int i40e_is_vsi_uplink_mode_veb(struct i40e_vsi *vsi) | |||
9224 | static int i40e_add_vsi(struct i40e_vsi *vsi) | 9225 | static int i40e_add_vsi(struct i40e_vsi *vsi) |
9225 | { | 9226 | { |
9226 | int ret = -ENODEV; | 9227 | int ret = -ENODEV; |
9228 | i40e_status aq_ret = 0; | ||
9227 | u8 laa_macaddr[ETH_ALEN]; | 9229 | u8 laa_macaddr[ETH_ALEN]; |
9228 | bool found_laa_mac_filter = false; | 9230 | bool found_laa_mac_filter = false; |
9229 | struct i40e_pf *pf = vsi->back; | 9231 | struct i40e_pf *pf = vsi->back; |
@@ -9413,6 +9415,18 @@ static int i40e_add_vsi(struct i40e_vsi *vsi) | |||
9413 | vsi->seid = ctxt.seid; | 9415 | vsi->seid = ctxt.seid; |
9414 | vsi->id = ctxt.vsi_number; | 9416 | vsi->id = ctxt.vsi_number; |
9415 | } | 9417 | } |
9418 | /* Except FDIR VSI, for all othet VSI set the broadcast filter */ | ||
9419 | if (vsi->type != I40E_VSI_FDIR) { | ||
9420 | aq_ret = i40e_aq_set_vsi_broadcast(hw, vsi->seid, true, NULL); | ||
9421 | if (aq_ret) { | ||
9422 | ret = i40e_aq_rc_to_posix(aq_ret, | ||
9423 | hw->aq.asq_last_status); | ||
9424 | dev_info(&pf->pdev->dev, | ||
9425 | "set brdcast promisc failed, err %s, aq_err %s\n", | ||
9426 | i40e_stat_str(hw, aq_ret), | ||
9427 | i40e_aq_str(hw, hw->aq.asq_last_status)); | ||
9428 | } | ||
9429 | } | ||
9416 | 9430 | ||
9417 | spin_lock_bh(&vsi->mac_filter_list_lock); | 9431 | spin_lock_bh(&vsi->mac_filter_list_lock); |
9418 | /* If macvlan filters already exist, force them to get loaded */ | 9432 | /* If macvlan filters already exist, force them to get loaded */ |
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index 55f151fca1dc..a8868e1bf832 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c | |||
@@ -1280,8 +1280,8 @@ static inline void i40e_rx_checksum(struct i40e_vsi *vsi, | |||
1280 | union i40e_rx_desc *rx_desc) | 1280 | union i40e_rx_desc *rx_desc) |
1281 | { | 1281 | { |
1282 | struct i40e_rx_ptype_decoded decoded; | 1282 | struct i40e_rx_ptype_decoded decoded; |
1283 | bool ipv4, ipv6, tunnel = false; | ||
1284 | u32 rx_error, rx_status; | 1283 | u32 rx_error, rx_status; |
1284 | bool ipv4, ipv6; | ||
1285 | u8 ptype; | 1285 | u8 ptype; |
1286 | u64 qword; | 1286 | u64 qword; |
1287 | 1287 | ||
@@ -1336,19 +1336,23 @@ static inline void i40e_rx_checksum(struct i40e_vsi *vsi, | |||
1336 | if (rx_error & BIT(I40E_RX_DESC_ERROR_PPRS_SHIFT)) | 1336 | if (rx_error & BIT(I40E_RX_DESC_ERROR_PPRS_SHIFT)) |
1337 | return; | 1337 | return; |
1338 | 1338 | ||
1339 | /* The hardware supported by this driver does not validate outer | 1339 | /* If there is an outer header present that might contain a checksum |
1340 | * checksums for tunneled VXLAN or GENEVE frames. I don't agree | 1340 | * we need to bump the checksum level by 1 to reflect the fact that |
1341 | * with it but the specification states that you "MAY validate", it | 1341 | * we are indicating we validated the inner checksum. |
1342 | * doesn't make it a hard requirement so if we have validated the | ||
1343 | * inner checksum report CHECKSUM_UNNECESSARY. | ||
1344 | */ | 1342 | */ |
1345 | if (decoded.inner_prot & (I40E_RX_PTYPE_INNER_PROT_TCP | | 1343 | if (decoded.tunnel_type >= I40E_RX_PTYPE_TUNNEL_IP_GRENAT) |
1346 | I40E_RX_PTYPE_INNER_PROT_UDP | | 1344 | skb->csum_level = 1; |
1347 | I40E_RX_PTYPE_INNER_PROT_SCTP)) | 1345 | |
1348 | tunnel = true; | 1346 | /* Only report checksum unnecessary for TCP, UDP, or SCTP */ |
1349 | 1347 | switch (decoded.inner_prot) { | |
1350 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 1348 | case I40E_RX_PTYPE_INNER_PROT_TCP: |
1351 | skb->csum_level = tunnel ? 1 : 0; | 1349 | case I40E_RX_PTYPE_INNER_PROT_UDP: |
1350 | case I40E_RX_PTYPE_INNER_PROT_SCTP: | ||
1351 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
1352 | /* fall though */ | ||
1353 | default: | ||
1354 | break; | ||
1355 | } | ||
1352 | 1356 | ||
1353 | return; | 1357 | return; |
1354 | 1358 | ||
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c index be99189da925..79d99cd91b24 100644 --- a/drivers/net/ethernet/intel/i40evf/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40evf/i40e_txrx.c | |||
@@ -752,8 +752,8 @@ static inline void i40e_rx_checksum(struct i40e_vsi *vsi, | |||
752 | union i40e_rx_desc *rx_desc) | 752 | union i40e_rx_desc *rx_desc) |
753 | { | 753 | { |
754 | struct i40e_rx_ptype_decoded decoded; | 754 | struct i40e_rx_ptype_decoded decoded; |
755 | bool ipv4, ipv6, tunnel = false; | ||
756 | u32 rx_error, rx_status; | 755 | u32 rx_error, rx_status; |
756 | bool ipv4, ipv6; | ||
757 | u8 ptype; | 757 | u8 ptype; |
758 | u64 qword; | 758 | u64 qword; |
759 | 759 | ||
@@ -808,19 +808,23 @@ static inline void i40e_rx_checksum(struct i40e_vsi *vsi, | |||
808 | if (rx_error & BIT(I40E_RX_DESC_ERROR_PPRS_SHIFT)) | 808 | if (rx_error & BIT(I40E_RX_DESC_ERROR_PPRS_SHIFT)) |
809 | return; | 809 | return; |
810 | 810 | ||
811 | /* The hardware supported by this driver does not validate outer | 811 | /* If there is an outer header present that might contain a checksum |
812 | * checksums for tunneled VXLAN or GENEVE frames. I don't agree | 812 | * we need to bump the checksum level by 1 to reflect the fact that |
813 | * with it but the specification states that you "MAY validate", it | 813 | * we are indicating we validated the inner checksum. |
814 | * doesn't make it a hard requirement so if we have validated the | ||
815 | * inner checksum report CHECKSUM_UNNECESSARY. | ||
816 | */ | 814 | */ |
817 | if (decoded.inner_prot & (I40E_RX_PTYPE_INNER_PROT_TCP | | 815 | if (decoded.tunnel_type >= I40E_RX_PTYPE_TUNNEL_IP_GRENAT) |
818 | I40E_RX_PTYPE_INNER_PROT_UDP | | 816 | skb->csum_level = 1; |
819 | I40E_RX_PTYPE_INNER_PROT_SCTP)) | 817 | |
820 | tunnel = true; | 818 | /* Only report checksum unnecessary for TCP, UDP, or SCTP */ |
821 | 819 | switch (decoded.inner_prot) { | |
822 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 820 | case I40E_RX_PTYPE_INNER_PROT_TCP: |
823 | skb->csum_level = tunnel ? 1 : 0; | 821 | case I40E_RX_PTYPE_INNER_PROT_UDP: |
822 | case I40E_RX_PTYPE_INNER_PROT_SCTP: | ||
823 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
824 | /* fall though */ | ||
825 | default: | ||
826 | break; | ||
827 | } | ||
824 | 828 | ||
825 | return; | 829 | return; |
826 | 830 | ||
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 088c47cf27d9..8bebd862a54c 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | |||
@@ -2887,7 +2887,7 @@ int ixgbe_poll(struct napi_struct *napi, int budget) | |||
2887 | if (!test_bit(__IXGBE_DOWN, &adapter->state)) | 2887 | if (!test_bit(__IXGBE_DOWN, &adapter->state)) |
2888 | ixgbe_irq_enable_queues(adapter, BIT_ULL(q_vector->v_idx)); | 2888 | ixgbe_irq_enable_queues(adapter, BIT_ULL(q_vector->v_idx)); |
2889 | 2889 | ||
2890 | return 0; | 2890 | return min(work_done, budget - 1); |
2891 | } | 2891 | } |
2892 | 2892 | ||
2893 | /** | 2893 | /** |