diff options
author | David S. Miller <davem@davemloft.net> | 2014-05-14 15:41:05 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-05-14 15:41:05 -0400 |
commit | 005e35f5f0783925428a78bb2b21ae92f3514e9c (patch) | |
tree | dddddda6e3f4e417065e91febffa04f16b9186cd | |
parent | 3763e7ef17143f5e9ae044638e65d2b0c0305fcf (diff) | |
parent | 7572038409d0288ff5ba9c77a053ddec6791a43c (diff) |
Merge branch 'mlx4-next'
Or Gerlitz says:
====================
Mellanox driver update 2014-05-12
This patchset introduce some small bug fixes:
Eyal fixed some compilation and syntactic checkers warnings. Ido fixed a
coruption in user priority mapping when changing number of channels. Shani
fixed some other problems when modifying MAC address. Yuval fixed a problem
when changing IRQ affinity during high traffic - IRQ changes got effective
only after the first pause in traffic.
This patchset was tested and applied over commit 93dccc5: "mdio_bus: fix
devm_mdiobus_alloc_size export"
Changes from V1:
- applied feedback from Dave to use true/false and not 0/1 in patch 1/9
- removed the patch from Noa which adddressed a bug in flow steering table
when using a bond device, as the fix might need to be in the bonding driver,
this is now dicussed in the netdev thread "bonding directly changes
underlying device address"
Changes from V0:
- Patch 1/9 - net/mlx4_core: Enforce irq affinity changes immediatly
- Moved the new members to a hot cache line as Eric suggested
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/cmd.c | 14 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/cq.c | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 12 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_rx.c | 11 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_tx.c | 6 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/eq.c | 62 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/main.c | 9 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mcg.c | 2 | ||||
-rw-r--r-- | include/linux/mlx4/device.h | 3 |
10 files changed, 110 insertions, 15 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c index 24201033661b..357dcb0f04fb 100644 --- a/drivers/net/ethernet/mellanox/mlx4/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c | |||
@@ -473,6 +473,13 @@ static int mlx4_cmd_poll(struct mlx4_dev *dev, u64 in_param, u64 *out_param, | |||
473 | goto out; | 473 | goto out; |
474 | } | 474 | } |
475 | 475 | ||
476 | if (out_is_imm && !out_param) { | ||
477 | mlx4_err(dev, "response expected while output mailbox is NULL for command 0x%x\n", | ||
478 | op); | ||
479 | err = -EINVAL; | ||
480 | goto out; | ||
481 | } | ||
482 | |||
476 | err = mlx4_cmd_post(dev, in_param, out_param ? *out_param : 0, | 483 | err = mlx4_cmd_post(dev, in_param, out_param ? *out_param : 0, |
477 | in_modifier, op_modifier, op, CMD_POLL_TOKEN, 0); | 484 | in_modifier, op_modifier, op, CMD_POLL_TOKEN, 0); |
478 | if (err) | 485 | if (err) |
@@ -551,6 +558,13 @@ static int mlx4_cmd_wait(struct mlx4_dev *dev, u64 in_param, u64 *out_param, | |||
551 | cmd->free_head = context->next; | 558 | cmd->free_head = context->next; |
552 | spin_unlock(&cmd->context_lock); | 559 | spin_unlock(&cmd->context_lock); |
553 | 560 | ||
561 | if (out_is_imm && !out_param) { | ||
562 | mlx4_err(dev, "response expected while output mailbox is NULL for command 0x%x\n", | ||
563 | op); | ||
564 | err = -EINVAL; | ||
565 | goto out; | ||
566 | } | ||
567 | |||
554 | init_completion(&context->done); | 568 | init_completion(&context->done); |
555 | 569 | ||
556 | mlx4_cmd_post(dev, in_param, out_param ? *out_param : 0, | 570 | mlx4_cmd_post(dev, in_param, out_param ? *out_param : 0, |
diff --git a/drivers/net/ethernet/mellanox/mlx4/cq.c b/drivers/net/ethernet/mellanox/mlx4/cq.c index 0487121e4a0f..8542030b89cf 100644 --- a/drivers/net/ethernet/mellanox/mlx4/cq.c +++ b/drivers/net/ethernet/mellanox/mlx4/cq.c | |||
@@ -293,6 +293,9 @@ int mlx4_cq_alloc(struct mlx4_dev *dev, int nent, | |||
293 | atomic_set(&cq->refcount, 1); | 293 | atomic_set(&cq->refcount, 1); |
294 | init_completion(&cq->free); | 294 | init_completion(&cq->free); |
295 | 295 | ||
296 | cq->irq = priv->eq_table.eq[cq->vector].irq; | ||
297 | cq->irq_affinity_change = false; | ||
298 | |||
296 | return 0; | 299 | return 0; |
297 | 300 | ||
298 | err_radix: | 301 | err_radix: |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c index c3736045e7af..a72d99fd7a2d 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | |||
@@ -1151,7 +1151,8 @@ static int mlx4_en_set_channels(struct net_device *dev, | |||
1151 | netif_set_real_num_tx_queues(dev, priv->tx_ring_num); | 1151 | netif_set_real_num_tx_queues(dev, priv->tx_ring_num); |
1152 | netif_set_real_num_rx_queues(dev, priv->rx_ring_num); | 1152 | netif_set_real_num_rx_queues(dev, priv->rx_ring_num); |
1153 | 1153 | ||
1154 | mlx4_en_setup_tc(dev, MLX4_EN_NUM_UP); | 1154 | if (dev->num_tc) |
1155 | mlx4_en_setup_tc(dev, MLX4_EN_NUM_UP); | ||
1155 | 1156 | ||
1156 | en_warn(priv, "Using %d TX rings\n", priv->tx_ring_num); | 1157 | en_warn(priv, "Using %d TX rings\n", priv->tx_ring_num); |
1157 | en_warn(priv, "Using %d RX rings\n", priv->rx_ring_num); | 1158 | en_warn(priv, "Using %d RX rings\n", priv->rx_ring_num); |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 79c6f467d17e..58209bd0c94c 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c | |||
@@ -130,7 +130,7 @@ static enum mlx4_net_trans_rule_id mlx4_ip_proto_to_trans_rule_id(u8 ip_proto) | |||
130 | case IPPROTO_TCP: | 130 | case IPPROTO_TCP: |
131 | return MLX4_NET_TRANS_RULE_ID_TCP; | 131 | return MLX4_NET_TRANS_RULE_ID_TCP; |
132 | default: | 132 | default: |
133 | return -EPROTONOSUPPORT; | 133 | return MLX4_NET_TRANS_RULE_NUM; |
134 | } | 134 | } |
135 | }; | 135 | }; |
136 | 136 | ||
@@ -177,7 +177,7 @@ static void mlx4_en_filter_work(struct work_struct *work) | |||
177 | int rc; | 177 | int rc; |
178 | __be64 mac_mask = cpu_to_be64(MLX4_MAC_MASK << 16); | 178 | __be64 mac_mask = cpu_to_be64(MLX4_MAC_MASK << 16); |
179 | 179 | ||
180 | if (spec_tcp_udp.id < 0) { | 180 | if (spec_tcp_udp.id >= MLX4_NET_TRANS_RULE_NUM) { |
181 | en_warn(priv, "RFS: ignoring unsupported ip protocol (%d)\n", | 181 | en_warn(priv, "RFS: ignoring unsupported ip protocol (%d)\n", |
182 | filter->ip_proto); | 182 | filter->ip_proto); |
183 | goto ignore; | 183 | goto ignore; |
@@ -770,11 +770,12 @@ static int mlx4_en_do_set_mac(struct mlx4_en_priv *priv) | |||
770 | priv->dev->dev_addr, priv->prev_mac); | 770 | priv->dev->dev_addr, priv->prev_mac); |
771 | if (err) | 771 | if (err) |
772 | en_err(priv, "Failed changing HW MAC address\n"); | 772 | en_err(priv, "Failed changing HW MAC address\n"); |
773 | memcpy(priv->prev_mac, priv->dev->dev_addr, | ||
774 | sizeof(priv->prev_mac)); | ||
775 | } else | 773 | } else |
776 | en_dbg(HW, priv, "Port is down while registering mac, exiting...\n"); | 774 | en_dbg(HW, priv, "Port is down while registering mac, exiting...\n"); |
777 | 775 | ||
776 | memcpy(priv->prev_mac, priv->dev->dev_addr, | ||
777 | sizeof(priv->prev_mac)); | ||
778 | |||
778 | return err; | 779 | return err; |
779 | } | 780 | } |
780 | 781 | ||
@@ -788,9 +789,8 @@ static int mlx4_en_set_mac(struct net_device *dev, void *addr) | |||
788 | if (!is_valid_ether_addr(saddr->sa_data)) | 789 | if (!is_valid_ether_addr(saddr->sa_data)) |
789 | return -EADDRNOTAVAIL; | 790 | return -EADDRNOTAVAIL; |
790 | 791 | ||
791 | memcpy(dev->dev_addr, saddr->sa_data, ETH_ALEN); | ||
792 | |||
793 | mutex_lock(&mdev->state_lock); | 792 | mutex_lock(&mdev->state_lock); |
793 | memcpy(dev->dev_addr, saddr->sa_data, ETH_ALEN); | ||
794 | err = mlx4_en_do_set_mac(priv); | 794 | err = mlx4_en_do_set_mac(priv); |
795 | mutex_unlock(&mdev->state_lock); | 795 | mutex_unlock(&mdev->state_lock); |
796 | 796 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c index a1512450816d..e8c0d2b832b7 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c | |||
@@ -895,10 +895,17 @@ int mlx4_en_poll_rx_cq(struct napi_struct *napi, int budget) | |||
895 | mlx4_en_cq_unlock_napi(cq); | 895 | mlx4_en_cq_unlock_napi(cq); |
896 | 896 | ||
897 | /* If we used up all the quota - we're probably not done yet... */ | 897 | /* If we used up all the quota - we're probably not done yet... */ |
898 | if (done == budget) | 898 | if (done == budget) { |
899 | INC_PERF_COUNTER(priv->pstats.napi_quota); | 899 | INC_PERF_COUNTER(priv->pstats.napi_quota); |
900 | else { | 900 | if (unlikely(cq->mcq.irq_affinity_change)) { |
901 | cq->mcq.irq_affinity_change = false; | ||
902 | napi_complete(napi); | ||
903 | mlx4_en_arm_cq(priv, cq); | ||
904 | return 0; | ||
905 | } | ||
906 | } else { | ||
901 | /* Done for now */ | 907 | /* Done for now */ |
908 | cq->mcq.irq_affinity_change = false; | ||
902 | napi_complete(napi); | 909 | napi_complete(napi); |
903 | mlx4_en_arm_cq(priv, cq); | 910 | mlx4_en_arm_cq(priv, cq); |
904 | } | 911 | } |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c index 89585c6311c3..cb964056d710 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c | |||
@@ -474,9 +474,15 @@ int mlx4_en_poll_tx_cq(struct napi_struct *napi, int budget) | |||
474 | /* If we used up all the quota - we're probably not done yet... */ | 474 | /* If we used up all the quota - we're probably not done yet... */ |
475 | if (done < budget) { | 475 | if (done < budget) { |
476 | /* Done for now */ | 476 | /* Done for now */ |
477 | cq->mcq.irq_affinity_change = false; | ||
477 | napi_complete(napi); | 478 | napi_complete(napi); |
478 | mlx4_en_arm_cq(priv, cq); | 479 | mlx4_en_arm_cq(priv, cq); |
479 | return done; | 480 | return done; |
481 | } else if (unlikely(cq->mcq.irq_affinity_change)) { | ||
482 | cq->mcq.irq_affinity_change = false; | ||
483 | napi_complete(napi); | ||
484 | mlx4_en_arm_cq(priv, cq); | ||
485 | return 0; | ||
480 | } | 486 | } |
481 | return budget; | 487 | return budget; |
482 | } | 488 | } |
diff --git a/drivers/net/ethernet/mellanox/mlx4/eq.c b/drivers/net/ethernet/mellanox/mlx4/eq.c index 6c088bc1845b..d954ec1eac17 100644 --- a/drivers/net/ethernet/mellanox/mlx4/eq.c +++ b/drivers/net/ethernet/mellanox/mlx4/eq.c | |||
@@ -53,6 +53,11 @@ enum { | |||
53 | MLX4_EQ_ENTRY_SIZE = 0x20 | 53 | MLX4_EQ_ENTRY_SIZE = 0x20 |
54 | }; | 54 | }; |
55 | 55 | ||
56 | struct mlx4_irq_notify { | ||
57 | void *arg; | ||
58 | struct irq_affinity_notify notify; | ||
59 | }; | ||
60 | |||
56 | #define MLX4_EQ_STATUS_OK ( 0 << 28) | 61 | #define MLX4_EQ_STATUS_OK ( 0 << 28) |
57 | #define MLX4_EQ_STATUS_WRITE_FAIL (10 << 28) | 62 | #define MLX4_EQ_STATUS_WRITE_FAIL (10 << 28) |
58 | #define MLX4_EQ_OWNER_SW ( 0 << 24) | 63 | #define MLX4_EQ_OWNER_SW ( 0 << 24) |
@@ -1083,6 +1088,57 @@ static void mlx4_unmap_clr_int(struct mlx4_dev *dev) | |||
1083 | iounmap(priv->clr_base); | 1088 | iounmap(priv->clr_base); |
1084 | } | 1089 | } |
1085 | 1090 | ||
1091 | static void mlx4_irq_notifier_notify(struct irq_affinity_notify *notify, | ||
1092 | const cpumask_t *mask) | ||
1093 | { | ||
1094 | struct mlx4_irq_notify *n = container_of(notify, | ||
1095 | struct mlx4_irq_notify, | ||
1096 | notify); | ||
1097 | struct mlx4_priv *priv = (struct mlx4_priv *)n->arg; | ||
1098 | struct radix_tree_iter iter; | ||
1099 | void **slot; | ||
1100 | |||
1101 | radix_tree_for_each_slot(slot, &priv->cq_table.tree, &iter, 0) { | ||
1102 | struct mlx4_cq *cq = (struct mlx4_cq *)(*slot); | ||
1103 | |||
1104 | if (cq->irq == notify->irq) | ||
1105 | cq->irq_affinity_change = true; | ||
1106 | } | ||
1107 | } | ||
1108 | |||
1109 | static void mlx4_release_irq_notifier(struct kref *ref) | ||
1110 | { | ||
1111 | struct mlx4_irq_notify *n = container_of(ref, struct mlx4_irq_notify, | ||
1112 | notify.kref); | ||
1113 | kfree(n); | ||
1114 | } | ||
1115 | |||
1116 | static void mlx4_assign_irq_notifier(struct mlx4_priv *priv, | ||
1117 | struct mlx4_dev *dev, int irq) | ||
1118 | { | ||
1119 | struct mlx4_irq_notify *irq_notifier = NULL; | ||
1120 | int err = 0; | ||
1121 | |||
1122 | irq_notifier = kzalloc(sizeof(*irq_notifier), GFP_KERNEL); | ||
1123 | if (!irq_notifier) { | ||
1124 | mlx4_warn(dev, "Failed to allocate irq notifier. irq %d\n", | ||
1125 | irq); | ||
1126 | return; | ||
1127 | } | ||
1128 | |||
1129 | irq_notifier->notify.irq = irq; | ||
1130 | irq_notifier->notify.notify = mlx4_irq_notifier_notify; | ||
1131 | irq_notifier->notify.release = mlx4_release_irq_notifier; | ||
1132 | irq_notifier->arg = priv; | ||
1133 | err = irq_set_affinity_notifier(irq, &irq_notifier->notify); | ||
1134 | if (err) { | ||
1135 | kfree(irq_notifier); | ||
1136 | irq_notifier = NULL; | ||
1137 | mlx4_warn(dev, "Failed to set irq notifier. irq %d\n", irq); | ||
1138 | } | ||
1139 | } | ||
1140 | |||
1141 | |||
1086 | int mlx4_alloc_eq_table(struct mlx4_dev *dev) | 1142 | int mlx4_alloc_eq_table(struct mlx4_dev *dev) |
1087 | { | 1143 | { |
1088 | struct mlx4_priv *priv = mlx4_priv(dev); | 1144 | struct mlx4_priv *priv = mlx4_priv(dev); |
@@ -1353,6 +1409,9 @@ int mlx4_assign_eq(struct mlx4_dev *dev, char *name, struct cpu_rmap *rmap, | |||
1353 | continue; | 1409 | continue; |
1354 | /*we dont want to break here*/ | 1410 | /*we dont want to break here*/ |
1355 | } | 1411 | } |
1412 | mlx4_assign_irq_notifier(priv, dev, | ||
1413 | priv->eq_table.eq[vec].irq); | ||
1414 | |||
1356 | eq_set_ci(&priv->eq_table.eq[vec], 1); | 1415 | eq_set_ci(&priv->eq_table.eq[vec], 1); |
1357 | } | 1416 | } |
1358 | } | 1417 | } |
@@ -1379,6 +1438,9 @@ void mlx4_release_eq(struct mlx4_dev *dev, int vec) | |||
1379 | Belonging to a legacy EQ*/ | 1438 | Belonging to a legacy EQ*/ |
1380 | mutex_lock(&priv->msix_ctl.pool_lock); | 1439 | mutex_lock(&priv->msix_ctl.pool_lock); |
1381 | if (priv->msix_ctl.pool_bm & 1ULL << i) { | 1440 | if (priv->msix_ctl.pool_bm & 1ULL << i) { |
1441 | irq_set_affinity_notifier( | ||
1442 | priv->eq_table.eq[vec].irq, | ||
1443 | NULL); | ||
1382 | free_irq(priv->eq_table.eq[vec].irq, | 1444 | free_irq(priv->eq_table.eq[vec].irq, |
1383 | &priv->eq_table.eq[vec]); | 1445 | &priv->eq_table.eq[vec]); |
1384 | priv->msix_ctl.pool_bm &= ~(1ULL << i); | 1446 | priv->msix_ctl.pool_bm &= ~(1ULL << i); |
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 5db97a4fdc01..a56f6012258d 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c | |||
@@ -104,8 +104,6 @@ module_param(enable_64b_cqe_eqe, bool, 0444); | |||
104 | MODULE_PARM_DESC(enable_64b_cqe_eqe, | 104 | MODULE_PARM_DESC(enable_64b_cqe_eqe, |
105 | "Enable 64 byte CQEs/EQEs when the FW supports this (default: True)"); | 105 | "Enable 64 byte CQEs/EQEs when the FW supports this (default: True)"); |
106 | 106 | ||
107 | #define HCA_GLOBAL_CAP_MASK 0 | ||
108 | |||
109 | #define PF_CONTEXT_BEHAVIOUR_MASK MLX4_FUNC_CAP_64B_EQE_CQE | 107 | #define PF_CONTEXT_BEHAVIOUR_MASK MLX4_FUNC_CAP_64B_EQE_CQE |
110 | 108 | ||
111 | static char mlx4_version[] = | 109 | static char mlx4_version[] = |
@@ -582,9 +580,10 @@ static int mlx4_slave_cap(struct mlx4_dev *dev) | |||
582 | return err; | 580 | return err; |
583 | } | 581 | } |
584 | 582 | ||
585 | /*fail if the hca has an unknown capability */ | 583 | /* fail if the hca has an unknown global capability |
586 | if ((hca_param.global_caps | HCA_GLOBAL_CAP_MASK) != | 584 | * at this time global_caps should be always zeroed |
587 | HCA_GLOBAL_CAP_MASK) { | 585 | */ |
586 | if (hca_param.global_caps) { | ||
588 | mlx4_err(dev, "Unknown hca global capabilities\n"); | 587 | mlx4_err(dev, "Unknown hca global capabilities\n"); |
589 | return -ENOSYS; | 588 | return -ENOSYS; |
590 | } | 589 | } |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c index 7c6eba622186..4c36def8e10f 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mcg.c +++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c | |||
@@ -897,7 +897,7 @@ int mlx4_flow_attach(struct mlx4_dev *dev, | |||
897 | ret = parse_trans_rule(dev, cur, mailbox->buf + size); | 897 | ret = parse_trans_rule(dev, cur, mailbox->buf + size); |
898 | if (ret < 0) { | 898 | if (ret < 0) { |
899 | mlx4_free_cmd_mailbox(dev, mailbox); | 899 | mlx4_free_cmd_mailbox(dev, mailbox); |
900 | return -EINVAL; | 900 | return ret; |
901 | } | 901 | } |
902 | size += ret; | 902 | size += ret; |
903 | } | 903 | } |
diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index ba87bd21295a..c0468e6f0442 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h | |||
@@ -577,6 +577,9 @@ struct mlx4_cq { | |||
577 | 577 | ||
578 | u32 cons_index; | 578 | u32 cons_index; |
579 | 579 | ||
580 | u16 irq; | ||
581 | bool irq_affinity_change; | ||
582 | |||
580 | __be32 *set_ci_db; | 583 | __be32 *set_ci_db; |
581 | __be32 *arm_db; | 584 | __be32 *arm_db; |
582 | int arm_sn; | 585 | int arm_sn; |