mr.c (6b7533869523ae58e2b914551305b0e47cbeb247) | mr.c (0113780870b1597ae49f30abfa4957c239f913d3) |
---|---|
1/* 2 * Copyright (c) 2013-2015, Mellanox Technologies. All rights reserved. 3 * Copyright (c) 2020, Intel Corporation. All rights reserved. 4 * 5 * This software is available to you under a choice of one of two 6 * licenses. You may choose to be licensed under the terms of the GNU 7 * General Public License (GPL) Version 2, available from the file 8 * COPYING in the main directory of this source tree, or the --- 105 unchanged lines hidden (view full) --- 114 MLX5_SET(create_mkey_in, async_create->in, opcode, 115 MLX5_CMD_OP_CREATE_MKEY); 116 assign_mkey_variant(dev, &async_create->mkey, async_create->in); 117 return mlx5_cmd_exec_cb(&dev->async_ctx, async_create->in, inlen, 118 async_create->out, outlen, create_mkey_callback, 119 &async_create->cb_work); 120} 121 | 1/* 2 * Copyright (c) 2013-2015, Mellanox Technologies. All rights reserved. 3 * Copyright (c) 2020, Intel Corporation. All rights reserved. 4 * 5 * This software is available to you under a choice of one of two 6 * licenses. You may choose to be licensed under the terms of the GNU 7 * General Public License (GPL) Version 2, available from the file 8 * COPYING in the main directory of this source tree, or the --- 105 unchanged lines hidden (view full) --- 114 MLX5_SET(create_mkey_in, async_create->in, opcode, 115 MLX5_CMD_OP_CREATE_MKEY); 116 assign_mkey_variant(dev, &async_create->mkey, async_create->in); 117 return mlx5_cmd_exec_cb(&dev->async_ctx, async_create->in, inlen, 118 async_create->out, outlen, create_mkey_callback, 119 &async_create->cb_work); 120} 121 |
122static int mr_cache_max_order(struct mlx5_ib_dev *dev); | 122static int mkey_cache_max_order(struct mlx5_ib_dev *dev); |
123static void queue_adjust_cache_locked(struct mlx5_cache_ent *ent); 124 125static int destroy_mkey(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr) 126{ 127 WARN_ON(xa_load(&dev->odp_mkeys, mlx5_base_mkey(mr->mmkey.key))); 128 129 return mlx5_core_destroy_mkey(dev->mdev, mr->mmkey.key); 130} --- 379 unchanged lines hidden (view full) --- 510 511static const struct file_operations limit_fops = { 512 .owner = THIS_MODULE, 513 .open = simple_open, 514 .write = limit_write, 515 .read = limit_read, 516}; 517 | 123static void queue_adjust_cache_locked(struct mlx5_cache_ent *ent); 124 125static int destroy_mkey(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr) 126{ 127 WARN_ON(xa_load(&dev->odp_mkeys, mlx5_base_mkey(mr->mmkey.key))); 128 129 return mlx5_core_destroy_mkey(dev->mdev, mr->mmkey.key); 130} --- 379 unchanged lines hidden (view full) --- 510 511static const struct file_operations limit_fops = { 512 .owner = THIS_MODULE, 513 .open = simple_open, 514 .write = limit_write, 515 .read = limit_read, 516}; 517 |
518static bool someone_adding(struct mlx5_mr_cache *cache) | 518static bool someone_adding(struct mlx5_mkey_cache *cache) |
519{ 520 unsigned int i; 521 | 519{ 520 unsigned int i; 521 |
522 for (i = 0; i < MAX_MR_CACHE_ENTRIES; i++) { | 522 for (i = 0; i < MAX_MKEY_CACHE_ENTRIES; i++) { |
523 struct mlx5_cache_ent *ent = &cache->ent[i]; 524 bool ret; 525 526 xa_lock_irq(&ent->mkeys); 527 ret = ent->stored < ent->limit; 528 xa_unlock_irq(&ent->mkeys); 529 if (ret) 530 return true; --- 33 unchanged lines hidden (view full) --- 564 else 565 mod_delayed_work(ent->dev->cache.wq, &ent->dwork, 0); 566 } 567} 568 569static void __cache_work_func(struct mlx5_cache_ent *ent) 570{ 571 struct mlx5_ib_dev *dev = ent->dev; | 523 struct mlx5_cache_ent *ent = &cache->ent[i]; 524 bool ret; 525 526 xa_lock_irq(&ent->mkeys); 527 ret = ent->stored < ent->limit; 528 xa_unlock_irq(&ent->mkeys); 529 if (ret) 530 return true; --- 33 unchanged lines hidden (view full) --- 564 else 565 mod_delayed_work(ent->dev->cache.wq, &ent->dwork, 0); 566 } 567} 568 569static void __cache_work_func(struct mlx5_cache_ent *ent) 570{ 571 struct mlx5_ib_dev *dev = ent->dev; |
572 struct mlx5_mr_cache *cache = &dev->cache; | 572 struct mlx5_mkey_cache *cache = &dev->cache; |
573 int err; 574 575 xa_lock_irq(&ent->mkeys); 576 if (ent->disabled) 577 goto out; 578 579 if (ent->fill_to_high_water && ent->reserved < 2 * ent->limit && 580 !READ_ONCE(dev->fill_delay)) { --- 95 unchanged lines hidden (view full) --- 676 mr->mmkey.cache_ent = ent; 677 mr->mmkey.type = MLX5_MKEY_MR; 678 init_waitqueue_head(&mr->mmkey.wait); 679 return mr; 680} 681 682static void clean_keys(struct mlx5_ib_dev *dev, int c) 683{ | 573 int err; 574 575 xa_lock_irq(&ent->mkeys); 576 if (ent->disabled) 577 goto out; 578 579 if (ent->fill_to_high_water && ent->reserved < 2 * ent->limit && 580 !READ_ONCE(dev->fill_delay)) { --- 95 unchanged lines hidden (view full) --- 676 mr->mmkey.cache_ent = ent; 677 mr->mmkey.type = MLX5_MKEY_MR; 678 init_waitqueue_head(&mr->mmkey.wait); 679 return mr; 680} 681 682static void clean_keys(struct mlx5_ib_dev *dev, int c) 683{ |
684 struct mlx5_mr_cache *cache = &dev->cache; | 684 struct mlx5_mkey_cache *cache = &dev->cache; |
685 struct mlx5_cache_ent *ent = &cache->ent[c]; 686 u32 mkey; 687 688 cancel_delayed_work(&ent->dwork); 689 xa_lock_irq(&ent->mkeys); 690 while (ent->stored) { 691 mkey = pop_stored_mkey(ent); 692 xa_unlock_irq(&ent->mkeys); 693 mlx5_core_destroy_mkey(dev->mdev, mkey); 694 xa_lock_irq(&ent->mkeys); 695 } 696 xa_unlock_irq(&ent->mkeys); 697} 698 | 685 struct mlx5_cache_ent *ent = &cache->ent[c]; 686 u32 mkey; 687 688 cancel_delayed_work(&ent->dwork); 689 xa_lock_irq(&ent->mkeys); 690 while (ent->stored) { 691 mkey = pop_stored_mkey(ent); 692 xa_unlock_irq(&ent->mkeys); 693 mlx5_core_destroy_mkey(dev->mdev, mkey); 694 xa_lock_irq(&ent->mkeys); 695 } 696 xa_unlock_irq(&ent->mkeys); 697} 698 |
699static void mlx5_mr_cache_debugfs_cleanup(struct mlx5_ib_dev *dev) | 699static void mlx5_mkey_cache_debugfs_cleanup(struct mlx5_ib_dev *dev) |
700{ 701 if (!mlx5_debugfs_root || dev->is_rep) 702 return; 703 704 debugfs_remove_recursive(dev->cache.root); 705 dev->cache.root = NULL; 706} 707 | 700{ 701 if (!mlx5_debugfs_root || dev->is_rep) 702 return; 703 704 debugfs_remove_recursive(dev->cache.root); 705 dev->cache.root = NULL; 706} 707 |
708static void mlx5_mr_cache_debugfs_init(struct mlx5_ib_dev *dev) | 708static void mlx5_mkey_cache_debugfs_init(struct mlx5_ib_dev *dev) |
709{ | 709{ |
710 struct mlx5_mr_cache *cache = &dev->cache; | 710 struct mlx5_mkey_cache *cache = &dev->cache; |
711 struct mlx5_cache_ent *ent; 712 struct dentry *dir; 713 int i; 714 715 if (!mlx5_debugfs_root || dev->is_rep) 716 return; 717 718 cache->root = debugfs_create_dir("mr_cache", mlx5_debugfs_get_dev_root(dev->mdev)); 719 | 711 struct mlx5_cache_ent *ent; 712 struct dentry *dir; 713 int i; 714 715 if (!mlx5_debugfs_root || dev->is_rep) 716 return; 717 718 cache->root = debugfs_create_dir("mr_cache", mlx5_debugfs_get_dev_root(dev->mdev)); 719 |
720 for (i = 0; i < MAX_MR_CACHE_ENTRIES; i++) { | 720 for (i = 0; i < MAX_MKEY_CACHE_ENTRIES; i++) { |
721 ent = &cache->ent[i]; 722 sprintf(ent->name, "%d", ent->order); 723 dir = debugfs_create_dir(ent->name, cache->root); 724 debugfs_create_file("size", 0600, dir, ent, &size_fops); 725 debugfs_create_file("limit", 0600, dir, ent, &limit_fops); 726 debugfs_create_ulong("cur", 0400, dir, &ent->stored); 727 debugfs_create_u32("miss", 0600, dir, &ent->miss); 728 } 729} 730 731static void delay_time_func(struct timer_list *t) 732{ 733 struct mlx5_ib_dev *dev = from_timer(dev, t, delay_timer); 734 735 WRITE_ONCE(dev->fill_delay, 0); 736} 737 | 721 ent = &cache->ent[i]; 722 sprintf(ent->name, "%d", ent->order); 723 dir = debugfs_create_dir(ent->name, cache->root); 724 debugfs_create_file("size", 0600, dir, ent, &size_fops); 725 debugfs_create_file("limit", 0600, dir, ent, &limit_fops); 726 debugfs_create_ulong("cur", 0400, dir, &ent->stored); 727 debugfs_create_u32("miss", 0600, dir, &ent->miss); 728 } 729} 730 731static void delay_time_func(struct timer_list *t) 732{ 733 struct mlx5_ib_dev *dev = from_timer(dev, t, delay_timer); 734 735 WRITE_ONCE(dev->fill_delay, 0); 736} 737 |
738int mlx5_mr_cache_init(struct mlx5_ib_dev *dev) | 738int mlx5_mkey_cache_init(struct mlx5_ib_dev *dev) |
739{ | 739{ |
740 struct mlx5_mr_cache *cache = &dev->cache; | 740 struct mlx5_mkey_cache *cache = &dev->cache; |
741 struct mlx5_cache_ent *ent; 742 int i; 743 744 mutex_init(&dev->slow_path_mutex); 745 cache->wq = alloc_ordered_workqueue("mkey_cache", WQ_MEM_RECLAIM); 746 if (!cache->wq) { 747 mlx5_ib_warn(dev, "failed to create work queue\n"); 748 return -ENOMEM; 749 } 750 751 mlx5_cmd_init_async_ctx(dev->mdev, &dev->async_ctx); 752 timer_setup(&dev->delay_timer, delay_time_func, 0); | 741 struct mlx5_cache_ent *ent; 742 int i; 743 744 mutex_init(&dev->slow_path_mutex); 745 cache->wq = alloc_ordered_workqueue("mkey_cache", WQ_MEM_RECLAIM); 746 if (!cache->wq) { 747 mlx5_ib_warn(dev, "failed to create work queue\n"); 748 return -ENOMEM; 749 } 750 751 mlx5_cmd_init_async_ctx(dev->mdev, &dev->async_ctx); 752 timer_setup(&dev->delay_timer, delay_time_func, 0); |
753 for (i = 0; i < MAX_MR_CACHE_ENTRIES; i++) { | 753 for (i = 0; i < MAX_MKEY_CACHE_ENTRIES; i++) { |
754 ent = &cache->ent[i]; 755 xa_init_flags(&ent->mkeys, XA_FLAGS_LOCK_IRQ); 756 ent->order = i + 2; 757 ent->dev = dev; 758 ent->limit = 0; 759 760 INIT_DELAYED_WORK(&ent->dwork, delayed_cache_work_func); 761 | 754 ent = &cache->ent[i]; 755 xa_init_flags(&ent->mkeys, XA_FLAGS_LOCK_IRQ); 756 ent->order = i + 2; 757 ent->dev = dev; 758 ent->limit = 0; 759 760 INIT_DELAYED_WORK(&ent->dwork, delayed_cache_work_func); 761 |
762 if (i > MR_CACHE_LAST_STD_ENTRY) { 763 mlx5_odp_init_mr_cache_entry(ent); | 762 if (i > MKEY_CACHE_LAST_STD_ENTRY) { 763 mlx5_odp_init_mkey_cache_entry(ent); |
764 continue; 765 } 766 | 764 continue; 765 } 766 |
767 if (ent->order > mr_cache_max_order(dev)) | 767 if (ent->order > mkey_cache_max_order(dev)) |
768 continue; 769 770 ent->page = PAGE_SHIFT; 771 ent->ndescs = 1 << ent->order; 772 ent->access_mode = MLX5_MKC_ACCESS_MODE_MTT; 773 if ((dev->mdev->profile.mask & MLX5_PROF_MASK_MR_CACHE) && 774 !dev->is_rep && mlx5_core_is_pf(dev->mdev) && 775 mlx5r_umr_can_load_pas(dev, 0)) 776 ent->limit = dev->mdev->profile.mr_cache[i].limit; 777 else 778 ent->limit = 0; 779 xa_lock_irq(&ent->mkeys); 780 queue_adjust_cache_locked(ent); 781 xa_unlock_irq(&ent->mkeys); 782 } 783 | 768 continue; 769 770 ent->page = PAGE_SHIFT; 771 ent->ndescs = 1 << ent->order; 772 ent->access_mode = MLX5_MKC_ACCESS_MODE_MTT; 773 if ((dev->mdev->profile.mask & MLX5_PROF_MASK_MR_CACHE) && 774 !dev->is_rep && mlx5_core_is_pf(dev->mdev) && 775 mlx5r_umr_can_load_pas(dev, 0)) 776 ent->limit = dev->mdev->profile.mr_cache[i].limit; 777 else 778 ent->limit = 0; 779 xa_lock_irq(&ent->mkeys); 780 queue_adjust_cache_locked(ent); 781 xa_unlock_irq(&ent->mkeys); 782 } 783 |
784 mlx5_mr_cache_debugfs_init(dev); | 784 mlx5_mkey_cache_debugfs_init(dev); |
785 786 return 0; 787} 788 | 785 786 return 0; 787} 788 |
789int mlx5_mr_cache_cleanup(struct mlx5_ib_dev *dev) | 789int mlx5_mkey_cache_cleanup(struct mlx5_ib_dev *dev) |
790{ 791 unsigned int i; 792 793 if (!dev->cache.wq) 794 return 0; 795 | 790{ 791 unsigned int i; 792 793 if (!dev->cache.wq) 794 return 0; 795 |
796 for (i = 0; i < MAX_MR_CACHE_ENTRIES; i++) { | 796 for (i = 0; i < MAX_MKEY_CACHE_ENTRIES; i++) { |
797 struct mlx5_cache_ent *ent = &dev->cache.ent[i]; 798 799 xa_lock_irq(&ent->mkeys); 800 ent->disabled = true; 801 xa_unlock_irq(&ent->mkeys); 802 cancel_delayed_work_sync(&ent->dwork); 803 } 804 | 797 struct mlx5_cache_ent *ent = &dev->cache.ent[i]; 798 799 xa_lock_irq(&ent->mkeys); 800 ent->disabled = true; 801 xa_unlock_irq(&ent->mkeys); 802 cancel_delayed_work_sync(&ent->dwork); 803 } 804 |
805 mlx5_mr_cache_debugfs_cleanup(dev); | 805 mlx5_mkey_cache_debugfs_cleanup(dev); |
806 mlx5_cmd_cleanup_async_ctx(&dev->async_ctx); 807 | 806 mlx5_cmd_cleanup_async_ctx(&dev->async_ctx); 807 |
808 for (i = 0; i < MAX_MR_CACHE_ENTRIES; i++) | 808 for (i = 0; i < MAX_MKEY_CACHE_ENTRIES; i++) |
809 clean_keys(dev, i); 810 811 destroy_workqueue(dev->cache.wq); 812 del_timer_sync(&dev->delay_timer); 813 814 return 0; 815} 816 --- 50 unchanged lines hidden (view full) --- 867 u64 offset; 868 int npages; 869 870 offset = addr & (page_size - 1); 871 npages = ALIGN(len + offset, page_size) >> page_shift; 872 return (npages + 1) / 2; 873} 874 | 809 clean_keys(dev, i); 810 811 destroy_workqueue(dev->cache.wq); 812 del_timer_sync(&dev->delay_timer); 813 814 return 0; 815} 816 --- 50 unchanged lines hidden (view full) --- 867 u64 offset; 868 int npages; 869 870 offset = addr & (page_size - 1); 871 npages = ALIGN(len + offset, page_size) >> page_shift; 872 return (npages + 1) / 2; 873} 874 |
875static int mr_cache_max_order(struct mlx5_ib_dev *dev) | 875static int mkey_cache_max_order(struct mlx5_ib_dev *dev) |
876{ 877 if (MLX5_CAP_GEN(dev->mdev, umr_extended_translation_offset)) | 876{ 877 if (MLX5_CAP_GEN(dev->mdev, umr_extended_translation_offset)) |
878 return MR_CACHE_LAST_STD_ENTRY + 2; | 878 return MKEY_CACHE_LAST_STD_ENTRY + 2; |
879 return MLX5_MAX_UMR_SHIFT; 880} 881 | 879 return MLX5_MAX_UMR_SHIFT; 880} 881 |
882static struct mlx5_cache_ent *mr_cache_ent_from_order(struct mlx5_ib_dev *dev, 883 unsigned int order) | 882static struct mlx5_cache_ent *mkey_cache_ent_from_order(struct mlx5_ib_dev *dev, 883 unsigned int order) |
884{ | 884{ |
885 struct mlx5_mr_cache *cache = &dev->cache; | 885 struct mlx5_mkey_cache *cache = &dev->cache; |
886 887 if (order < cache->ent[0].order) 888 return &cache->ent[0]; 889 order = order - cache->ent[0].order; | 886 887 if (order < cache->ent[0].order) 888 return &cache->ent[0]; 889 order = order - cache->ent[0].order; |
890 if (order > MR_CACHE_LAST_STD_ENTRY) | 890 if (order > MKEY_CACHE_LAST_STD_ENTRY) |
891 return NULL; 892 return &cache->ent[order]; 893} 894 895static void set_mr_fields(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr, 896 u64 length, int access_flags, u64 iova) 897{ 898 mr->ibmr.lkey = mr->mmkey.key; --- 26 unchanged lines hidden (view full) --- 925 926 if (umem->is_dmabuf) 927 page_size = mlx5_umem_dmabuf_default_pgsz(umem, iova); 928 else 929 page_size = mlx5_umem_find_best_pgsz(umem, mkc, log_page_size, 930 0, iova); 931 if (WARN_ON(!page_size)) 932 return ERR_PTR(-EINVAL); | 891 return NULL; 892 return &cache->ent[order]; 893} 894 895static void set_mr_fields(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr, 896 u64 length, int access_flags, u64 iova) 897{ 898 mr->ibmr.lkey = mr->mmkey.key; --- 26 unchanged lines hidden (view full) --- 925 926 if (umem->is_dmabuf) 927 page_size = mlx5_umem_dmabuf_default_pgsz(umem, iova); 928 else 929 page_size = mlx5_umem_find_best_pgsz(umem, mkc, log_page_size, 930 0, iova); 931 if (WARN_ON(!page_size)) 932 return ERR_PTR(-EINVAL); |
933 ent = mr_cache_ent_from_order( | 933 ent = mkey_cache_ent_from_order( |
934 dev, order_base_2(ib_umem_num_dma_blocks(umem, page_size))); 935 /* 936 * Matches access in alloc_cache_mr(). If the MR can't come from the 937 * cache then synchronously create an uncached one. 938 */ 939 if (!ent || ent->limit == 0 || 940 !mlx5r_umr_can_reconfig(dev, 0, access_flags)) { 941 mutex_lock(&dev->slow_path_mutex); --- 1403 unchanged lines hidden --- | 934 dev, order_base_2(ib_umem_num_dma_blocks(umem, page_size))); 935 /* 936 * Matches access in alloc_cache_mr(). If the MR can't come from the 937 * cache then synchronously create an uncached one. 938 */ 939 if (!ent || ent->limit == 0 || 940 !mlx5r_umr_can_reconfig(dev, 0, access_flags)) { 941 mutex_lock(&dev->slow_path_mutex); --- 1403 unchanged lines hidden --- |