aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/mthca/mthca_provider.c
diff options
context:
space:
mode:
authorMichael S. Tsirkin <mst@mellanox.co.il>2005-04-16 18:26:30 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:26:30 -0400
commite0f5fdca1ca9d1659b920827e5cf6dbad20e5391 (patch)
tree71e6410e14c4c285ce128e99070a38ded75a14f7 /drivers/infiniband/hw/mthca/mthca_provider.c
parentd0a9d25cdcd511dd523357bc902979220dc72a2e (diff)
[PATCH] IB/mthca: add fast memory region implementation
Implement fast memory regions (FMRs), where the driver writes directly into the HCA's translation tables rather than requiring a firmware command. For Tavor, MTTs for FMR are separate from regular MTTs, and are reserved at driver initialization. This is done to limit the amount of virtual memory needed to map the MTTs. For Arbel, there's no such limitation, and all MTTs and MPTs may be used for FMR or for regular MR. Signed-off-by: Michael S. Tsirkin <mst@mellanox.co.il> Signed-off-by: Roland Dreier <roland@topspin.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/infiniband/hw/mthca/mthca_provider.c')
-rw-r--r--drivers/infiniband/hw/mthca/mthca_provider.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c
index daa54db00aa9..28199e42b36f 100644
--- a/drivers/infiniband/hw/mthca/mthca_provider.c
+++ b/drivers/infiniband/hw/mthca/mthca_provider.c
@@ -574,6 +574,74 @@ static int mthca_dereg_mr(struct ib_mr *mr)
574 return 0; 574 return 0;
575} 575}
576 576
577static struct ib_fmr *mthca_alloc_fmr(struct ib_pd *pd, int mr_access_flags,
578 struct ib_fmr_attr *fmr_attr)
579{
580 struct mthca_fmr *fmr;
581 int err;
582
583 fmr = kmalloc(sizeof *fmr, GFP_KERNEL);
584 if (!fmr)
585 return ERR_PTR(-ENOMEM);
586
587 memcpy(&fmr->attr, fmr_attr, sizeof *fmr_attr);
588 err = mthca_fmr_alloc(to_mdev(pd->device), to_mpd(pd)->pd_num,
589 convert_access(mr_access_flags), fmr);
590
591 if (err) {
592 kfree(fmr);
593 return ERR_PTR(err);
594 }
595
596 return &fmr->ibmr;
597}
598
599static int mthca_dealloc_fmr(struct ib_fmr *fmr)
600{
601 struct mthca_fmr *mfmr = to_mfmr(fmr);
602 int err;
603
604 err = mthca_free_fmr(to_mdev(fmr->device), mfmr);
605 if (err)
606 return err;
607
608 kfree(mfmr);
609 return 0;
610}
611
612static int mthca_unmap_fmr(struct list_head *fmr_list)
613{
614 struct ib_fmr *fmr;
615 int err;
616 u8 status;
617 struct mthca_dev *mdev = NULL;
618
619 list_for_each_entry(fmr, fmr_list, list) {
620 if (mdev && to_mdev(fmr->device) != mdev)
621 return -EINVAL;
622 mdev = to_mdev(fmr->device);
623 }
624
625 if (!mdev)
626 return 0;
627
628 if (mdev->hca_type == ARBEL_NATIVE) {
629 list_for_each_entry(fmr, fmr_list, list)
630 mthca_arbel_fmr_unmap(mdev, to_mfmr(fmr));
631
632 wmb();
633 } else
634 list_for_each_entry(fmr, fmr_list, list)
635 mthca_tavor_fmr_unmap(mdev, to_mfmr(fmr));
636
637 err = mthca_SYNC_TPT(mdev, &status);
638 if (err)
639 return err;
640 if (status)
641 return -EINVAL;
642 return 0;
643}
644
577static ssize_t show_rev(struct class_device *cdev, char *buf) 645static ssize_t show_rev(struct class_device *cdev, char *buf)
578{ 646{
579 struct mthca_dev *dev = container_of(cdev, struct mthca_dev, ib_dev.class_dev); 647 struct mthca_dev *dev = container_of(cdev, struct mthca_dev, ib_dev.class_dev);
@@ -637,6 +705,17 @@ int mthca_register_device(struct mthca_dev *dev)
637 dev->ib_dev.get_dma_mr = mthca_get_dma_mr; 705 dev->ib_dev.get_dma_mr = mthca_get_dma_mr;
638 dev->ib_dev.reg_phys_mr = mthca_reg_phys_mr; 706 dev->ib_dev.reg_phys_mr = mthca_reg_phys_mr;
639 dev->ib_dev.dereg_mr = mthca_dereg_mr; 707 dev->ib_dev.dereg_mr = mthca_dereg_mr;
708
709 if (dev->mthca_flags & MTHCA_FLAG_FMR) {
710 dev->ib_dev.alloc_fmr = mthca_alloc_fmr;
711 dev->ib_dev.unmap_fmr = mthca_unmap_fmr;
712 dev->ib_dev.dealloc_fmr = mthca_dealloc_fmr;
713 if (dev->hca_type == ARBEL_NATIVE)
714 dev->ib_dev.map_phys_fmr = mthca_arbel_map_phys_fmr;
715 else
716 dev->ib_dev.map_phys_fmr = mthca_tavor_map_phys_fmr;
717 }
718
640 dev->ib_dev.attach_mcast = mthca_multicast_attach; 719 dev->ib_dev.attach_mcast = mthca_multicast_attach;
641 dev->ib_dev.detach_mcast = mthca_multicast_detach; 720 dev->ib_dev.detach_mcast = mthca_multicast_detach;
642 dev->ib_dev.process_mad = mthca_process_mad; 721 dev->ib_dev.process_mad = mthca_process_mad;