aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Cohen <eli@dev.mellanox.co.il>2013-10-23 02:53:19 -0400
committerRoland Dreier <roland@purestorage.com>2013-11-08 17:43:00 -0500
commitbf0bf77f6519e5dcd57a77b47e1d151c1e81b7ec (patch)
tree18f449ec92393cb3f828c9f9c95c25234f807d3a
parent952f5f6e807ba82e1b82fcfcf7f73db022342aa7 (diff)
mlx5: Support communicating arbitrary host page size to firmware
Connect-IB firmware requires 4K pages to be communicated with the driver. This patch breaks larger pages to 4K units to enable support for architectures utilizing larger page size, such as PowerPC. This patch also fixes several places that referred to PAGE_SHIFT instead of explicit 12 which is the inherent page shift on Connect-IB. Signed-off-by: Eli Cohen <eli@mellanox.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
-rw-r--r--drivers/infiniband/hw/mlx5/cq.c2
-rw-r--r--drivers/infiniband/hw/mlx5/qp.c4
-rw-r--r--drivers/infiniband/hw/mlx5/srq.c4
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/eq.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c174
-rw-r--r--include/linux/mlx5/driver.h1
6 files changed, 127 insertions, 60 deletions
diff --git a/drivers/infiniband/hw/mlx5/cq.c b/drivers/infiniband/hw/mlx5/cq.c
index 84591865e39d..eecac7b52bcb 100644
--- a/drivers/infiniband/hw/mlx5/cq.c
+++ b/drivers/infiniband/hw/mlx5/cq.c
@@ -620,7 +620,7 @@ static int create_cq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *cq,
620 } 620 }
621 mlx5_fill_page_array(&cq->buf.buf, (*cqb)->pas); 621 mlx5_fill_page_array(&cq->buf.buf, (*cqb)->pas);
622 622
623 (*cqb)->ctx.log_pg_sz = cq->buf.buf.page_shift - PAGE_SHIFT; 623 (*cqb)->ctx.log_pg_sz = cq->buf.buf.page_shift - 12;
624 *index = dev->mdev.priv.uuari.uars[0].index; 624 *index = dev->mdev.priv.uuari.uars[0].index;
625 625
626 return 0; 626 return 0;
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index 8a36fd78c89f..ce14008a5702 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -551,7 +551,7 @@ static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
551 } 551 }
552 mlx5_ib_populate_pas(dev, qp->umem, page_shift, (*in)->pas, 0); 552 mlx5_ib_populate_pas(dev, qp->umem, page_shift, (*in)->pas, 0);
553 (*in)->ctx.log_pg_sz_remote_qpn = 553 (*in)->ctx.log_pg_sz_remote_qpn =
554 cpu_to_be32((page_shift - PAGE_SHIFT) << 24); 554 cpu_to_be32((page_shift - 12) << 24);
555 (*in)->ctx.params2 = cpu_to_be32(offset << 6); 555 (*in)->ctx.params2 = cpu_to_be32(offset << 6);
556 556
557 (*in)->ctx.qp_counter_set_usr_page = cpu_to_be32(uar_index); 557 (*in)->ctx.qp_counter_set_usr_page = cpu_to_be32(uar_index);
@@ -648,7 +648,7 @@ static int create_kernel_qp(struct mlx5_ib_dev *dev,
648 goto err_buf; 648 goto err_buf;
649 } 649 }
650 (*in)->ctx.qp_counter_set_usr_page = cpu_to_be32(uar_index); 650 (*in)->ctx.qp_counter_set_usr_page = cpu_to_be32(uar_index);
651 (*in)->ctx.log_pg_sz_remote_qpn = cpu_to_be32((qp->buf.page_shift - PAGE_SHIFT) << 24); 651 (*in)->ctx.log_pg_sz_remote_qpn = cpu_to_be32((qp->buf.page_shift - 12) << 24);
652 /* Set "fast registration enabled" for all kernel QPs */ 652 /* Set "fast registration enabled" for all kernel QPs */
653 (*in)->ctx.params1 |= cpu_to_be32(1 << 11); 653 (*in)->ctx.params1 |= cpu_to_be32(1 << 11);
654 (*in)->ctx.sq_crq_size |= cpu_to_be16(1 << 4); 654 (*in)->ctx.sq_crq_size |= cpu_to_be16(1 << 4);
diff --git a/drivers/infiniband/hw/mlx5/srq.c b/drivers/infiniband/hw/mlx5/srq.c
index f1e5845b42b0..dbc2c7188c5e 100644
--- a/drivers/infiniband/hw/mlx5/srq.c
+++ b/drivers/infiniband/hw/mlx5/srq.c
@@ -123,7 +123,7 @@ static int create_srq_user(struct ib_pd *pd, struct mlx5_ib_srq *srq,
123 goto err_in; 123 goto err_in;
124 } 124 }
125 125
126 (*in)->ctx.log_pg_sz = page_shift - PAGE_SHIFT; 126 (*in)->ctx.log_pg_sz = page_shift - 12;
127 (*in)->ctx.pgoff_cqn = cpu_to_be32(offset << 26); 127 (*in)->ctx.pgoff_cqn = cpu_to_be32(offset << 26);
128 128
129 return 0; 129 return 0;
@@ -192,7 +192,7 @@ static int create_srq_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_srq *srq,
192 } 192 }
193 srq->wq_sig = !!srq_signature; 193 srq->wq_sig = !!srq_signature;
194 194
195 (*in)->ctx.log_pg_sz = page_shift - PAGE_SHIFT; 195 (*in)->ctx.log_pg_sz = page_shift - 12;
196 196
197 return 0; 197 return 0;
198 198
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eq.c b/drivers/net/ethernet/mellanox/mlx5/core/eq.c
index 2231d93cc7ad..6b4b436840bd 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eq.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eq.c
@@ -354,7 +354,7 @@ int mlx5_create_map_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq, u8 vecidx,
354 in->hdr.opcode = cpu_to_be16(MLX5_CMD_OP_CREATE_EQ); 354 in->hdr.opcode = cpu_to_be16(MLX5_CMD_OP_CREATE_EQ);
355 in->ctx.log_sz_usr_page = cpu_to_be32(ilog2(eq->nent) << 24 | uar->index); 355 in->ctx.log_sz_usr_page = cpu_to_be32(ilog2(eq->nent) << 24 | uar->index);
356 in->ctx.intr = vecidx; 356 in->ctx.intr = vecidx;
357 in->ctx.log_page_size = PAGE_SHIFT - 12; 357 in->ctx.log_page_size = eq->buf.page_shift - 12;
358 in->events_mask = cpu_to_be64(mask); 358 in->events_mask = cpu_to_be64(mask);
359 359
360 err = mlx5_cmd_exec(dev, in, inlen, &out, sizeof(out)); 360 err = mlx5_cmd_exec(dev, in, inlen, &out, sizeof(out));
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
index a0d0da35578c..013aa422adee 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c
@@ -57,10 +57,13 @@ struct mlx5_pages_req {
57}; 57};
58 58
59struct fw_page { 59struct fw_page {
60 struct rb_node rb_node; 60 struct rb_node rb_node;
61 u64 addr; 61 u64 addr;
62 struct page *page; 62 struct page *page;
63 u16 func_id; 63 u16 func_id;
64 unsigned long bitmask;
65 struct list_head list;
66 unsigned free_count;
64}; 67};
65 68
66struct mlx5_query_pages_inbox { 69struct mlx5_query_pages_inbox {
@@ -94,6 +97,11 @@ enum {
94 MAX_RECLAIM_TIME_MSECS = 5000, 97 MAX_RECLAIM_TIME_MSECS = 5000,
95}; 98};
96 99
100enum {
101 MLX5_MAX_RECLAIM_TIME_MILI = 5000,
102 MLX5_NUM_4K_IN_PAGE = PAGE_SIZE / 4096,
103};
104
97static int insert_page(struct mlx5_core_dev *dev, u64 addr, struct page *page, u16 func_id) 105static int insert_page(struct mlx5_core_dev *dev, u64 addr, struct page *page, u16 func_id)
98{ 106{
99 struct rb_root *root = &dev->priv.page_root; 107 struct rb_root *root = &dev->priv.page_root;
@@ -101,6 +109,7 @@ static int insert_page(struct mlx5_core_dev *dev, u64 addr, struct page *page, u
101 struct rb_node *parent = NULL; 109 struct rb_node *parent = NULL;
102 struct fw_page *nfp; 110 struct fw_page *nfp;
103 struct fw_page *tfp; 111 struct fw_page *tfp;
112 int i;
104 113
105 while (*new) { 114 while (*new) {
106 parent = *new; 115 parent = *new;
@@ -113,25 +122,29 @@ static int insert_page(struct mlx5_core_dev *dev, u64 addr, struct page *page, u
113 return -EEXIST; 122 return -EEXIST;
114 } 123 }
115 124
116 nfp = kmalloc(sizeof(*nfp), GFP_KERNEL); 125 nfp = kzalloc(sizeof(*nfp), GFP_KERNEL);
117 if (!nfp) 126 if (!nfp)
118 return -ENOMEM; 127 return -ENOMEM;
119 128
120 nfp->addr = addr; 129 nfp->addr = addr;
121 nfp->page = page; 130 nfp->page = page;
122 nfp->func_id = func_id; 131 nfp->func_id = func_id;
132 nfp->free_count = MLX5_NUM_4K_IN_PAGE;
133 for (i = 0; i < MLX5_NUM_4K_IN_PAGE; i++)
134 set_bit(i, &nfp->bitmask);
123 135
124 rb_link_node(&nfp->rb_node, parent, new); 136 rb_link_node(&nfp->rb_node, parent, new);
125 rb_insert_color(&nfp->rb_node, root); 137 rb_insert_color(&nfp->rb_node, root);
138 list_add(&nfp->list, &dev->priv.free_list);
126 139
127 return 0; 140 return 0;
128} 141}
129 142
130static struct page *remove_page(struct mlx5_core_dev *dev, u64 addr) 143static struct fw_page *find_fw_page(struct mlx5_core_dev *dev, u64 addr)
131{ 144{
132 struct rb_root *root = &dev->priv.page_root; 145 struct rb_root *root = &dev->priv.page_root;
133 struct rb_node *tmp = root->rb_node; 146 struct rb_node *tmp = root->rb_node;
134 struct page *result = NULL; 147 struct fw_page *result = NULL;
135 struct fw_page *tfp; 148 struct fw_page *tfp;
136 149
137 while (tmp) { 150 while (tmp) {
@@ -141,9 +154,7 @@ static struct page *remove_page(struct mlx5_core_dev *dev, u64 addr)
141 } else if (tfp->addr > addr) { 154 } else if (tfp->addr > addr) {
142 tmp = tmp->rb_right; 155 tmp = tmp->rb_right;
143 } else { 156 } else {