diff options
Diffstat (limited to 'drivers/infiniband/hw/ehca/ehca_cq.c')
-rw-r--r-- | drivers/infiniband/hw/ehca/ehca_cq.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/infiniband/hw/ehca/ehca_cq.c b/drivers/infiniband/hw/ehca/ehca_cq.c index 6ebfa27e4e16..e2cdc1a16fe9 100644 --- a/drivers/infiniband/hw/ehca/ehca_cq.c +++ b/drivers/infiniband/hw/ehca/ehca_cq.c | |||
@@ -146,6 +146,7 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, | |||
146 | spin_lock_init(&my_cq->spinlock); | 146 | spin_lock_init(&my_cq->spinlock); |
147 | spin_lock_init(&my_cq->cb_lock); | 147 | spin_lock_init(&my_cq->cb_lock); |
148 | spin_lock_init(&my_cq->task_lock); | 148 | spin_lock_init(&my_cq->task_lock); |
149 | init_waitqueue_head(&my_cq->wait_completion); | ||
149 | my_cq->ownpid = current->tgid; | 150 | my_cq->ownpid = current->tgid; |
150 | 151 | ||
151 | cq = &my_cq->ib_cq; | 152 | cq = &my_cq->ib_cq; |
@@ -302,6 +303,16 @@ create_cq_exit1: | |||
302 | return cq; | 303 | return cq; |
303 | } | 304 | } |
304 | 305 | ||
306 | static int get_cq_nr_events(struct ehca_cq *my_cq) | ||
307 | { | ||
308 | int ret; | ||
309 | unsigned long flags; | ||
310 | spin_lock_irqsave(&ehca_cq_idr_lock, flags); | ||
311 | ret = my_cq->nr_events; | ||
312 | spin_unlock_irqrestore(&ehca_cq_idr_lock, flags); | ||
313 | return ret; | ||
314 | } | ||
315 | |||
305 | int ehca_destroy_cq(struct ib_cq *cq) | 316 | int ehca_destroy_cq(struct ib_cq *cq) |
306 | { | 317 | { |
307 | u64 h_ret; | 318 | u64 h_ret; |
@@ -329,10 +340,11 @@ int ehca_destroy_cq(struct ib_cq *cq) | |||
329 | } | 340 | } |
330 | 341 | ||
331 | spin_lock_irqsave(&ehca_cq_idr_lock, flags); | 342 | spin_lock_irqsave(&ehca_cq_idr_lock, flags); |
332 | while (my_cq->nr_callbacks) { | 343 | while (my_cq->nr_events) { |
333 | spin_unlock_irqrestore(&ehca_cq_idr_lock, flags); | 344 | spin_unlock_irqrestore(&ehca_cq_idr_lock, flags); |
334 | yield(); | 345 | wait_event(my_cq->wait_completion, !get_cq_nr_events(my_cq)); |
335 | spin_lock_irqsave(&ehca_cq_idr_lock, flags); | 346 | spin_lock_irqsave(&ehca_cq_idr_lock, flags); |
347 | /* recheck nr_events to assure no cqe has just arrived */ | ||
336 | } | 348 | } |
337 | 349 | ||
338 | idr_remove(&ehca_cq_idr, my_cq->token); | 350 | idr_remove(&ehca_cq_idr, my_cq->token); |