aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/hw/mlx5/mlx5_ib.h15
-rw-r--r--drivers/infiniband/hw/mlx5/mr.c29
-rw-r--r--drivers/infiniband/hw/mlx5/qp.c100
-rw-r--r--include/linux/mlx5/device.h13
4 files changed, 109 insertions, 48 deletions
diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h b/drivers/infiniband/hw/mlx5/mlx5_ib.h
index 29da55222070..53d19e6e69a4 100644
--- a/drivers/infiniband/hw/mlx5/mlx5_ib.h
+++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h
@@ -111,6 +111,8 @@ struct mlx5_ib_pd {
111 */ 111 */
112 112
113#define MLX5_IB_SEND_UMR_UNREG IB_SEND_RESERVED_START 113#define MLX5_IB_SEND_UMR_UNREG IB_SEND_RESERVED_START
114#define MLX5_IB_SEND_UMR_FAIL_IF_FREE (IB_SEND_RESERVED_START << 1)
115#define MLX5_IB_SEND_UMR_UPDATE_MTT (IB_SEND_RESERVED_START << 2)
114#define MLX5_IB_QPT_REG_UMR IB_QPT_RESERVED1 116#define MLX5_IB_QPT_REG_UMR IB_QPT_RESERVED1
115#define MLX5_IB_WR_UMR IB_WR_RESERVED1 117#define MLX5_IB_WR_UMR IB_WR_RESERVED1
116 118
@@ -206,6 +208,19 @@ enum mlx5_ib_qp_flags {
206 MLX5_IB_QP_SIGNATURE_HANDLING = 1 << 1, 208 MLX5_IB_QP_SIGNATURE_HANDLING = 1 << 1,
207}; 209};
208 210
211struct mlx5_umr_wr {
212 union {
213 u64 virt_addr;
214 u64 offset;
215 } target;
216 struct ib_pd *pd;
217 unsigned int page_shift;
218 unsigned int npages;
219 u32 length;
220 int access_flags;
221 u32 mkey;
222};
223
209struct mlx5_shared_mr_info { 224struct mlx5_shared_mr_info {
210 int mr_id; 225 int mr_id;
211 struct ib_umem *umem; 226 struct ib_umem *umem;
diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c
index 2ab081cdbca0..2de4f4448f8a 100644
--- a/drivers/infiniband/hw/mlx5/mr.c
+++ b/drivers/infiniband/hw/mlx5/mr.c
@@ -37,6 +37,7 @@
37#include <linux/export.h> 37#include <linux/export.h>
38#include <linux/delay.h> 38#include <linux/delay.h>
39#include <rdma/ib_umem.h> 39#include <rdma/ib_umem.h>
40#include <rdma/ib_verbs.h>
40#include "mlx5_ib.h" 41#include "mlx5_ib.h"
41 42
42enum { 43enum {
@@ -146,7 +147,7 @@ static int add_keys(struct mlx5_ib_dev *dev, int c, int num)
146 mr->order = ent->order; 147 mr->order = ent->order;
147 mr->umred = 1; 148 mr->umred = 1;
148 mr->dev = dev; 149 mr->dev = dev;
149 in->seg.status = 1 << 6; 150 in->seg.status = MLX5_MKEY_STATUS_FREE;
150 in->seg.xlt_oct_size = cpu_to_be32((npages + 1) / 2); 151 in->seg.xlt_oct_size = cpu_to_be32((npages + 1) / 2);
151 in->seg.qpn_mkey7_0 = cpu_to_be32(0xffffff << 8); 152 in->seg.qpn_mkey7_0 = cpu_to_be32(0xffffff << 8);
152 in->seg.flags = MLX5_ACCESS_MODE_MTT | MLX5_PERM_UMR_EN; 153 in->seg.flags = MLX5_ACCESS_MODE_MTT | MLX5_PERM_UMR_EN;
@@ -678,6 +679,7 @@ static void prep_umr_reg_wqe(struct ib_pd *pd, struct ib_send_wr *wr,
678{ 679{
679 struct mlx5_ib_dev *dev = to_mdev(pd->device); 680 struct mlx5_ib_dev *dev = to_mdev(pd->device);
680 struct ib_mr *mr = dev->umrc.mr; 681 struct ib_mr *mr = dev->umrc.mr;
682 struct mlx5_umr_wr *umrwr = (struct mlx5_umr_wr *)&wr->wr.fast_reg;
681 683
682 sg->addr = dma; 684 sg->addr = dma;
683 sg->length = ALIGN(sizeof(u64) * n, 64); 685 sg->length = ALIGN(sizeof(u64) * n, 64);
@@ -692,21 +694,24 @@ static void prep_umr_reg_wqe(struct ib_pd *pd, struct ib_send_wr *wr,
692 wr->num_sge = 0; 694 wr->num_sge = 0;
693 695
694 wr->opcode = MLX5_IB_WR_UMR; 696 wr->opcode = MLX5_IB_WR_UMR;
695 wr->wr.fast_reg.page_list_len = n; 697
696 wr->wr.fast_reg.page_shift = page_shift; 698 umrwr->npages = n;
697 wr->wr.fast_reg.rkey = key; 699 umrwr->page_shift = page_shift;
698 wr->wr.fast_reg.iova_start = virt_addr; 700 umrwr->mkey = key;
699 wr->wr.fast_reg.length = len; 701 umrwr->target.virt_addr = virt_addr;
700 wr->wr.fast_reg.access_flags = access_flags; 702 umrwr->length = len;
701 wr->wr.fast_reg.page_list = (struct ib_fast_reg_page_list *)pd; 703 umrwr->access_flags = access_flags;
704 umrwr->pd = pd;
702} 705}
703 706
704static void prep_umr_unreg_wqe(struct mlx5_ib_dev *dev, 707static void prep_umr_unreg_wqe(struct mlx5_ib_dev *dev,
705 struct ib_send_wr *wr, u32 key) 708 struct ib_send_wr *wr, u32 key)
706{ 709{
707 wr->send_flags = MLX5_IB_SEND_UMR_UNREG; 710 struct mlx5_umr_wr *umrwr = (struct mlx5_umr_wr *)&wr->wr.fast_reg;
711
712 wr->send_flags = MLX5_IB_SEND_UMR_UNREG | MLX5_IB_SEND_UMR_FAIL_IF_FREE;
708 wr->opcode = MLX5_IB_WR_UMR; 713 wr->opcode = MLX5_IB_WR_UMR;
709 wr->wr.fast_reg.rkey = key; 714 umrwr->mkey = key;
710} 715}
711 716
712void mlx5_umr_cq_handler(struct ib_cq *cq, void *cq_context) 717void mlx5_umr_cq_handler(struct ib_cq *cq, void *cq_context)
@@ -1031,7 +1036,7 @@ struct ib_mr *mlx5_ib_create_mr(struct ib_pd *pd,
1031 goto err_free; 1036 goto err_free;
1032 } 1037 }
1033 1038
1034 in->seg.status = 1 << 6; /* free */ 1039 in->seg.status = MLX5_MKEY_STATUS_FREE;
1035 in->seg.xlt_oct_size = cpu_to_be32(ndescs); 1040 in->seg.xlt_oct_size = cpu_to_be32(ndescs);
1036 in->seg.qpn_mkey7_0 = cpu_to_be32(0xffffff << 8); 1041 in->seg.qpn_mkey7_0 = cpu_to_be32(0xffffff << 8);
1037 in->seg.flags_pd = cpu_to_be32(to_mpd(pd)->pdn); 1042 in->seg.flags_pd = cpu_to_be32(to_mpd(pd)->pdn);
@@ -1146,7 +1151,7 @@ struct ib_mr *mlx5_ib_alloc_fast_reg_mr(struct ib_pd *pd,
1146 goto err_free; 1151 goto err_free;
1147 } 1152 }
1148 1153
1149 in->seg.status = 1 << 6; /* free */ 1154 in->seg.status = MLX5_MKEY_STATUS_FREE;
1150 in->seg.xlt_oct_size = cpu_to_be32((max_page_list_len + 1) / 2); 1155 in->seg.xlt_oct_size = cpu_to_be32((max_page_list_len + 1) / 2);
1151 in->seg.qpn_mkey7_0 = cpu_to_be32(0xffffff << 8); 1156 in->seg.qpn_mkey7_0 = cpu_to_be32(0xffffff << 8);
1152 in->seg.flags = MLX5_PERM_UMR_EN | MLX5_ACCESS_MODE_MTT; 1157 in->seg.flags = MLX5_PERM_UMR_EN | MLX5_ACCESS_MODE_MTT;
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index 1cae1c7132b4..36e2cfe1c2fe 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -70,15 +70,6 @@ static const u32 mlx5_ib_opcode[] = {
70 [MLX5_IB_WR_UMR] = MLX5_OPCODE_UMR, 70 [MLX5_IB_WR_UMR] = MLX5_OPCODE_UMR,
71}; 71};
72 72
73struct umr_wr {
74 u64 virt_addr;
75 struct ib_pd *pd;
76 unsigned int page_shift;
77 unsigned int npages;
78 u32 length;
79 int access_flags;
80 u32 mkey;
81};
82 73
83static int is_qp0(enum ib_qp_type qp_type) 74static int is_qp0(enum ib_qp_type qp_type)
84{ 75{
@@ -1848,37 +1839,70 @@ static void set_frwr_umr_segment(struct mlx5_wqe_umr_ctrl_seg *umr,
1848 umr->mkey_mask = frwr_mkey_mask(); 1839 umr->mkey_mask = frwr_mkey_mask();
1849} 1840}
1850 1841
1842static __be64 get_umr_reg_mr_mask(void)
1843{
1844 u64 result;
1845
1846 result = MLX5_MKEY_MASK_LEN |
1847 MLX5_MKEY_MASK_PAGE_SIZE |
1848 MLX5_MKEY_MASK_START_ADDR |
1849 MLX5_MKEY_MASK_PD |
1850 MLX5_MKEY_MASK_LR |
1851 MLX5_MKEY_MASK_LW |
1852 MLX5_MKEY_MASK_KEY |
1853 MLX5_MKEY_MASK_RR |
1854 MLX5_MKEY_MASK_RW |
1855 MLX5_MKEY_MASK_A |
1856 MLX5_MKEY_MASK_FREE;
1857
1858 return cpu_to_be64(result);
1859}
1860
1861static __be64 get_umr_unreg_mr_mask(void)
1862{
1863 u64 result;
1864
1865 result = MLX5_MKEY_MASK_FREE;
1866
1867 return cpu_to_be64(result);
1868}
1869
1870static __be64 get_umr_update_mtt_mask(void)
1871{
1872 u64 result;
1873
1874 result = MLX5_MKEY_MASK_FREE;
1875
1876 return cpu_to_be64(result);
1877}
1878
1851static void set_reg_umr_segment(struct mlx5_wqe_umr_ctrl_seg *umr, 1879static void set_reg_umr_segment(struct mlx5_wqe_umr_ctrl_seg *umr,
1852 struct ib_send_wr *wr) 1880 struct ib_send_wr *wr)
1853{ 1881{
1854 struct umr_wr *umrwr = (struct umr_wr *)&wr->wr.fast_reg; 1882 struct mlx5_umr_wr *umrwr = (struct mlx5_umr_wr *)&wr->wr.fast_reg;
1855 u64 mask;
1856 1883
1857 memset(umr, 0, sizeof(*umr)); 1884 memset(umr, 0, sizeof(*umr));
1858 1885
1886 if (wr->send_flags & MLX5_IB_SEND_UMR_FAIL_IF_FREE)
1887 umr->flags = MLX5_UMR_CHECK_FREE; /* fail if free */
1888 else
1889 umr->flags = MLX5_UMR_CHECK_NOT_FREE; /* fail if not free */
1890
1859 if (!(wr->send_flags & MLX5_IB_SEND_UMR_UNREG)) { 1891 if (!(wr->send_flags & MLX5_IB_SEND_UMR_UNREG)) {
1860 umr->flags = 1 << 5; /* fail if not free */
1861 umr->klm_octowords = get_klm_octo(umrwr->npages); 1892 umr->klm_octowords = get_klm_octo(umrwr->npages);
1862 mask = MLX5_MKEY_MASK_LEN | 1893 if (wr->send_flags & MLX5_IB_SEND_UMR_UPDATE_MTT) {
1863 MLX5_MKEY_MASK_PAGE_SIZE | 1894 umr->mkey_mask = get_umr_update_mtt_mask();
1864 MLX5_MKEY_MASK_START_ADDR | 1895 umr->bsf_octowords = get_klm_octo(umrwr->target.offset);
1865 MLX5_MKEY_MASK_PD | 1896 umr->flags |= MLX5_UMR_TRANSLATION_OFFSET_EN;
1866 MLX5_MKEY_MASK_LR | 1897 } else {
1867 MLX5_MKEY_MASK_LW | 1898 umr->mkey_mask = get_umr_reg_mr_mask();
1868 MLX5_MKEY_MASK_KEY | 1899 }
1869 MLX5_MKEY_MASK_RR |
1870 MLX5_MKEY_MASK_RW |
1871 MLX5_MKEY_MASK_A |
1872 MLX5_MKEY_MASK_FREE;
1873 umr->mkey_mask = cpu_to_be64(mask);
1874 } else { 1900 } else {
1875 umr->flags = 2 << 5; /* fail if free */ 1901 umr->mkey_mask = get_umr_unreg_mr_mask();
1876 mask = MLX5_MKEY_MASK_FREE;
1877 umr->mkey_mask = cpu_to_be64(mask);
1878 } 1902 }
1879 1903
1880 if (!wr->num_sge) 1904 if (!wr->num_sge)
1881 umr->flags |= (1 << 7); /* inline */ 1905 umr->flags |= MLX5_UMR_INLINE;
1882} 1906}
1883 1907
1884static u8 get_umr_flags(int acc) 1908static u8 get_umr_flags(int acc)
@@ -1895,7 +1919,7 @@ static void set_mkey_segment(struct mlx5_mkey_seg *seg, struct ib_send_wr *wr,
1895{ 1919{
1896 memset(seg, 0, sizeof(*seg)); 1920 memset(seg, 0, sizeof(*seg));
1897 if (li) { 1921 if (li) {
1898 seg->status = 1 << 6; 1922 seg->status = MLX5_MKEY_STATUS_FREE;
1899 return; 1923 return;
1900 } 1924 }
1901 1925
@@ -1912,19 +1936,23 @@ static void set_mkey_segment(struct mlx5_mkey_seg *seg, struct ib_send_wr *wr,
1912 1936
1913static void set_reg_mkey_segment(struct mlx5_mkey_seg *seg, struct ib_send_wr *wr) 1937static void set_reg_mkey_segment(struct mlx5_mkey_seg *seg, struct ib_send_wr *wr)
1914{ 1938{
1939 struct mlx5_umr_wr *umrwr = (struct mlx5_umr_wr *)&wr->wr.fast_reg;
1940
1915 memset(seg, 0, sizeof(*seg)); 1941 memset(seg, 0, sizeof(*seg));
1916 if (wr->send_flags & MLX5_IB_SEND_UMR_UNREG) { 1942 if (wr->send_flags & MLX5_IB_SEND_UMR_UNREG) {
1917 seg->status = 1 << 6; 1943 seg->status = MLX5_MKEY_STATUS_FREE;
1918 return; 1944 return;
1919 } 1945 }
1920 1946
1921 seg->flags = convert_access(wr->wr.fast_reg.access_flags); 1947 seg->flags = convert_access(umrwr->access_flags);
1922 seg->flags_pd = cpu_to_be32(to_mpd((struct ib_pd *)wr->wr.fast_reg.page_list)->pdn); 1948 if (!(wr->send_flags & MLX5_IB_SEND_UMR_UPDATE_MTT)) {
1923 seg->start_addr = cpu_to_be64(wr->wr.fast_reg.iova_start); 1949 seg->flags_pd = cpu_to_be32(to_mpd(umrwr->pd)->pdn);
1924 seg->len = cpu_to_be64(wr->wr.fast_reg.length); 1950 seg->start_addr = cpu_to_be64(umrwr->target.virt_addr);
1925 seg->log2_page_size = wr->wr.fast_reg.page_shift; 1951 }
1952 seg->len = cpu_to_be64(umrwr->length);
1953 seg->log2_page_size = umrwr->page_shift;
1926 seg->qpn_mkey7_0 = cpu_to_be32(0xffffff00 | 1954 seg->qpn_mkey7_0 = cpu_to_be32(0xffffff00 |
1927 mlx5_mkey_variant(wr->wr.fast_reg.rkey)); 1955 mlx5_mkey_variant(umrwr->mkey));
1928} 1956}
1929 1957
1930static void set_frwr_pages(struct mlx5_wqe_data_seg *dseg, 1958static void set_frwr_pages(struct mlx5_wqe_data_seg *dseg,
diff --git a/include/linux/mlx5/device.h b/include/linux/mlx5/device.h
index ea4f1c46f761..fa07bfda0e15 100644
--- a/include/linux/mlx5/device.h
+++ b/include/linux/mlx5/device.h
@@ -180,6 +180,15 @@ enum {
180 MLX5_MKEY_MASK_FREE = 1ull << 29, 180 MLX5_MKEY_MASK_FREE = 1ull << 29,
181}; 181};
182 182
183enum {
184 MLX5_UMR_TRANSLATION_OFFSET_EN = (1 << 4),
185
186 MLX5_UMR_CHECK_NOT_FREE = (1 << 5),
187 MLX5_UMR_CHECK_FREE = (2 << 5),
188
189 MLX5_UMR_INLINE = (1 << 7),
190};
191
183enum mlx5_event { 192enum mlx5_event {
184 MLX5_EVENT_TYPE_COMP = 0x0, 193 MLX5_EVENT_TYPE_COMP = 0x0,
185 194
@@ -776,6 +785,10 @@ struct mlx5_query_eq_mbox_out {
776 struct mlx5_eq_context ctx; 785 struct mlx5_eq_context ctx;
777}; 786};
778 787
788enum {
789 MLX5_MKEY_STATUS_FREE = 1 << 6,
790};
791
779struct mlx5_mkey_seg { 792struct mlx5_mkey_seg {
780 /* This is a two bit field occupying bits 31-30. 793 /* This is a two bit field occupying bits 31-30.
781 * bit 31 is always 0, 794 * bit 31 is always 0,