aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuilherme G. Piccoli <gpiccoli@linux.vnet.ibm.com>2016-06-27 11:16:43 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2016-07-15 02:39:12 -0400
commit7f6c553902bfa1c4e3f6cfa955c5ea036c7fe8e4 (patch)
treeb4bcb66ccdeb56bb2db13c7fca4a6f84d12aa67e
parent4b732cd4bb6006ad7fd4d5cdba27fcb751cdf4b7 (diff)
i40e: use valid online CPU on q_vector initialization
Currently, the q_vector initialization routine sets the affinity_mask of a q_vector based on v_idx value. Meaning 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). If we disable some logical CPUs, by turning SMT off for example, we will end up with a sparse cpu_online_mask, i.e., only the first CPU in a core is online, and incremental filling in q_vector cpumask might lead to multiple offline CPUs being assigned to q_vectors. Example: if we have a system with 8 cores each one containing 8 logical CPUs (SMT == 8 in this case), we have 64 CPUs in total. But if SMT is disabled, only the 1st CPU in each core remains online, so the cpu_online_mask in this case would have only 8 bits set, in a sparse way. In general case, when SMT is off the cpu_online_mask has only C bits set: 0, 1*N, 2*N, ..., C*(N-1) where C == # of cores; N == # of logical CPUs per core. In our example, only bits 0, 8, 16, 24, 32, 40, 48, 56 would be set. This patch changes the way q_vector's affinity_mask is created: it iterates on v_idx, but consumes the CPU index from the cpu_online_mask instead of just using the v_idx incremental value. No functional changes were introduced. Signed-off-by: Guilherme G Piccoli <gpiccoli@linux.vnet.ibm.com> Tested-by: Andrew Bowers <andrewx.bowers@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_main.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 1592dcbed790..501f15d9f4d6 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -7721,10 +7721,11 @@ static int i40e_init_msix(struct i40e_pf *pf)
7721 * 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
7722 * @vsi: the VSI being configured 7722 * @vsi: the VSI being configured
7723 * @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
7724 * 7725 *
7725 * We allocate one q_vector. If allocation fails we return -ENOMEM. 7726 * We allocate one q_vector. If allocation fails we return -ENOMEM.
7726 **/ 7727 **/
7727static int i40e_vsi_alloc_q_vector(struct i40e_vsi *vsi, int v_idx) 7728static int i40e_vsi_alloc_q_vector(struct i40e_vsi *vsi, int v_idx, int cpu)
7728{ 7729{
7729 struct i40e_q_vector *q_vector; 7730 struct i40e_q_vector *q_vector;
7730 7731
@@ -7735,7 +7736,8 @@ static int i40e_vsi_alloc_q_vector(struct i40e_vsi *vsi, int v_idx)
7735 7736
7736 q_vector->vsi = vsi; 7737 q_vector->vsi = vsi;
7737 q_vector->v_idx = v_idx; 7738 q_vector->v_idx = v_idx;
7738 cpumask_set_cpu(v_idx, &q_vector->affinity_mask); 7739 cpumask_set_cpu(cpu, &q_vector->affinity_mask);
7740
7739 if (vsi->netdev) 7741 if (vsi->netdev)
7740 netif_napi_add(vsi->netdev, &q_vector->napi, 7742 netif_napi_add(vsi->netdev, &q_vector->napi,
7741 i40e_napi_poll, NAPI_POLL_WEIGHT); 7743 i40e_napi_poll, NAPI_POLL_WEIGHT);
@@ -7759,8 +7761,7 @@ static int i40e_vsi_alloc_q_vector(struct i40e_vsi *vsi, int v_idx)
7759static int i40e_vsi_alloc_q_vectors(struct i40e_vsi *vsi) 7761static int i40e_vsi_alloc_q_vectors(struct i40e_vsi *vsi)
7760{ 7762{
7761 struct i40e_pf *pf = vsi->back; 7763 struct i40e_pf *pf = vsi->back;
7762 int v_idx, num_q_vectors; 7764 int err, v_idx, num_q_vectors, current_cpu;
7763 int err;
7764 7765
7765 /* 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 */
7766 if (pf->flags & I40E_FLAG_MSIX_ENABLED) 7767 if (pf->flags & I40E_FLAG_MSIX_ENABLED)
@@ -7770,10 +7771,15 @@ static int i40e_vsi_alloc_q_vectors(struct i40e_vsi *vsi)
7770 else 7771 else
7771 return -EINVAL; 7772 return -EINVAL;
7772 7773
7774 current_cpu = cpumask_first(cpu_online_mask);
7775
7773 for (v_idx = 0; v_idx < num_q_vectors; v_idx++) { 7776 for (v_idx = 0; v_idx < num_q_vectors; v_idx++) {
7774 err = i40e_vsi_alloc_q_vector(vsi, v_idx); 7777 err = i40e_vsi_alloc_q_vector(vsi, v_idx, current_cpu);
7775 if (err) 7778 if (err)
7776 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);
7777 } 7783 }
7778 7784
7779 return 0; 7785 return 0;