diff options
| author | Eli Cohen <eli@dev.mellanox.co.il> | 2013-10-23 02:53:19 -0400 |
|---|---|---|
| committer | Roland Dreier <roland@purestorage.com> | 2013-11-08 17:43:00 -0500 |
| commit | bf0bf77f6519e5dcd57a77b47e1d151c1e81b7ec (patch) | |
| tree | 18f449ec92393cb3f828c9f9c95c25234f807d3a | |
| parent | 952f5f6e807ba82e1b82fcfcf7f73db022342aa7 (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.c | 2 | ||||
| -rw-r--r-- | drivers/infiniband/hw/mlx5/qp.c | 4 | ||||
| -rw-r--r-- | drivers/infiniband/hw/mlx5/srq.c | 4 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/eq.c | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c | 174 | ||||
| -rw-r--r-- | include/linux/mlx5/driver.h | 1 |
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 | ||
| 59 | struct fw_page { | 59 | struct 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 | ||
| 66 | struct mlx5_query_pages_inbox { | 69 | struct 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 | ||
| 100 | enum { | ||
| 101 | MLX5_MAX_RECLAIM_TIME_MILI = 5000, | ||
| 102 | MLX5_NUM_4K_IN_PAGE = PAGE_SIZE / 4096, | ||
| 103 | }; | ||
| 104 | |||
| 97 | static int insert_page(struct mlx5_core_dev *dev, u64 addr, struct page *page, u16 func_id) | 105 | static 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 | ||
| 130 | static struct page *remove_page(struct mlx5_core_dev *dev, u64 addr) | 143 | static 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 { |
