From: Arumugam, Kamenee <kamenee.arumugam@xxxxxxxxx> 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@xxxxxxxxx> Signed-off-by: Kamenee Arumugam <kamenee.arumugam@xxxxxxxxx> --- 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