History

RDMA/ucma: Support write an event into a CM

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().

Mark Zhang committed 1 year ago

Commit a3c9d0f1 parent 810f8743 files · +70 −3Browse files

Unified · Split

3 files
  1. drivers/infiniband/core/ucma.c +51 −1
  2. include/rdma/rdma_cm.h +4 −1
  3. include/uapi/rdma/rdma_user_cm.h +15 −1
drivers/infiniband/core/ucma.c+51−1
@@ -1745,6 +1745,55 @@ err_unlock: · 1744 unmodified lines
1745 return ret;1745 return ret;
1746}1746}
1747 1747
1748static 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
1792out:
1793 ucma_put_ctx(ctx);
1794 return ret;
1795}
1796
1748static ssize_t (*ucma_cmd_table[])(struct ucma_file *file,1797static 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_service1823 [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
1777static ssize_t ucma_write(struct file *filp, const char __user *buf,1827static ssize_t ucma_write(struct file *filp, const char __user *buf,
include/rdma/rdma_cm.h+4−1
@@ -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_ERROR38 RDMA_CM_EVENT_ADDRINFO_ERROR,
39 RDMA_CM_EVENT_USER,
40 RDMA_CM_EVENT_INTERNAL,
39};41};
40 42
41const char *__attribute_const__ rdma_event_msg(enum rdma_cm_event_type event);43const 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};
include/uapi/rdma/rdma_user_cm.h+15−1
@@ -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_SERVICE71 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
368struct 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 */