* [PATCH for-next 0/3] RDMA/efa: Add Completion Actions support
@ 2026-11-09 8:13 Ilia Kolominsky
2026-11-09 8:13 ` [PATCH for-next 1/3] RDMA/efa: Update device interface Ilia Kolominsky
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Ilia Kolominsky @ 2026-11-09 8:13 UTC (permalink / raw)
To: jgg, leon, linux-rdma; +Cc: sleybo, matua, gal.pressman
EFA Completion actions let an application observe work request
completions without polling a completion queue: when a work request
completes, locally or at the remote side, the device performs an action
that the work request names, such as writing a value to a user buffer.
This series adds the control path for memory completion actions:
Patch 1 updates the device interface definitions: the create and
destroy action admin commands, the supported action events mask in the
queue attributes, and the action descriptor and status codes in the
I/O definitions.
Patch 2 maps the admin RESOURCE_BUSY status to EBUSY, which the device
returns when a PD is deallocated while an action still references it.
Patch 3 adds the completion action uverbs object, the QP creation
attributes for the action descriptor block, and the capability, limit
and supported operation reporting through query device.
The user space counterpart (rdma-core efa provider) follows separately.
Ilia Kolominsky (3):
RDMA/efa: Update device interface
RDMA/efa: Report the admin RESOURCE_BUSY status as EBUSY
RDMA/efa: Add Completion Actions support
drivers/infiniband/hw/efa/efa.h | 7 +
.../infiniband/hw/efa/efa_admin_cmds_defs.h | 111 ++++++++-
drivers/infiniband/hw/efa/efa_com.c | 10 +
drivers/infiniband/hw/efa/efa_com_cmd.c | 73 ++++++
drivers/infiniband/hw/efa/efa_com_cmd.h | 31 +++
drivers/infiniband/hw/efa/efa_io_defs.h | 26 +-
drivers/infiniband/hw/efa/efa_verbs.c | 235 +++++++++++++++++-
include/uapi/rdma/efa-abi.h | 56 ++++-
8 files changed, 542 insertions(+), 7 deletions(-)
--
2.47.3
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH for-next 1/3] RDMA/efa: Update device interface
2026-11-09 8:13 [PATCH for-next 0/3] RDMA/efa: Add Completion Actions support Ilia Kolominsky
@ 2026-11-09 8:13 ` Ilia Kolominsky
2026-11-09 8:17 ` sashiko-bot
2026-11-09 8:13 ` [PATCH for-next 2/3] RDMA/efa: Report the admin RESOURCE_BUSY status as EBUSY Ilia Kolominsky
2026-11-09 8:13 ` [PATCH for-next 3/3] RDMA/efa: Add Completion Actions support Ilia Kolominsky
2 siblings, 1 reply; 7+ messages in thread
From: Ilia Kolominsky @ 2026-11-09 8:13 UTC (permalink / raw)
To: jgg, leon, linux-rdma
Cc: sleybo, matua, gal.pressman, Michael Margolin, Yonatan Nachum
Align device interface definitions.
Reviewed-by: Michael Margolin <mrgolin@amazon.com>
Reviewed-by: Yonatan Nachum <ynachum@amazon.com>
Signed-off-by: Ilia Kolominsky <ikolomin@amazon.com>
---
.../infiniband/hw/efa/efa_admin_cmds_defs.h | 111 +++++++++++++++++-
drivers/infiniband/hw/efa/efa_io_defs.h | 26 +++-
2 files changed, 132 insertions(+), 5 deletions(-)
diff --git a/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h b/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h
index 30a38e633..b28ae294a 100644
--- a/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h
+++ b/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h
@@ -29,6 +29,8 @@ enum efa_admin_aq_opcode {
EFA_ADMIN_DESTROY_EQ = 19,
EFA_ADMIN_ALLOC_MR = 20,
EFA_ADMIN_SERVICE = 21,
+ EFA_ADMIN_CREATE_ACTION = 22,
+ EFA_ADMIN_DESTROY_ACTION = 23,
EFA_ADMIN_CREATE_EVENT_COUNTER = 25,
EFA_ADMIN_DESTROY_EVENT_COUNTER = 26,
EFA_ADMIN_ATTACH_EVENT_COUNTER = 27,
@@ -162,8 +164,20 @@ struct efa_admin_create_qp_cmd {
/* MBZ */
u8 reserved;
+ /*
+ * Enablement bitmap for WQE configurable feature blocks
+ * 0 : action_with_data - If set, action with data
+ * block is used - offset in the WQE is provided by
+ * action_with_data_wqe_offset
+ * 15:1 : reserved - MBZ
+ */
+ u16 wqe_blocks_enablement;
+
+ /* Offset in SQ WQE to action w/ data descriptor */
+ u8 action_with_data_wqe_offset;
+
/* MBZ */
- u32 reserved2;
+ u8 reserved2;
} __packed;
struct efa_admin_create_qp_resp {
@@ -701,7 +715,8 @@ struct efa_admin_feature_device_attr_desc {
* 9:6 : reserved1 - MBZ
* 10 : sq_64_bit_req_id - If set, SQ can use 64-bit
* work request ids
- * 31:11 : reserved2 - MBZ
+ * 11 : actions - If set, actions are supported
+ * 31:12 : reserved2 - MBZ
*/
u32 device_caps;
@@ -792,7 +807,10 @@ struct efa_admin_feature_queue_attr_desc_2 {
u16 inline_buf_size_ex;
/* MBZ */
- u8 reserved[6];
+ u8 reserved[2];
+
+ /* Maximum number of actions supported per device */
+ u32 max_actions;
/*
* Supported counter QP events
@@ -818,6 +836,27 @@ struct efa_admin_feature_queue_attr_desc_2 {
* this value
*/
u64 event_counter_max_val;
+
+ /*
+ * Bitmask indicating which completion events can trigger actions
+ * 0 : action_send_comp - Send completion
+ * 1 : action_recv_comp - Receive completion
+ * 2 : action_read_comp - RDMA read initiator
+ * completion
+ * 3 : action_remote_read_comp - RDMA read target
+ * (responder) completion
+ * 4 : action_write_comp - RDMA write initiator
+ * completion (w/ or w/o immediate)
+ * 5 : action_remote_write_comp - RDMA write target
+ * completion
+ * 6 : action_remote_write_imm_comp - RDMA write with
+ * immediate target completion
+ * 31:7 : reserved - MBZ
+ */
+ u32 supported_action_events;
+
+ /* MBZ */
+ u32 reserved2;
};
struct efa_admin_event_queue_attr_desc {
@@ -1086,6 +1125,62 @@ struct efa_admin_service_resp {
u8 buffer[56];
};
+enum efa_admin_action_type {
+ /* Memset action - write a value to a target memory location */
+ EFA_ADMIN_ACTION_TYPE_MEMSET = 0,
+};
+
+/* Memset action attributes */
+struct efa_admin_action_memset_attr {
+ /* Target physical address. */
+ u64 paddr;
+
+ /* Size of the memory range in bytes. */
+ u32 length;
+
+ /* Size of memset in bytes. Only 1, 2 or 4 are accepted */
+ u8 write_size;
+
+ /* MBZ */
+ u8 flags;
+
+ /* MBZ */
+ u16 reserved;
+};
+
+/* Create Action command parameters. */
+struct efa_admin_create_action_cmd {
+ /* Action type, defined in enum efa_admin_action_type */
+ u16 type;
+
+ /* Protection Domain associated with this action */
+ u16 pd;
+
+ union {
+ struct efa_admin_action_memset_attr memset;
+ } action_data;
+} __packed;
+
+struct efa_admin_create_action_resp {
+ /* Common Admin Queue completion descriptor */
+ struct efa_admin_acq_common_desc acq_common_desc;
+
+ /* Opaque handle to be used for consequent admin operation */
+ u32 action_handle;
+
+ /* Action id to be used in work requests */
+ u32 action_id;
+};
+
+struct efa_admin_destroy_action_cmd {
+ u32 action_handle;
+} __packed;
+
+struct efa_admin_destroy_action_resp {
+ /* Common Admin Queue completion descriptor */
+ struct efa_admin_acq_common_desc acq_common_desc;
+};
+
/* Create Counter command */
struct efa_admin_create_event_counter_cmd {
/* UAR number */
@@ -1191,8 +1286,8 @@ struct efa_admin_modify_event_counter_resp {
#define EFA_ADMIN_CREATE_QP_CMD_SQ_VIRT_MASK BIT(0)
#define EFA_ADMIN_CREATE_QP_CMD_RQ_VIRT_MASK BIT(1)
#define EFA_ADMIN_CREATE_QP_CMD_UNSOLICITED_WRITE_RECV_MASK BIT(2)
-#define EFA_ADMIN_CREATE_QP_CMD_SQ_64_BIT_REQ_ID_SHIFT 3
#define EFA_ADMIN_CREATE_QP_CMD_SQ_64_BIT_REQ_ID_MASK BIT(3)
+#define EFA_ADMIN_CREATE_QP_CMD_ACTION_WITH_DATA_MASK BIT(0)
/* modify_qp_cmd */
#define EFA_ADMIN_MODIFY_QP_CMD_QP_STATE_MASK BIT(0)
@@ -1234,6 +1329,7 @@ struct efa_admin_modify_event_counter_resp {
#define EFA_ADMIN_FEATURE_DEVICE_ATTR_DESC_UNSOLICITED_WRITE_RECV_MASK BIT(4)
#define EFA_ADMIN_FEATURE_DEVICE_ATTR_DESC_EVENT_COUNTERS_MASK BIT(5)
#define EFA_ADMIN_FEATURE_DEVICE_ATTR_DESC_SQ_64_BIT_REQ_ID_MASK BIT(10)
+#define EFA_ADMIN_FEATURE_DEVICE_ATTR_DESC_ACTIONS_MASK BIT(11)
/* feature_queue_attr_desc_2 */
#define EFA_ADMIN_FEATURE_QUEUE_ATTR_DESC_2_SEND_COMP_MASK BIT(0)
@@ -1246,6 +1342,13 @@ struct efa_admin_modify_event_counter_resp {
#define EFA_ADMIN_FEATURE_QUEUE_ATTR_DESC_2_WRITE_COMP_ERR_MASK BIT(7)
#define EFA_ADMIN_FEATURE_QUEUE_ATTR_DESC_2_REMOTE_READ_COMP_MASK BIT(8)
#define EFA_ADMIN_FEATURE_QUEUE_ATTR_DESC_2_REMOTE_WRITE_COMP_MASK BIT(9)
+#define EFA_ADMIN_FEATURE_QUEUE_ATTR_DESC_2_ACTION_SEND_COMP_MASK BIT(0)
+#define EFA_ADMIN_FEATURE_QUEUE_ATTR_DESC_2_ACTION_RECV_COMP_MASK BIT(1)
+#define EFA_ADMIN_FEATURE_QUEUE_ATTR_DESC_2_ACTION_READ_COMP_MASK BIT(2)
+#define EFA_ADMIN_FEATURE_QUEUE_ATTR_DESC_2_ACTION_REMOTE_READ_COMP_MASK BIT(3)
+#define EFA_ADMIN_FEATURE_QUEUE_ATTR_DESC_2_ACTION_WRITE_COMP_MASK BIT(4)
+#define EFA_ADMIN_FEATURE_QUEUE_ATTR_DESC_2_ACTION_REMOTE_WRITE_COMP_MASK BIT(5)
+#define EFA_ADMIN_FEATURE_QUEUE_ATTR_DESC_2_ACTION_REMOTE_WRITE_IMM_COMP_MASK BIT(6)
/* create_eq_cmd */
#define EFA_ADMIN_CREATE_EQ_CMD_ENTRY_SIZE_WORDS_MASK GENMASK(4, 0)
diff --git a/drivers/infiniband/hw/efa/efa_io_defs.h b/drivers/infiniband/hw/efa/efa_io_defs.h
index 1444552de..fb2afe7aa 100644
--- a/drivers/infiniband/hw/efa/efa_io_defs.h
+++ b/drivers/infiniband/hw/efa/efa_io_defs.h
@@ -65,6 +65,10 @@ enum efa_io_comp_status {
EFA_IO_COMP_STATUS_REMOTE_ERROR_UNKNOWN_PEER = 14,
/* Unreachable remote - never received a response */
EFA_IO_COMP_STATUS_LOCAL_ERROR_UNREACH_REMOTE = 15,
+ /* Local action not valid */
+ EFA_IO_COMP_STATUS_LOCAL_ERROR_INVALID_ACTION = 16,
+ /* No valid action at remote side */
+ EFA_IO_COMP_STATUS_REMOTE_ERROR_INVALID_ACTION = 17,
/* Remote feature mismatch */
EFA_IO_COMP_STATUS_REMOTE_ERROR_FEATURE_MISMATCH = 18,
};
@@ -83,6 +87,20 @@ struct efa_io_req_id_ex {
u16 w[3];
};
+/*
+ * Action descriptor, placed in WQE inline space. Holds local and remote
+ * action handles and data. One entry per local and remote action.
+ */
+struct efa_io_action_with_data_block {
+ u32 local_action_handle;
+
+ u32 remote_action_handle;
+
+ u64 local_action_data;
+
+ u64 remote_action_data;
+};
+
struct efa_io_tx_meta_desc {
/* Verbs-generated Request ID */
u16 req_id;
@@ -112,7 +130,11 @@ struct efa_io_tx_meta_desc {
* 4 : comp_req - Indicates whether completion should
* be posted, after packet is transmitted. Valid only
* for the first descriptor
- * 7:5 : reserved29 - MBZ
+ * 5 : reserved29 - MBZ
+ * 6 : local_action_req - Indicates local action
+ * should be triggered post local WR completion.
+ * 7 : remote_action_req - Indicates remote action
+ * should be triggered post remote completion.
*/
u8 ctrl2;
@@ -388,6 +410,8 @@ struct efa_io_rx_cdesc_ex {
#define EFA_IO_TX_META_DESC_FIRST_MASK BIT(2)
#define EFA_IO_TX_META_DESC_LAST_MASK BIT(3)
#define EFA_IO_TX_META_DESC_COMP_REQ_MASK BIT(4)
+#define EFA_IO_TX_META_DESC_LOCAL_ACTION_REQ_MASK BIT(6)
+#define EFA_IO_TX_META_DESC_REMOTE_ACTION_REQ_MASK BIT(7)
#define EFA_IO_TX_META_DESC_PROCESSING_HINTS_MASK GENMASK(1, 0)
/* tx_buf_desc */
--
2.47.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH for-next 2/3] RDMA/efa: Report the admin RESOURCE_BUSY status as EBUSY
2026-11-09 8:13 [PATCH for-next 0/3] RDMA/efa: Add Completion Actions support Ilia Kolominsky
2026-11-09 8:13 ` [PATCH for-next 1/3] RDMA/efa: Update device interface Ilia Kolominsky
@ 2026-11-09 8:13 ` Ilia Kolominsky
2026-11-09 8:19 ` sashiko-bot
2026-11-09 8:13 ` [PATCH for-next 3/3] RDMA/efa: Add Completion Actions support Ilia Kolominsky
2 siblings, 1 reply; 7+ messages in thread
From: Ilia Kolominsky @ 2026-11-09 8:13 UTC (permalink / raw)
To: jgg, leon, linux-rdma
Cc: sleybo, matua, gal.pressman, Michael Margolin, Yonatan Nachum
The device completes a command with RESOURCE_BUSY when the object it
targets is still in use, for example a destroy of an object that other
objects still reference. Map that status to EBUSY instead of the generic
EINVAL so that callers can tell the two apart.
Reviewed-by: Michael Margolin <mrgolin@amazon.com>
Reviewed-by: Yonatan Nachum <ynachum@amazon.com>
Signed-off-by: Ilia Kolominsky <ikolomin@amazon.com>
---
drivers/infiniband/hw/efa/efa_com.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/infiniband/hw/efa/efa_com.c b/drivers/infiniband/hw/efa/efa_com.c
index 9c59d127e..e8045b43f 100644
--- a/drivers/infiniband/hw/efa/efa_com.c
+++ b/drivers/infiniband/hw/efa/efa_com.c
@@ -584,6 +584,8 @@ static int efa_com_comp_status_to_errno(u8 comp_status)
case EFA_ADMIN_ILLEGAL_PARAMETER:
case EFA_ADMIN_UNKNOWN_ERROR:
return -EINVAL;
+ case EFA_ADMIN_RESOURCE_BUSY:
+ return -EBUSY;
default:
return -EINVAL;
}
--
2.47.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH for-next 3/3] RDMA/efa: Add Completion Actions support
2026-11-09 8:13 [PATCH for-next 0/3] RDMA/efa: Add Completion Actions support Ilia Kolominsky
2026-11-09 8:13 ` [PATCH for-next 1/3] RDMA/efa: Update device interface Ilia Kolominsky
2026-11-09 8:13 ` [PATCH for-next 2/3] RDMA/efa: Report the admin RESOURCE_BUSY status as EBUSY Ilia Kolominsky
@ 2026-11-09 8:13 ` Ilia Kolominsky
2026-11-09 8:26 ` sashiko-bot
2 siblings, 1 reply; 7+ messages in thread
From: Ilia Kolominsky @ 2026-11-09 8:13 UTC (permalink / raw)
To: jgg, leon, linux-rdma
Cc: sleybo, matua, gal.pressman, Michael Margolin, Yonatan Nachum
Completion actions are device-side effects triggered by work requests:
when a work request completes, locally or at the remote side, the device
performs the action, so completions can be observed without polling a
completion queue.
Implement the control path. A memory completion action object pins a
user buffer (VA or dmabuf) on a protection domain and yields the action
id that work requests carry; on each completion the device modifies
mem_modify_size bytes (1, 2 or 4) of that buffer with the operand the
work request supplies. The buffer must be physically contiguous. The
device also returns an action handle, which the driver keeps for the
destroy command.
The object is an EFA ioctl object, exposed only when the device reports
the actions capability. It holds a reference on its protection domain,
so deallocating the PD while the action exists fails with EBUSY. QP
creation accepts a WQE feature block configuration - an enablement
bitmap and the offset of the action descriptor within the WQE -
determined by the user space provider, which owns the WQE layout, and
passed through to the device. The device capability, the maximum number
of memory completion actions and the supported work request types are
reported through query device.
Reviewed-by: Michael Margolin <mrgolin@amazon.com>
Reviewed-by: Yonatan Nachum <ynachum@amazon.com>
Signed-off-by: Ilia Kolominsky <ikolomin@amazon.com>
---
drivers/infiniband/hw/efa/efa.h | 7 +
drivers/infiniband/hw/efa/efa_com.c | 8 +
drivers/infiniband/hw/efa/efa_com_cmd.c | 73 ++++++++
drivers/infiniband/hw/efa/efa_com_cmd.h | 31 ++++
drivers/infiniband/hw/efa/efa_verbs.c | 235 +++++++++++++++++++++++-
include/uapi/rdma/efa-abi.h | 56 +++++-
6 files changed, 408 insertions(+), 2 deletions(-)
diff --git a/drivers/infiniband/hw/efa/efa.h b/drivers/infiniband/hw/efa/efa.h
index 6f6686eef..c61dd0014 100644
--- a/drivers/infiniband/hw/efa/efa.h
+++ b/drivers/infiniband/hw/efa/efa.h
@@ -118,6 +118,13 @@ struct efa_comp_cntr {
u32 err_handle;
};
+struct efa_comp_action {
+ struct efa_dev *dev;
+ struct ib_pd *pd;
+ struct ib_umem *umem;
+ u32 action_handle;
+};
+
struct efa_qp {
struct ib_qp ibqp;
dma_addr_t rq_dma_addr;
diff --git a/drivers/infiniband/hw/efa/efa_com.c b/drivers/infiniband/hw/efa/efa_com.c
index e8045b43f..6491932e7 100644
--- a/drivers/infiniband/hw/efa/efa_com.c
+++ b/drivers/infiniband/hw/efa/efa_com.c
@@ -77,6 +77,14 @@ static const char *efa_com_cmd_str(u8 cmd)
EFA_CMD_STR_CASE(DEALLOC_UAR);
EFA_CMD_STR_CASE(CREATE_EQ);
EFA_CMD_STR_CASE(DESTROY_EQ);
+ EFA_CMD_STR_CASE(SERVICE);
+ EFA_CMD_STR_CASE(CREATE_ACTION);
+ EFA_CMD_STR_CASE(DESTROY_ACTION);
+ EFA_CMD_STR_CASE(CREATE_EVENT_COUNTER);
+ EFA_CMD_STR_CASE(DESTROY_EVENT_COUNTER);
+ EFA_CMD_STR_CASE(ATTACH_EVENT_COUNTER);
+ EFA_CMD_STR_CASE(MODIFY_EVENT_COUNTER);
+ EFA_CMD_STR_CASE(DETACH_EVENT_COUNTER);
default: return "unknown command opcode";
}
#undef EFA_CMD_STR_CASE
diff --git a/drivers/infiniband/hw/efa/efa_com_cmd.c b/drivers/infiniband/hw/efa/efa_com_cmd.c
index 07bfcb093..a613cdc63 100644
--- a/drivers/infiniband/hw/efa/efa_com_cmd.c
+++ b/drivers/infiniband/hw/efa/efa_com_cmd.c
@@ -39,6 +39,13 @@ int efa_com_create_qp(struct efa_com_dev *edev,
if (params->sq_64_bit_req_id)
EFA_SET(&create_qp_cmd.flags, EFA_ADMIN_CREATE_QP_CMD_SQ_64_BIT_REQ_ID, 1);
+ if (params->wqe_blocks_en.action_with_data) {
+ EFA_SET(&create_qp_cmd.wqe_blocks_enablement,
+ EFA_ADMIN_CREATE_QP_CMD_ACTION_WITH_DATA, 1);
+ create_qp_cmd.action_with_data_wqe_offset =
+ params->wqe_blocks_offsets.action_with_data;
+ }
+
err = efa_com_cmd_exec(aq, EFA_ADMIN_CREATE_QP, 0,
&create_qp_cmd, sizeof(create_qp_cmd),
(struct efa_admin_acq_entry *)&cmd_completion,
@@ -542,6 +549,8 @@ int efa_com_get_device_attr(struct efa_com_dev *edev,
result->event_counter_max_val = resp.u.queue_attr_2.event_counter_max_val;
result->supported_event_counter_qp_events =
resp.u.queue_attr_2.supported_event_counter_qp_events;
+ result->max_actions = resp.u.queue_attr_2.max_actions;
+ result->supported_action_events = resp.u.queue_attr_2.supported_action_events;
} else {
result->inline_buf_size_ex = result->inline_buf_size;
}
@@ -983,3 +992,67 @@ int efa_com_modify_event_counter(struct efa_com_dev *edev,
return 0;
}
+
+int efa_com_create_action(struct efa_com_dev *edev,
+ struct efa_com_create_action_params *params,
+ struct efa_com_create_action_result *result)
+{
+ struct efa_admin_create_action_cmd cmd = {};
+ struct efa_com_admin_queue *aq = &edev->aq;
+ struct efa_admin_create_action_resp resp;
+ int err;
+
+ /*
+ * The command carries the length of the target buffer in 32 bits and
+ * the write size in a byte
+ */
+ if (params->length > U32_MAX || params->write_size > U8_MAX) {
+ ibdev_dbg(edev->efa_dev,
+ "Action length[%llu] or write size[%u] out of range\n",
+ params->length, params->write_size);
+ return -EINVAL;
+ }
+
+ cmd.type = EFA_ADMIN_ACTION_TYPE_MEMSET;
+ cmd.pd = params->pdn;
+ cmd.action_data.memset.paddr = params->dma_addr;
+ cmd.action_data.memset.length = params->length;
+ cmd.action_data.memset.write_size = params->write_size;
+
+ err = efa_com_cmd_exec(aq, EFA_ADMIN_CREATE_ACTION, 0,
+ &cmd, sizeof(cmd),
+ (struct efa_admin_acq_entry *)&resp,
+ sizeof(resp));
+ if (err) {
+ ibdev_err_ratelimited(edev->efa_dev,
+ "Failed to create action [%d]\n", err);
+ return err;
+ }
+
+ result->action_handle = resp.action_handle;
+ result->action_id = resp.action_id;
+ return 0;
+}
+
+int efa_com_destroy_action(struct efa_com_dev *edev,
+ struct efa_com_destroy_action_params *params)
+{
+ struct efa_admin_destroy_action_cmd cmd = {};
+ struct efa_com_admin_queue *aq = &edev->aq;
+ struct efa_admin_destroy_action_resp resp;
+ int err;
+
+ cmd.action_handle = params->action_handle;
+
+ err = efa_com_cmd_exec(aq, EFA_ADMIN_DESTROY_ACTION, 0,
+ &cmd, sizeof(cmd),
+ (struct efa_admin_acq_entry *)&resp,
+ sizeof(resp));
+ if (err) {
+ ibdev_err_ratelimited(edev->efa_dev,
+ "Failed to destroy action [%d]\n", err);
+ return err;
+ }
+
+ return 0;
+}
diff --git a/drivers/infiniband/hw/efa/efa_com_cmd.h b/drivers/infiniband/hw/efa/efa_com_cmd.h
index 524407f36..a75ffeb37 100644
--- a/drivers/infiniband/hw/efa/efa_com_cmd.h
+++ b/drivers/infiniband/hw/efa/efa_com_cmd.h
@@ -30,6 +30,14 @@ struct efa_com_create_qp_params {
u8 sl;
u8 unsolicited_write_recv : 1;
u8 sq_64_bit_req_id : 1;
+ /* Enablement of WQE feature blocks */
+ struct {
+ u8 action_with_data:1;
+ } wqe_blocks_en;
+ /* Offsets in SQ WQE of the enabled WQE feature blocks */
+ struct {
+ u8 action_with_data;
+ } wqe_blocks_offsets;
};
struct efa_com_create_qp_result {
@@ -151,6 +159,8 @@ struct efa_com_get_device_attr_result {
u32 max_event_counters;
u64 event_counter_max_val;
u32 supported_event_counter_qp_events;
+ u32 max_actions;
+ u32 supported_action_events;
};
struct efa_com_get_hw_hints_result {
@@ -341,6 +351,22 @@ struct efa_com_modify_event_counter_params {
u64 value;
};
+struct efa_com_create_action_params {
+ dma_addr_t dma_addr;
+ u64 length;
+ u32 write_size;
+ u16 pdn;
+};
+
+struct efa_com_create_action_result {
+ u32 action_handle;
+ u32 action_id;
+};
+
+struct efa_com_destroy_action_params {
+ u32 action_handle;
+};
+
int efa_com_create_qp(struct efa_com_dev *edev,
struct efa_com_create_qp_params *params,
struct efa_com_create_qp_result *res);
@@ -402,5 +428,10 @@ int efa_com_detach_event_counter(struct efa_com_dev *edev,
struct efa_com_detach_event_counter_params *params);
int efa_com_modify_event_counter(struct efa_com_dev *edev,
struct efa_com_modify_event_counter_params *params);
+int efa_com_create_action(struct efa_com_dev *edev,
+ struct efa_com_create_action_params *params,
+ struct efa_com_create_action_result *result);
+int efa_com_destroy_action(struct efa_com_dev *edev,
+ struct efa_com_destroy_action_params *params);
#endif /* _EFA_COM_CMD_H_ */
diff --git a/drivers/infiniband/hw/efa/efa_verbs.c b/drivers/infiniband/hw/efa/efa_verbs.c
index d56eb1325..e8099f52d 100644
--- a/drivers/infiniband/hw/efa/efa_verbs.c
+++ b/drivers/infiniband/hw/efa/efa_verbs.c
@@ -212,6 +212,29 @@ static void efa_free_mapped(struct efa_dev *dev, void *cpu_addr,
free_pages_exact(cpu_addr, size);
}
+static u32 efa_comp_action_supp_ops(u32 action_events)
+{
+ u32 supp_ops = 0;
+
+ if (EFA_GET(&action_events, EFA_ADMIN_FEATURE_QUEUE_ATTR_DESC_2_ACTION_SEND_COMP))
+ supp_ops |= EFA_QUERY_DEVICE_COMP_ACTION_SUPP_OP_SEND;
+ if (EFA_GET(&action_events, EFA_ADMIN_FEATURE_QUEUE_ATTR_DESC_2_ACTION_RECV_COMP))
+ supp_ops |= EFA_QUERY_DEVICE_COMP_ACTION_SUPP_OP_RECV;
+ if (EFA_GET(&action_events, EFA_ADMIN_FEATURE_QUEUE_ATTR_DESC_2_ACTION_READ_COMP))
+ supp_ops |= EFA_QUERY_DEVICE_COMP_ACTION_SUPP_OP_RDMA_READ;
+ if (EFA_GET(&action_events, EFA_ADMIN_FEATURE_QUEUE_ATTR_DESC_2_ACTION_REMOTE_READ_COMP))
+ supp_ops |= EFA_QUERY_DEVICE_COMP_ACTION_SUPP_OP_REMOTE_RDMA_READ;
+ if (EFA_GET(&action_events, EFA_ADMIN_FEATURE_QUEUE_ATTR_DESC_2_ACTION_WRITE_COMP))
+ supp_ops |= EFA_QUERY_DEVICE_COMP_ACTION_SUPP_OP_RDMA_WRITE;
+ if (EFA_GET(&action_events, EFA_ADMIN_FEATURE_QUEUE_ATTR_DESC_2_ACTION_REMOTE_WRITE_COMP))
+ supp_ops |= EFA_QUERY_DEVICE_COMP_ACTION_SUPP_OP_REMOTE_RDMA_WRITE;
+ if (EFA_GET(&action_events,
+ EFA_ADMIN_FEATURE_QUEUE_ATTR_DESC_2_ACTION_REMOTE_WRITE_IMM_COMP))
+ supp_ops |= EFA_QUERY_DEVICE_COMP_ACTION_SUPP_OP_REMOTE_RDMA_WRITE_IMM;
+
+ return supp_ops;
+}
+
int efa_query_device(struct ib_device *ibdev,
struct ib_device_attr *props,
struct ib_udata *udata)
@@ -272,6 +295,13 @@ int efa_query_device(struct ib_device *ibdev,
if (EFA_DEV_CAP(dev, EVENT_COUNTERS))
resp.device_caps |= EFA_QUERY_DEVICE_CAPS_COMP_CNTR;
+ if (EFA_DEV_CAP(dev, ACTIONS)) {
+ resp.device_caps |= EFA_QUERY_DEVICE_CAPS_COMP_ACTION;
+ resp.max_comp_actions = dev_attr->max_actions;
+ resp.comp_action_supp_ops =
+ efa_comp_action_supp_ops(dev_attr->supported_action_events);
+ }
+
if (EFA_DEV_CAP(dev, SQ_64_BIT_REQ_ID))
resp.device_caps |= EFA_QUERY_DEVICE_CAPS_SQ_64_BIT_REQ_ID;
@@ -692,6 +722,30 @@ static int efa_qp_validate_attr(struct efa_dev *dev,
return 0;
}
+static int efa_qp_validate_wqe_blocks(struct efa_dev *dev,
+ struct efa_ibv_create_qp *cmd)
+{
+ u32 supported_wqe_blocks = 0;
+
+ if (EFA_DEV_CAP(dev, ACTIONS))
+ supported_wqe_blocks |= EFA_CREATE_QP_WQE_BLOCK_ACTION_WITH_DATA;
+
+ if (cmd->wqe_blocks_enablement & ~supported_wqe_blocks) {
+ ibdev_dbg(&dev->ibdev, "Unsupported WQE blocks[%#x], supported[%#x]\n",
+ cmd->wqe_blocks_enablement, supported_wqe_blocks);
+ return -EOPNOTSUPP;
+ }
+
+ if ((cmd->wqe_blocks_enablement & EFA_CREATE_QP_WQE_BLOCK_ACTION_WITH_DATA) &&
+ cmd->action_with_data_wqe_offset > U8_MAX) {
+ ibdev_dbg(&dev->ibdev, "Invalid action with data WQE offset[%u]\n",
+ cmd->action_with_data_wqe_offset);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
int efa_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *init_attr,
struct ib_udata *udata)
{
@@ -712,7 +766,8 @@ int efa_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *init_attr,
if (err)
goto err_out;
- if (!is_reserved_cleared(cmd.reserved_98)) {
+ if (!is_reserved_cleared(cmd.reserved_98) ||
+ !is_reserved_cleared(cmd.reserved_d0)) {
ibdev_dbg(&dev->ibdev,
"Incompatible ABI params, unknown fields in udata\n");
err = -EINVAL;
@@ -732,6 +787,10 @@ int efa_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *init_attr,
goto err_out;
}
+ err = efa_qp_validate_wqe_blocks(dev, &cmd);
+ if (err)
+ goto err_out;
+
err = efa_qp_validate_cap(dev, init_attr, cmd.sq_ring_size);
if (err)
goto err_out;
@@ -787,6 +846,12 @@ int efa_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *init_attr,
if (cmd.flags & EFA_CREATE_QP_WITH_SQ_64_BIT_REQ_ID)
create_qp_params.sq_64_bit_req_id = true;
+ if (cmd.wqe_blocks_enablement & EFA_CREATE_QP_WQE_BLOCK_ACTION_WITH_DATA) {
+ create_qp_params.wqe_blocks_en.action_with_data = true;
+ create_qp_params.wqe_blocks_offsets.action_with_data =
+ cmd.action_with_data_wqe_offset;
+ }
+
err = efa_com_create_qp(&dev->edev, &create_qp_params,
&create_qp_resp);
if (err)
@@ -2500,6 +2565,132 @@ int efa_qp_attach_comp_cntr(struct ib_qp *ibqp, struct ib_comp_cntr *ibcc,
return 0;
}
+static int efa_free_comp_action(struct ib_uobject *uobject, enum rdma_remove_reason why,
+ struct uverbs_attr_bundle *attrs)
+{
+ struct efa_com_destroy_action_params params = {};
+ struct efa_comp_action *action = uobject->object;
+ int err;
+
+ params.action_handle = action->action_handle;
+ err = efa_com_destroy_action(&action->dev->edev, ¶ms);
+ if (err)
+ return err;
+
+ atomic_dec(&action->pd->usecnt);
+ ib_umem_release(action->umem);
+ kfree(action);
+ return 0;
+}
+
+static int UVERBS_HANDLER(EFA_IB_METHOD_COMP_ACTION_CREATE)(struct uverbs_attr_bundle *attrs)
+{
+ struct efa_com_destroy_action_params destroy_params = {};
+ enum efa_mem_comp_action_modify_type mem_modify_type;
+ struct efa_com_create_action_params params = {};
+ struct efa_com_create_action_result result;
+ enum efa_comp_action_type type;
+ struct efa_comp_action *action;
+ struct ib_uobject *uobj;
+ struct ib_umem *umem;
+ struct efa_dev *dev;
+ u32 mem_modify_size;
+ struct ib_pd *ibpd;
+ u64 mem_size;
+ int err;
+
+ uobj = uverbs_attr_get_uobject(attrs, EFA_IB_ATTR_COMP_ACTION_CREATE_HANDLE);
+ ibpd = uverbs_attr_get_obj(attrs, EFA_IB_ATTR_COMP_ACTION_CREATE_PD_HANDLE);
+ dev = to_edev(ibpd->device);
+
+ err = uverbs_get_const(&type, attrs, EFA_IB_ATTR_COMP_ACTION_CREATE_TYPE);
+ if (err)
+ return err;
+
+ if (type != EFA_COMP_ACTION_TYPE_MEM)
+ return -EOPNOTSUPP;
+
+ err = uverbs_get_const(&mem_modify_type, attrs,
+ EFA_IB_ATTR_COMP_ACTION_CREATE_MEM_MODIFY_TYPE);
+ if (err)
+ return err;
+
+ if (mem_modify_type != EFA_MEM_COMP_ACTION_SET_INITIATOR_VAL)
+ return -EOPNOTSUPP;
+
+ err = uverbs_copy_from(&mem_modify_size, attrs,
+ EFA_IB_ATTR_COMP_ACTION_CREATE_MEM_MODIFY_SIZE);
+ if (err)
+ return err;
+
+ err = uverbs_copy_from(&mem_size, attrs, EFA_IB_ATTR_COMP_ACTION_CREATE_MEM_SIZE);
+ if (err)
+ return err;
+
+ if (!mem_size || !mem_modify_size) {
+ ibdev_dbg(&dev->ibdev, "Invalid action memory size[%llu] or modify size[%u]\n",
+ mem_size, mem_modify_size);
+ return -EINVAL;
+ }
+
+ umem = ib_umem_get_attr(ibpd->device, attrs,
+ EFA_IB_ATTR_COMP_ACTION_CREATE_MEM_BUFFER, mem_size,
+ IB_ACCESS_LOCAL_WRITE | IB_ACCESS_REMOTE_WRITE);
+ if (IS_ERR(umem))
+ return PTR_ERR(umem);
+
+ if (!ib_umem_is_contiguous(umem)) {
+ ibdev_dbg(&dev->ibdev, "Non contiguous action memory unsupported\n");
+ err = -EINVAL;
+ goto err_umem;
+ }
+
+ action = kzalloc_obj(*action);
+ if (!action) {
+ err = -ENOMEM;
+ goto err_umem;
+ }
+
+ params.pdn = to_epd(ibpd)->pdn;
+ params.dma_addr = ib_umem_start_dma_addr(umem);
+ params.length = mem_size;
+ params.write_size = mem_modify_size;
+
+ err = efa_com_create_action(&dev->edev, ¶ms, &result);
+ if (err)
+ goto err_free;
+
+ /* Work requests carry the action id; the handle is kept for the destroy command */
+ err = uverbs_copy_to(attrs, EFA_IB_ATTR_COMP_ACTION_CREATE_RESP_ACTION_ID,
+ &result.action_id, sizeof(result.action_id));
+ if (IS_UVERBS_COPY_ERR(err))
+ goto err_destroy;
+
+ action->dev = dev;
+ action->pd = ibpd;
+ action->umem = umem;
+ action->action_handle = result.action_handle;
+ atomic_inc(&ibpd->usecnt);
+
+ uobj->object = action;
+ uverbs_finalize_uobj_create(attrs, EFA_IB_ATTR_COMP_ACTION_CREATE_HANDLE);
+ return 0;
+
+err_destroy:
+ destroy_params.action_handle = result.action_handle;
+ efa_com_destroy_action(&dev->edev, &destroy_params);
+err_free:
+ kfree(action);
+err_umem:
+ ib_umem_release(umem);
+ return err;
+}
+
+static bool efa_comp_actions_supported(struct ib_device *ibdev)
+{
+ return EFA_DEV_CAP(to_edev(ibdev), ACTIONS);
+}
+
DECLARE_UVERBS_NAMED_METHOD(EFA_IB_METHOD_MR_QUERY,
UVERBS_ATTR_IDR(EFA_IB_ATTR_QUERY_MR_HANDLE,
UVERBS_OBJECT_MR,
@@ -2535,10 +2726,52 @@ ADD_UVERBS_ATTRIBUTES_SIMPLE(
UVERBS_ATTR_STRUCT(struct ib_uverbs_buffer_desc, length),
UA_MANDATORY));
+DECLARE_UVERBS_NAMED_METHOD(EFA_IB_METHOD_COMP_ACTION_CREATE,
+ UVERBS_ATTR_IDR(EFA_IB_ATTR_COMP_ACTION_CREATE_HANDLE,
+ EFA_IB_OBJECT_COMP_ACTION,
+ UVERBS_ACCESS_NEW,
+ UA_MANDATORY),
+ UVERBS_ATTR_IDR(EFA_IB_ATTR_COMP_ACTION_CREATE_PD_HANDLE,
+ UVERBS_OBJECT_PD,
+ UVERBS_ACCESS_READ,
+ UA_MANDATORY),
+ UVERBS_ATTR_CONST_IN(EFA_IB_ATTR_COMP_ACTION_CREATE_TYPE,
+ enum efa_comp_action_type,
+ UA_MANDATORY),
+ UVERBS_ATTR_CONST_IN(EFA_IB_ATTR_COMP_ACTION_CREATE_MEM_MODIFY_TYPE,
+ enum efa_mem_comp_action_modify_type,
+ UA_MANDATORY),
+ UVERBS_ATTR_PTR_IN(EFA_IB_ATTR_COMP_ACTION_CREATE_MEM_MODIFY_SIZE,
+ UVERBS_ATTR_TYPE(u32),
+ UA_MANDATORY),
+ UVERBS_ATTR_PTR_IN(EFA_IB_ATTR_COMP_ACTION_CREATE_MEM_SIZE,
+ UVERBS_ATTR_TYPE(u64),
+ UA_MANDATORY),
+ UVERBS_ATTR_PTR_IN(EFA_IB_ATTR_COMP_ACTION_CREATE_MEM_BUFFER,
+ UVERBS_ATTR_STRUCT(struct ib_uverbs_buffer_desc,
+ length),
+ UA_MANDATORY),
+ UVERBS_ATTR_PTR_OUT(EFA_IB_ATTR_COMP_ACTION_CREATE_RESP_ACTION_ID,
+ UVERBS_ATTR_TYPE(u32),
+ UA_MANDATORY));
+
+DECLARE_UVERBS_NAMED_METHOD_DESTROY(EFA_IB_METHOD_COMP_ACTION_DESTROY,
+ UVERBS_ATTR_IDR(EFA_IB_ATTR_COMP_ACTION_DESTROY_HANDLE,
+ EFA_IB_OBJECT_COMP_ACTION,
+ UVERBS_ACCESS_DESTROY,
+ UA_MANDATORY));
+
+DECLARE_UVERBS_NAMED_OBJECT(EFA_IB_OBJECT_COMP_ACTION,
+ UVERBS_TYPE_ALLOC_IDR(efa_free_comp_action),
+ &UVERBS_METHOD(EFA_IB_METHOD_COMP_ACTION_CREATE),
+ &UVERBS_METHOD(EFA_IB_METHOD_COMP_ACTION_DESTROY));
+
const struct uapi_definition efa_uapi_defs[] = {
UAPI_DEF_CHAIN_OBJ_TREE(UVERBS_OBJECT_MR,
&efa_mr),
UAPI_DEF_CHAIN_OBJ_TREE(UVERBS_OBJECT_COMP_CNTR,
&efa_comp_cntr_create),
+ UAPI_DEF_CHAIN_OBJ_TREE_NAMED(EFA_IB_OBJECT_COMP_ACTION,
+ UAPI_DEF_IS_OBJ_SUPPORTED(efa_comp_actions_supported)),
{},
};
diff --git a/include/uapi/rdma/efa-abi.h b/include/uapi/rdma/efa-abi.h
index 2094b4bcc..c907d966b 100644
--- a/include/uapi/rdma/efa-abi.h
+++ b/include/uapi/rdma/efa-abi.h
@@ -92,6 +92,10 @@ enum {
EFA_CREATE_QP_WITH_SQ_64_BIT_REQ_ID = 1 << 1,
};
+enum {
+ EFA_CREATE_QP_WQE_BLOCK_ACTION_WITH_DATA = 1 << 0,
+};
+
struct efa_ibv_create_qp {
__u32 comp_mask;
__u32 rq_ring_size; /* bytes */
@@ -99,7 +103,12 @@ struct efa_ibv_create_qp {
__u32 driver_qp_type;
__u16 flags;
__u8 sl;
- __u8 reserved_98[5];
+ __u8 reserved_98[1];
+ /* enablement bitmap for WQE configurable feature blocks */
+ __u32 wqe_blocks_enablement;
+ /* offset in SQ WQE to the action with data descriptor */
+ __u16 action_with_data_wqe_offset;
+ __u8 reserved_d0[6];
};
struct efa_ibv_create_qp_resp {
@@ -137,6 +146,17 @@ enum {
EFA_QUERY_DEVICE_CAPS_CQ_WITH_EXT_MEM = 1 << 7,
EFA_QUERY_DEVICE_CAPS_COMP_CNTR = 1 << 8,
EFA_QUERY_DEVICE_CAPS_SQ_64_BIT_REQ_ID = 1 << 9,
+ EFA_QUERY_DEVICE_CAPS_COMP_ACTION = 1 << 10,
+};
+
+enum efa_query_device_comp_action_supp_ops {
+ EFA_QUERY_DEVICE_COMP_ACTION_SUPP_OP_SEND = 1 << 0,
+ EFA_QUERY_DEVICE_COMP_ACTION_SUPP_OP_RECV = 1 << 1,
+ EFA_QUERY_DEVICE_COMP_ACTION_SUPP_OP_RDMA_READ = 1 << 2,
+ EFA_QUERY_DEVICE_COMP_ACTION_SUPP_OP_REMOTE_RDMA_READ = 1 << 3,
+ EFA_QUERY_DEVICE_COMP_ACTION_SUPP_OP_RDMA_WRITE = 1 << 4,
+ EFA_QUERY_DEVICE_COMP_ACTION_SUPP_OP_REMOTE_RDMA_WRITE = 1 << 5,
+ EFA_QUERY_DEVICE_COMP_ACTION_SUPP_OP_REMOTE_RDMA_WRITE_IMM = 1 << 6,
};
struct efa_ibv_ex_query_device_resp {
@@ -147,6 +167,8 @@ struct efa_ibv_ex_query_device_resp {
__u16 max_rq_sge;
__u32 max_rdma_size;
__u32 device_caps;
+ __u32 max_comp_actions;
+ __u32 comp_action_supp_ops;
};
enum {
@@ -172,4 +194,36 @@ enum efa_comp_cntr_create_attrs {
EFA_IB_ATTR_CREATE_COMP_CNTR_ERR_BUFFER,
};
+enum efa_objects {
+ EFA_IB_OBJECT_COMP_ACTION = (1U << UVERBS_ID_NS_SHIFT),
+};
+
+enum efa_comp_action_type {
+ EFA_COMP_ACTION_TYPE_MEM,
+};
+
+enum efa_mem_comp_action_modify_type {
+ EFA_MEM_COMP_ACTION_SET_INITIATOR_VAL,
+};
+
+enum efa_comp_action_methods {
+ EFA_IB_METHOD_COMP_ACTION_CREATE = (1U << UVERBS_ID_NS_SHIFT),
+ EFA_IB_METHOD_COMP_ACTION_DESTROY,
+};
+
+enum efa_comp_action_create_attrs {
+ EFA_IB_ATTR_COMP_ACTION_CREATE_HANDLE = (1U << UVERBS_ID_NS_SHIFT),
+ EFA_IB_ATTR_COMP_ACTION_CREATE_PD_HANDLE,
+ EFA_IB_ATTR_COMP_ACTION_CREATE_TYPE,
+ EFA_IB_ATTR_COMP_ACTION_CREATE_MEM_MODIFY_TYPE,
+ EFA_IB_ATTR_COMP_ACTION_CREATE_MEM_MODIFY_SIZE,
+ EFA_IB_ATTR_COMP_ACTION_CREATE_MEM_SIZE,
+ EFA_IB_ATTR_COMP_ACTION_CREATE_MEM_BUFFER,
+ EFA_IB_ATTR_COMP_ACTION_CREATE_RESP_ACTION_ID,
+};
+
+enum efa_comp_action_destroy_attrs {
+ EFA_IB_ATTR_COMP_ACTION_DESTROY_HANDLE = (1U << UVERBS_ID_NS_SHIFT),
+};
+
#endif /* EFA_ABI_USER_H */
--
2.47.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH for-next 1/3] RDMA/efa: Update device interface
2026-11-09 8:13 ` [PATCH for-next 1/3] RDMA/efa: Update device interface Ilia Kolominsky
@ 2026-11-09 8:17 ` sashiko-bot
0 siblings, 0 replies; 7+ messages in thread
From: sashiko-bot @ 2026-11-09 8:17 UTC (permalink / raw)
To: Ilia Kolominsky, linux-rdma
> Align device interface definitions.
>
> Reviewed-by: Michael Margolin <mrgolin@amazon.com>
> Reviewed-by: Yonatan Nachum <ynachum@amazon.com>
> Signed-off-by: Ilia Kolominsky <ikolomin@amazon.com>
Sashiko has reviewed this patch and found no issues.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261109081349.27316-1-ikolomin@amazon.com?part=1
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH for-next 2/3] RDMA/efa: Report the admin RESOURCE_BUSY status as EBUSY
2026-11-09 8:13 ` [PATCH for-next 2/3] RDMA/efa: Report the admin RESOURCE_BUSY status as EBUSY Ilia Kolominsky
@ 2026-11-09 8:19 ` sashiko-bot
0 siblings, 0 replies; 7+ messages in thread
From: sashiko-bot @ 2026-11-09 8:19 UTC (permalink / raw)
To: Ilia Kolominsky, linux-rdma
> The device completes a command with RESOURCE_BUSY when the object it
> targets is still in use, for example a destroy of an object that other
> objects still reference. Map that status to EBUSY instead of the generic
> EINVAL so that callers can tell the two apart.
>
> Reviewed-by: Michael Margolin <mrgolin@amazon.com>
> Reviewed-by: Yonatan Nachum <ynachum@amazon.com>
> Signed-off-by: Ilia Kolominsky <ikolomin@amazon.com>
Sashiko has reviewed this patch and found no issues.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261109081349.27316-1-ikolomin@amazon.com?part=2
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH for-next 3/3] RDMA/efa: Add Completion Actions support
2026-11-09 8:13 ` [PATCH for-next 3/3] RDMA/efa: Add Completion Actions support Ilia Kolominsky
@ 2026-11-09 8:26 ` sashiko-bot
0 siblings, 0 replies; 7+ messages in thread
From: sashiko-bot @ 2026-11-09 8:26 UTC (permalink / raw)
To: Ilia Kolominsky, linux-rdma
> Completion actions are device-side effects triggered by work requests:
> when a work request completes, locally or at the remote side, the device
> performs the action, so completions can be observed without polling a
> completion queue.
>
> Implement the control path. A memory completion action object pins a
> user buffer (VA or dmabuf) on a protection domain and yields the action
> id that work requests carry; on each completion the device modifies
> mem_modify_size bytes (1, 2 or 4) of that buffer with the operand the
> work request supplies. The buffer must be physically contiguous. The
> device also returns an action handle, which the driver keeps for the
> destroy command.
>
> The object is an EFA ioctl object, exposed only when the device reports
> the actions capability. It holds a reference on its protection domain,
> so deallocating the PD while the action exists fails with EBUSY. QP
> creation accepts a WQE feature block configuration - an enablement
> bitmap and the offset of the action descriptor within the WQE -
> determined by the user space provider, which owns the WQE layout, and
> passed through to the device. The device capability, the maximum number
> of memory completion actions and the supported work request types are
> reported through query device.
>
> Reviewed-by: Michael Margolin <mrgolin@amazon.com>
> Reviewed-by: Yonatan Nachum <ynachum@amazon.com>
> Signed-off-by: Ilia Kolominsky <ikolomin@amazon.com>
Sashiko has reviewed this patch and found no issues.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261109081349.27316-1-ikolomin@amazon.com?part=3
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-11-09 8:26 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-09 8:13 [PATCH for-next 0/3] RDMA/efa: Add Completion Actions support Ilia Kolominsky
2026-11-09 8:13 ` [PATCH for-next 1/3] RDMA/efa: Update device interface Ilia Kolominsky
2026-11-09 8:17 ` sashiko-bot
2026-11-09 8:13 ` [PATCH for-next 2/3] RDMA/efa: Report the admin RESOURCE_BUSY status as EBUSY Ilia Kolominsky
2026-11-09 8:19 ` sashiko-bot
2026-11-09 8:13 ` [PATCH for-next 3/3] RDMA/efa: Add Completion Actions support Ilia Kolominsky
2026-11-09 8:26 ` sashiko-bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox