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
17451745 return ret;
17461746 }
17471747
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+
17481797 static ssize_t (*ucma_cmd_table[])(struct ucma_file *file,
17491798 const char __user *inbuf,
17501799 int in_len, int out_len) = {
@@ -1771,7 +1820,8 @@ static ssize_t (*ucma_cmd_table[])(struct ucma_file *file, · 20 unmodified lines
17711820 [RDMA_USER_CM_CMD_BIND] = ucma_bind,
17721821 [RDMA_USER_CM_CMD_RESOLVE_ADDR] = ucma_resolve_addr,
17731822 [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,
17751825 };
17761826
17771827 static 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
3535 RDMA_CM_EVENT_ADDR_CHANGE,
3636 RDMA_CM_EVENT_TIMEWAIT_EXIT,
3737 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,
3941 };
4042
4143 const char *__attribute_const__ rdma_event_msg(enum rdma_cm_event_type event);
@@ -98,6 +100,7 @@ struct rdma_cm_event { · 56 unmodified lines
98100 union {
99101 struct rdma_conn_param conn;
100102 struct rdma_ud_param ud;
103+ u64 arg;
101104 } param;
102105 struct rdma_ucm_ece ece;
103106 };
include/uapi/rdma/rdma_user_cm.h+15−1
@@ -68,7 +68,8 @@ enum { · 67 unmodified lines
6868 RDMA_USER_CM_CMD_BIND,
6969 RDMA_USER_CM_CMD_RESOLVE_ADDR,
7070 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,
7273 };
7374
7475 /* See IBTA Annex A11, servies ID bytes 4 & 5 */
@@ -304,6 +305,7 @@ struct rdma_ucm_event_resp { · 229 unmodified lines
304305 union {
305306 struct rdma_ucm_conn_param conn;
306307 struct rdma_ucm_ud_param ud;
308+ __u32 arg32[2];
307309 } param;
308310 __u32 reserved;
309311 struct rdma_ucm_ece ece;
@@ -362,4 +364,16 @@ struct rdma_ucm_resolve_ib_service { · 52 unmodified lines
362364 __u32 id;
363365 struct rdma_ucm_ib_service ibs;
364366 };
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+};
365379 #endif /* RDMA_USER_CM_H */