IB/rxe: Avoid scheduling tasklet for userspace QP
authorParav Pandit <pandit.parav@gmail.com>
Wed, 28 Sep 2016 20:24:12 +0000 (20:24 +0000)
committerDoug Ledford <dledford@redhat.com>
Thu, 6 Oct 2016 17:50:04 +0000 (13:50 -0400)
This patch avoids scheduing tasklet for WQE and protocol processing
for user space QP. It performs the task in calling process context.

To improve code readability kernel specific post_send handling moved to
post_send_kernel() function.

Signed-off-by: Parav Pandit <pandit.parav@gmail.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/infiniband/sw/rxe/rxe_verbs.c

index 4552be960c6ace8b89f0d92b5fe6d426965173f2..a5af6917fc1cfe543b5712d0ad3b98ae099392aa 100644 (file)
@@ -801,26 +801,15 @@ err1:
        return err;
 }
 
-static int rxe_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
-                        struct ib_send_wr **bad_wr)
+static int rxe_post_send_kernel(struct rxe_qp *qp, struct ib_send_wr *wr,
+                               struct ib_send_wr **bad_wr)
 {
        int err = 0;
-       struct rxe_qp *qp = to_rqp(ibqp);
        unsigned int mask;
        unsigned int length = 0;
        int i;
        int must_sched;
 
-       if (unlikely(!qp->valid)) {
-               *bad_wr = wr;
-               return -EINVAL;
-       }
-
-       if (unlikely(qp->req.state < QP_STATE_READY)) {
-               *bad_wr = wr;
-               return -EINVAL;
-       }
-
        while (wr) {
                mask = wr_opcode_mask(wr->opcode, qp);
                if (unlikely(!mask)) {
@@ -861,6 +850,29 @@ static int rxe_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
        return err;
 }
 
+static int rxe_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
+                        struct ib_send_wr **bad_wr)
+{
+       struct rxe_qp *qp = to_rqp(ibqp);
+
+       if (unlikely(!qp->valid)) {
+               *bad_wr = wr;
+               return -EINVAL;
+       }
+
+       if (unlikely(qp->req.state < QP_STATE_READY)) {
+               *bad_wr = wr;
+               return -EINVAL;
+       }
+
+       if (qp->is_user) {
+               /* Utilize process context to do protocol processing */
+               rxe_run_task(&qp->req.task, 0);
+               return 0;
+       } else
+               return rxe_post_send_kernel(qp, wr, bad_wr);
+}
+
 static int rxe_post_recv(struct ib_qp *ibqp, struct ib_recv_wr *wr,
                         struct ib_recv_wr **bad_wr)
 {