[openib-general] [PATCH 2/3] ucma: add kernel support for get/set options
Sean Hefty
sean.hefty at intel.com
Thu May 4 16:13:45 PDT 2006
Add kernel support for retrieving and setting options on an rdma_cm_id.
This provides functionality conceptually similar to getsockopt/getsockopt.
Add an option to retrieve possible routes (path records) for a connection.
A client may use this to select a path that a connection will use when
being established.
Signed-off-by: Sean Hefty <sean.hefty at intel.com>
---
Index: core/ucma.c
===================================================================
--- core/ucma.c (revision 6884)
+++ core/ucma.c (working copy)
@@ -41,6 +41,8 @@
#include <rdma/ib_marshall.h>
#include <rdma/rdma_cm.h>
+#include "ucma_ib.h"
+
MODULE_AUTHOR("Sean Hefty");
MODULE_DESCRIPTION("RDMA Userspace Connection Manager Access");
MODULE_LICENSE("Dual BSD/GPL");
@@ -656,6 +658,83 @@ out:
return ret;
}
+static ssize_t ucma_get_option(struct ucma_file *file, const char __user *inbuf,
+ int in_len, int out_len)
+{
+ struct rdma_ucm_get_option cmd;
+ struct rdma_ucm_get_option_resp resp;
+ struct ucma_context *ctx;
+ int ret;
+
+ if (out_len < sizeof(resp))
+ return -ENOSPC;
+
+ if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+ return -EFAULT;
+
+ ctx = ucma_get_ctx(file, cmd.id);
+ if (IS_ERR(ctx))
+ return PTR_ERR(ctx);
+
+ resp.optlen = cmd.optlen;
+
+ switch (cmd.level) {
+ case RDMA_PROTO_IP:
+ ret = -ENOSYS;
+ break;
+ case RDMA_PROTO_IB:
+ ret = ucma_get_ib_option(ctx->cm_id, cmd.optname,
+ (void *) (unsigned long) cmd.optval,
+ &resp.optlen);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ if (ret)
+ goto out;
+
+ if (copy_to_user((void __user *)(unsigned long)cmd.response,
+ &resp, sizeof(resp)))
+ ret = -EFAULT;
+out:
+ ucma_put_ctx(ctx);
+ return ret;
+}
+
+static ssize_t ucma_set_option(struct ucma_file *file, const char __user *inbuf,
+ int in_len, int out_len)
+{
+ struct rdma_ucm_set_option cmd;
+ struct ucma_context *ctx;
+ int ret;
+
+ if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
+ return -EFAULT;
+
+ ctx = ucma_get_ctx(file, cmd.id);
+ if (IS_ERR(ctx))
+ return PTR_ERR(ctx);
+
+ switch (cmd.level) {
+ case RDMA_PROTO_IP:
+ ret = -ENOSYS;
+ break;
+ case RDMA_PROTO_IB:
+ ret = ucma_set_ib_option(ctx->cm_id, cmd.optname,
+ (void *) (unsigned long) cmd.optval,
+ cmd.optlen);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ ucma_put_ctx(ctx);
+ return ret;
+}
+
static ssize_t (*ucma_cmd_table[])(struct ucma_file *file,
const char __user *inbuf,
int in_len, int out_len) = {
@@ -671,7 +750,9 @@ static ssize_t (*ucma_cmd_table[])(struc
[RDMA_USER_CM_CMD_REJECT] = ucma_reject,
[RDMA_USER_CM_CMD_DISCONNECT] = ucma_disconnect,
[RDMA_USER_CM_CMD_INIT_QP_ATTR] = ucma_init_qp_attr,
- [RDMA_USER_CM_CMD_GET_EVENT] = ucma_get_event
+ [RDMA_USER_CM_CMD_GET_EVENT] = ucma_get_event,
+ [RDMA_USER_CM_CMD_GET_OPTION] = ucma_get_option,
+ [RDMA_USER_CM_CMD_SET_OPTION] = ucma_set_option
};
static ssize_t ucma_write(struct file *filp, const char __user *buf,
Index: core/ucma_ib.c
===================================================================
--- core/ucma_ib.c (revision 0)
+++ core/ucma_ib.c (revision 0)
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2006 Intel Corporation. All rights reserved.
+ *
+ * This Software is licensed under one of the following licenses:
+ *
+ * 1) under the terms of the "Common Public License 1.0" a copy of which is
+ * available from the Open Source Initiative, see
+ * http://www.opensource.org/licenses/cpl.php.
+ *
+ * 2) under the terms of the "The BSD License" a copy of which is
+ * available from the Open Source Initiative, see
+ * http://www.opensource.org/licenses/bsd-license.php.
+ *
+ * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
+ * copy of which is available from the Open Source Initiative, see
+ * http://www.opensource.org/licenses/gpl-license.php.
+ *
+ * Licensee has the right to choose one of the above licenses.
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice and one of the license notices.
+ *
+ * Redistributions in binary form must reproduce both the above copyright
+ * notice, one of the license notices in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ */
+
+#include <rdma/ib_addr.h>
+#include <rdma/ib_local_sa.h>
+#include <rdma/ib_marshall.h>
+#include <rdma/rdma_cm_ib.h>
+#include <rdma/rdma_user_cm.h>
+
+#include "ucma_ib.h"
+
+static int ucma_get_paths(struct rdma_cm_id *id,
+ void __user *paths, size_t *len)
+{
+ struct ib_sa_cursor *cursor;
+ struct ib_sa_path_rec *path;
+ struct ib_user_path_rec user_path;
+ union ib_gid *gid;
+ int left, ret = 0;
+ u16 pkey;
+
+ if (!id->device)
+ return -ENODEV;
+
+ gid = ib_addr_get_dgid(&id->route.addr.dev_addr);
+ pkey = ib_addr_get_pkey(&id->route.addr.dev_addr);
+ cursor = ib_create_path_cursor(id->device, id->port_num, gid);
+ if (IS_ERR(cursor))
+ return PTR_ERR(cursor);
+
+ gid = ib_addr_get_sgid(&id->route.addr.dev_addr);
+ left = *len;
+ *len = 0;
+
+ for (path = ib_get_next_sa_attr(&cursor); path;
+ path = ib_get_next_sa_attr(&cursor)) {
+ if (pkey == path->pkey &&
+ !memcmp(gid, path->sgid.raw, sizeof *gid)) {
+ if (paths) {
+ ib_copy_path_rec_to_user(&user_path, path);
+ if (copy_to_user(paths, &user_path,
+ sizeof(user_path))) {
+ ret = -EFAULT;
+ break;
+ }
+ left -= sizeof(user_path);
+ if (left < sizeof(user_path))
+ break;
+ paths += sizeof(user_path);
+ }
+ *len += sizeof(user_path);
+ }
+ }
+
+ ib_free_sa_cursor(cursor);
+ return ret;
+}
+
+int ucma_get_ib_option(struct rdma_cm_id *id, int optname,
+ void *optval, size_t *optlen)
+{
+ switch (optname) {
+ case IB_PATH_OPTIONS:
+ return ucma_get_paths(id, optval, optlen);
+ default:
+ return -EINVAL;
+ }
+}
+
+static int ucma_set_paths(struct rdma_cm_id *id,
+ void __user *paths, size_t len)
+{
+ struct ib_sa_path_rec *path_rec;
+ struct ib_user_path_rec *user_path;
+ int ret, num_paths, i;
+
+ if (len == sizeof(*user_path))
+ num_paths = 1;
+ else if (len == (sizeof(*user_path) << 1))
+ num_paths = 2;
+ else
+ return -EINVAL;
+
+ path_rec = kmalloc(sizeof *path_rec * num_paths, GFP_KERNEL);
+ if (!path_rec)
+ return -ENOMEM;
+
+ user_path = kmalloc(sizeof *user_path * num_paths, GFP_KERNEL);
+ if (!user_path) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ if (copy_from_user(user_path, paths, sizeof *user_path * num_paths)) {
+ ret = -EFAULT;
+ goto out2;
+ }
+
+ for (i = 0; i < num_paths; i++)
+ ib_copy_path_rec_from_user(path_rec + i, user_path + i);
+
+ ret = rdma_set_ib_paths(id, path_rec, num_paths);
+out2:
+ kfree(user_path);
+out:
+ kfree(path_rec);
+ return ret;
+}
+
+int ucma_set_ib_option(struct rdma_cm_id *id, int optname,
+ void *optval, size_t optlen)
+{
+ switch (optname) {
+ case IB_PATH_OPTIONS:
+ return ucma_set_paths(id, optval, optlen);
+ default:
+ return -EINVAL;
+ }
+}
Property changes on: core/ucma_ib.c
___________________________________________________________________
Name: svn:executable
+ *
Index: core/ucma_ib.h
===================================================================
--- core/ucma_ib.h (revision 0)
+++ core/ucma_ib.h (revision 0)
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2006 Intel Corporation. All rights reserved.
+ *
+ * This Software is licensed under one of the following licenses:
+ *
+ * 1) under the terms of the "Common Public License 1.0" a copy of which is
+ * available from the Open Source Initiative, see
+ * http://www.opensource.org/licenses/cpl.php.
+ *
+ * 2) under the terms of the "The BSD License" a copy of which is
+ * available from the Open Source Initiative, see
+ * http://www.opensource.org/licenses/bsd-license.php.
+ *
+ * 3) under the terms of the "GNU General Public License (GPL) Version 2" a
+ * copy of which is available from the Open Source Initiative, see
+ * http://www.opensource.org/licenses/gpl-license.php.
+ *
+ * Licensee has the right to choose one of the above licenses.
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice and one of the license notices.
+ *
+ * Redistributions in binary form must reproduce both the above copyright
+ * notice, one of the license notices in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ */
+
+#if !defined(UCMA_IB_H)
+#define UCMA_IB_H
+
+#include <rdma/rdma_cm.h>
+
+int ucma_get_ib_option(struct rdma_cm_id *id, int optname,
+ void *optval, size_t *optlen);
+
+int ucma_set_ib_option(struct rdma_cm_id *id, int optname,
+ void *optval, size_t optlen);
+
+#endif /* UCMA_IB_H */
Property changes on: core/ucma_ib.h
___________________________________________________________________
Name: svn:executable
+ *
Index: core/Makefile
===================================================================
--- core/Makefile (revision 6884)
+++ core/Makefile (working copy)
@@ -22,7 +22,7 @@ ib_cm-y := cm.o
rdma_cm-y := cma.o
-rdma_ucm-y := ucma.o
+rdma_ucm-y := ucma.o ucma_ib.o
ib_addr-y := addr.o
Index: include/rdma/rdma_user_cm.h
===================================================================
--- include/rdma/rdma_user_cm.h (revision 6884)
+++ include/rdma/rdma_user_cm.h (working copy)
@@ -55,7 +55,9 @@ enum {
RDMA_USER_CM_CMD_REJECT,
RDMA_USER_CM_CMD_DISCONNECT,
RDMA_USER_CM_CMD_INIT_QP_ATTR,
- RDMA_USER_CM_CMD_GET_EVENT
+ RDMA_USER_CM_CMD_GET_EVENT,
+ RDMA_USER_CM_CMD_GET_OPTION,
+ RDMA_USER_CM_CMD_SET_OPTION,
};
/*
@@ -183,4 +185,36 @@ struct rdma_ucm_event_resp {
__u8 private_data[RDMA_MAX_PRIVATE_DATA];
};
+struct rdma_ucm_get_option {
+ __u64 response;
+ __u64 optval;
+ __u32 id;
+ __u32 level;
+ __u32 optname;
+ __u32 optlen;
+};
+
+/* Protocol levels for get/set options. */
+enum {
+ RDMA_PROTO_IP = 0,
+ RDMA_PROTO_IB = 1,
+};
+
+/* IB specific option names for get/set. */
+enum {
+ IB_PATH_OPTIONS = 1,
+};
+
+struct rdma_ucm_get_option_resp {
+ __u32 optlen;
+};
+
+struct rdma_ucm_set_option {
+ __u64 optval;
+ __u32 id;
+ __u32 level;
+ __u32 optname;
+ __u32 optlen;
+};
+
#endif /* RDMA_USER_CM_H */
More information about the general
mailing list