mr.c (d5ea2df9cefa9c81a66021b5bb89562d02bbc2f7) | mr.c (3161625589c1d7c54e949d462f4d0c327664881a) |
---|---|
1/* 2 * Copyright (c) 2013-2015, Mellanox Technologies. All rights reserved. 3 * 4 * This software is available to you under a choice of one of two 5 * licenses. You may choose to be licensed under the terms of the GNU 6 * General Public License (GPL) Version 2, available from the file 7 * COPYING in the main directory of this source tree, or the 8 * OpenIB.org BSD license below: --- 760 unchanged lines hidden (view full) --- 769 __be64 *pas; 770 struct device *ddev = dev->ib_dev.dma_device; 771 772 /* 773 * UMR copies MTTs in units of MLX5_UMR_MTT_ALIGNMENT bytes. 774 * To avoid copying garbage after the pas array, we allocate 775 * a little more. 776 */ | 1/* 2 * Copyright (c) 2013-2015, Mellanox Technologies. All rights reserved. 3 * 4 * This software is available to you under a choice of one of two 5 * licenses. You may choose to be licensed under the terms of the GNU 6 * General Public License (GPL) Version 2, available from the file 7 * COPYING in the main directory of this source tree, or the 8 * OpenIB.org BSD license below: --- 760 unchanged lines hidden (view full) --- 769 __be64 *pas; 770 struct device *ddev = dev->ib_dev.dma_device; 771 772 /* 773 * UMR copies MTTs in units of MLX5_UMR_MTT_ALIGNMENT bytes. 774 * To avoid copying garbage after the pas array, we allocate 775 * a little more. 776 */ |
777 *size = ALIGN(sizeof(u64) * npages, MLX5_UMR_MTT_ALIGNMENT); | 777 *size = ALIGN(sizeof(struct mlx5_mtt) * npages, MLX5_UMR_MTT_ALIGNMENT); |
778 *mr_pas = kmalloc(*size + MLX5_UMR_ALIGN - 1, GFP_KERNEL); 779 if (!(*mr_pas)) 780 return -ENOMEM; 781 782 pas = PTR_ALIGN(*mr_pas, MLX5_UMR_ALIGN); 783 mlx5_ib_populate_pas(dev, umem, page_shift, pas, MLX5_IB_MTT_PRESENT); 784 /* Clear padding after the actual pages. */ | 778 *mr_pas = kmalloc(*size + MLX5_UMR_ALIGN - 1, GFP_KERNEL); 779 if (!(*mr_pas)) 780 return -ENOMEM; 781 782 pas = PTR_ALIGN(*mr_pas, MLX5_UMR_ALIGN); 783 mlx5_ib_populate_pas(dev, umem, page_shift, pas, MLX5_IB_MTT_PRESENT); 784 /* Clear padding after the actual pages. */ |
785 memset(pas + npages, 0, *size - npages * sizeof(u64)); | 785 memset(pas + npages, 0, *size - npages * sizeof(struct mlx5_mtt)); |
786 787 *dma = dma_map_single(ddev, pas, *size, DMA_TO_DEVICE); 788 if (dma_mapping_error(ddev, *dma)) { 789 kfree(*mr_pas); 790 return -ENOMEM; 791 } 792 793 return 0; 794} 795 796static void prep_umr_wqe_common(struct ib_pd *pd, struct ib_send_wr *wr, 797 struct ib_sge *sg, u64 dma, int n, u32 key, 798 int page_shift) 799{ 800 struct mlx5_ib_dev *dev = to_mdev(pd->device); 801 struct mlx5_umr_wr *umrwr = umr_wr(wr); 802 803 sg->addr = dma; | 786 787 *dma = dma_map_single(ddev, pas, *size, DMA_TO_DEVICE); 788 if (dma_mapping_error(ddev, *dma)) { 789 kfree(*mr_pas); 790 return -ENOMEM; 791 } 792 793 return 0; 794} 795 796static void prep_umr_wqe_common(struct ib_pd *pd, struct ib_send_wr *wr, 797 struct ib_sge *sg, u64 dma, int n, u32 key, 798 int page_shift) 799{ 800 struct mlx5_ib_dev *dev = to_mdev(pd->device); 801 struct mlx5_umr_wr *umrwr = umr_wr(wr); 802 803 sg->addr = dma; |
804 sg->length = ALIGN(sizeof(u64) * n, 64); | 804 sg->length = ALIGN(sizeof(struct mlx5_mtt) * n, 805 MLX5_IB_UMR_XLT_ALIGNMENT); |
805 sg->lkey = dev->umrc.pd->local_dma_lkey; 806 807 wr->next = NULL; 808 wr->sg_list = sg; 809 if (n) 810 wr->num_sge = 1; 811 else 812 wr->num_sge = 0; 813 814 wr->opcode = MLX5_IB_WR_UMR; 815 | 806 sg->lkey = dev->umrc.pd->local_dma_lkey; 807 808 wr->next = NULL; 809 wr->sg_list = sg; 810 if (n) 811 wr->num_sge = 1; 812 else 813 wr->num_sge = 0; 814 815 wr->opcode = MLX5_IB_WR_UMR; 816 |
816 umrwr->npages = n; | 817 umrwr->xlt_size = sg->length; |
817 umrwr->page_shift = page_shift; 818 umrwr->mkey = key; 819} 820 821static void prep_umr_reg_wqe(struct ib_pd *pd, struct ib_send_wr *wr, 822 struct ib_sge *sg, u64 dma, int n, u32 key, 823 int page_shift, u64 virt_addr, u64 len, 824 int access_flags) 825{ 826 struct mlx5_umr_wr *umrwr = umr_wr(wr); 827 828 prep_umr_wqe_common(pd, wr, sg, dma, n, key, page_shift); 829 | 818 umrwr->page_shift = page_shift; 819 umrwr->mkey = key; 820} 821 822static void prep_umr_reg_wqe(struct ib_pd *pd, struct ib_send_wr *wr, 823 struct ib_sge *sg, u64 dma, int n, u32 key, 824 int page_shift, u64 virt_addr, u64 len, 825 int access_flags) 826{ 827 struct mlx5_umr_wr *umrwr = umr_wr(wr); 828 829 prep_umr_wqe_common(pd, wr, sg, dma, n, key, page_shift); 830 |
830 wr->send_flags = 0; | 831 wr->send_flags = MLX5_IB_SEND_UMR_ENABLE_MR | 832 MLX5_IB_SEND_UMR_UPDATE_TRANSLATION | 833 MLX5_IB_SEND_UMR_UPDATE_PD_ACCESS; |
831 | 834 |
832 umrwr->target.virt_addr = virt_addr; | 835 umrwr->virt_addr = virt_addr; |
833 umrwr->length = len; 834 umrwr->access_flags = access_flags; 835 umrwr->pd = pd; 836} 837 838static void prep_umr_unreg_wqe(struct mlx5_ib_dev *dev, 839 struct ib_send_wr *wr, u32 key) 840{ 841 struct mlx5_umr_wr *umrwr = umr_wr(wr); 842 | 836 umrwr->length = len; 837 umrwr->access_flags = access_flags; 838 umrwr->pd = pd; 839} 840 841static void prep_umr_unreg_wqe(struct mlx5_ib_dev *dev, 842 struct ib_send_wr *wr, u32 key) 843{ 844 struct mlx5_umr_wr *umrwr = umr_wr(wr); 845 |
843 wr->send_flags = MLX5_IB_SEND_UMR_UNREG | MLX5_IB_SEND_UMR_FAIL_IF_FREE; | 846 wr->send_flags = MLX5_IB_SEND_UMR_DISABLE_MR | 847 MLX5_IB_SEND_UMR_FAIL_IF_FREE; |
844 wr->opcode = MLX5_IB_WR_UMR; 845 umrwr->mkey = key; 846} 847 848static int mr_umem_get(struct ib_pd *pd, u64 start, u64 length, 849 int access_flags, struct ib_umem **umem, 850 int *npages, int *page_shift, int *ncont, 851 int *order) --- 136 unchanged lines hidden (view full) --- 988 struct device *ddev = dev->ib_dev.dma_device; 989 struct ib_umem *umem = mr->umem; 990 int size; 991 __be64 *pas; 992 dma_addr_t dma; 993 struct mlx5_umr_wr wr; 994 struct ib_sge sg; 995 int err = 0; | 848 wr->opcode = MLX5_IB_WR_UMR; 849 umrwr->mkey = key; 850} 851 852static int mr_umem_get(struct ib_pd *pd, u64 start, u64 length, 853 int access_flags, struct ib_umem **umem, 854 int *npages, int *page_shift, int *ncont, 855 int *order) --- 136 unchanged lines hidden (view full) --- 992 struct device *ddev = dev->ib_dev.dma_device; 993 struct ib_umem *umem = mr->umem; 994 int size; 995 __be64 *pas; 996 dma_addr_t dma; 997 struct mlx5_umr_wr wr; 998 struct ib_sge sg; 999 int err = 0; |
996 const int page_index_alignment = MLX5_UMR_MTT_ALIGNMENT / sizeof(u64); | 1000 const int page_index_alignment = MLX5_UMR_MTT_ALIGNMENT / 1001 sizeof(struct mlx5_mtt); |
997 const int page_index_mask = page_index_alignment - 1; 998 size_t pages_mapped = 0; 999 size_t pages_to_map = 0; 1000 size_t pages_iter = 0; 1001 int use_emergency_buf = 0; 1002 1003 /* UMR copies MTTs in units of MLX5_UMR_MTT_ALIGNMENT bytes, 1004 * so we need to align the offset and length accordingly */ 1005 if (start_page_index & page_index_mask) { 1006 npages += start_page_index & page_index_mask; 1007 start_page_index &= ~page_index_mask; 1008 } 1009 1010 pages_to_map = ALIGN(npages, page_index_alignment); 1011 1012 if (start_page_index + pages_to_map > MLX5_MAX_UMR_PAGES) 1013 return -EINVAL; 1014 | 1002 const int page_index_mask = page_index_alignment - 1; 1003 size_t pages_mapped = 0; 1004 size_t pages_to_map = 0; 1005 size_t pages_iter = 0; 1006 int use_emergency_buf = 0; 1007 1008 /* UMR copies MTTs in units of MLX5_UMR_MTT_ALIGNMENT bytes, 1009 * so we need to align the offset and length accordingly */ 1010 if (start_page_index & page_index_mask) { 1011 npages += start_page_index & page_index_mask; 1012 start_page_index &= ~page_index_mask; 1013 } 1014 1015 pages_to_map = ALIGN(npages, page_index_alignment); 1016 1017 if (start_page_index + pages_to_map > MLX5_MAX_UMR_PAGES) 1018 return -EINVAL; 1019 |
1015 size = sizeof(u64) * pages_to_map; | 1020 size = sizeof(struct mlx5_mtt) * pages_to_map; |
1016 size = min_t(int, PAGE_SIZE, size); 1017 /* We allocate with GFP_ATOMIC to avoid recursion into page-reclaim 1018 * code, when we are called from an invalidation. The pas buffer must 1019 * be 2k-aligned for Connect-IB. */ 1020 pas = (__be64 *)get_zeroed_page(GFP_ATOMIC); 1021 if (!pas) { 1022 mlx5_ib_warn(dev, "unable to allocate memory during MTT update, falling back to slower chunked mechanism.\n"); 1023 pas = mlx5_ib_update_mtt_emergency_buffer; 1024 size = MLX5_UMR_MTT_MIN_CHUNK_SIZE; 1025 use_emergency_buf = 1; 1026 mutex_lock(&mlx5_ib_update_mtt_emergency_buffer_mutex); 1027 memset(pas, 0, size); 1028 } | 1021 size = min_t(int, PAGE_SIZE, size); 1022 /* We allocate with GFP_ATOMIC to avoid recursion into page-reclaim 1023 * code, when we are called from an invalidation. The pas buffer must 1024 * be 2k-aligned for Connect-IB. */ 1025 pas = (__be64 *)get_zeroed_page(GFP_ATOMIC); 1026 if (!pas) { 1027 mlx5_ib_warn(dev, "unable to allocate memory during MTT update, falling back to slower chunked mechanism.\n"); 1028 pas = mlx5_ib_update_mtt_emergency_buffer; 1029 size = MLX5_UMR_MTT_MIN_CHUNK_SIZE; 1030 use_emergency_buf = 1; 1031 mutex_lock(&mlx5_ib_update_mtt_emergency_buffer_mutex); 1032 memset(pas, 0, size); 1033 } |
1029 pages_iter = size / sizeof(u64); | 1034 pages_iter = size / sizeof(struct mlx5_mtt); |
1030 dma = dma_map_single(ddev, pas, size, DMA_TO_DEVICE); 1031 if (dma_mapping_error(ddev, dma)) { 1032 mlx5_ib_err(dev, "unable to map DMA during MTT update.\n"); 1033 err = -ENOMEM; 1034 goto free_pas; 1035 } 1036 1037 for (pages_mapped = 0; --- 6 unchanged lines hidden (view full) --- 1044 ib_umem_num_pages(umem) - start_page_index); 1045 1046 if (!zap) { 1047 __mlx5_ib_populate_pas(dev, umem, PAGE_SHIFT, 1048 start_page_index, npages, pas, 1049 MLX5_IB_MTT_PRESENT); 1050 /* Clear padding after the pages brought from the 1051 * umem. */ | 1035 dma = dma_map_single(ddev, pas, size, DMA_TO_DEVICE); 1036 if (dma_mapping_error(ddev, dma)) { 1037 mlx5_ib_err(dev, "unable to map DMA during MTT update.\n"); 1038 err = -ENOMEM; 1039 goto free_pas; 1040 } 1041 1042 for (pages_mapped = 0; --- 6 unchanged lines hidden (view full) --- 1049 ib_umem_num_pages(umem) - start_page_index); 1050 1051 if (!zap) { 1052 __mlx5_ib_populate_pas(dev, umem, PAGE_SHIFT, 1053 start_page_index, npages, pas, 1054 MLX5_IB_MTT_PRESENT); 1055 /* Clear padding after the pages brought from the 1056 * umem. */ |
1052 memset(pas + npages, 0, size - npages * sizeof(u64)); | 1057 memset(pas + npages, 0, size - npages * 1058 sizeof(struct mlx5_mtt)); |
1053 } 1054 1055 dma_sync_single_for_device(ddev, dma, size, DMA_TO_DEVICE); 1056 1057 memset(&wr, 0, sizeof(wr)); 1058 1059 sg.addr = dma; | 1059 } 1060 1061 dma_sync_single_for_device(ddev, dma, size, DMA_TO_DEVICE); 1062 1063 memset(&wr, 0, sizeof(wr)); 1064 1065 sg.addr = dma; |
1060 sg.length = ALIGN(npages * sizeof(u64), | 1066 sg.length = ALIGN(npages * sizeof(struct mlx5_mtt), |
1061 MLX5_UMR_MTT_ALIGNMENT); 1062 sg.lkey = dev->umrc.pd->local_dma_lkey; 1063 1064 wr.wr.send_flags = MLX5_IB_SEND_UMR_FAIL_IF_FREE | | 1067 MLX5_UMR_MTT_ALIGNMENT); 1068 sg.lkey = dev->umrc.pd->local_dma_lkey; 1069 1070 wr.wr.send_flags = MLX5_IB_SEND_UMR_FAIL_IF_FREE | |
1065 MLX5_IB_SEND_UMR_UPDATE_MTT; | 1071 MLX5_IB_SEND_UMR_UPDATE_XLT; |
1066 wr.wr.sg_list = &sg; 1067 wr.wr.num_sge = 1; 1068 wr.wr.opcode = MLX5_IB_WR_UMR; | 1072 wr.wr.sg_list = &sg; 1073 wr.wr.num_sge = 1; 1074 wr.wr.opcode = MLX5_IB_WR_UMR; |
1069 wr.npages = sg.length / sizeof(u64); | 1075 wr.xlt_size = sg.length; |
1070 wr.page_shift = PAGE_SHIFT; 1071 wr.mkey = mr->mmkey.key; | 1076 wr.page_shift = PAGE_SHIFT; 1077 wr.mkey = mr->mmkey.key; |
1072 wr.target.offset = start_page_index; | 1078 wr.offset = start_page_index * sizeof(struct mlx5_mtt); |
1073 1074 err = mlx5_ib_post_send_wait(dev, &wr); 1075 } 1076 dma_unmap_single(ddev, dma, size, DMA_TO_DEVICE); 1077 1078free_pas: 1079 if (!use_emergency_buf) 1080 free_page((unsigned long)pas); --- 186 unchanged lines hidden (view full) --- 1267 umrwr.wr.send_flags = MLX5_IB_SEND_UMR_FAIL_IF_FREE; 1268 1269 if (flags & IB_MR_REREG_TRANS) { 1270 err = dma_map_mr_pas(dev, mr->umem, npages, page_shift, &size, 1271 &mr_pas, &dma); 1272 if (err) 1273 return err; 1274 | 1079 1080 err = mlx5_ib_post_send_wait(dev, &wr); 1081 } 1082 dma_unmap_single(ddev, dma, size, DMA_TO_DEVICE); 1083 1084free_pas: 1085 if (!use_emergency_buf) 1086 free_page((unsigned long)pas); --- 186 unchanged lines hidden (view full) --- 1273 umrwr.wr.send_flags = MLX5_IB_SEND_UMR_FAIL_IF_FREE; 1274 1275 if (flags & IB_MR_REREG_TRANS) { 1276 err = dma_map_mr_pas(dev, mr->umem, npages, page_shift, &size, 1277 &mr_pas, &dma); 1278 if (err) 1279 return err; 1280 |
1275 umrwr.target.virt_addr = virt_addr; | 1281 umrwr.virt_addr = virt_addr; |
1276 umrwr.length = length; 1277 umrwr.wr.send_flags |= MLX5_IB_SEND_UMR_UPDATE_TRANSLATION; 1278 } 1279 1280 prep_umr_wqe_common(pd, &umrwr.wr, &sg, dma, npages, mr->mmkey.key, 1281 page_shift); 1282 | 1282 umrwr.length = length; 1283 umrwr.wr.send_flags |= MLX5_IB_SEND_UMR_UPDATE_TRANSLATION; 1284 } 1285 1286 prep_umr_wqe_common(pd, &umrwr.wr, &sg, dma, npages, mr->mmkey.key, 1287 page_shift); 1288 |
1283 if (flags & IB_MR_REREG_PD) { | 1289 if (flags & IB_MR_REREG_PD || flags & IB_MR_REREG_ACCESS) { |
1284 umrwr.pd = pd; | 1290 umrwr.pd = pd; |
1285 umrwr.wr.send_flags |= MLX5_IB_SEND_UMR_UPDATE_PD; 1286 } 1287 1288 if (flags & IB_MR_REREG_ACCESS) { | |
1289 umrwr.access_flags = access_flags; | 1291 umrwr.access_flags = access_flags; |
1290 umrwr.wr.send_flags |= MLX5_IB_SEND_UMR_UPDATE_ACCESS; | 1292 umrwr.wr.send_flags |= MLX5_IB_SEND_UMR_UPDATE_PD_ACCESS; |
1291 } 1292 1293 /* post send request to UMR QP */ 1294 err = mlx5_ib_post_send_wait(dev, &umrwr); 1295 1296 if (flags & IB_MR_REREG_TRANS) { 1297 dma_unmap_single(ddev, dma, size, DMA_TO_DEVICE); 1298 kfree(mr_pas); --- 248 unchanged lines hidden (view full) --- 1547 MLX5_SET(mkc, mkc, translations_octword_size, ndescs); 1548 MLX5_SET(mkc, mkc, qpn, 0xffffff); 1549 MLX5_SET(mkc, mkc, pd, to_mpd(pd)->pdn); 1550 1551 if (mr_type == IB_MR_TYPE_MEM_REG) { 1552 mr->access_mode = MLX5_MKC_ACCESS_MODE_MTT; 1553 MLX5_SET(mkc, mkc, log_page_size, PAGE_SHIFT); 1554 err = mlx5_alloc_priv_descs(pd->device, mr, | 1293 } 1294 1295 /* post send request to UMR QP */ 1296 err = mlx5_ib_post_send_wait(dev, &umrwr); 1297 1298 if (flags & IB_MR_REREG_TRANS) { 1299 dma_unmap_single(ddev, dma, size, DMA_TO_DEVICE); 1300 kfree(mr_pas); --- 248 unchanged lines hidden (view full) --- 1549 MLX5_SET(mkc, mkc, translations_octword_size, ndescs); 1550 MLX5_SET(mkc, mkc, qpn, 0xffffff); 1551 MLX5_SET(mkc, mkc, pd, to_mpd(pd)->pdn); 1552 1553 if (mr_type == IB_MR_TYPE_MEM_REG) { 1554 mr->access_mode = MLX5_MKC_ACCESS_MODE_MTT; 1555 MLX5_SET(mkc, mkc, log_page_size, PAGE_SHIFT); 1556 err = mlx5_alloc_priv_descs(pd->device, mr, |
1555 ndescs, sizeof(u64)); | 1557 ndescs, sizeof(struct mlx5_mtt)); |
1556 if (err) 1557 goto err_free_in; 1558 | 1558 if (err) 1559 goto err_free_in; 1560 |
1559 mr->desc_size = sizeof(u64); | 1561 mr->desc_size = sizeof(struct mlx5_mtt); |
1560 mr->max_descs = ndescs; 1561 } else if (mr_type == IB_MR_TYPE_SG_GAPS) { 1562 mr->access_mode = MLX5_MKC_ACCESS_MODE_KLMS; 1563 1564 err = mlx5_alloc_priv_descs(pd->device, mr, 1565 ndescs, sizeof(struct mlx5_klm)); 1566 if (err) 1567 goto err_free_in; --- 265 unchanged lines hidden --- | 1562 mr->max_descs = ndescs; 1563 } else if (mr_type == IB_MR_TYPE_SG_GAPS) { 1564 mr->access_mode = MLX5_MKC_ACCESS_MODE_KLMS; 1565 1566 err = mlx5_alloc_priv_descs(pd->device, mr, 1567 ndescs, sizeof(struct mlx5_klm)); 1568 if (err) 1569 goto err_free_in; --- 265 unchanged lines hidden --- |