diff mbox series

hfi1verbs: Update rvt cq headers in rdma_core hfi1 provider

Message ID 20180910141200.31858.84739.stgit@scvm10.sc.intel.com (mailing list archive)
State Changes Requested
Headers show
Series hfi1verbs: Update rvt cq headers in rdma_core hfi1 provider | expand

Commit Message

Arumugam, Kamenee Sept. 10, 2018, 2:12 p.m. UTC
From: Arumugam, Kamenee <kamenee.arumugam@intel.com>

hfi1_wc struct is the same struct as ib_uverbs_wc and hfi1_cq_wc
is not in the uapi header. Remove hfi1_wc and hfi1_cq_wc struct
from providers. Include rvt-abi.h header that have rvt_cq_wc
struct definition into kernel-headers.

The member ib_uverbs_wc arrray in rvt_cq_wc is replaced with
one in rvt-abi. Therefore,plus one to the number of cq entries.

Change-Id: I01250acb9d17f63ac737f632462f34617fd5b61a
Reviewed-by: Mike Marciniszyn <mike.marciniszyn@intel.com>
Signed-off-by: Kamenee Arumugam <kamenee.arumugam@intel.com>
---
 kernel-headers/CMakeLists.txt  |    1 +
 kernel-headers/rdma/rvt-abi.h  |   74 ++++++++++++++++++++++++++++++++++++++++
 providers/hfi1verbs/hfiverbs.h |   37 +++-----------------
 providers/hfi1verbs/verbs.c    |   23 +++++++-----
 4 files changed, 93 insertions(+), 42 deletions(-)
 create mode 100755 kernel-headers/rdma/rvt-abi.h

Comments

Arumugam, Kamenee Sept. 10, 2018, 2:24 p.m. UTC | #1
I just noticed the Gerrit id in the commit message.  I will send a patch v2 shortly to fix that.

Thanks,
Kamenee

-----Original Message-----
From: linux-rdma-owner@vger.kernel.org [mailto:linux-rdma-owner@vger.kernel.org] On Behalf Of Kamenee Arumugam
Sent: Monday, September 10, 2018 10:12 AM
To: linux-rdma@vger.kernel.org
Cc: Dalessandro, Dennis <dennis.dalessandro@intel.com>
Subject: [PATCH] hfi1verbs: Update rvt cq headers in rdma_core hfi1 provider

From: Arumugam, Kamenee <kamenee.arumugam@intel.com>

hfi1_wc struct is the same struct as ib_uverbs_wc and hfi1_cq_wc is not in the uapi header. Remove hfi1_wc and hfi1_cq_wc struct from providers. Include rvt-abi.h header that have rvt_cq_wc struct definition into kernel-headers.

The member ib_uverbs_wc arrray in rvt_cq_wc is replaced with one in rvt-abi. Therefore,plus one to the number of cq entries.

Change-Id: I01250acb9d17f63ac737f632462f34617fd5b61a
Reviewed-by: Mike Marciniszyn <mike.marciniszyn@intel.com>
Signed-off-by: Kamenee Arumugam <kamenee.arumugam@intel.com>
---
 kernel-headers/CMakeLists.txt  |    1 +
 kernel-headers/rdma/rvt-abi.h  |   74 ++++++++++++++++++++++++++++++++++++++++
 providers/hfi1verbs/hfiverbs.h |   37 +++-----------------
 providers/hfi1verbs/verbs.c    |   23 +++++++-----
 4 files changed, 93 insertions(+), 42 deletions(-)  create mode 100755 kernel-headers/rdma/rvt-abi.h

diff --git a/kernel-headers/CMakeLists.txt b/kernel-headers/CMakeLists.txt index 16ba165..631db9c 100644
--- a/kernel-headers/CMakeLists.txt
+++ b/kernel-headers/CMakeLists.txt
@@ -24,6 +24,7 @@ publish_internal_headers(rdma
   rdma/rdma_user_ioctl_cmds.h
   rdma/rdma_user_rxe.h
   rdma/vmw_pvrdma-abi.h
+  rdma/rvt-abi.h
   )
 
 publish_internal_headers(rdma/hfi
diff --git a/kernel-headers/rdma/rvt-abi.h b/kernel-headers/rdma/rvt-abi.h new file mode 100755 index 0000000..8cff1df
--- /dev/null
+++ b/kernel-headers/rdma/rvt-abi.h
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
+/*
+ * Copyright(c) 2015 - 2018 Intel Corporation.
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  - Neither the name of Intel Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 
+USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 
+ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *
+ */
+
+/*
+ * This file contains defines, structures, etc. that are used
+ * to communicate between kernel and user code.
+ */
+
+#ifndef RVT_ABI_USER_H
+#define RVT_ABI_USER_H
+
+#include <linux/types.h>
+#ifndef RDMA_ATOMIC_UAPI
+#define RDMA_ATOMIC_UAPI(_type, _name) _type _name #endif
+/*
+ * This structure is used to contain the head pointer, tail pointer,
+ * and completion queue entries as a single memory allocation so
+ * it can be mmap'ed into user space.
+ */
+struct rvt_cq_wc {
+	/* index of next entry to fill */
+	RDMA_ATOMIC_UAPI(u32, head);
+	/* index of next ib_poll_cq() entry */
+	RDMA_ATOMIC_UAPI(u32, tail);
+
+	/* these are actually size ibcq.cqe + 1 */
+	struct ib_uverbs_wc uqueue[0];
+};
+
+#endif /* RVT_ABI_USER_H */
diff --git a/providers/hfi1verbs/hfiverbs.h b/providers/hfi1verbs/hfiverbs.h index 070a01c..558fa2a 100644
--- a/providers/hfi1verbs/hfiverbs.h
+++ b/providers/hfi1verbs/hfiverbs.h
@@ -65,7 +65,8 @@
 
 #include <infiniband/driver.h>
 #include <infiniband/verbs.h>
-
+#define RDMA_ATOMIC_UAPI(_type, _name)  _Atomic(__##_type) _name 
+#include "rdma/rvt-abi.h"
 #define PFX		"hfi1: "
 
 struct hfi1_device {
@@ -77,39 +78,11 @@ struct hfi1_context {
 	struct verbs_context	ibv_ctx;
 };
 
-/*
- * This structure needs to have the same size and offsets as
- * the kernel's ib_wc structure since it is memory mapped.
- */
-struct hfi1_wc {
-	uint64_t		wr_id;
-	enum ibv_wc_status	status;
-	enum ibv_wc_opcode	opcode;
-	uint32_t		vendor_err;
-	uint32_t		byte_len;
-	uint32_t		imm_data;	/* in network byte order */
-	uint32_t		qp_num;
-	uint32_t		src_qp;
-	enum ibv_wc_flags	wc_flags;
-	uint16_t		pkey_index;
-	uint16_t		slid;
-	uint8_t			sl;
-	uint8_t			dlid_path_bits;
-	uint8_t			port_num;
-};
-
-struct hfi1_cq_wc {
-	_Atomic(uint32_t)	head;
-	_Atomic(uint32_t)	tail;
-	struct hfi1_wc		queue[1];
-};
-
 struct hfi1_cq {
-	struct ibv_cq		ibv_cq;
-	struct hfi1_cq_wc	*queue;
-	pthread_spinlock_t	lock;
+       struct ibv_cq           ibv_cq;
+       struct rvt_cq_wc       *queue;
+       pthread_spinlock_t      lock;
 };
-
 /*
  * Receive work request queue entry.
  * The size of the sg_list is determined when the QP is created and stored diff --git a/providers/hfi1verbs/verbs.c b/providers/hfi1verbs/verbs.c index ff001f6..dcf6714 100644
--- a/providers/hfi1verbs/verbs.c
+++ b/providers/hfi1verbs/verbs.c
@@ -63,10 +63,15 @@
 #include <pthread.h>
 #include <sys/mman.h>
 #include <errno.h>
-
 #include "hfiverbs.h"
 #include "hfi-abi.h"
 
+static size_t hfi1_cq_size(int cqe)
+{
+	return sizeof(struct rvt_cq_wc) +
+	       sizeof(struct ib_uverbs_wc) * (cqe + 1); }
+
 int hfi1_query_device(struct ibv_context *context,
 		       struct ibv_device_attr *attr)
 {
@@ -186,7 +191,7 @@ struct ibv_cq *hfi1_create_cq(struct ibv_context *context, int cqe,
 		return NULL;
 	}
 
-	size = sizeof(struct hfi1_cq_wc) + sizeof(struct hfi1_wc) * cqe;
+	size = hfi1_cq_size(cqe);
 	cq->queue = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED,
 			 context->cmd_fd, resp.offset);
 	if ((void *) cq->queue == MAP_FAILED) { @@ -231,8 +236,7 @@ int hfi1_resize_cq(struct ibv_cq *ibcq, int cqe)
 	memset(&resp, 0, sizeof(resp));
 	pthread_spin_lock(&cq->lock);
 	/* Save the old size so we can unmmap the queue. */
-	size = sizeof(struct hfi1_cq_wc) +
-		(sizeof(struct hfi1_wc) * cq->ibv_cq.cqe);
+	size = hfi1_cq_size(cq->ibv_cq.cqe);
 	ret = ibv_cmd_resize_cq(ibcq, cqe, &cmd, sizeof cmd,
 				&resp.ibv_resp, sizeof resp);
 	if (ret) {
@@ -240,8 +244,7 @@ int hfi1_resize_cq(struct ibv_cq *ibcq, int cqe)
 		return ret;
 	}
 	(void) munmap(cq->queue, size);
-	size = sizeof(struct hfi1_cq_wc) +
-		(sizeof(struct hfi1_wc) * cq->ibv_cq.cqe);
+	size = hfi1_cq_size(cqe);
 	cq->queue = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED,
 			 ibcq->context->cmd_fd, resp.offset);
 	ret = errno;
@@ -269,8 +272,8 @@ int hfi1_destroy_cq(struct ibv_cq *ibcq)
 	if (ret)
 		return ret;
 
-	(void) munmap(cq->queue, sizeof(struct hfi1_cq_wc) +
-				 (sizeof(struct hfi1_wc) * cq->ibv_cq.cqe));
+	(void) munmap(cq->queue, hfi1_cq_size(cq->ibv_cq.cqe));
+
 	free(cq);
 	return 0;
 }
@@ -288,7 +291,7 @@ int hfi1_destroy_cq_v1(struct ibv_cq *ibcq)  int hfi1_poll_cq(struct ibv_cq *ibcq, int ne, struct ibv_wc *wc)  {
 	struct hfi1_cq *cq = to_icq(ibcq);
-	struct hfi1_cq_wc *q;
+	struct rvt_cq_wc *q;
 	int npolled;
 	uint32_t tail;
 
@@ -300,7 +303,7 @@ int hfi1_poll_cq(struct ibv_cq *ibcq, int ne, struct ibv_wc *wc)
 			break;
 		/* Make sure entry is read after head index is read. */
 		atomic_thread_fence(memory_order_acquire);
-		memcpy(wc, &q->queue[tail], sizeof(*wc));
+		memcpy(wc, &q->uqueue[tail], sizeof(*wc));
 		if (tail == cq->ibv_cq.cqe)
 			tail = 0;
 		else
Jason Gunthorpe Sept. 10, 2018, 3:14 p.m. UTC | #2
On Mon, Sep 10, 2018 at 07:12:00AM -0700, Kamenee Arumugam wrote:
> From: Arumugam, Kamenee <kamenee.arumugam@intel.com>
> 
> hfi1_wc struct is the same struct as ib_uverbs_wc and hfi1_cq_wc
> is not in the uapi header. Remove hfi1_wc and hfi1_cq_wc struct
> from providers. Include rvt-abi.h header that have rvt_cq_wc
> struct definition into kernel-headers.
> 
> The member ib_uverbs_wc arrray in rvt_cq_wc is replaced with
> one in rvt-abi. Therefore,plus one to the number of cq entries.
> 
> Change-Id: I01250acb9d17f63ac737f632462f34617fd5b61a
> Reviewed-by: Mike Marciniszyn <mike.marciniszyn@intel.com>
> Signed-off-by: Kamenee Arumugam <kamenee.arumugam@intel.com>
>  kernel-headers/CMakeLists.txt  |    1 +
>  kernel-headers/rdma/rvt-abi.h  |   74 ++++++++++++++++++++++++++++++++++++++++

Changes in these files have to be sent through the kernel tree.

Jason

>  providers/hfi1verbs/hfiverbs.h |   37 +++-----------------
>  providers/hfi1verbs/verbs.c    |   23 +++++++-----
>  4 files changed, 93 insertions(+), 42 deletions(-)
>  create mode 100755 kernel-headers/rdma/rvt-abi.h
>
> diff --git a/kernel-headers/CMakeLists.txt b/kernel-headers/CMakeLists.txt
> index 16ba165..631db9c 100644
> +++ b/kernel-headers/CMakeLists.txt
> @@ -24,6 +24,7 @@ publish_internal_headers(rdma
>    rdma/rdma_user_ioctl_cmds.h
>    rdma/rdma_user_rxe.h
>    rdma/vmw_pvrdma-abi.h
> +  rdma/rvt-abi.h
>    )
>  
>  publish_internal_headers(rdma/hfi
> diff --git a/kernel-headers/rdma/rvt-abi.h b/kernel-headers/rdma/rvt-abi.h
> new file mode 100755
> index 0000000..8cff1df
> +++ b/kernel-headers/rdma/rvt-abi.h
> @@ -0,0 +1,74 @@
> +/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
> +/*
> + * Copyright(c) 2015 - 2018 Intel Corporation.
> + *
> + * This file is provided under a dual BSD/GPLv2 license.  When using or
> + * redistributing this file, you may do so under either license.
> + *
> + * GPL LICENSE SUMMARY
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of version 2 of the GNU General Public License as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * General Public License for more details.
> + *
> + * BSD LICENSE
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + *
> + *  - Redistributions of source code must retain the above copyright
> + *    notice, this list of conditions and the following disclaimer.
> + *  - Redistributions in binary form must reproduce the above copyright
> + *    notice, this list of conditions and the following disclaimer in
> + *    the documentation and/or other materials provided with the
> + *    distribution.
> + *  - Neither the name of Intel Corporation nor the names of its
> + *    contributors may be used to endorse or promote products derived
> + *    from this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + *
> + */
> +
> +/*
> + * This file contains defines, structures, etc. that are used
> + * to communicate between kernel and user code.
> + */
> +
> +#ifndef RVT_ABI_USER_H
> +#define RVT_ABI_USER_H
> +
> +#include <linux/types.h>
> +#ifndef RDMA_ATOMIC_UAPI
> +#define RDMA_ATOMIC_UAPI(_type, _name) _type _name
> +#endif
> +/*
> + * This structure is used to contain the head pointer, tail pointer,
> + * and completion queue entries as a single memory allocation so
> + * it can be mmap'ed into user space.
> + */
> +struct rvt_cq_wc {
> +	/* index of next entry to fill */
> +	RDMA_ATOMIC_UAPI(u32, head);
> +	/* index of next ib_poll_cq() entry */
> +	RDMA_ATOMIC_UAPI(u32, tail);
> +
> +	/* these are actually size ibcq.cqe + 1 */
> +	struct ib_uverbs_wc uqueue[0];
> +};
> +
> +#endif /* RVT_ABI_USER_H */
> diff --git a/providers/hfi1verbs/hfiverbs.h b/providers/hfi1verbs/hfiverbs.h
> index 070a01c..558fa2a 100644
> +++ b/providers/hfi1verbs/hfiverbs.h
> @@ -65,7 +65,8 @@
>  
>  #include <infiniband/driver.h>
>  #include <infiniband/verbs.h>
> -
> +#define RDMA_ATOMIC_UAPI(_type, _name)  _Atomic(__##_type) _name

Hmm, we have a at least on other place I know of that could use this,
currently it just casts in the single place it reads..

Jason
diff mbox series

Patch

diff --git a/kernel-headers/CMakeLists.txt b/kernel-headers/CMakeLists.txt
index 16ba165..631db9c 100644
--- a/kernel-headers/CMakeLists.txt
+++ b/kernel-headers/CMakeLists.txt
@@ -24,6 +24,7 @@  publish_internal_headers(rdma
   rdma/rdma_user_ioctl_cmds.h
   rdma/rdma_user_rxe.h
   rdma/vmw_pvrdma-abi.h
+  rdma/rvt-abi.h
   )
 
 publish_internal_headers(rdma/hfi
diff --git a/kernel-headers/rdma/rvt-abi.h b/kernel-headers/rdma/rvt-abi.h
new file mode 100755
index 0000000..8cff1df
--- /dev/null
+++ b/kernel-headers/rdma/rvt-abi.h
@@ -0,0 +1,74 @@ 
+/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
+/*
+ * Copyright(c) 2015 - 2018 Intel Corporation.
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  - Neither the name of Intel Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *
+ */
+
+/*
+ * This file contains defines, structures, etc. that are used
+ * to communicate between kernel and user code.
+ */
+
+#ifndef RVT_ABI_USER_H
+#define RVT_ABI_USER_H
+
+#include <linux/types.h>
+#ifndef RDMA_ATOMIC_UAPI
+#define RDMA_ATOMIC_UAPI(_type, _name) _type _name
+#endif
+/*
+ * This structure is used to contain the head pointer, tail pointer,
+ * and completion queue entries as a single memory allocation so
+ * it can be mmap'ed into user space.
+ */
+struct rvt_cq_wc {
+	/* index of next entry to fill */
+	RDMA_ATOMIC_UAPI(u32, head);
+	/* index of next ib_poll_cq() entry */
+	RDMA_ATOMIC_UAPI(u32, tail);
+
+	/* these are actually size ibcq.cqe + 1 */
+	struct ib_uverbs_wc uqueue[0];
+};
+
+#endif /* RVT_ABI_USER_H */
diff --git a/providers/hfi1verbs/hfiverbs.h b/providers/hfi1verbs/hfiverbs.h
index 070a01c..558fa2a 100644
--- a/providers/hfi1verbs/hfiverbs.h
+++ b/providers/hfi1verbs/hfiverbs.h
@@ -65,7 +65,8 @@ 
 
 #include <infiniband/driver.h>
 #include <infiniband/verbs.h>
-
+#define RDMA_ATOMIC_UAPI(_type, _name)  _Atomic(__##_type) _name
+#include "rdma/rvt-abi.h"
 #define PFX		"hfi1: "
 
 struct hfi1_device {
@@ -77,39 +78,11 @@  struct hfi1_context {
 	struct verbs_context	ibv_ctx;
 };
 
-/*
- * This structure needs to have the same size and offsets as
- * the kernel's ib_wc structure since it is memory mapped.
- */
-struct hfi1_wc {
-	uint64_t		wr_id;
-	enum ibv_wc_status	status;
-	enum ibv_wc_opcode	opcode;
-	uint32_t		vendor_err;
-	uint32_t		byte_len;
-	uint32_t		imm_data;	/* in network byte order */
-	uint32_t		qp_num;
-	uint32_t		src_qp;
-	enum ibv_wc_flags	wc_flags;
-	uint16_t		pkey_index;
-	uint16_t		slid;
-	uint8_t			sl;
-	uint8_t			dlid_path_bits;
-	uint8_t			port_num;
-};
-
-struct hfi1_cq_wc {
-	_Atomic(uint32_t)	head;
-	_Atomic(uint32_t)	tail;
-	struct hfi1_wc		queue[1];
-};
-
 struct hfi1_cq {
-	struct ibv_cq		ibv_cq;
-	struct hfi1_cq_wc	*queue;
-	pthread_spinlock_t	lock;
+       struct ibv_cq           ibv_cq;
+       struct rvt_cq_wc       *queue;
+       pthread_spinlock_t      lock;
 };
-
 /*
  * Receive work request queue entry.
  * The size of the sg_list is determined when the QP is created and stored
diff --git a/providers/hfi1verbs/verbs.c b/providers/hfi1verbs/verbs.c
index ff001f6..dcf6714 100644
--- a/providers/hfi1verbs/verbs.c
+++ b/providers/hfi1verbs/verbs.c
@@ -63,10 +63,15 @@ 
 #include <pthread.h>
 #include <sys/mman.h>
 #include <errno.h>
-
 #include "hfiverbs.h"
 #include "hfi-abi.h"
 
+static size_t hfi1_cq_size(int cqe)
+{
+	return sizeof(struct rvt_cq_wc) +
+	       sizeof(struct ib_uverbs_wc) * (cqe + 1);
+}
+
 int hfi1_query_device(struct ibv_context *context,
 		       struct ibv_device_attr *attr)
 {
@@ -186,7 +191,7 @@  struct ibv_cq *hfi1_create_cq(struct ibv_context *context, int cqe,
 		return NULL;
 	}
 
-	size = sizeof(struct hfi1_cq_wc) + sizeof(struct hfi1_wc) * cqe;
+	size = hfi1_cq_size(cqe);
 	cq->queue = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED,
 			 context->cmd_fd, resp.offset);
 	if ((void *) cq->queue == MAP_FAILED) {
@@ -231,8 +236,7 @@  int hfi1_resize_cq(struct ibv_cq *ibcq, int cqe)
 	memset(&resp, 0, sizeof(resp));
 	pthread_spin_lock(&cq->lock);
 	/* Save the old size so we can unmmap the queue. */
-	size = sizeof(struct hfi1_cq_wc) +
-		(sizeof(struct hfi1_wc) * cq->ibv_cq.cqe);
+	size = hfi1_cq_size(cq->ibv_cq.cqe);
 	ret = ibv_cmd_resize_cq(ibcq, cqe, &cmd, sizeof cmd,
 				&resp.ibv_resp, sizeof resp);
 	if (ret) {
@@ -240,8 +244,7 @@  int hfi1_resize_cq(struct ibv_cq *ibcq, int cqe)
 		return ret;
 	}
 	(void) munmap(cq->queue, size);
-	size = sizeof(struct hfi1_cq_wc) +
-		(sizeof(struct hfi1_wc) * cq->ibv_cq.cqe);
+	size = hfi1_cq_size(cqe);
 	cq->queue = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED,
 			 ibcq->context->cmd_fd, resp.offset);
 	ret = errno;
@@ -269,8 +272,8 @@  int hfi1_destroy_cq(struct ibv_cq *ibcq)
 	if (ret)
 		return ret;
 
-	(void) munmap(cq->queue, sizeof(struct hfi1_cq_wc) +
-				 (sizeof(struct hfi1_wc) * cq->ibv_cq.cqe));
+	(void) munmap(cq->queue, hfi1_cq_size(cq->ibv_cq.cqe));
+
 	free(cq);
 	return 0;
 }
@@ -288,7 +291,7 @@  int hfi1_destroy_cq_v1(struct ibv_cq *ibcq)
 int hfi1_poll_cq(struct ibv_cq *ibcq, int ne, struct ibv_wc *wc)
 {
 	struct hfi1_cq *cq = to_icq(ibcq);
-	struct hfi1_cq_wc *q;
+	struct rvt_cq_wc *q;
 	int npolled;
 	uint32_t tail;
 
@@ -300,7 +303,7 @@  int hfi1_poll_cq(struct ibv_cq *ibcq, int ne, struct ibv_wc *wc)
 			break;
 		/* Make sure entry is read after head index is read. */
 		atomic_thread_fence(memory_order_acquire);
-		memcpy(wc, &q->queue[tail], sizeof(*wc));
+		memcpy(wc, &q->uqueue[tail], sizeof(*wc));
 		if (tail == cq->ibv_cq.cqe)
 			tail = 0;
 		else