net/mlx4: fix Rx after updating number of queues

When not in isolated mode, internal flow rules are automatically
maintained by the PMD to receive traffic according to global device
settings (MAC, VLAN, promiscuous mode and so on).

Since RSS support was added to the mix, it must also check whether Rx
queue configuration has changed when refreshing flow rules to prevent
the following from happening:

- With a smaller number of Rx queues, traffic is implicitly dropped
  since the existing RSS context cannot be re-applied.
- With a larger number of Rx queues, traffic remains balanced within the
  original (smaller) set of queues.

One workaround before this commit was to temporarily enter/leave
isolated mode to make it regenerate internal flow rules.

Fixes: 7d8675956f57 ("net/mlx4: add RSS support outside flow API")

Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
This commit is contained in:
Adrien Mazarguil 2017-10-31 11:31:04 +01:00 committed by Ferruh Yigit
parent d8a4baafe8
commit a9b3568e73

View File

@ -1342,6 +1342,7 @@ next_vlan:
assert(flow->ibv_attr->type == IBV_FLOW_ATTR_NORMAL); assert(flow->ibv_attr->type == IBV_FLOW_ATTR_NORMAL);
assert(flow->ibv_attr->num_of_specs == 1); assert(flow->ibv_attr->num_of_specs == 1);
assert(eth->type == IBV_FLOW_SPEC_ETH); assert(eth->type == IBV_FLOW_SPEC_ETH);
assert(flow->rss);
if (rule_vlan && if (rule_vlan &&
(eth->val.vlan_tag != *rule_vlan || (eth->val.vlan_tag != *rule_vlan ||
eth->mask.vlan_tag != RTE_BE16(0x0fff))) eth->mask.vlan_tag != RTE_BE16(0x0fff)))
@ -1354,8 +1355,13 @@ next_vlan:
eth->val.src_mac[j] != UINT8_C(0x00) || eth->val.src_mac[j] != UINT8_C(0x00) ||
eth->mask.src_mac[j] != UINT8_C(0x00)) eth->mask.src_mac[j] != UINT8_C(0x00))
break; break;
if (j == sizeof(mac->addr_bytes)) if (j != sizeof(mac->addr_bytes))
break; continue;
if (flow->rss->queues != queues ||
memcmp(flow->rss->queue_id, rss_conf->queue,
queues * sizeof(flow->rss->queue_id[0])))
continue;
break;
} }
if (!flow || !flow->internal) { if (!flow || !flow->internal) {
/* Not found, create a new flow rule. */ /* Not found, create a new flow rule. */
@ -1389,6 +1395,13 @@ next_vlan:
break; break;
} }
} }
if (flow && flow->internal) {
assert(flow->rss);
if (flow->rss->queues != queues ||
memcmp(flow->rss->queue_id, rss_conf->queue,
queues * sizeof(flow->rss->queue_id[0])))
flow = NULL;
}
if (!flow || !flow->internal) { if (!flow || !flow->internal) {
/* Not found, create a new flow rule. */ /* Not found, create a new flow rule. */
if (priv->dev->data->promiscuous) { if (priv->dev->data->promiscuous) {