aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/core/uverbs.h1
-rw-r--r--drivers/infiniband/core/uverbs_main.c14
-rw-r--r--drivers/infiniband/hw/mthca/mthca_cq.c6
-rw-r--r--drivers/infiniband/hw/mthca/mthca_provider.c6
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_ib.c6
5 files changed, 25 insertions, 8 deletions
diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h
index 57347f1e82c1..7696022f9a4e 100644
--- a/drivers/infiniband/core/uverbs.h
+++ b/drivers/infiniband/core/uverbs.h
@@ -61,6 +61,7 @@ struct ib_uverbs_event_file {
61 int fd; 61 int fd;
62 int is_async; 62 int is_async;
63 wait_queue_head_t poll_wait; 63 wait_queue_head_t poll_wait;
64 struct fasync_struct *async_queue;
64 struct list_head event_list; 65 struct list_head event_list;
65}; 66};
66 67
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index fbbe03d8c901..eb99e693dec2 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -257,11 +257,19 @@ static void ib_uverbs_event_release(struct ib_uverbs_event_file *file)
257 spin_unlock_irq(&file->lock); 257 spin_unlock_irq(&file->lock);
258} 258}
259 259
260static int ib_uverbs_event_fasync(int fd, struct file *filp, int on)
261{
262 struct ib_uverbs_event_file *file = filp->private_data;
263
264 return fasync_helper(fd, filp, on, &file->async_queue);
265}
266
260static int ib_uverbs_event_close(struct inode *inode, struct file *filp) 267static int ib_uverbs_event_close(struct inode *inode, struct file *filp)
261{ 268{
262 struct ib_uverbs_event_file *file = filp->private_data; 269 struct ib_uverbs_event_file *file = filp->private_data;
263 270
264 ib_uverbs_event_release(file); 271 ib_uverbs_event_release(file);
272 ib_uverbs_event_fasync(-1, filp, 0);
265 kref_put(&file->uverbs_file->ref, ib_uverbs_release_file); 273 kref_put(&file->uverbs_file->ref, ib_uverbs_release_file);
266 274
267 return 0; 275 return 0;
@@ -276,7 +284,8 @@ static struct file_operations uverbs_event_fops = {
276 */ 284 */
277 .read = ib_uverbs_event_read, 285 .read = ib_uverbs_event_read,
278 .poll = ib_uverbs_event_poll, 286 .poll = ib_uverbs_event_poll,
279 .release = ib_uverbs_event_close 287 .release = ib_uverbs_event_close,
288 .fasync = ib_uverbs_event_fasync
280}; 289};
281 290
282void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context) 291void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context)
@@ -296,6 +305,7 @@ void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context)
296 spin_unlock_irqrestore(&file->comp_file[0].lock, flags); 305 spin_unlock_irqrestore(&file->comp_file[0].lock, flags);
297 306
298 wake_up_interruptible(&file->comp_file[0].poll_wait); 307 wake_up_interruptible(&file->comp_file[0].poll_wait);
308 kill_fasync(&file->comp_file[0].async_queue, SIGIO, POLL_IN);
299} 309}
300 310
301static void ib_uverbs_async_handler(struct ib_uverbs_file *file, 311static void ib_uverbs_async_handler(struct ib_uverbs_file *file,
@@ -316,6 +326,7 @@ static void ib_uverbs_async_handler(struct ib_uverbs_file *file,
316 spin_unlock_irqrestore(&file->async_file.lock, flags); 326 spin_unlock_irqrestore(&file->async_file.lock, flags);
317 327
318 wake_up_interruptible(&file->async_file.poll_wait); 328 wake_up_interruptible(&file->async_file.poll_wait);
329 kill_fasync(&file->async_file.async_queue, SIGIO, POLL_IN);
319} 330}
320 331
321void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr) 332void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr)
@@ -350,6 +361,7 @@ static int ib_uverbs_event_init(struct ib_uverbs_event_file *file,
350 INIT_LIST_HEAD(&file->event_list); 361 INIT_LIST_HEAD(&file->event_list);
351 init_waitqueue_head(&file->poll_wait); 362 init_waitqueue_head(&file->poll_wait);
352 file->uverbs_file = uverbs_file; 363 file->uverbs_file = uverbs_file;
364 file->async_queue = NULL;
353 365
354 file->fd = get_unused_fd(); 366 file->fd = get_unused_fd();
355 if (file->fd < 0) 367 if (file->fd < 0)
diff --git a/drivers/infiniband/hw/mthca/mthca_cq.c b/drivers/infiniband/hw/mthca/mthca_cq.c
index b5aea7b869f6..5687c3014522 100644
--- a/drivers/infiniband/hw/mthca/mthca_cq.c
+++ b/drivers/infiniband/hw/mthca/mthca_cq.c
@@ -373,8 +373,12 @@ static int handle_error_cqe(struct mthca_dev *dev, struct mthca_cq *cq,
373 * If we're at the end of the WQE chain, or we've used up our 373 * If we're at the end of the WQE chain, or we've used up our
374 * doorbell count, free the CQE. Otherwise just update it for 374 * doorbell count, free the CQE. Otherwise just update it for
375 * the next poll operation. 375 * the next poll operation.
376 *
377 * This does not apply to mem-free HCAs: they don't use the
378 * doorbell count field, and so we should always free the CQE.
376 */ 379 */
377 if (!(new_wqe & cpu_to_be32(0x3f)) || (!cqe->db_cnt && dbd)) 380 if (mthca_is_memfree(dev) ||
381 !(new_wqe & cpu_to_be32(0x3f)) || (!cqe->db_cnt && dbd))
378 return 0; 382 return 0;
379 383
380 cqe->db_cnt = cpu_to_be16(be16_to_cpu(cqe->db_cnt) - dbd); 384 cqe->db_cnt = cpu_to_be16(be16_to_cpu(cqe->db_cnt) - dbd);
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
index 7a58ce90e179..81919a7b4935 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.c
+++ b/drivers/infiniband/hw/mthca/mthca_provider.c
@@ -349,9 +349,9 @@ static int mthca_mmap_uar(struct ib_ucontext *context,
349 349
350 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 350 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
351 351
352 if (remap_pfn_range(vma, vma->vm_start, 352 if (io_remap_pfn_range(vma, vma->vm_start,
353 to_mucontext(context)->uar.pfn, 353 to_mucontext(context)->uar.pfn,
354 PAGE_SIZE, vma->vm_page_prot)) 354 PAGE_SIZE, vma->vm_page_prot))
355 return -EAGAIN; 355 return -EAGAIN;
356 356
357 return 0; 357 return 0;
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index 8238766746b2..eee82363167d 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -81,7 +81,7 @@ void ipoib_free_ah(struct kref *kref)
81 81
82 unsigned long flags; 82 unsigned long flags;
83 83
84 if (ah->last_send <= priv->tx_tail) { 84 if ((int) priv->tx_tail - (int) ah->last_send >= 0) {
85 ipoib_dbg(priv, "Freeing ah %p\n", ah->ah); 85 ipoib_dbg(priv, "Freeing ah %p\n", ah->ah);
86 ib_destroy_ah(ah->ah); 86 ib_destroy_ah(ah->ah);
87 kfree(ah); 87 kfree(ah);
@@ -355,7 +355,7 @@ static void __ipoib_reap_ah(struct net_device *dev)
355 355
356 spin_lock_irq(&priv->lock); 356 spin_lock_irq(&priv->lock);
357 list_for_each_entry_safe(ah, tah, &priv->dead_ahs, list) 357 list_for_each_entry_safe(ah, tah, &priv->dead_ahs, list)
358 if (ah->last_send <= priv->tx_tail) { 358 if ((int) priv->tx_tail - (int) ah->last_send >= 0) {
359 list_del(&ah->list); 359 list_del(&ah->list);
360 list_add_tail(&ah->list, &remove_list); 360 list_add_tail(&ah->list, &remove_list);
361 } 361 }
@@ -486,7 +486,7 @@ int ipoib_ib_dev_stop(struct net_device *dev)
486 * assume the HW is wedged and just free up 486 * assume the HW is wedged and just free up
487 * all our pending work requests. 487 * all our pending work requests.
488 */ 488 */
489 while (priv->tx_tail < priv->tx_head) { 489 while ((int) priv->tx_tail - (int) priv->tx_head < 0) {
490 tx_req = &priv->tx_ring[priv->tx_tail & 490 tx_req = &priv->tx_ring[priv->tx_tail &
491 (IPOIB_TX_RING_SIZE - 1)]; 491 (IPOIB_TX_RING_SIZE - 1)];
492 dma_unmap_single(priv->ca->dma_device, 492 dma_unmap_single(priv->ca->dma_device,