IB/cma: Define option to set ack timeout and pack tos_set
authorDanit Goldberg <danitg@mellanox.com>
Thu, 24 Jan 2019 12:18:15 +0000 (14:18 +0200)
committerJason Gunthorpe <jgg@mellanox.com>
Fri, 8 Feb 2019 23:14:21 +0000 (16:14 -0700)
Define new option in 'rdma_set_option' to override calculated QP timeout
when requested to provide QP attributes to modify a QP.

At the same time, pack tos_set to be bitfield.

Signed-off-by: Danit Goldberg <danitg@mellanox.com>
Reviewed-by: Moni Shoua <monis@mellanox.com>
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
Reviewed-by: Parav Pandit <parav@mellanox.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
drivers/infiniband/core/cma.c
drivers/infiniband/core/cma_priv.h
drivers/infiniband/core/ucma.c
include/rdma/rdma_cm.h
include/uapi/rdma/rdma_user_cm.h

index e15546ae4d0f0c5cfceda9407ab8c2919df866a0..83aa2ad0c27e45c63ead71b8c8e7b88b29f4d818 100644 (file)
@@ -888,6 +888,7 @@ struct rdma_cm_id *__rdma_create_id(struct net *net,
        id_priv->id.ps = ps;
        id_priv->id.qp_type = qp_type;
        id_priv->tos_set = false;
+       id_priv->timeout_set = false;
        id_priv->gid_type = IB_GID_TYPE_IB;
        spin_lock_init(&id_priv->lock);
        mutex_init(&id_priv->qp_mutex);
@@ -1130,6 +1131,9 @@ int rdma_init_qp_attr(struct rdma_cm_id *id, struct ib_qp_attr *qp_attr,
        } else
                ret = -ENOSYS;
 
+       if ((*qp_attr_mask & IB_QP_TIMEOUT) && id_priv->timeout_set)
+               qp_attr->timeout = id_priv->timeout;
+
        return ret;
 }
 EXPORT_SYMBOL(rdma_init_qp_attr);
@@ -2490,6 +2494,34 @@ void rdma_set_service_type(struct rdma_cm_id *id, int tos)
 }
 EXPORT_SYMBOL(rdma_set_service_type);
 
+/**
+ * rdma_set_ack_timeout() - Set the ack timeout of QP associated
+ *                          with a connection identifier.
+ * @id: Communication identifier to associated with service type.
+ * @timeout: Ack timeout to set a QP, expressed as 4.096 * 2^(timeout) usec.
+ *
+ * This function should be called before rdma_connect() on active side,
+ * and on passive side before rdma_accept(). It is applicable to primary
+ * path only. The timeout will affect the local side of the QP, it is not
+ * negotiated with remote side and zero disables the timer.
+ *
+ * Return: 0 for success
+ */
+int rdma_set_ack_timeout(struct rdma_cm_id *id, u8 timeout)
+{
+       struct rdma_id_private *id_priv;
+
+       if (id->qp_type != IB_QPT_RC)
+               return -EINVAL;
+
+       id_priv = container_of(id, struct rdma_id_private, id);
+       id_priv->timeout = timeout;
+       id_priv->timeout_set = true;
+
+       return 0;
+}
+EXPORT_SYMBOL(rdma_set_ack_timeout);
+
 static void cma_query_handler(int status, struct sa_path_rec *path_rec,
                              void *context)
 {
index cf47c69436a76b5ecdf88f3c06400f0e1ed85999..ca7307277518b44ba3cd94512fb18ea378b6618c 100644 (file)
@@ -84,9 +84,11 @@ struct rdma_id_private {
        u32                     options;
        u8                      srq;
        u8                      tos;
-       bool                    tos_set;
+       u8                      tos_set:1;
+       u8                      timeout_set:1;
        u8                      reuseaddr;
        u8                      afonly;
+       u8                      timeout;
        enum ib_gid_type        gid_type;
 
        /*
index 01d68ed46c1b6c530a717a7efd8866dd62dc6506..7468b26b8a01b5ac685ddf1f18230d0ea70201c9 100644 (file)
@@ -1236,6 +1236,13 @@ static int ucma_set_option_id(struct ucma_context *ctx, int optname,
                }
                ret = rdma_set_afonly(ctx->cm_id, *((int *) optval) ? 1 : 0);
                break;
+       case RDMA_OPTION_ID_ACK_TIMEOUT:
+               if (optlen != sizeof(u8)) {
+                       ret = -EINVAL;
+                       break;
+               }
+               ret = rdma_set_ack_timeout(ctx->cm_id, *((u8 *)optval));
+               break;
        default:
                ret = -ENOSYS;
        }
index 60987a5903b786323306b8ee02bd2bb9e040e83f..71f48cfdc24cde951e35565c9198d744ed5f9483 100644 (file)
@@ -374,6 +374,7 @@ int rdma_set_reuseaddr(struct rdma_cm_id *id, int reuse);
  */
 int rdma_set_afonly(struct rdma_cm_id *id, int afonly);
 
+int rdma_set_ack_timeout(struct rdma_cm_id *id, u8 timeout);
  /**
  * rdma_get_service_id - Return the IB service ID for a specified address.
  * @id: Communication identifier associated with the address.
index 0d1e78ebad05154097ffa8b3bfb8708f5c7a0cb3..e42940a215a3058845e3e4971b6b7ea5cdd644e7 100644 (file)
@@ -300,6 +300,10 @@ enum {
        RDMA_OPTION_ID_TOS       = 0,
        RDMA_OPTION_ID_REUSEADDR = 1,
        RDMA_OPTION_ID_AFONLY    = 2,
+       RDMA_OPTION_ID_ACK_TIMEOUT = 3
+};
+
+enum {
        RDMA_OPTION_IB_PATH      = 1
 };