[PATCH rdma-core 10/10] verbs: use the execute_cmd_write/_ex path for the ioctl fallback

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Jason Gunthorpe <jgg@xxxxxxxxxxxx>

This is slightly less efficient than the old path, but it creates only two
places where write() are called.

Signed-off-by: Jason Gunthorpe <jgg@xxxxxxxxxxxx>
---
 libibverbs/cmd_cq.c       |  6 ++-
 libibverbs/cmd_fallback.c | 68 +-------------------------------
 libibverbs/cmd_write.h    | 83 +++++++++++++++++++++------------------
 3 files changed, 51 insertions(+), 106 deletions(-)

diff --git a/libibverbs/cmd_cq.c b/libibverbs/cmd_cq.c
index 03e5ca4c5e13bf..542daa7b63936f 100644
--- a/libibverbs/cmd_cq.c
+++ b/libibverbs/cmd_cq.c
@@ -69,7 +69,8 @@ static int ibv_icmd_create_cq(struct ibv_context *context, int cqe,
 			.comp_channel = channel ? channel->fd : -1,
 		};
 
-		ret = execute_write_bufs(cq->context, req, resp);
+		ret = execute_write_bufs(
+			cq->context, IB_USER_VERBS_CMD_CREATE_CQ, req, resp);
 		if (ret)
 			return ret;
 
@@ -90,7 +91,8 @@ static int ibv_icmd_create_cq(struct ibv_context *context, int cqe,
 			.flags = flags,
 		};
 
-		ret = execute_write_bufs_ex(cq->context, req);
+		ret = execute_write_bufs_ex(
+			cq->context, IB_USER_VERBS_EX_CMD_CREATE_CQ, req, resp);
 		if (ret)
 			return ret;
 
diff --git a/libibverbs/cmd_fallback.c b/libibverbs/cmd_fallback.c
index cad8b21756a6a6..0e50503e003484 100644
--- a/libibverbs/cmd_fallback.c
+++ b/libibverbs/cmd_fallback.c
@@ -120,8 +120,7 @@ enum write_fallback _execute_ioctl_fallback(struct ibv_context *ctx,
  * directly before the UHW memory (see _write_set_uhw)
  */
 void *_write_get_req(struct ibv_command_buffer *link,
-		     struct ib_uverbs_cmd_hdr *onstack, size_t size,
-		     uint32_t cmdnum)
+		     struct ib_uverbs_cmd_hdr *onstack, size_t size)
 {
 	struct ib_uverbs_cmd_hdr *hdr;
 
@@ -139,13 +138,11 @@ void *_write_get_req(struct ibv_command_buffer *link,
 		hdr->in_words = __check_divide(size, 4);
 	}
 
-	hdr->command = cmdnum;
-
 	return hdr + 1;
 }
 
 void *_write_get_req_ex(struct ibv_command_buffer *link, struct ex_hdr *onstack,
-			size_t size, uint32_t cmdnum)
+			size_t size)
 {
 	struct ex_hdr *hdr;
 	size_t full_size = size + sizeof(*hdr);
@@ -156,17 +153,12 @@ void *_write_get_req_ex(struct ibv_command_buffer *link, struct ex_hdr *onstack,
 		assert(uhw->attr_id == UVERBS_ATTR_UHW_IN);
 		assert(link->uhw_in_headroom_dwords * 4 >= full_size);
 		hdr = (void *)((uintptr_t)uhw->data - full_size);
-		hdr->hdr.in_words = __check_divide(size, 8);
 		hdr->ex_hdr.provider_in_words = __check_divide(uhw->len, 8);
 	} else {
 		hdr = onstack;
-		hdr->hdr.in_words = __check_divide(size, 8);
 		hdr->ex_hdr.provider_in_words = 0;
 	}
 
-	hdr->hdr.command = IB_USER_VERBS_CMD_FLAG_EXTENDED | cmdnum;
-	hdr->ex_hdr.cmd_hdr_reserved = 0;
-
 	return hdr + 1;
 }
 
@@ -205,46 +197,15 @@ void *_write_get_resp_ex(struct ibv_command_buffer *link,
 		assert(uhw->attr_id == UVERBS_ATTR_UHW_OUT);
 		assert(link->uhw_out_headroom_dwords * 4 >= resp_size);
 		resp_start = (void *)((uintptr_t)uhw->data - resp_size);
-		hdr->hdr.out_words = __check_divide(resp_size, 8);
 		hdr->ex_hdr.provider_out_words = __check_divide(uhw->len, 8);
 	} else {
 		resp_start = onstack;
-		hdr->hdr.out_words = __check_divide(resp_size, 8);
 		hdr->ex_hdr.provider_out_words = 0;
 	}
 
-	hdr->ex_hdr.response = ioctl_ptr_to_u64(resp_start);
-
 	return resp_start;
 }
 
-int _execute_write_raw(struct ibv_context *ctx, struct ib_uverbs_cmd_hdr *hdr,
-		       void *resp)
-{
-	/*
-	 * Users assumes the stack buffer is zeroed before passing to the
-	 * kernel for writing.
-	 */
-	if (resp) {
-		/*
-		 * The helper macros prove the response is at offset 0 of the
-		 * request.
-		 */
-		uint64_t *response = (uint64_t *)(hdr + 1);
-
-		*response = ioctl_ptr_to_u64(resp);
-		memset(resp, 0, hdr->out_words * 4);
-	}
-
-	if (write(ctx->cmd_fd, hdr, hdr->in_words * 4) != hdr->in_words * 4)
-		return errno;
-
-	if (resp)
-		VALGRIND_MAKE_MEM_DEFINED(resp, hdr->out_words * 4);
-
-	return 0;
-}
-
 int _execute_cmd_write(struct ibv_context *ctx, unsigned int write_method,
 		       struct ib_uverbs_cmd_hdr *req, size_t core_req_size,
 		       size_t req_size, void *resp, size_t core_resp_size,
@@ -262,31 +223,6 @@ int _execute_cmd_write(struct ibv_context *ctx, unsigned int write_method,
 	return 0;
 }
 
-int _execute_write_raw_ex(struct ibv_context *ctx, struct ex_hdr *hdr)
-{
-	size_t write_bytes =
-		sizeof(*hdr) +
-		(hdr->hdr.in_words + hdr->ex_hdr.provider_in_words) * 8;
-	size_t resp_bytes =
-		(hdr->hdr.out_words + hdr->ex_hdr.provider_out_words) * 8;
-	void *resp = (void *)(uintptr_t)hdr->ex_hdr.response;
-
-	/*
-	 * Users assumes the stack buffer is zeroed before passing to the
-	 * kernel for writing.
-	 */
-	if (resp)
-		memset(resp, 0, resp_bytes);
-
-	if (write(ctx->cmd_fd, hdr, write_bytes) != write_bytes)
-		return errno;
-
-	if (resp)
-		VALGRIND_MAKE_MEM_DEFINED(resp, resp_bytes);
-
-	return 0;
-}
-
 /*
  * req_size is the total length of the ex_hdr, core payload and driver data.
  * core_req_size is the total length of the ex_hdr and core_payload.
diff --git a/libibverbs/cmd_write.h b/libibverbs/cmd_write.h
index 88ff66600bc118..1d8c462522e2a9 100644
--- a/libibverbs/cmd_write.h
+++ b/libibverbs/cmd_write.h
@@ -40,21 +40,10 @@
 
 #include <stdbool.h>
 
-static inline struct ib_uverbs_cmd_hdr *get_req_hdr(void *req)
-{
-	return ((struct ib_uverbs_cmd_hdr *)req) - 1;
-}
-
-static inline struct ex_hdr *get_req_hdr_ex(void *req)
-{
-	return ((struct ex_hdr *)req) - 1;
-}
-
 void *_write_get_req(struct ibv_command_buffer *link,
-		     struct ib_uverbs_cmd_hdr *onstack, size_t size,
-		     uint32_t cmdnum);
+		     struct ib_uverbs_cmd_hdr *onstack, size_t size);
 void *_write_get_req_ex(struct ibv_command_buffer *link, struct ex_hdr *onstack,
-			size_t size, uint32_t cmdnum);
+			size_t size);
 void *_write_get_resp(struct ibv_command_buffer *link,
 		      struct ib_uverbs_cmd_hdr *hdr, void *onstack,
 		      size_t resp_size);
@@ -71,23 +60,26 @@ void *_write_get_resp_ex(struct ibv_command_buffer *link,
 #define DECLARE_LEGACY_UHW_BUFS(_link, _enum)                                  \
 	IBV_ABI_REQ(_enum) __req_onstack;                                      \
 	IBV_KABI_RESP(_enum) __resp_onstack;                                   \
-	static_assert(offsetof(IBV_KABI_REQ(_enum), response) == 0,            \
-		      "Bad response offset");                                  \
-	IBV_KABI_REQ(_enum) *req = _write_get_req(_link, &__req_onstack.hdr,   \
-						  sizeof(*req), _enum);        \
+	IBV_KABI_REQ(_enum) *req =                                             \
+		_write_get_req(_link, &__req_onstack.hdr, sizeof(*req));       \
 	IBV_KABI_RESP(_enum) *resp = ({                                        \
-		void *_resp = _write_get_resp(_link, get_req_hdr(req),         \
-					      &__resp_onstack, sizeof(*resp)); \
+		void *_resp = _write_get_resp(                                 \
+			_link,                                                 \
+			&container_of(req, IBV_ABI_REQ(_enum), core_payload)   \
+				 ->hdr,                                        \
+			&__resp_onstack, sizeof(*resp));                       \
 		_resp;                                                         \
 	})
 
 #define DECLARE_LEGACY_UHW_BUFS_EX(_link, _enum)                               \
 	IBV_ABI_REQ(_enum) __req_onstack;                                      \
 	IBV_KABI_RESP(_enum) __resp_onstack;                                   \
-	IBV_KABI_REQ(_enum) *req = _write_get_req_ex(                          \
-		_link, &__req_onstack.hdr, sizeof(*req), _enum);               \
+	IBV_KABI_REQ(_enum) *req =                                             \
+		_write_get_req_ex(_link, &__req_onstack.hdr, sizeof(*req));    \
 	IBV_KABI_RESP(_enum) *resp = _write_get_resp_ex(                       \
-		_link, get_req_hdr_ex(req), &__resp_onstack, sizeof(*resp))
+		_link,                                                         \
+		&container_of(req, IBV_ABI_REQ(_enum), core_payload)->hdr,     \
+		&__resp_onstack, sizeof(*resp))
 
 /*
  * This macro is used to implement the compatibility command call wrappers.
@@ -143,20 +135,6 @@ enum write_fallback _execute_ioctl_fallback(struct ibv_context *ctx,
 #define execute_ioctl_fallback(ctx, cmd_name, cmdb, ret)                       \
 	_execute_ioctl_fallback(ctx, _CMD_BIT(cmd_name), cmdb, ret)
 
-/* These helpers replace the raw write() and IBV_INIT_CMD macros */
-int _execute_write_raw(struct ibv_context *ctx, struct ib_uverbs_cmd_hdr *req,
-		       void *resp);
-
-/* For users of DECLARE_LEGACY_UHW_BUFS */
-#define execute_write_bufs(ctx, req, resp)                             \
-		_execute_write_raw(ctx, get_req_hdr(req), resp)
-
-int _execute_write_raw_ex(struct ibv_context *ctx, struct ex_hdr *req);
-
-/* For users of DECLARE_LEGACY_UHW_BUFS_EX */
-#define execute_write_bufs_ex(ctx, req)                                        \
-	_execute_write_raw_ex(ctx, get_req_hdr_ex(req))
-
 /*
  * For write() only commands that have fixed core structures and may take uhw
  * driver data. The last arguments are the same ones passed into the typical
@@ -206,6 +184,18 @@ int _execute_cmd_write(struct ibv_context *ctx, unsigned int write_method,
 			resp_size, resp_size);                                 \
 	})
 
+/*
+ * For users of DECLARE_LEGACY_UHW_BUFS, in this case the machinery has
+ * already stored the full req/resp length in the hdr.
+ */
+#define execute_write_bufs(ctx, enum, req, resp)                               \
+	({                                                                     \
+		IBV_ABI_REQ(enum) *_hdr =                                      \
+			container_of(req, IBV_ABI_REQ(enum), core_payload);    \
+		execute_cmd_write(ctx, enum, _hdr, _hdr->hdr.in_words * 4,     \
+				  resp, _hdr->hdr.out_words * 4);              \
+	})
+
 /*
  * For write() commands that use the _ex protocol. _full allows the caller to
  * specify all 4 sizes directly. This version is used when the core structs
@@ -236,6 +226,20 @@ int _execute_cmd_write_ex(struct ibv_context *ctx, unsigned int write_method,
 			sizeof(*(cmd)), cmd_size, NULL, 0, 0);                 \
 	})
 
+/* For users of DECLARE_LEGACY_UHW_BUFS_EX */
+#define execute_write_bufs_ex(ctx, enum, req, resp)                            \
+	({                                                                     \
+		IBV_ABI_REQ(enum) *_hdr =                                      \
+			container_of(req, IBV_ABI_REQ(enum), core_payload);    \
+		execute_cmd_write_ex(                                          \
+			ctx, enum, _hdr,                                       \
+			sizeof(*_hdr) +                                        \
+				_hdr->hdr.ex_hdr.provider_in_words * 8,        \
+			resp,                                                  \
+			sizeof(*(resp)) +                                      \
+				_hdr->hdr.ex_hdr.provider_out_words * 8);      \
+	})
+
 /*
  * These two macros are used only with execute_ioctl_fallback - they allow the
  * IOCTL code to be elided by the compiler when disabled.
@@ -263,14 +267,17 @@ _execute_ioctl_only(struct ibv_context *context, struct ibv_command_buffer *cmd,
 	_execute_ioctl_only(ctx, cmdb, ret)
 
 #undef execute_write_bufs
-static inline int execute_write_bufs(struct ibv_context *ctx, void *req,
+static inline int execute_write_bufs(struct ibv_context *ctx,
+				     unsigned int write_command, void *req,
 				     void *resp)
 {
 	return ENOSYS;
 }
 
 #undef execute_write_bufs_ex
-static inline int execute_write_bufs_ex(struct ibv_context *ctx, void *req)
+static inline int execute_write_bufs_ex(struct ibv_context *ctx,
+					unsigned int write_command, void *req,
+					void *resp)
 {
 	return ENOSYS;
 }
-- 
2.19.1




[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Yosemite Photos]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux