IB/mlx5: Fix binary compatibility with libmlx5
authorEli Cohen <eli@dev.mellanox.co.il>
Thu, 30 Jan 2014 11:49:48 +0000 (13:49 +0200)
committerRoland Dreier <roland@purestorage.com>
Fri, 7 Feb 2014 07:00:48 +0000 (23:00 -0800)
Commit c1be5232d21d ("Fix micro UAR allocator") broke binary compatibility
between libmlx5 and mlx5_ib since it defines a different value to the number
of micro UARs per page, leading to wrong calculation in libmlx5. This patch
defines struct mlx5_ib_alloc_ucontext_req_v2 as an extension to struct
mlx5_ib_alloc_ucontext_req.  The extended size is determined in mlx5_ib_alloc_ucontext()
and in case of old library we use uuarn 0 which works fine -- this is
acheived due to create_user_qp() falling back from high to medium then to
low class where low class will return 0.  For new libraries we use the
more sophisticated allocation algorithm.

Signed-off-by: Eli Cohen <eli@mellanox.com>
Reviewed-by: Yann Droneaud <ydroneaud@opteya.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
drivers/infiniband/hw/mlx5/main.c
drivers/infiniband/hw/mlx5/qp.c
drivers/infiniband/hw/mlx5/user.h
include/linux/mlx5/driver.h

index 9660d093f8cf14cdb686f2b432f6eca96519fb8b..f4ef4a24d410167f4029e252783a0c5dd56c5769 100644 (file)
@@ -536,24 +536,38 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
                                                  struct ib_udata *udata)
 {
        struct mlx5_ib_dev *dev = to_mdev(ibdev);
-       struct mlx5_ib_alloc_ucontext_req req;
+       struct mlx5_ib_alloc_ucontext_req_v2 req;
        struct mlx5_ib_alloc_ucontext_resp resp;
        struct mlx5_ib_ucontext *context;
        struct mlx5_uuar_info *uuari;
        struct mlx5_uar *uars;
        int gross_uuars;
        int num_uars;
+       int ver;
        int uuarn;
        int err;
        int i;
+       int reqlen;
 
        if (!dev->ib_active)
                return ERR_PTR(-EAGAIN);
 
-       err = ib_copy_from_udata(&req, udata, sizeof(req));
+       memset(&req, 0, sizeof(req));
+       reqlen = udata->inlen - sizeof(struct ib_uverbs_cmd_hdr);
+       if (reqlen == sizeof(struct mlx5_ib_alloc_ucontext_req))
+               ver = 0;
+       else if (reqlen == sizeof(struct mlx5_ib_alloc_ucontext_req_v2))
+               ver = 2;
+       else
+               return ERR_PTR(-EINVAL);
+
+       err = ib_copy_from_udata(&req, udata, reqlen);
        if (err)
                return ERR_PTR(err);
 
+       if (req.flags || req.reserved)
+               return ERR_PTR(-EINVAL);
+
        if (req.total_num_uuars > MLX5_MAX_UUARS)
                return ERR_PTR(-ENOMEM);
 
@@ -626,6 +640,7 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
        if (err)
                goto out_uars;
 
+       uuari->ver = ver;
        uuari->num_low_latency_uuars = req.num_low_latency_uuars;
        uuari->uars = uars;
        uuari->num_uars = num_uars;
index 492dc330e907a527021052e62f7df372b9eead33..091576a777e975b827ce9aed2e3bc3f950855993 100644 (file)
@@ -430,11 +430,17 @@ static int alloc_uuar(struct mlx5_uuar_info *uuari,
                break;
 
        case MLX5_IB_LATENCY_CLASS_MEDIUM:
-               uuarn = alloc_med_class_uuar(uuari);
+               if (uuari->ver < 2)
+                       uuarn = -ENOMEM;
+               else
+                       uuarn = alloc_med_class_uuar(uuari);
                break;
 
        case MLX5_IB_LATENCY_CLASS_HIGH:
-               uuarn = alloc_high_class_uuar(uuari);
+               if (uuari->ver < 2)
+                       uuarn = -ENOMEM;
+               else
+                       uuarn = alloc_high_class_uuar(uuari);
                break;
 
        case MLX5_IB_LATENCY_CLASS_FAST_PATH:
index 32a2a5dfc52308549b8e9457da44041936c38d70..0f4f8e42a17fe5f067d68782f21598980451c48f 100644 (file)
@@ -62,6 +62,13 @@ struct mlx5_ib_alloc_ucontext_req {
        __u32   num_low_latency_uuars;
 };
 
+struct mlx5_ib_alloc_ucontext_req_v2 {
+       __u32   total_num_uuars;
+       __u32   num_low_latency_uuars;
+       __u32   flags;
+       __u32   reserved;
+};
+
 struct mlx5_ib_alloc_ucontext_resp {
        __u32   qp_tab_size;
        __u32   bf_reg_size;
index 554548cd3dd4683145ce5ef0a4b1e66fb829365d..32cb18c399c2048692f0c173d8708365ae849455 100644 (file)
@@ -227,6 +227,7 @@ struct mlx5_uuar_info {
         * protect uuar allocation data structs
         */
        struct mutex            lock;
+       u32                     ver;
 };
 
 struct mlx5_bf {