Commit 2f8fab7a authored by David S. Miller's avatar David S. Miller

Merge branch '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue

Jeff Kirsher says:

====================
40GbE Intel Wired LAN Driver Updates 2016-10-03

This series contains fixes to i40e only.

Stefan Assmann provides the changes in this series to resolve an issue
where when we run out of MSIx vectors, iWARP gets disabled automatically.
First adds a check for "no vectors left" during MSIx vector allocation
for VMDq, which will prevent more vectors being allocated than available.
Then fixed the MSIx vector redistribution when we reach the hardware limit
for vectors so that additional features like VMDq, iWARP, etc do not get
starved for vectors because the PF is hogging all the resources.  Lastly,
fix the issue for flow director by moving the check for the reaching the
vector limit earlier in the code so that a decision can be made on
disabling flow director.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents b462d22b abd97a94
...@@ -7641,7 +7641,6 @@ static int i40e_init_msix(struct i40e_pf *pf) ...@@ -7641,7 +7641,6 @@ static int i40e_init_msix(struct i40e_pf *pf)
vectors_left--; vectors_left--;
} else { } else {
pf->num_fdsb_msix = 0; pf->num_fdsb_msix = 0;
pf->flags &= ~I40E_FLAG_FD_SB_ENABLED;
} }
} }
...@@ -7661,6 +7660,8 @@ static int i40e_init_msix(struct i40e_pf *pf) ...@@ -7661,6 +7660,8 @@ static int i40e_init_msix(struct i40e_pf *pf)
#endif #endif
/* can we reserve enough for iWARP? */ /* can we reserve enough for iWARP? */
if (pf->flags & I40E_FLAG_IWARP_ENABLED) { if (pf->flags & I40E_FLAG_IWARP_ENABLED) {
iwarp_requested = pf->num_iwarp_msix;
if (!vectors_left) if (!vectors_left)
pf->num_iwarp_msix = 0; pf->num_iwarp_msix = 0;
else if (vectors_left < pf->num_iwarp_msix) else if (vectors_left < pf->num_iwarp_msix)
...@@ -7674,6 +7675,10 @@ static int i40e_init_msix(struct i40e_pf *pf) ...@@ -7674,6 +7675,10 @@ static int i40e_init_msix(struct i40e_pf *pf)
int vmdq_vecs_wanted = pf->num_vmdq_vsis * pf->num_vmdq_qps; int vmdq_vecs_wanted = pf->num_vmdq_vsis * pf->num_vmdq_qps;
int vmdq_vecs = min_t(int, vectors_left, vmdq_vecs_wanted); int vmdq_vecs = min_t(int, vectors_left, vmdq_vecs_wanted);
if (!vectors_left) {
pf->num_vmdq_msix = 0;
pf->num_vmdq_qps = 0;
} else {
/* if we're short on vectors for what's desired, we limit /* if we're short on vectors for what's desired, we limit
* the queues per vmdq. If this is still more than are * the queues per vmdq. If this is still more than are
* available, the user will need to change the number of * available, the user will need to change the number of
...@@ -7687,6 +7692,7 @@ static int i40e_init_msix(struct i40e_pf *pf) ...@@ -7687,6 +7692,7 @@ static int i40e_init_msix(struct i40e_pf *pf)
v_budget += vmdq_vecs; v_budget += vmdq_vecs;
vectors_left -= vmdq_vecs; vectors_left -= vmdq_vecs;
} }
}
pf->msix_entries = kcalloc(v_budget, sizeof(struct msix_entry), pf->msix_entries = kcalloc(v_budget, sizeof(struct msix_entry),
GFP_KERNEL); GFP_KERNEL);
...@@ -7697,21 +7703,6 @@ static int i40e_init_msix(struct i40e_pf *pf) ...@@ -7697,21 +7703,6 @@ static int i40e_init_msix(struct i40e_pf *pf)
pf->msix_entries[i].entry = i; pf->msix_entries[i].entry = i;
v_actual = i40e_reserve_msix_vectors(pf, v_budget); v_actual = i40e_reserve_msix_vectors(pf, v_budget);
if (v_actual != v_budget) {
/* If we have limited resources, we will start with no vectors
* for the special features and then allocate vectors to some
* of these features based on the policy and at the end disable
* the features that did not get any vectors.
*/
iwarp_requested = pf->num_iwarp_msix;
pf->num_iwarp_msix = 0;
#ifdef I40E_FCOE
pf->num_fcoe_qps = 0;
pf->num_fcoe_msix = 0;
#endif
pf->num_vmdq_msix = 0;
}
if (v_actual < I40E_MIN_MSIX) { if (v_actual < I40E_MIN_MSIX) {
pf->flags &= ~I40E_FLAG_MSIX_ENABLED; pf->flags &= ~I40E_FLAG_MSIX_ENABLED;
kfree(pf->msix_entries); kfree(pf->msix_entries);
...@@ -7725,9 +7716,16 @@ static int i40e_init_msix(struct i40e_pf *pf) ...@@ -7725,9 +7716,16 @@ static int i40e_init_msix(struct i40e_pf *pf)
pf->num_lan_qps = 1; pf->num_lan_qps = 1;
pf->num_lan_msix = 1; pf->num_lan_msix = 1;
} else if (v_actual != v_budget) { } else if (!vectors_left) {
/* If we have limited resources, we will start with no vectors
* for the special features and then allocate vectors to some
* of these features based on the policy and at the end disable
* the features that did not get any vectors.
*/
int vec; int vec;
dev_info(&pf->pdev->dev,
"MSI-X vector limit reached, attempting to redistribute vectors\n");
/* reserve the misc vector */ /* reserve the misc vector */
vec = v_actual - 1; vec = v_actual - 1;
...@@ -7735,7 +7733,10 @@ static int i40e_init_msix(struct i40e_pf *pf) ...@@ -7735,7 +7733,10 @@ static int i40e_init_msix(struct i40e_pf *pf)
pf->num_vmdq_msix = 1; /* force VMDqs to only one vector */ pf->num_vmdq_msix = 1; /* force VMDqs to only one vector */
pf->num_vmdq_vsis = 1; pf->num_vmdq_vsis = 1;
pf->num_vmdq_qps = 1; pf->num_vmdq_qps = 1;
pf->flags &= ~I40E_FLAG_FD_SB_ENABLED; #ifdef I40E_FCOE
pf->num_fcoe_qps = 0;
pf->num_fcoe_msix = 0;
#endif
/* partition out the remaining vectors */ /* partition out the remaining vectors */
switch (vec) { switch (vec) {
...@@ -7767,9 +7768,14 @@ static int i40e_init_msix(struct i40e_pf *pf) ...@@ -7767,9 +7768,14 @@ static int i40e_init_msix(struct i40e_pf *pf)
pf->num_vmdq_vsis = min_t(int, (vec / 2), pf->num_vmdq_vsis = min_t(int, (vec / 2),
I40E_DEFAULT_NUM_VMDQ_VSI); I40E_DEFAULT_NUM_VMDQ_VSI);
} }
if (pf->flags & I40E_FLAG_FD_SB_ENABLED) {
pf->num_fdsb_msix = 1;
vec--;
}
pf->num_lan_msix = min_t(int, pf->num_lan_msix = min_t(int,
(vec - (pf->num_iwarp_msix + pf->num_vmdq_vsis)), (vec - (pf->num_iwarp_msix + pf->num_vmdq_vsis)),
pf->num_lan_msix); pf->num_lan_msix);
pf->num_lan_qps = pf->num_lan_msix;
#ifdef I40E_FCOE #ifdef I40E_FCOE
/* give one vector to FCoE */ /* give one vector to FCoE */
if (pf->flags & I40E_FLAG_FCOE_ENABLED) { if (pf->flags & I40E_FLAG_FCOE_ENABLED) {
...@@ -7781,6 +7787,11 @@ static int i40e_init_msix(struct i40e_pf *pf) ...@@ -7781,6 +7787,11 @@ static int i40e_init_msix(struct i40e_pf *pf)
} }
} }
if ((pf->flags & I40E_FLAG_FD_SB_ENABLED) &&
(pf->num_fdsb_msix == 0)) {
dev_info(&pf->pdev->dev, "Sideband Flowdir disabled, not enough MSI-X vectors\n");
pf->flags &= ~I40E_FLAG_FD_SB_ENABLED;
}
if ((pf->flags & I40E_FLAG_VMDQ_ENABLED) && if ((pf->flags & I40E_FLAG_VMDQ_ENABLED) &&
(pf->num_vmdq_msix == 0)) { (pf->num_vmdq_msix == 0)) {
dev_info(&pf->pdev->dev, "VMDq disabled, not enough MSI-X vectors\n"); dev_info(&pf->pdev->dev, "VMDq disabled, not enough MSI-X vectors\n");
...@@ -7799,6 +7810,13 @@ static int i40e_init_msix(struct i40e_pf *pf) ...@@ -7799,6 +7810,13 @@ static int i40e_init_msix(struct i40e_pf *pf)
pf->flags &= ~I40E_FLAG_FCOE_ENABLED; pf->flags &= ~I40E_FLAG_FCOE_ENABLED;
} }
#endif #endif
i40e_debug(&pf->hw, I40E_DEBUG_INIT,
"MSI-X vector distribution: PF %d, VMDq %d, FDSB %d, iWARP %d\n",
pf->num_lan_msix,
pf->num_vmdq_msix * pf->num_vmdq_vsis,
pf->num_fdsb_msix,
pf->num_iwarp_msix);
return v_actual; return v_actual;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment