diff options
| author | Sean Hefty <sean.hefty@intel.com> | 2007-08-08 18:51:13 -0400 |
|---|---|---|
| committer | Roland Dreier <rolandd@cisco.com> | 2007-10-09 22:59:12 -0400 |
| commit | 7ce86409adcd2fda652b628173a66e905950ece1 (patch) | |
| tree | 37ec32b859f358c77267c465a6e04a642d7c5ff3 | |
| parent | a81c994d5eef87ed77cb30d8343d6be296528b3f (diff) | |
RDMA/ucma: Allow user space to set service type
Export the ability to set the type of service to user space. Model
the interface after setsockopt.
Signed-off-by: Sean Hefty <sean.hefty@intel.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
| -rw-r--r-- | drivers/infiniband/core/ucma.c | 74 | ||||
| -rw-r--r-- | include/rdma/rdma_user_cm.h | 18 |
2 files changed, 91 insertions, 1 deletions
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index 53b4c94a7e..90d675ad9e 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c | |||
| @@ -792,6 +792,78 @@ out: | |||
| 792 | return ret; | 792 | return ret; |
| 793 | } | 793 | } |
| 794 | 794 | ||
| 795 | static int ucma_set_option_id(struct ucma_context *ctx, int optname, | ||
| 796 | void *optval, size_t optlen) | ||
| 797 | { | ||
| 798 | int ret = 0; | ||
| 799 | |||
| 800 | switch (optname) { | ||
| 801 | case RDMA_OPTION_ID_TOS: | ||
| 802 | if (optlen != sizeof(u8)) { | ||
| 803 | ret = -EINVAL; | ||
| 804 | break; | ||
| 805 | } | ||
| 806 | rdma_set_service_type(ctx->cm_id, *((u8 *) optval)); | ||
| 807 | break; | ||
| 808 | default: | ||
| 809 | ret = -ENOSYS; | ||
| 810 | } | ||
| 811 | |||
| 812 | return ret; | ||
| 813 | } | ||
| 814 | |||
| 815 | static int ucma_set_option_level(struct ucma_context *ctx, int level, | ||
| 816 | int optname, void *optval, size_t optlen) | ||
| 817 | { | ||
| 818 | int ret; | ||
| 819 | |||
| 820 | switch (level) { | ||
| 821 | case RDMA_OPTION_ID: | ||
| 822 | ret = ucma_set_option_id(ctx, optname, optval, optlen); | ||
| 823 | break; | ||
| 824 | default: | ||
| 825 | ret = -ENOSYS; | ||
| 826 | } | ||
| 827 | |||
| 828 | return ret; | ||
| 829 | } | ||
| 830 | |||
| 831 | static ssize_t ucma_set_option(struct ucma_file *file, const char __user *inbuf, | ||
| 832 | int in_len, int out_len) | ||
| 833 | { | ||
| 834 | struct rdma_ucm_set_option cmd; | ||
| 835 | struct ucma_context *ctx; | ||
| 836 | void *optval; | ||
| 837 | int ret; | ||
| 838 | |||
| 839 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) | ||
| 840 | return -EFAULT; | ||
| 841 | |||
| 842 | ctx = ucma_get_ctx(file, cmd.id); | ||
| 843 | if (IS_ERR(ctx)) | ||
| 844 | return PTR_ERR(ctx); | ||
| 845 | |||
| 846 | optval = kmalloc(cmd.optlen, GFP_KERNEL); | ||
| 847 | if (!optval) { | ||
| 848 | ret = -ENOMEM; | ||
| 849 | goto out1; | ||
| 850 | } | ||
| 851 | |||
| 852 | if (copy_from_user(optval, (void __user *) (unsigned long) cmd.optval, | ||
| 853 | cmd.optlen)) { | ||
| 854 | ret = -EFAULT; | ||
| 855 | goto out2; | ||
| 856 | } | ||
| 857 | |||
| 858 | ret = ucma_set_option_level(ctx, cmd.level, cmd.optname, optval, | ||
| 859 | cmd.optlen); | ||
| 860 | out2: | ||
| 861 | kfree(optval); | ||
| 862 | out1: | ||
| 863 | ucma_put_ctx(ctx); | ||
| 864 | return ret; | ||
| 865 | } | ||
| 866 | |||
| 795 | static ssize_t ucma_notify(struct ucma_file *file, const char __user *inbuf, | 867 | static ssize_t ucma_notify(struct ucma_file *file, const char __user *inbuf, |
| 796 | int in_len, int out_len) | 868 | int in_len, int out_len) |
| 797 | { | 869 | { |
| @@ -936,7 +1008,7 @@ static ssize_t (*ucma_cmd_table[])(struct ucma_file *file, | |||
| 936 | [RDMA_USER_CM_CMD_INIT_QP_ATTR] = ucma_init_qp_attr, | 1008 | [RDMA_USER_CM_CMD_INIT_QP_ATTR] = ucma_init_qp_attr, |
| 937 | [RDMA_USER_CM_CMD_GET_EVENT] = ucma_get_event, | 1009 | [RDMA_USER_CM_CMD_GET_EVENT] = ucma_get_event, |
| 938 | [RDMA_USER_CM_CMD_GET_OPTION] = NULL, | 1010 | [RDMA_USER_CM_CMD_GET_OPTION] = NULL, |
| 939 | [RDMA_USER_CM_CMD_SET_OPTION] = NULL, | 1011 | [RDMA_USER_CM_CMD_SET_OPTION] = ucma_set_option, |
| 940 | [RDMA_USER_CM_CMD_NOTIFY] = ucma_notify, | 1012 | [RDMA_USER_CM_CMD_NOTIFY] = ucma_notify, |
| 941 | [RDMA_USER_CM_CMD_JOIN_MCAST] = ucma_join_multicast, | 1013 | [RDMA_USER_CM_CMD_JOIN_MCAST] = ucma_join_multicast, |
| 942 | [RDMA_USER_CM_CMD_LEAVE_MCAST] = ucma_leave_multicast, | 1014 | [RDMA_USER_CM_CMD_LEAVE_MCAST] = ucma_leave_multicast, |
diff --git a/include/rdma/rdma_user_cm.h b/include/rdma/rdma_user_cm.h index f632b0c007..9749c1b34d 100644 --- a/include/rdma/rdma_user_cm.h +++ b/include/rdma/rdma_user_cm.h | |||
| @@ -212,4 +212,22 @@ struct rdma_ucm_event_resp { | |||
| 212 | } param; | 212 | } param; |
| 213 | }; | 213 | }; |
| 214 | 214 | ||
| 215 | /* Option levels */ | ||
| 216 | enum { | ||
| 217 | RDMA_OPTION_ID = 0 | ||
| 218 | }; | ||
| 219 | |||
| 220 | /* Option details */ | ||
| 221 | enum { | ||
| 222 | RDMA_OPTION_ID_TOS = 0 | ||
| 223 | }; | ||
| 224 | |||
| 225 | struct rdma_ucm_set_option { | ||
| 226 | __u64 optval; | ||
| 227 | __u32 id; | ||
| 228 | __u32 level; | ||
| 229 | __u32 optname; | ||
| 230 | __u32 optlen; | ||
| 231 | }; | ||
| 232 | |||
| 215 | #endif /* RDMA_USER_CM_H */ | 233 | #endif /* RDMA_USER_CM_H */ |
