diff options
author | Devesh Sharma <devesh.sharma@emulex.com> | 2014-02-04 01:26:54 -0500 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2014-04-03 11:29:34 -0400 |
commit | ea61762679cd4d409dcaa6f502f190f4c8156d09 (patch) | |
tree | 5827d101e41788a4ff93c2368eaa4d3ec5ae337a /drivers/infiniband/hw/ocrdma/ocrdma.h | |
parent | bc1b04ab34a1485339571242cb0fbad823835685 (diff) |
RDMA/ocrdma: EQ full catastrophe avoidance
Stale entries in the CQ being destroyed causes hardware to generate
EQEs indefinitely for a given CQ. Thus causing uncontrolled execution
of irq_handler. This patch fixes this using following sementics:
* irq_handler will ring EQ doorbell atleast once and implement budgeting scheme.
* cq_destroy will count number of valid entires during destroy and ring
cq-db so that hardware does not generate uncontrolled EQE.
* cq_destroy will synchronize with last running irq_handler instance.
* arm_cq will always defer arming CQ till poll_cq, except for the first arm_cq call.
* poll_cq will always ring cq-db with arm=SET if arm_cq was called prior to enter poll_cq.
* poll_cq will always ring cq-db with arm=UNSET if arm_cq was not called prior to enter poll_cq.
Signed-off-by: Devesh Sharma <devesh.sharma@emulex.com>
Signed-off-by: Selvin Xavier <selvin.xavier@emulex.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband/hw/ocrdma/ocrdma.h')
-rw-r--r-- | drivers/infiniband/hw/ocrdma/ocrdma.h | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma.h b/drivers/infiniband/hw/ocrdma/ocrdma.h index 7c001b97b23f..61f508e74823 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma.h +++ b/drivers/infiniband/hw/ocrdma/ocrdma.h | |||
@@ -209,8 +209,8 @@ struct ocrdma_cq { | |||
209 | */ | 209 | */ |
210 | u32 max_hw_cqe; | 210 | u32 max_hw_cqe; |
211 | bool phase_change; | 211 | bool phase_change; |
212 | bool armed, solicited; | 212 | bool deferred_arm, deferred_sol; |
213 | bool arm_needed; | 213 | bool first_arm; |
214 | 214 | ||
215 | spinlock_t cq_lock ____cacheline_aligned; /* provide synchronization | 215 | spinlock_t cq_lock ____cacheline_aligned; /* provide synchronization |
216 | * to cq polling | 216 | * to cq polling |
@@ -223,6 +223,7 @@ struct ocrdma_cq { | |||
223 | struct ocrdma_ucontext *ucontext; | 223 | struct ocrdma_ucontext *ucontext; |
224 | dma_addr_t pa; | 224 | dma_addr_t pa; |
225 | u32 len; | 225 | u32 len; |
226 | u32 cqe_cnt; | ||
226 | 227 | ||
227 | /* head of all qp's sq and rq for which cqes need to be flushed | 228 | /* head of all qp's sq and rq for which cqes need to be flushed |
228 | * by the software. | 229 | * by the software. |
@@ -436,4 +437,17 @@ static inline int ocrdma_resolve_dmac(struct ocrdma_dev *dev, | |||
436 | return 0; | 437 | return 0; |
437 | } | 438 | } |
438 | 439 | ||
440 | static inline int ocrdma_get_eq_table_index(struct ocrdma_dev *dev, | ||
441 | int eqid) | ||
442 | { | ||
443 | int indx; | ||
444 | |||
445 | for (indx = 0; indx < dev->eq_cnt; indx++) { | ||
446 | if (dev->eq_tbl[indx].q.id == eqid) | ||
447 | return indx; | ||
448 | } | ||
449 | |||
450 | return -EINVAL; | ||
451 | } | ||
452 | |||
439 | #endif | 453 | #endif |