IB/iser: Optimize completion polling
authorSagi Grimberg <sagig@mellanox.com>
Wed, 1 Oct 2014 11:02:11 +0000 (14:02 +0300)
committerRoland Dreier <roland@purestorage.com>
Thu, 9 Oct 2014 07:06:07 +0000 (00:06 -0700)
Poll in batch of 16. Since we don't want it on the stack, keep under
iser completion context (iser_comp).

Signed-off-by: Sagi Grimberg <sagig@mellanox.com>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
drivers/infiniband/ulp/iser/iscsi_iser.h
drivers/infiniband/ulp/iser/iser_verbs.c

index 4fcb256..6c3743b 100644 (file)
                                        ISER_MAX_TX_MISC_PDUS         + \
                                        ISER_MAX_RX_MISC_PDUS)
 
+#define ISER_WC_BATCH_COUNT   16
+
 #define ISER_VER                       0x10
 #define ISER_WSV                       0x08
 #define ISER_RSV                       0x04
@@ -273,6 +275,7 @@ struct iscsi_iser_task;
  *
  * @device:     pointer to device handle
  * @cq:         completion queue
+ * @wcs:        work completion array
  * @tasklet:    Tasklet handle
  * @active_qps: Number of active QPs attached
  *              to completion context
@@ -280,6 +283,7 @@ struct iscsi_iser_task;
 struct iser_comp {
        struct iser_device      *device;
        struct ib_cq            *cq;
+       struct ib_wc             wcs[ISER_WC_BATCH_COUNT];
        struct tasklet_struct    tasklet;
        int                      active_qps;
 };
index 805a9bd..82bedbc 100644 (file)
@@ -1232,13 +1232,15 @@ static void iser_cq_tasklet_fn(unsigned long data)
 {
        struct iser_comp *comp = (struct iser_comp *)data;
        struct ib_cq *cq = comp->cq;
-       struct ib_wc wc;
-       int completed = 0;
+       struct ib_wc *const wcs = comp->wcs;
+       int i, n, completed = 0;
 
-       while (ib_poll_cq(cq, 1, &wc) == 1) {
-               iser_handle_wc(&wc);
+       while ((n = ib_poll_cq(cq, ARRAY_SIZE(comp->wcs), wcs)) > 0) {
+               for (i = 0; i < n; i++)
+                       iser_handle_wc(&wcs[i]);
 
-               if (++completed >= iser_cq_poll_limit)
+               completed += n;
+               if (completed >= iser_cq_poll_limit)
                        break;
        }