diff options
Diffstat (limited to 'drivers/infiniband/hw/mlx5/mem.c')
-rw-r--r-- | drivers/infiniband/hw/mlx5/mem.c | 47 |
1 files changed, 17 insertions, 30 deletions
diff --git a/drivers/infiniband/hw/mlx5/mem.c b/drivers/infiniband/hw/mlx5/mem.c index 914f212e7ef6..f3dbd75a0a96 100644 --- a/drivers/infiniband/hw/mlx5/mem.c +++ b/drivers/infiniband/hw/mlx5/mem.c | |||
@@ -50,13 +50,9 @@ void mlx5_ib_cont_pages(struct ib_umem *umem, u64 addr, | |||
50 | { | 50 | { |
51 | unsigned long tmp; | 51 | unsigned long tmp; |
52 | unsigned long m; | 52 | unsigned long m; |
53 | int i, k; | 53 | u64 base = ~0, p = 0; |
54 | u64 base = 0; | 54 | u64 len, pfn; |
55 | int p = 0; | 55 | int i = 0; |
56 | int skip; | ||
57 | int mask; | ||
58 | u64 len; | ||
59 | u64 pfn; | ||
60 | struct scatterlist *sg; | 56 | struct scatterlist *sg; |
61 | int entry; | 57 | int entry; |
62 | unsigned long page_shift = umem->page_shift; | 58 | unsigned long page_shift = umem->page_shift; |
@@ -76,33 +72,24 @@ void mlx5_ib_cont_pages(struct ib_umem *umem, u64 addr, | |||
76 | m = find_first_bit(&tmp, BITS_PER_LONG); | 72 | m = find_first_bit(&tmp, BITS_PER_LONG); |
77 | if (max_page_shift) | 73 | if (max_page_shift) |
78 | m = min_t(unsigned long, max_page_shift - page_shift, m); | 74 | m = min_t(unsigned long, max_page_shift - page_shift, m); |
79 | skip = 1 << m; | 75 | |
80 | mask = skip - 1; | ||
81 | i = 0; | ||
82 | for_each_sg(umem->sg_head.sgl, sg, umem->nmap, entry) { | 76 | for_each_sg(umem->sg_head.sgl, sg, umem->nmap, entry) { |
83 | len = sg_dma_len(sg) >> page_shift; | 77 | len = sg_dma_len(sg) >> page_shift; |
84 | pfn = sg_dma_address(sg) >> page_shift; | 78 | pfn = sg_dma_address(sg) >> page_shift; |
85 | for (k = 0; k < len; k++) { | 79 | if (base + p != pfn) { |
86 | if (!(i & mask)) { | 80 | /* If either the offset or the new |
87 | tmp = (unsigned long)pfn; | 81 | * base are unaligned update m |
88 | m = min_t(unsigned long, m, find_first_bit(&tmp, BITS_PER_LONG)); | 82 | */ |
89 | skip = 1 << m; | 83 | tmp = (unsigned long)(pfn | p); |
90 | mask = skip - 1; | 84 | if (!IS_ALIGNED(tmp, 1 << m)) |
91 | base = pfn; | 85 | m = find_first_bit(&tmp, BITS_PER_LONG); |
92 | p = 0; | 86 | |
93 | } else { | 87 | base = pfn; |
94 | if (base + p != pfn) { | 88 | p = 0; |
95 | tmp = (unsigned long)p; | ||
96 | m = find_first_bit(&tmp, BITS_PER_LONG); | ||
97 | skip = 1 << m; | ||
98 | mask = skip - 1; | ||
99 | base = pfn; | ||
100 | p = 0; | ||
101 | } | ||
102 | } | ||
103 | p++; | ||
104 | i++; | ||
105 | } | 89 | } |
90 | |||
91 | p += len; | ||
92 | i += len; | ||
106 | } | 93 | } |
107 | 94 | ||
108 | if (i) { | 95 | if (i) { |