]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
RDS: RDMA: Fix the composite message user notification
authorSantosh Shilimkar <santosh.shilimkar@oracle.com>
Fri, 19 Feb 2016 04:06:47 +0000 (20:06 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 8 Oct 2017 08:14:16 +0000 (10:14 +0200)
[ Upstream commit 941f8d55f6d613a460a5e080d25a38509f45eb75 ]

When application sends an RDS RDMA composite message consist of
RDMA transfer to be followed up by non RDMA payload, it expect to
be notified *only* when the full message gets delivered. RDS RDMA
notification doesn't behave this way though.

Thanks to Venkat for debug and root casuing the issue
where only first part of the message(RDMA) was
successfully delivered but remainder payload delivery failed.
In that case, application should not be notified with
a false positive of message delivery success.

Fix this case by making sure the user gets notified only after
the full message delivery.

Reviewed-by: Venkat Venkatsubra <venkat.x.venkatsubra@oracle.com>
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
net/rds/ib_send.c
net/rds/rdma.c
net/rds/rds.h
net/rds/send.c

index eac30bf486d747ce5a78f001de2d65cc5fc7d891..094e2a12860a8a267b9f7dcf137e590d137364ed 100644 (file)
@@ -68,16 +68,6 @@ static void rds_ib_send_complete(struct rds_message *rm,
        complete(rm, notify_status);
 }
 
-static void rds_ib_send_unmap_data(struct rds_ib_connection *ic,
-                                  struct rm_data_op *op,
-                                  int wc_status)
-{
-       if (op->op_nents)
-               ib_dma_unmap_sg(ic->i_cm_id->device,
-                               op->op_sg, op->op_nents,
-                               DMA_TO_DEVICE);
-}
-
 static void rds_ib_send_unmap_rdma(struct rds_ib_connection *ic,
                                   struct rm_rdma_op *op,
                                   int wc_status)
@@ -138,6 +128,21 @@ static void rds_ib_send_unmap_atomic(struct rds_ib_connection *ic,
                rds_ib_stats_inc(s_ib_atomic_fadd);
 }
 
+static void rds_ib_send_unmap_data(struct rds_ib_connection *ic,
+                                  struct rm_data_op *op,
+                                  int wc_status)
+{
+       struct rds_message *rm = container_of(op, struct rds_message, data);
+
+       if (op->op_nents)
+               ib_dma_unmap_sg(ic->i_cm_id->device,
+                               op->op_sg, op->op_nents,
+                               DMA_TO_DEVICE);
+
+       if (rm->rdma.op_active && rm->data.op_notify)
+               rds_ib_send_unmap_rdma(ic, &rm->rdma, wc_status);
+}
+
 /*
  * Unmap the resources associated with a struct send_work.
  *
index 4c93badeabf2236d3d90c933e6169174b3ba68d1..8d3a851a347697a0bf3c03666cad863d78962c3a 100644 (file)
@@ -626,6 +626,16 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm,
                }
                op->op_notifier->n_user_token = args->user_token;
                op->op_notifier->n_status = RDS_RDMA_SUCCESS;
+
+               /* Enable rmda notification on data operation for composite
+                * rds messages and make sure notification is enabled only
+                * for the data operation which follows it so that application
+                * gets notified only after full message gets delivered.
+                */
+               if (rm->data.op_sg) {
+                       rm->rdma.op_notify = 0;
+                       rm->data.op_notify = !!(args->flags & RDS_RDMA_NOTIFY_ME);
+               }
        }
 
        /* The cookie contains the R_Key of the remote memory region, and
index 0e2797bdc3162b26995aeee2974187fdea62f5bf..4588860f4c3bb4e1cc7bed295349917d25912484 100644 (file)
@@ -378,6 +378,7 @@ struct rds_message {
                } rdma;
                struct rm_data_op {
                        unsigned int            op_active:1;
+                       unsigned int            op_notify:1;
                        unsigned int            op_nents;
                        unsigned int            op_count;
                        unsigned int            op_dmasg;
index c9cdb358ea885e3e356cc675b579f1313ed94ff9..6815f03324d759bd78412c0435749ff717adf907 100644 (file)
@@ -467,12 +467,14 @@ void rds_rdma_send_complete(struct rds_message *rm, int status)
        struct rm_rdma_op *ro;
        struct rds_notifier *notifier;
        unsigned long flags;
+       unsigned int notify = 0;
 
        spin_lock_irqsave(&rm->m_rs_lock, flags);
 
+       notify =  rm->rdma.op_notify | rm->data.op_notify;
        ro = &rm->rdma;
        if (test_bit(RDS_MSG_ON_SOCK, &rm->m_flags) &&
-           ro->op_active && ro->op_notify && ro->op_notifier) {
+           ro->op_active && notify && ro->op_notifier) {
                notifier = ro->op_notifier;
                rs = rm->m_rs;
                sock_hold(rds_rs_to_sk(rs));