diff options
author | Haggai Eran <haggaie@mellanox.com> | 2016-02-29 08:45:07 -0500 |
---|---|---|
committer | Doug Ledford <dledford@redhat.com> | 2016-03-01 11:04:07 -0500 |
commit | 7722f47e71e58592a2ba4437d27c802ba1c64e08 (patch) | |
tree | 27123283835d44c1e647b080357daac5752eefaf | |
parent | ebab41cff4db96c42dfc9939d1c1715496bcf961 (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.c | 10 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx5/main.c | 28 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx5/mlx5_ib.h | 3 |
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 | |||
345 | void 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 | ||
1724 | static 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 | |||
1724 | static void mlx5_ib_event(struct mlx5_core_dev *dev, void *context, | 1735 | static 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 | ||
2064 | error5: | 2084 | error5: |
@@ -2077,12 +2097,20 @@ error0: | |||
2077 | 2097 | ||
2078 | static void destroy_dev_resources(struct mlx5_ib_resources *devr) | 2098 | static 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 | ||
2088 | static u32 get_core_cap_flags(struct ib_device *ibdev) | 2116 | static 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 { | |||
510 | struct mlx5_ib_gsi_qp; | 510 | struct mlx5_ib_gsi_qp; |
511 | 511 | ||
512 | struct mlx5_ib_port_resources { | 512 | struct 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 | ||
516 | struct mlx5_ib_resources { | 518 | struct 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); |
782 | int mlx5_ib_gsi_post_recv(struct ib_qp *qp, struct ib_recv_wr *wr, | 784 | int 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); |
786 | void mlx5_ib_gsi_pkey_change(struct mlx5_ib_gsi_qp *gsi); | ||
784 | 787 | ||
785 | static inline void init_query_mad(struct ib_smp *mad) | 788 | static inline void init_query_mad(struct ib_smp *mad) |
786 | { | 789 | { |