]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
sif: Refactor PQP state out of sif_dev.
authorKnut Omang <knut.omang@oracle.com>
Sun, 23 Oct 2016 07:31:26 +0000 (09:31 +0200)
committerKnut Omang <knut.omang@oracle.com>
Fri, 11 Nov 2016 16:36:53 +0000 (17:36 +0100)
Prepare handling of PQPs for the additional complexity
of resurrect upon errors and query for undetected
error conditions by moving some of the state
now directly in sif_dev into a new sif_pqp_info
struct.

Already complex logic for PQP handling is going to
increase in complexity. We need to consolidate
to be able to keep clean and easily maintainable
interfaces.

Orabug: 24715634

Signed-off-by: Knut Omang <knut.omang@oracle.com>
drivers/infiniband/hw/sif/sif_dev.h
drivers/infiniband/hw/sif/sif_fmr.c
drivers/infiniband/hw/sif/sif_hwi.c
drivers/infiniband/hw/sif/sif_pqp.c
drivers/infiniband/hw/sif/sif_pqp.h

index 30bd7282e39dd2f8a1a0d0c4c37e1ad0f9592909..24ebec373f0abdbf5b1d00cec865cbea7d9c3e40 100644 (file)
@@ -282,14 +282,11 @@ struct sif_dev {
        atomic_t cq_miss_occ; /* Global #times sif_poll_cq had to busy wait (upd.by destroy_cq) */
        struct sif_eps *es; /* State for the EPS comm (sif_epsc.h) */
        struct sif_table ba[sif_tab_max]; /* Base address setup structures */
-       struct sif_pqp **pqp;  /* PSIF management QPs */
+       struct sif_pqp_info pqi;  /* PSIF management QP infrastructure */
        struct sif_cb **kernel_cb[2]; /* cb's for the kernel (bw and low latency per cpu) */
-       int pqp_cnt;              /* Number of PQPs set up */
-       atomic_t next_pqp;        /* Used for round robin assignment of pqp */
        int kernel_cb_cnt[2];     /* Number of CBs set up for the kernel for each kind */
        struct sif_idr xrcd_refs; /* Mgmt of sif_xrcd allocations */
        struct sif_idr pd_refs;   /* Mgmt of sif_pd allocations */
-       struct sif_spqp_pool ki_spqp; /* Stencil PQPs for key invalidates */
        /* Misc settings */
        struct completion ready_for_events; /* Set when we are ready to receive events from sif */
        bool registered;        /* Set when we are registered with the verbs layer */
index 0dc18dd28ea9e33ae1592187aa47284ed1149673..35ea394a707ffd48d75bae8de387c0ae5cea4471 100644 (file)
@@ -166,7 +166,7 @@ int sif_unmap_phys_fmr_list(struct list_head *fmr_list)
                if (!spqp)
                        sif_log(sdev, SIF_PQPT,
                                "All %u configured stencil pqps busy, consider increasing ki_spqp_size",
-                               sdev->ki_spqp.pool_sz);
+                               sdev->pqi.ki_s.pool_sz);
        }
 
        /* Check if we should do a brute force whole MMU caches flush */
index 560fa5466ff945034a948b319f6d8894bfd97b9b..007facc1894fa8349191c6b13c79a6ea5c0a9a4e 100644 (file)
@@ -49,8 +49,8 @@ static int sif_pqp_init(struct sif_dev *sdev)
        int ret = 0;
        uint n_pqps = es->eqs.cnt - 2;
 
-       sdev->pqp = sif_kmalloc(sdev, sizeof(struct sif_pqp *) * n_pqps, GFP_KERNEL | __GFP_ZERO);
-       if (!sdev->pqp)
+       sdev->pqi.pqp = sif_kmalloc(sdev, sizeof(struct sif_pqp *) * n_pqps, GFP_KERNEL | __GFP_ZERO);
+       if (!sdev->pqi.pqp)
                return -ENOMEM;
 
        for (i = 0; i < n_pqps; i++) {
@@ -65,14 +65,14 @@ static int sif_pqp_init(struct sif_dev *sdev)
                        ret = PTR_ERR(pqp);
                        goto failed;
                }
-               sdev->pqp[i] = pqp;
+               sdev->pqi.pqp[i] = pqp;
        }
-       sdev->pqp_cnt = i;
-       atomic_set(&sdev->next_pqp, 0);
+       sdev->pqi.cnt = i;
+       atomic_set(&sdev->pqi.next, 0);
        return 0;
 
 failed:
-       sdev->pqp_cnt = i;
+       sdev->pqi.cnt = i;
        sif_pqp_fini(sdev);
        return ret;
 }
@@ -84,21 +84,21 @@ static void sif_pqp_fini(struct sif_dev *sdev)
         * during takedown as these operations themselves
         * generate PQP requests..
         */
-       while (sdev->pqp_cnt > 0) {
-               int i = sdev->pqp_cnt - 1;
-               struct sif_pqp *pqp = sdev->pqp[i];
+       while (sdev->pqi.cnt > 0) {
+               int i = sdev->pqi.cnt - 1;
+               struct sif_pqp *pqp = sdev->pqi.pqp[i];
 
                if (i > 0) {
                        /* Remove ourselves first, except the final PQP */
-                       sdev->pqp[i] = NULL;
-                       sdev->pqp_cnt--;
+                       sdev->pqi.pqp[i] = NULL;
+                       sdev->pqi.cnt--;
                }
                sif_destroy_pqp(sdev, pqp);
                if (i == 0)
-                       sdev->pqp_cnt--;
+                       sdev->pqi.cnt--;
        }
-       kfree(sdev->pqp);
-       sdev->pqp = NULL;
+       kfree(sdev->pqi.pqp);
+       sdev->pqi.pqp = NULL;
 }
 
 
@@ -111,25 +111,25 @@ static int sif_ki_spqp_init(struct sif_dev *sdev)
        int n = max(sif_ki_spqp_size, 0U);
        int bm_len = max(1, n/8);
 
-       mutex_init(&sdev->ki_spqp.lock);
-       sdev->ki_spqp.spqp =
+       mutex_init(&sdev->pqi.ki_s.lock);
+       sdev->pqi.ki_s.spqp =
 #ifdef CONFIG_NUMA
                kmalloc_node(sizeof(struct sif_st_pqp *) * n, GFP_KERNEL | __GFP_ZERO,
                        sdev->pdev->dev.numa_node);
 #else
                kmalloc(sizeof(struct sif_st_pqp *) * n, GFP_KERNEL | __GFP_ZERO);
 #endif
-       if (!sdev->ki_spqp.spqp)
+       if (!sdev->pqi.ki_s.spqp)
                return -ENOMEM;
 
-       sdev->ki_spqp.bitmap =
+       sdev->pqi.ki_s.bitmap =
 #ifdef CONFIG_NUMA
                kmalloc_node(sizeof(ulong) * bm_len, GFP_KERNEL | __GFP_ZERO,
                        sdev->pdev->dev.numa_node);
 #else
                kmalloc(sizeof(ulong) * bm_len, GFP_KERNEL | __GFP_ZERO);
 #endif
-       if (!sdev->ki_spqp.bitmap) {
+       if (!sdev->pqi.ki_s.bitmap) {
                ret = -ENOMEM;
                goto bm_failed;
        }
@@ -141,10 +141,10 @@ static int sif_ki_spqp_init(struct sif_dev *sdev)
                        ret = PTR_ERR(spqp);
                        break;
                }
-               sdev->ki_spqp.spqp[i] = spqp;
+               sdev->pqi.ki_s.spqp[i] = spqp;
                spqp->index = i;
        }
-       sdev->ki_spqp.pool_sz = i;
+       sdev->pqi.ki_s.pool_sz = i;
        if (ret && i) {
                sif_log(sdev, SIF_INFO, "Failed to create %d INVALIDATE_KEY stencil QPs", i);
                sif_ki_spqp_fini(sdev);
@@ -154,7 +154,7 @@ static int sif_ki_spqp_init(struct sif_dev *sdev)
                sif_log(sdev, SIF_INIT, "Created %d INVALIDATE_KEY stencil QPs", i);
 bm_failed:
        if (ret)
-               kfree(sdev->ki_spqp.spqp);
+               kfree(sdev->pqi.ki_s.spqp);
        return 0;  /* Never fail on stencil PQP allocation */
 }
 
@@ -163,13 +163,13 @@ static void sif_ki_spqp_fini(struct sif_dev *sdev)
 {
        int i;
 
-       if (!sdev->ki_spqp.spqp)
+       if (!sdev->pqi.ki_s.spqp)
                return;
-       for (i = sdev->ki_spqp.pool_sz - 1; i >= 0; i--)
-               sif_destroy_st_pqp(sdev, sdev->ki_spqp.spqp[i]);
-       kfree(sdev->ki_spqp.bitmap);
-       kfree(sdev->ki_spqp.spqp);
-       sdev->ki_spqp.spqp = NULL;
+       for (i = sdev->pqi.ki_s.pool_sz - 1; i >= 0; i--)
+               sif_destroy_st_pqp(sdev, sdev->pqi.ki_s.spqp[i]);
+       kfree(sdev->pqi.ki_s.bitmap);
+       kfree(sdev->pqi.ki_s.spqp);
+       sdev->pqi.ki_s.spqp = NULL;
 }
 
 
index 04f917c29c881e2414b48ff60a2ce37ac10808ee..a78ee531f03a79724ad2f1c93334436dd4c3a929 100644 (file)
@@ -376,9 +376,9 @@ static struct sif_pqp *find_any_pqp(struct sif_dev *sdev)
 {
        int cpu;
 
-       for (cpu = 0; cpu < sdev->pqp_cnt; cpu++)
-               if (sdev->pqp[cpu])
-                       return sdev->pqp[cpu];
+       for (cpu = 0; cpu < sdev->pqi.cnt; cpu++)
+               if (sdev->pqi.pqp[cpu])
+                       return sdev->pqi.pqp[cpu];
        return NULL;
 }
 
@@ -386,7 +386,7 @@ static struct sif_pqp *find_any_pqp(struct sif_dev *sdev)
 struct sif_pqp *get_pqp_same_eq(struct sif_dev *sdev, int comp_vector)
 {
        unsigned int pqp_index = comp_vector - 2;
-       struct sif_pqp *pqp = sdev->pqp_cnt ? sdev->pqp[pqp_index % sdev->pqp_cnt] : NULL;
+       struct sif_pqp *pqp = sdev->pqi.cnt ? sdev->pqi.pqp[pqp_index % sdev->pqi.cnt] : NULL;
 
        if (unlikely(!pqp)) {
                /* Typically during take down */
@@ -400,7 +400,7 @@ struct sif_pqp *get_pqp_same_eq(struct sif_dev *sdev, int comp_vector)
 struct sif_pqp *get_pqp(struct sif_dev *sdev)
 {
        unsigned int cpu = smp_processor_id();
-       struct sif_pqp *pqp = sdev->pqp_cnt ? sdev->pqp[cpu % sdev->pqp_cnt] : NULL;
+       struct sif_pqp *pqp = sdev->pqi.cnt ? sdev->pqi.pqp[cpu % sdev->pqi.cnt] : NULL;
 
        if (unlikely(!pqp)) {
                /* Typically during take down */
@@ -413,9 +413,9 @@ struct sif_pqp *get_pqp(struct sif_dev *sdev)
 struct sif_pqp *get_next_pqp(struct sif_dev *sdev)
 {
        struct sif_pqp *pqp;
-       int next = atomic_inc_return(&sdev->next_pqp) % sdev->pqp_cnt;
+       int next = atomic_inc_return(&sdev->pqi.next) % sdev->pqi.cnt;
 
-       pqp = sdev->pqp[next];
+       pqp = sdev->pqi.pqp[next];
        if (unlikely(!pqp)) {
                /* Typically during take down */
                return find_any_pqp(sdev);
@@ -1044,13 +1044,13 @@ struct sif_st_pqp *sif_alloc_ki_spqp(struct sif_dev *sdev)
        int index;
        struct sif_st_pqp *spqp = NULL;
 
-       mutex_lock(&sdev->ki_spqp.lock);
-       index = find_next_zero_bit(sdev->ki_spqp.bitmap, sdev->ki_spqp.pool_sz, 0);
-       if (index < sdev->ki_spqp.pool_sz) {
-               set_bit(index, sdev->ki_spqp.bitmap);
-               spqp = sdev->ki_spqp.spqp[index];
+       mutex_lock(&sdev->pqi.ki_s.lock);
+       index = find_next_zero_bit(sdev->pqi.ki_s.bitmap, sdev->pqi.ki_s.pool_sz, 0);
+       if (index < sdev->pqi.ki_s.pool_sz) {
+               set_bit(index, sdev->pqi.ki_s.bitmap);
+               spqp = sdev->pqi.ki_s.spqp[index];
        }
-       mutex_unlock(&sdev->ki_spqp.lock);
+       mutex_unlock(&sdev->pqi.ki_s.lock);
        sif_log(sdev, SIF_PQPT, "bit index %d", index);
        return spqp;
 }
@@ -1059,8 +1059,8 @@ void sif_release_ki_spqp(struct sif_st_pqp *spqp)
 {
        struct sif_dev *sdev = to_sdev(spqp->pqp.cq->ibcq.device);
 
-       mutex_lock(&sdev->ki_spqp.lock);
-       clear_bit(spqp->index, sdev->ki_spqp.bitmap);
-       mutex_unlock(&sdev->ki_spqp.lock);
+       mutex_lock(&sdev->pqi.ki_s.lock);
+       clear_bit(spqp->index, sdev->pqi.ki_s.bitmap);
+       mutex_unlock(&sdev->pqi.ki_s.lock);
        sif_log(sdev, SIF_PQPT, "bit index %d", spqp->index);
 }
index 106aec75e2585a03bf4bdc2345b44e12c6231076..1f94338816ce6640393ba1a803291063e1398f21 100644 (file)
@@ -72,6 +72,8 @@ struct sif_cqe {
        }
 
 
+
+/* Per PQP state/configuration info */
 struct sif_pqp {
        struct sif_qp *qp;  /* The qp used */
        struct sif_cq *cq;  /* Associated completion queue for this priv.QP */
@@ -83,6 +85,43 @@ struct sif_pqp {
        u16 lowpri_lim;  /* Max number of outstanding low priority reqs */
 };
 
+/* Stencil PQP support - pre-populated PQPs for special performance sensitive use cases */
+
+#define SPQP_DOORBELL_INTERVAL 8192
+
+struct sif_st_pqp {
+       struct sif_pqp pqp;     /* The PQP to use - must be first */
+       struct sif_sq *sq;      /* Short path to sq */
+       struct sif_sq_sw *sq_sw;/* Short path to sq_sw */
+       int index;              /* The index of this st_pqp within it's pool */
+       u16 doorbell_interval;  /* Interval between each doorbell write */
+       u16 doorbell_seq;       /* Seq.no to use in next doorbell */
+       u16 next_doorbell_seq;  /* Next seqno to ring doorbell */
+       u16 req_compl;          /* Number of completions requested */
+       u16 next_poll_seq;      /* Next seqno to set completion and wait/poll for one */
+       u64 checksum;           /* Host endian partial checksum of stencil WR entries */
+};
+
+
+/* Stencil PQP management */
+struct sif_spqp_pool {
+       struct mutex lock;        /* Protects access to this pool */
+       struct sif_st_pqp **spqp; /* Key invalidate stencil PQPs */
+       u32 pool_sz;              /* Number of stencil PQPs set up */
+       ulong *bitmap;            /* Bitmap for allocation from spqp */
+};
+
+/* PQP specific global state/configuration (embedded in sif_dev)
+ */
+struct sif_pqp_info {
+       struct sif_pqp **pqp; /* The array of "normal" PQPs */
+       int cnt;        /* Number of PQPs set up */
+       atomic_t next;  /* Used for round robin assignment of pqp */
+
+       /* Stencil PQPs for key invalidates */
+       struct sif_spqp_pool ki_s;
+};
+
 struct sif_pqp *sif_create_pqp(struct sif_dev *sdev, int comp_vector);
 int sif_destroy_pqp(struct sif_dev *sdev, struct sif_pqp *pqp);
 
@@ -148,31 +187,6 @@ int sif_gen_sq_flush_cqe(struct sif_dev *sdev, struct sif_sq *sq,
 
 /* Stencil PQP support - pre-populated PQPs for special performance sensitive use cases */
 
-#define SPQP_DOORBELL_INTERVAL 8192
-
-struct sif_st_pqp {
-       struct sif_pqp pqp;     /* The PQP to use - must be first */
-       struct sif_sq *sq;      /* Short path to sq */
-       struct sif_sq_sw *sq_sw;/* Short path to sq_sw */
-       int index;              /* The index of this st_pqp within it's pool */
-       u16 doorbell_interval;  /* Interval between each doorbell write */
-       u16 doorbell_seq;       /* Seq.no to use in next doorbell */
-       u16 next_doorbell_seq;  /* Next seqno to ring doorbell */
-       u16 req_compl;          /* Number of completions requested */
-       u16 next_poll_seq;      /* Next seqno to set completion and wait/poll for one */
-       u64 checksum;           /* Host endian partial checksum of stencil WR entries */
-};
-
-
-/* Stencil PQP management */
-struct sif_spqp_pool {
-       struct mutex lock;        /* Protects access to this pool */
-       struct sif_st_pqp **spqp; /* Key invalidate stencil PQPs */
-       u32 pool_sz;              /* Number of stencil PQPs set up */
-       ulong *bitmap;            /* Bitmap for allocation from spqp */
-};
-
-
 struct sif_st_pqp *sif_create_inv_key_st_pqp(struct sif_dev *sdev);
 
 /* get exclusive access to a stencil pqp */