Enable user-space to inject an event into a CM through it's event channel. Two new events are added and supported: RDMA_CM_EVENT_USER and RDMA_CM_EVENT_INTERNAL. With these 2 events a new event parameter "arg" is supported, which is passed from sender to receiver transparently. With this feature an application is able to write an event into a CM channel with a new user-space rdmacm API. For example thread T1 could write an event with the API: rdma_write_cm_event(cm_id, RDMA_CM_EVENT_USER, status, arg); and thread T2 could receive the event with rdma_get_cm_event().
Unified · Split
| @@ -1745,6 +1745,55 @@ err_unlock: · 1744 unmodified lines | |||
| 1745 | return ret; | 1745 | return ret; |
| 1746 | } | 1746 | } |
| 1747 | 1747 | ||
| 1748 | static ssize_t ucma_write_cm_event(struct ucma_file *file, | ||
| 1749 | const char __user *inbuf, int in_len, | ||
| 1750 | int out_len) | ||
| 1751 | { | ||
| 1752 | struct rdma_ucm_write_cm_event cmd; | ||
| 1753 | struct rdma_cm_event event = {}; | ||
| 1754 | struct ucma_event *uevent; | ||
| 1755 | struct ucma_context *ctx; | ||
| 1756 | int ret = 0; | ||
| 1757 | |||
| 1758 | if (copy_from_user(&cmd, inbuf, sizeof(cmd))) | ||
| 1759 | return -EFAULT; | ||
| 1760 | |||
| 1761 | if ((cmd.event != RDMA_CM_EVENT_USER) && | ||
| 1762 | (cmd.event != RDMA_CM_EVENT_INTERNAL)) | ||
| 1763 | return -EINVAL; | ||
| 1764 | |||
| 1765 | ctx = ucma_get_ctx(file, cmd.id); | ||
| 1766 | if (IS_ERR(ctx)) | ||
| 1767 | return PTR_ERR(ctx); | ||
| 1768 | |||
| 1769 | event.event = cmd.event; | ||
| 1770 | event.status = cmd.status; | ||
| 1771 | event.param.arg = cmd.param.arg; | ||
| 1772 | |||
| 1773 | uevent = kzalloc(sizeof(*uevent), GFP_KERNEL); | ||
| 1774 | if (!uevent) { | ||
| 1775 | ret = -ENOMEM; | ||
| 1776 | goto out; | ||
| 1777 | } | ||
| 1778 | |||
| 1779 | uevent->ctx = ctx; | ||
| 1780 | uevent->resp.uid = ctx->uid; | ||
| 1781 | uevent->resp.id = ctx->id; | ||
| 1782 | uevent->resp.event = event.event; | ||
| 1783 | uevent->resp.status = event.status; | ||
| 1784 | memcpy(uevent->resp.param.arg32, &event.param.arg, | ||
| 1785 | sizeof(event.param.arg)); | ||
| 1786 | |||
| 1787 | mutex_lock(&ctx->file->mut); | ||
| 1788 | list_add_tail(&uevent->list, &ctx->file->event_list); | ||
| 1789 | mutex_unlock(&ctx->file->mut); | ||
| 1790 | wake_up_interruptible(&ctx->file->poll_wait); | ||
| 1791 | |||
| 1792 | out: | ||
| 1793 | ucma_put_ctx(ctx); | ||
| 1794 | return ret; | ||
| 1795 | } | ||
| 1796 | |||
| 1748 | static ssize_t (*ucma_cmd_table[])(struct ucma_file *file, | 1797 | static ssize_t (*ucma_cmd_table[])(struct ucma_file *file, |
| 1749 | const char __user *inbuf, | 1798 | const char __user *inbuf, |
| 1750 | int in_len, int out_len) = { | 1799 | int in_len, int out_len) = { |
| @@ -1771,7 +1820,8 @@ static ssize_t (*ucma_cmd_table[])(struct ucma_file *file, · 20 unmodified lines | |||
| 1771 | [RDMA_USER_CM_CMD_BIND] = ucma_bind, | 1820 | [RDMA_USER_CM_CMD_BIND] = ucma_bind, |
| 1772 | [RDMA_USER_CM_CMD_RESOLVE_ADDR] = ucma_resolve_addr, | 1821 | [RDMA_USER_CM_CMD_RESOLVE_ADDR] = ucma_resolve_addr, |
| 1773 | [RDMA_USER_CM_CMD_JOIN_MCAST] = ucma_join_multicast, | 1822 | [RDMA_USER_CM_CMD_JOIN_MCAST] = ucma_join_multicast, |
| 1774 | [RDMA_USER_CM_CMD_RESOLVE_IB_SERVICE] = ucma_resolve_ib_service | 1823 | [RDMA_USER_CM_CMD_RESOLVE_IB_SERVICE] = ucma_resolve_ib_service, |
| 1824 | [RDMA_USER_CM_CMD_WRITE_CM_EVENT] = ucma_write_cm_event, | ||
| 1775 | }; | 1825 | }; |
| 1776 | 1826 | ||
| 1777 | static ssize_t ucma_write(struct file *filp, const char __user *buf, | 1827 | static ssize_t ucma_write(struct file *filp, const char __user *buf, |
| @@ -35,7 +35,9 @@ enum rdma_cm_event_type { · 34 unmodified lines | |||
| 35 | RDMA_CM_EVENT_ADDR_CHANGE, | 35 | RDMA_CM_EVENT_ADDR_CHANGE, |
| 36 | RDMA_CM_EVENT_TIMEWAIT_EXIT, | 36 | RDMA_CM_EVENT_TIMEWAIT_EXIT, |
| 37 | RDMA_CM_EVENT_ADDRINFO_RESOLVED, | 37 | RDMA_CM_EVENT_ADDRINFO_RESOLVED, |
| 38 | RDMA_CM_EVENT_ADDRINFO_ERROR | 38 | RDMA_CM_EVENT_ADDRINFO_ERROR, |
| 39 | RDMA_CM_EVENT_USER, | ||
| 40 | RDMA_CM_EVENT_INTERNAL, | ||
| 39 | }; | 41 | }; |
| 40 | 42 | ||
| 41 | const char *__attribute_const__ rdma_event_msg(enum rdma_cm_event_type event); | 43 | const char *__attribute_const__ rdma_event_msg(enum rdma_cm_event_type event); |
| @@ -98,6 +100,7 @@ struct rdma_cm_event { · 56 unmodified lines | |||
| 98 | union { | 100 | union { |
| 99 | struct rdma_conn_param conn; | 101 | struct rdma_conn_param conn; |
| 100 | struct rdma_ud_param ud; | 102 | struct rdma_ud_param ud; |
| 103 | u64 arg; | ||
| 101 | } param; | 104 | } param; |
| 102 | struct rdma_ucm_ece ece; | 105 | struct rdma_ucm_ece ece; |
| 103 | }; | 106 | }; |
| @@ -68,7 +68,8 @@ enum { · 67 unmodified lines | |||
| 68 | RDMA_USER_CM_CMD_BIND, | 68 | RDMA_USER_CM_CMD_BIND, |
| 69 | RDMA_USER_CM_CMD_RESOLVE_ADDR, | 69 | RDMA_USER_CM_CMD_RESOLVE_ADDR, |
| 70 | RDMA_USER_CM_CMD_JOIN_MCAST, | 70 | RDMA_USER_CM_CMD_JOIN_MCAST, |
| 71 | RDMA_USER_CM_CMD_RESOLVE_IB_SERVICE | 71 | RDMA_USER_CM_CMD_RESOLVE_IB_SERVICE, |
| 72 | RDMA_USER_CM_CMD_WRITE_CM_EVENT, | ||
| 72 | }; | 73 | }; |
| 73 | 74 | ||
| 74 | /* See IBTA Annex A11, servies ID bytes 4 & 5 */ | 75 | /* See IBTA Annex A11, servies ID bytes 4 & 5 */ |
| @@ -304,6 +305,7 @@ struct rdma_ucm_event_resp { · 229 unmodified lines | |||
| 304 | union { | 305 | union { |
| 305 | struct rdma_ucm_conn_param conn; | 306 | struct rdma_ucm_conn_param conn; |
| 306 | struct rdma_ucm_ud_param ud; | 307 | struct rdma_ucm_ud_param ud; |
| 308 | __u32 arg32[2]; | ||
| 307 | } param; | 309 | } param; |
| 308 | __u32 reserved; | 310 | __u32 reserved; |
| 309 | struct rdma_ucm_ece ece; | 311 | struct rdma_ucm_ece ece; |
| @@ -362,4 +364,16 @@ struct rdma_ucm_resolve_ib_service { · 52 unmodified lines | |||
| 362 | __u32 id; | 364 | __u32 id; |
| 363 | struct rdma_ucm_ib_service ibs; | 365 | struct rdma_ucm_ib_service ibs; |
| 364 | }; | 366 | }; |
| 367 | |||
| 368 | struct rdma_ucm_write_cm_event { | ||
| 369 | __u32 id; | ||
| 370 | __u32 reserved; | ||
| 371 | __u32 event; | ||
| 372 | __u32 status; | ||
| 373 | union { | ||
| 374 | struct rdma_ucm_conn_param conn; | ||
| 375 | struct rdma_ucm_ud_param ud; | ||
| 376 | __u64 arg; | ||
| 377 | } param; | ||
| 378 | }; | ||
| 365 | #endif /* RDMA_USER_CM_H */ | 379 | #endif /* RDMA_USER_CM_H */ |