RDMA/siw: Change CQ flags from 64->32 bits
authorBernard Metzler <bmt@zurich.ibm.com>
Fri, 9 Aug 2019 15:18:16 +0000 (17:18 +0200)
committerDoug Ledford <dledford@redhat.com>
Tue, 13 Aug 2019 16:22:06 +0000 (12:22 -0400)
This patch changes the driver/user shared (mmapped) CQ notification
flags field from unsigned 64-bits size to unsigned 32-bits size. This
enables building siw on 32-bit architectures.

This patch changes the siw-abi, but as siw was only just merged in
this merge window cycle, there are no released kernels with the prior
abi.  We are making no attempt to be binary compatible with siw user
space libraries prior to the merge of siw into the upstream kernel,
only moving forward with upstream kernels and upstream rdma-core
provided siw libraries are we guaranteeing compatibility.

Signed-off-by: Bernard Metzler <bmt@zurich.ibm.com>
Link: https://lore.kernel.org/r/20190809151816.13018-1-bmt@zurich.ibm.com
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/infiniband/sw/siw/Kconfig
drivers/infiniband/sw/siw/siw.h
drivers/infiniband/sw/siw/siw_qp.c
drivers/infiniband/sw/siw/siw_verbs.c
include/uapi/rdma/siw-abi.h

index dace276aea1413baa46f292a7e522381c6f00250..b622fc62f2cd6d4699cb9a1ed6ead9e44cd6bee2 100644 (file)
@@ -1,6 +1,6 @@
 config RDMA_SIW
        tristate "Software RDMA over TCP/IP (iWARP) driver"
-       depends on INET && INFINIBAND && LIBCRC32C && 64BIT
+       depends on INET && INFINIBAND && LIBCRC32C
        select DMA_VIRT_OPS
        help
        This driver implements the iWARP RDMA transport over
index 03fd7b2f595f1f35c5a535e068a60913d5b879ed..77b1aabf6ff357245ea7b3c3b04ee570320eb9b1 100644 (file)
@@ -214,7 +214,7 @@ struct siw_wqe {
 struct siw_cq {
        struct ib_cq base_cq;
        spinlock_t lock;
-       u64 *notify;
+       struct siw_cq_ctrl *notify;
        struct siw_cqe *queue;
        u32 cq_put;
        u32 cq_get;
index e27bd5b35b966280e5ecfc2c2cc2affbc75ec597..0990307c5d2cde951d646b2d06e990670f44a709 100644 (file)
@@ -1013,18 +1013,24 @@ out:
  */
 static bool siw_cq_notify_now(struct siw_cq *cq, u32 flags)
 {
-       u64 cq_notify;
+       u32 cq_notify;
 
        if (!cq->base_cq.comp_handler)
                return false;
 
-       cq_notify = READ_ONCE(*cq->notify);
+       /* Read application shared notification state */
+       cq_notify = READ_ONCE(cq->notify->flags);
 
        if ((cq_notify & SIW_NOTIFY_NEXT_COMPLETION) ||
            ((cq_notify & SIW_NOTIFY_SOLICITED) &&
             (flags & SIW_WQE_SOLICITED))) {
-               /* dis-arm CQ */
-               smp_store_mb(*cq->notify, SIW_NOTIFY_NOT);
+               /*
+                * CQ notification is one-shot: Since the
+                * current CQE causes user notification,
+                * the CQ gets dis-aremd and must be re-aremd
+                * by the user for a new notification.
+                */
+               WRITE_ONCE(cq->notify->flags, SIW_NOTIFY_NOT);
 
                return true;
        }
index 32dc79d0e8981770ddf2069f69b286adc5116b3d..e7f3a2379d9d87858ddb83bd7abce843ed330a7a 100644 (file)
@@ -1049,7 +1049,7 @@ int siw_create_cq(struct ib_cq *base_cq, const struct ib_cq_init_attr *attr,
 
        spin_lock_init(&cq->lock);
 
-       cq->notify = &((struct siw_cq_ctrl *)&cq->queue[size])->notify;
+       cq->notify = (struct siw_cq_ctrl *)&cq->queue[size];
 
        if (udata) {
                struct siw_uresp_create_cq uresp = {};
@@ -1141,11 +1141,17 @@ int siw_req_notify_cq(struct ib_cq *base_cq, enum ib_cq_notify_flags flags)
        siw_dbg_cq(cq, "flags: 0x%02x\n", flags);
 
        if ((flags & IB_CQ_SOLICITED_MASK) == IB_CQ_SOLICITED)
-               /* CQ event for next solicited completion */
-               smp_store_mb(*cq->notify, SIW_NOTIFY_SOLICITED);
+               /*
+                * Enable CQ event for next solicited completion.
+                * and make it visible to all associated producers.
+                */
+               smp_store_mb(cq->notify->flags, SIW_NOTIFY_SOLICITED);
        else
-               /* CQ event for any signalled completion */
-               smp_store_mb(*cq->notify, SIW_NOTIFY_ALL);
+               /*
+                * Enable CQ event for any signalled completion.
+                * and make it visible to all associated producers.
+                */
+               smp_store_mb(cq->notify->flags, SIW_NOTIFY_ALL);
 
        if (flags & IB_CQ_REPORT_MISSED_EVENTS)
                return cq->cq_put - cq->cq_get;
index 7de68f1dc707f0d55805e3fafa3c97a363d06e0b..af735f55b2911208077ad70d2e83e750125001e0 100644 (file)
@@ -180,6 +180,7 @@ struct siw_cqe {
  * to control CQ arming.
  */
 struct siw_cq_ctrl {
-       __aligned_u64 notify;
+       __u32 flags;
+       __u32 pad;
 };
 #endif