[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