aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHaggai Eran <haggaie@mellanox.com>2016-02-29 08:45:07 -0500
committerDoug Ledford <dledford@redhat.com>2016-03-01 11:04:07 -0500
commit7722f47e71e58592a2ba4437d27c802ba1c64e08 (patch)
tree27123283835d44c1e647b080357daac5752eefaf
parentebab41cff4db96c42dfc9939d1c1715496bcf961 (diff)
IB/mlx5: Create GSI transmission QPs when P_Key table is changed
Whenever the P_Key table is changed, we create the required GSI transmission QPs on-demand. Reviewed-by: Leon Romanovsky <leonro@mellanox.com> Signed-off-by: Haggai Eran <haggaie@mellanox.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
-rw-r--r--drivers/infiniband/hw/mlx5/gsi.c10
-rw-r--r--drivers/infiniband/hw/mlx5/main.c28
-rw-r--r--drivers/infiniband/hw/mlx5/mlx5_ib.h3
3 files changed, 41 insertions, 0 deletions
diff --git a/drivers/infiniband/hw/mlx5/gsi.c b/drivers/infiniband/hw/mlx5/gsi.c
index 91bd20eb59b7..1648f539c836 100644
--- a/drivers/infiniband/hw/mlx5/gsi.c
+++ b/drivers/infiniband/hw/mlx5/gsi.c
@@ -341,3 +341,13 @@ int mlx5_ib_gsi_post_recv(struct ib_qp *qp, struct ib_recv_wr *wr,
341 341
342 return ib_post_recv(gsi->rx_qp, wr, bad_wr); 342 return ib_post_recv(gsi->rx_qp, wr, bad_wr);
343} 343}
344
345void mlx5_ib_gsi_pkey_change(struct mlx5_ib_gsi_qp *gsi)
346{
347 if (!gsi)
348 return;
349
350 mutex_lock(&gsi->mutex);
351 setup_qps(gsi);
352 mutex_unlock(&gsi->mutex);
353}
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
index 0b30dc53c925..d4224fab98f7 100644
--- a/drivers/infiniband/hw/mlx5/main.c
+++ b/drivers/infiniband/hw/mlx5/main.c
@@ -1721,6 +1721,17 @@ static struct device_attribute *mlx5_class_attributes[] = {
1721 &dev_attr_reg_pages, 1721 &dev_attr_reg_pages,
1722}; 1722};
1723 1723
1724static void pkey_change_handler(struct work_struct *work)
1725{
1726 struct mlx5_ib_port_resources *ports =
1727 container_of(work, struct mlx5_ib_port_resources,
1728 pkey_change_work);
1729
1730 mutex_lock(&ports->devr->mutex);
1731 mlx5_ib_gsi_pkey_change(ports->gsi);
1732 mutex_unlock(&ports->devr->mutex);
1733}
1734
1724static void mlx5_ib_event(struct mlx5_core_dev *dev, void *context, 1735static void mlx5_ib_event(struct mlx5_core_dev *dev, void *context,
1725 enum mlx5_dev_event event, unsigned long param) 1736 enum mlx5_dev_event event, unsigned long param)
1726{ 1737{
@@ -1757,6 +1768,8 @@ static void mlx5_ib_event(struct mlx5_core_dev *dev, void *context,
1757 case MLX5_DEV_EVENT_PKEY_CHANGE: 1768 case MLX5_DEV_EVENT_PKEY_CHANGE:
1758 ibev.event = IB_EVENT_PKEY_CHANGE; 1769 ibev.event = IB_EVENT_PKEY_CHANGE;
1759 port = (u8)param; 1770 port = (u8)param;
1771
1772 schedule_work(&ibdev->devr.ports[port - 1].pkey_change_work);
1760 break; 1773 break;
1761 1774
1762 case MLX5_DEV_EVENT_GUID_CHANGE: 1775 case MLX5_DEV_EVENT_GUID_CHANGE:
@@ -1966,6 +1979,7 @@ static int create_dev_resources(struct mlx5_ib_resources *devr)
1966 struct ib_srq_init_attr attr; 1979 struct ib_srq_init_attr attr;
1967 struct mlx5_ib_dev *dev; 1980 struct mlx5_ib_dev *dev;
1968 struct ib_cq_init_attr cq_attr = {.cqe = 1}; 1981 struct ib_cq_init_attr cq_attr = {.cqe = 1};
1982 int port;
1969 int ret = 0; 1983 int ret = 0;
1970 1984
1971 dev = container_of(devr, struct mlx5_ib_dev, devr); 1985 dev = container_of(devr, struct mlx5_ib_dev, devr);
@@ -2059,6 +2073,12 @@ static int create_dev_resources(struct mlx5_ib_resources *devr)
2059 atomic_inc(&devr->p0->usecnt); 2073 atomic_inc(&devr->p0->usecnt);
2060 atomic_set(&devr->s0->usecnt, 0); 2074 atomic_set(&devr->s0->usecnt, 0);
2061 2075
2076 for (port = 0; port < ARRAY_SIZE(devr->ports); ++port) {
2077 INIT_WORK(&devr->ports[port].pkey_change_work,
2078 pkey_change_handler);
2079 devr->ports[port].devr = devr;
2080 }
2081
2062 return 0; 2082 return 0;
2063 2083
2064error5: 2084error5:
@@ -2077,12 +2097,20 @@ error0:
2077 2097
2078static void destroy_dev_resources(struct mlx5_ib_resources *devr) 2098static void destroy_dev_resources(struct mlx5_ib_resources *devr)
2079{ 2099{
2100 struct mlx5_ib_dev *dev =
2101 container_of(devr, struct mlx5_ib_dev, devr);
2102 int port;
2103
2080 mlx5_ib_destroy_srq(devr->s1); 2104 mlx5_ib_destroy_srq(devr->s1);
2081 mlx5_ib_destroy_srq(devr->s0); 2105 mlx5_ib_destroy_srq(devr->s0);
2082 mlx5_ib_dealloc_xrcd(devr->x0); 2106 mlx5_ib_dealloc_xrcd(devr->x0);
2083 mlx5_ib_dealloc_xrcd(devr->x1); 2107 mlx5_ib_dealloc_xrcd(devr->x1);
2084 mlx5_ib_destroy_cq(devr->c0); 2108 mlx5_ib_destroy_cq(devr->c0);
2085 mlx5_ib_dealloc_pd(devr->p0); 2109 mlx5_ib_dealloc_pd(devr->p0);
2110
2111 /* Make sure no change P_Key work items are still executing */
2112 for (port = 0; port < dev->num_ports; ++port)
2113 cancel_work_sync(&devr->ports[port].pkey_change_work);
2086} 2114}
2087 2115
2088static u32 get_core_cap_flags(struct ib_device *ibdev) 2116static u32 get_core_cap_flags(struct ib_device *ibdev)
diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h
index c68a9135831f..a8fc345c088a 100644
--- a/drivers/infiniband/hw/mlx5/mlx5_ib.h
+++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h
@@ -510,7 +510,9 @@ struct mlx5_mr_cache {
510struct mlx5_ib_gsi_qp; 510struct mlx5_ib_gsi_qp;
511 511
512struct mlx5_ib_port_resources { 512struct mlx5_ib_port_resources {
513 struct mlx5_ib_resources *devr;
513 struct mlx5_ib_gsi_qp *gsi; 514 struct mlx5_ib_gsi_qp *gsi;
515 struct work_struct pkey_change_work;
514}; 516};
515 517
516struct mlx5_ib_resources { 518struct mlx5_ib_resources {
@@ -781,6 +783,7 @@ int mlx5_ib_gsi_post_send(struct ib_qp *qp, struct ib_send_wr *wr,
781 struct ib_send_wr **bad_wr); 783 struct ib_send_wr **bad_wr);
782int mlx5_ib_gsi_post_recv(struct ib_qp *qp, struct ib_recv_wr *wr, 784int mlx5_ib_gsi_post_recv(struct ib_qp *qp, struct ib_recv_wr *wr,
783 struct ib_recv_wr **bad_wr); 785 struct ib_recv_wr **bad_wr);
786void mlx5_ib_gsi_pkey_change(struct mlx5_ib_gsi_qp *gsi);
784 787
785static inline void init_query_mad(struct ib_smp *mad) 788static inline void init_query_mad(struct ib_smp *mad)
786{ 789{