diff options
author | Eli Cohen <eli@mellanox.co.il> | 2006-03-02 15:40:46 -0500 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2006-03-20 13:08:22 -0500 |
commit | 651eaac92894f8b6761c51b6637ea9cacea7fba2 (patch) | |
tree | 8be06461ef870b7d130ebce39f55fe93af6ac542 /drivers/infiniband/hw/mthca/mthca_mr.c | |
parent | 27d56300647f6e76847bc2407d7abc782fe87495 (diff) |
IB/mthca: Optimize large messages on Sinai HCAs
Sinai (one-port PCI Express) HCAs get improved throughput for messages
bigger than 80 KB in DDR mode if memory keys are formatted in a
specific way. The enhancement only works if the memory key table is
smaller than 2^24 entries. For larger tables, the enhancement is off
and a warning is printed (to avoid silent performance loss).
Signed-off-by: Eli Cohen <eli@mellanox.co.il>
Signed-off-by: Michael Tsirkin <mst@mellanox.co.il>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/hw/mthca/mthca_mr.c')
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_mr.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/drivers/infiniband/hw/mthca/mthca_mr.c b/drivers/infiniband/hw/mthca/mthca_mr.c index 0b48048ad0f8..698b62125765 100644 --- a/drivers/infiniband/hw/mthca/mthca_mr.c +++ b/drivers/infiniband/hw/mthca/mthca_mr.c | |||
@@ -76,6 +76,8 @@ struct mthca_mpt_entry { | |||
76 | #define MTHCA_MPT_STATUS_SW 0xF0 | 76 | #define MTHCA_MPT_STATUS_SW 0xF0 |
77 | #define MTHCA_MPT_STATUS_HW 0x00 | 77 | #define MTHCA_MPT_STATUS_HW 0x00 |
78 | 78 | ||
79 | #define SINAI_FMR_KEY_INC 0x1000000 | ||
80 | |||
79 | /* | 81 | /* |
80 | * Buddy allocator for MTT segments (currently not very efficient | 82 | * Buddy allocator for MTT segments (currently not very efficient |
81 | * since it doesn't keep a free list and just searches linearly | 83 | * since it doesn't keep a free list and just searches linearly |
@@ -330,6 +332,14 @@ static inline u32 key_to_hw_index(struct mthca_dev *dev, u32 key) | |||
330 | return tavor_key_to_hw_index(key); | 332 | return tavor_key_to_hw_index(key); |
331 | } | 333 | } |
332 | 334 | ||
335 | static inline u32 adjust_key(struct mthca_dev *dev, u32 key) | ||
336 | { | ||
337 | if (dev->mthca_flags & MTHCA_FLAG_SINAI_OPT) | ||
338 | return ((key << 20) & 0x800000) | (key & 0x7fffff); | ||
339 | else | ||
340 | return key; | ||
341 | } | ||
342 | |||
333 | int mthca_mr_alloc(struct mthca_dev *dev, u32 pd, int buffer_size_shift, | 343 | int mthca_mr_alloc(struct mthca_dev *dev, u32 pd, int buffer_size_shift, |
334 | u64 iova, u64 total_size, u32 access, struct mthca_mr *mr) | 344 | u64 iova, u64 total_size, u32 access, struct mthca_mr *mr) |
335 | { | 345 | { |
@@ -345,6 +355,7 @@ int mthca_mr_alloc(struct mthca_dev *dev, u32 pd, int buffer_size_shift, | |||
345 | key = mthca_alloc(&dev->mr_table.mpt_alloc); | 355 | key = mthca_alloc(&dev->mr_table.mpt_alloc); |
346 | if (key == -1) | 356 | if (key == -1) |
347 | return -ENOMEM; | 357 | return -ENOMEM; |
358 | key = adjust_key(dev, key); | ||
348 | mr->ibmr.rkey = mr->ibmr.lkey = hw_index_to_key(dev, key); | 359 | mr->ibmr.rkey = mr->ibmr.lkey = hw_index_to_key(dev, key); |
349 | 360 | ||
350 | if (mthca_is_memfree(dev)) { | 361 | if (mthca_is_memfree(dev)) { |
@@ -504,6 +515,7 @@ int mthca_fmr_alloc(struct mthca_dev *dev, u32 pd, | |||
504 | key = mthca_alloc(&dev->mr_table.mpt_alloc); | 515 | key = mthca_alloc(&dev->mr_table.mpt_alloc); |
505 | if (key == -1) | 516 | if (key == -1) |
506 | return -ENOMEM; | 517 | return -ENOMEM; |
518 | key = adjust_key(dev, key); | ||
507 | 519 | ||
508 | idx = key & (dev->limits.num_mpts - 1); | 520 | idx = key & (dev->limits.num_mpts - 1); |
509 | mr->ibmr.rkey = mr->ibmr.lkey = hw_index_to_key(dev, key); | 521 | mr->ibmr.rkey = mr->ibmr.lkey = hw_index_to_key(dev, key); |
@@ -687,7 +699,10 @@ int mthca_arbel_map_phys_fmr(struct ib_fmr *ibfmr, u64 *page_list, | |||
687 | ++fmr->maps; | 699 | ++fmr->maps; |
688 | 700 | ||
689 | key = arbel_key_to_hw_index(fmr->ibmr.lkey); | 701 | key = arbel_key_to_hw_index(fmr->ibmr.lkey); |
690 | key += dev->limits.num_mpts; | 702 | if (dev->mthca_flags & MTHCA_FLAG_SINAI_OPT) |
703 | key += SINAI_FMR_KEY_INC; | ||
704 | else | ||
705 | key += dev->limits.num_mpts; | ||
691 | fmr->ibmr.lkey = fmr->ibmr.rkey = arbel_hw_index_to_key(key); | 706 | fmr->ibmr.lkey = fmr->ibmr.rkey = arbel_hw_index_to_key(key); |
692 | 707 | ||
693 | *(u8 *) fmr->mem.arbel.mpt = MTHCA_MPT_STATUS_SW; | 708 | *(u8 *) fmr->mem.arbel.mpt = MTHCA_MPT_STATUS_SW; |
@@ -760,6 +775,9 @@ int __devinit mthca_init_mr_table(struct mthca_dev *dev) | |||
760 | else | 775 | else |
761 | dev->mthca_flags |= MTHCA_FLAG_FMR; | 776 | dev->mthca_flags |= MTHCA_FLAG_FMR; |
762 | 777 | ||
778 | if (dev->mthca_flags & MTHCA_FLAG_SINAI_OPT) | ||
779 | mthca_dbg(dev, "Memory key throughput optimization activated.\n"); | ||
780 | |||
763 | err = mthca_buddy_init(&dev->mr_table.mtt_buddy, | 781 | err = mthca_buddy_init(&dev->mr_table.mtt_buddy, |
764 | fls(dev->limits.num_mtt_segs - 1)); | 782 | fls(dev->limits.num_mtt_segs - 1)); |
765 | 783 | ||