|
@@ -69,6 +69,14 @@ err1:
|
|
|
static void rxe_send_complete(unsigned long data)
|
|
|
{
|
|
|
struct rxe_cq *cq = (struct rxe_cq *)data;
|
|
|
+ unsigned long flags;
|
|
|
+
|
|
|
+ spin_lock_irqsave(&cq->cq_lock, flags);
|
|
|
+ if (cq->is_dying) {
|
|
|
+ spin_unlock_irqrestore(&cq->cq_lock, flags);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ spin_unlock_irqrestore(&cq->cq_lock, flags);
|
|
|
|
|
|
cq->ibcq.comp_handler(&cq->ibcq, cq->ibcq.cq_context);
|
|
|
}
|
|
@@ -97,6 +105,8 @@ int rxe_cq_from_init(struct rxe_dev *rxe, struct rxe_cq *cq, int cqe,
|
|
|
if (udata)
|
|
|
cq->is_user = 1;
|
|
|
|
|
|
+ cq->is_dying = false;
|
|
|
+
|
|
|
tasklet_init(&cq->comp_task, rxe_send_complete, (unsigned long)cq);
|
|
|
|
|
|
spin_lock_init(&cq->cq_lock);
|
|
@@ -156,6 +166,15 @@ int rxe_cq_post(struct rxe_cq *cq, struct rxe_cqe *cqe, int solicited)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+void rxe_cq_disable(struct rxe_cq *cq)
|
|
|
+{
|
|
|
+ unsigned long flags;
|
|
|
+
|
|
|
+ spin_lock_irqsave(&cq->cq_lock, flags);
|
|
|
+ cq->is_dying = true;
|
|
|
+ spin_unlock_irqrestore(&cq->cq_lock, flags);
|
|
|
+}
|
|
|
+
|
|
|
void rxe_cq_cleanup(struct rxe_pool_entry *arg)
|
|
|
{
|
|
|
struct rxe_cq *cq = container_of(arg, typeof(*cq), pelem);
|