]> git.hungrycats.org Git - linux/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:11:18 +0000 (10:11 +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 1dde91e3dc7033c575dcfc041a23402f98e52239..5deecf4cce7184d0b01b330e833526b834a7bb48 100644 (file)
@@ -102,16 +102,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)
@@ -172,6 +162,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 40084d843e9fe33bc1545f1f573a32780880e223..3738b1920c098d0f785ab5f076125d799b78644f 100644 (file)
@@ -625,6 +625,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 48f8ffc60f8f1cee8e63448fe3aa7aaac0d5d4c1..42af715b63fcaa9c7485c595ca6325180ac493c5 100644 (file)
@@ -360,6 +360,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;
                        struct scatterlist      *op_sg;
index 0bae8d43b0127a5c819755264d0afde918b7ab60..45b800c3cc8381344717dbf06969f617c0ea4b32 100644 (file)
@@ -425,12 +425,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));