aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMoni Shoua <monis@mellanox.com>2015-02-03 09:48:39 -0500
committerDavid S. Miller <davem@davemloft.net>2015-02-04 19:14:25 -0500
commitc6215745b66a7fbeeda1a826f94dd864a2ccf654 (patch)
tree93990685d6fdba0784d68bf5ca0dbf523c930bb4
parent146d6e19832a72136089afca51e5229d1fd72dcd (diff)
IB/mlx4: Load balance ports in port aggregation mode
When the mlx4 IB (RoCE) device works in link aggregation mode, it exposes a single port to upper layers. Therefore, applications always set '1' in port_num attribute when modifying a QP or creating an address handle. To make sure that a node uses all available ports the mlx4 driver will override the port_num attribute with a round robin policy. Signed-off-by: Moni Shoua <monis@mellanox.com> Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/infiniband/hw/mlx4/ah.c1
-rw-r--r--drivers/infiniband/hw/mlx4/main.c1
-rw-r--r--drivers/infiniband/hw/mlx4/mlx4_ib.h8
-rw-r--r--drivers/infiniband/hw/mlx4/qp.c19
4 files changed, 29 insertions, 0 deletions
diff --git a/drivers/infiniband/hw/mlx4/ah.c b/drivers/infiniband/hw/mlx4/ah.c
index 2d8c3397774f..f50a546224ad 100644
--- a/drivers/infiniband/hw/mlx4/ah.c
+++ b/drivers/infiniband/hw/mlx4/ah.c
@@ -36,6 +36,7 @@
36#include <linux/slab.h> 36#include <linux/slab.h>
37#include <linux/inet.h> 37#include <linux/inet.h>
38#include <linux/string.h> 38#include <linux/string.h>
39#include <linux/mlx4/driver.h>
39 40
40#include "mlx4_ib.h" 41#include "mlx4_ib.h"
41 42
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index ca522382dedc..2ed5b996b2f4 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -2153,6 +2153,7 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
2153 MLX4_INIT_DOORBELL_LOCK(&ibdev->uar_lock); 2153 MLX4_INIT_DOORBELL_LOCK(&ibdev->uar_lock);
2154 2154
2155 ibdev->dev = dev; 2155 ibdev->dev = dev;
2156 ibdev->bond_next_port = 0;
2156 2157
2157 strlcpy(ibdev->ib_dev.name, "mlx4_%d", IB_DEVICE_NAME_MAX); 2158 strlcpy(ibdev->ib_dev.name, "mlx4_%d", IB_DEVICE_NAME_MAX);
2158 ibdev->ib_dev.owner = THIS_MODULE; 2159 ibdev->ib_dev.owner = THIS_MODULE;
diff --git a/drivers/infiniband/hw/mlx4/mlx4_ib.h b/drivers/infiniband/hw/mlx4/mlx4_ib.h
index 2b49f9de2556..721540c9163d 100644
--- a/drivers/infiniband/hw/mlx4/mlx4_ib.h
+++ b/drivers/infiniband/hw/mlx4/mlx4_ib.h
@@ -534,6 +534,7 @@ struct mlx4_ib_dev {
534 struct mlx4_ib_qp *qp1_proxy[MLX4_MAX_PORTS]; 534 struct mlx4_ib_qp *qp1_proxy[MLX4_MAX_PORTS];
535 /* lock when destroying qp1_proxy and getting netdev events */ 535 /* lock when destroying qp1_proxy and getting netdev events */
536 struct mutex qp1_proxy_lock[MLX4_MAX_PORTS]; 536 struct mutex qp1_proxy_lock[MLX4_MAX_PORTS];
537 u8 bond_next_port;
537}; 538};
538 539
539struct ib_event_work { 540struct ib_event_work {
@@ -629,6 +630,13 @@ static inline struct mlx4_ib_ah *to_mah(struct ib_ah *ibah)
629 return container_of(ibah, struct mlx4_ib_ah, ibah); 630 return container_of(ibah, struct mlx4_ib_ah, ibah);
630} 631}
631 632
633static inline u8 mlx4_ib_bond_next_port(struct mlx4_ib_dev *dev)
634{
635 dev->bond_next_port = (dev->bond_next_port + 1) % dev->num_ports;
636
637 return dev->bond_next_port + 1;
638}
639
632int mlx4_ib_init_sriov(struct mlx4_ib_dev *dev); 640int mlx4_ib_init_sriov(struct mlx4_ib_dev *dev);
633void mlx4_ib_close_sriov(struct mlx4_ib_dev *dev); 641void mlx4_ib_close_sriov(struct mlx4_ib_dev *dev);
634 642
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c
index 2f85fc762865..792f9dc86ada 100644
--- a/drivers/infiniband/hw/mlx4/qp.c
+++ b/drivers/infiniband/hw/mlx4/qp.c
@@ -1905,6 +1905,22 @@ int mlx4_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
1905 goto out; 1905 goto out;
1906 } 1906 }
1907 1907
1908 if (mlx4_is_bonded(dev->dev) && (attr_mask & IB_QP_PORT)) {
1909 if ((cur_state == IB_QPS_RESET) && (new_state == IB_QPS_INIT)) {
1910 if ((ibqp->qp_type == IB_QPT_RC) ||
1911 (ibqp->qp_type == IB_QPT_UD) ||
1912 (ibqp->qp_type == IB_QPT_UC) ||
1913 (ibqp->qp_type == IB_QPT_RAW_PACKET) ||
1914 (ibqp->qp_type == IB_QPT_XRC_INI)) {
1915 attr->port_num = mlx4_ib_bond_next_port(dev);
1916 }
1917 } else {
1918 /* no sense in changing port_num
1919 * when ports are bonded */
1920 attr_mask &= ~IB_QP_PORT;
1921 }
1922 }
1923
1908 if ((attr_mask & IB_QP_PORT) && 1924 if ((attr_mask & IB_QP_PORT) &&
1909 (attr->port_num == 0 || attr->port_num > dev->num_ports)) { 1925 (attr->port_num == 0 || attr->port_num > dev->num_ports)) {
1910 pr_debug("qpn 0x%x: invalid port number (%d) specified " 1926 pr_debug("qpn 0x%x: invalid port number (%d) specified "
@@ -1955,6 +1971,9 @@ int mlx4_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr,
1955 1971
1956 err = __mlx4_ib_modify_qp(ibqp, attr, attr_mask, cur_state, new_state); 1972 err = __mlx4_ib_modify_qp(ibqp, attr, attr_mask, cur_state, new_state);
1957 1973
1974 if (mlx4_is_bonded(dev->dev) && (attr_mask & IB_QP_PORT))
1975 attr->port_num = 1;
1976
1958out: 1977out:
1959 mutex_unlock(&qp->mutex); 1978 mutex_unlock(&qp->mutex);
1960 return err; 1979 return err;