1 /* 2 * Copyright (c) 2016 Hisilicon Limited. 3 * Copyright (c) 2007, 2008 Mellanox Technologies. 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 9 * OpenIB.org BSD license below: 10 * 11 * Redistribution and use in source and binary forms, with or 12 * without modification, are permitted provided that the following 13 * conditions are met: 14 * 15 * - Redistributions of source code must retain the above 16 * copyright notice, this list of conditions and the following 17 * disclaimer. 18 * 19 * - Redistributions in binary form must reproduce the above 20 * copyright notice, this list of conditions and the following 21 * disclaimer in the documentation and/or other materials 22 * provided with the distribution. 23 * 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 * SOFTWARE. 32 */ 33 34 #include <linux/platform_device.h> 35 #include <linux/vmalloc.h> 36 #include "hns_roce_device.h" 37 #include <rdma/ib_umem.h> 38 39 int hns_roce_bitmap_alloc(struct hns_roce_bitmap *bitmap, unsigned long *obj) 40 { 41 int ret = 0; 42 43 spin_lock(&bitmap->lock); 44 *obj = find_next_zero_bit(bitmap->table, bitmap->max, bitmap->last); 45 if (*obj >= bitmap->max) { 46 bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top) 47 & bitmap->mask; 48 *obj = find_first_zero_bit(bitmap->table, bitmap->max); 49 } 50 51 if (*obj < bitmap->max) { 52 set_bit(*obj, bitmap->table); 53 bitmap->last = (*obj + 1); 54 if (bitmap->last == bitmap->max) 55 bitmap->last = 0; 56 *obj |= bitmap->top; 57 } else { 58 ret = -EINVAL; 59 } 60 61 spin_unlock(&bitmap->lock); 62 63 return ret; 64 } 65 66 void hns_roce_bitmap_free(struct hns_roce_bitmap *bitmap, unsigned long obj) 67 { 68 obj &= bitmap->max + bitmap->reserved_top - 1; 69 70 spin_lock(&bitmap->lock); 71 clear_bit(obj, bitmap->table); 72 73 bitmap->last = min(bitmap->last, obj); 74 bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top) 75 & bitmap->mask; 76 spin_unlock(&bitmap->lock); 77 } 78 79 int hns_roce_bitmap_init(struct hns_roce_bitmap *bitmap, u32 num, u32 mask, 80 u32 reserved_bot, u32 reserved_top) 81 { 82 u32 i; 83 84 if (num != roundup_pow_of_two(num)) 85 return -EINVAL; 86 87 bitmap->last = 0; 88 bitmap->top = 0; 89 bitmap->max = num - reserved_top; 90 bitmap->mask = mask; 91 bitmap->reserved_top = reserved_top; 92 spin_lock_init(&bitmap->lock); 93 bitmap->table = kcalloc(BITS_TO_LONGS(bitmap->max), sizeof(long), 94 GFP_KERNEL); 95 if (!bitmap->table) 96 return -ENOMEM; 97 98 for (i = 0; i < reserved_bot; ++i) 99 set_bit(i, bitmap->table); 100 101 return 0; 102 } 103 104 void hns_roce_bitmap_cleanup(struct hns_roce_bitmap *bitmap) 105 { 106 kfree(bitmap->table); 107 } 108 109 void hns_roce_buf_free(struct hns_roce_dev *hr_dev, struct hns_roce_buf *buf) 110 { 111 struct hns_roce_buf_list *trunks; 112 u32 i; 113 114 if (!buf) 115 return; 116 117 trunks = buf->trunk_list; 118 if (trunks) { 119 buf->trunk_list = NULL; 120 for (i = 0; i < buf->ntrunks; i++) 121 dma_free_coherent(hr_dev->dev, 1 << buf->trunk_shift, 122 trunks[i].buf, trunks[i].map); 123 124 kfree(trunks); 125 } 126 127 kfree(buf); 128 } 129 130 /* 131 * Allocate the dma buffer for storing ROCEE table entries 132 * 133 * @size: required size 134 * @page_shift: the unit size in a continuous dma address range 135 * @flags: HNS_ROCE_BUF_ flags to control the allocation flow. 136 */ 137 struct hns_roce_buf *hns_roce_buf_alloc(struct hns_roce_dev *hr_dev, u32 size, 138 u32 page_shift, u32 flags) 139 { 140 u32 trunk_size, page_size, alloced_size; 141 struct hns_roce_buf_list *trunks; 142 struct hns_roce_buf *buf; 143 gfp_t gfp_flags; 144 u32 ntrunk, i; 145 146 /* The minimum shift of the page accessed by hw is HNS_HW_PAGE_SHIFT */ 147 if (WARN_ON(page_shift < HNS_HW_PAGE_SHIFT)) 148 return ERR_PTR(-EINVAL); 149 150 gfp_flags = (flags & HNS_ROCE_BUF_NOSLEEP) ? GFP_ATOMIC : GFP_KERNEL; 151 buf = kzalloc(sizeof(*buf), gfp_flags); 152 if (!buf) 153 return ERR_PTR(-ENOMEM); 154 155 buf->page_shift = page_shift; 156 page_size = 1 << buf->page_shift; 157 158 /* Calc the trunk size and num by required size and page_shift */ 159 if (flags & HNS_ROCE_BUF_DIRECT) { 160 buf->trunk_shift = order_base_2(ALIGN(size, PAGE_SIZE)); 161 ntrunk = 1; 162 } else { 163 buf->trunk_shift = order_base_2(ALIGN(page_size, PAGE_SIZE)); 164 ntrunk = DIV_ROUND_UP(size, 1 << buf->trunk_shift); 165 } 166 167 trunks = kcalloc(ntrunk, sizeof(*trunks), gfp_flags); 168 if (!trunks) { 169 kfree(buf); 170 return ERR_PTR(-ENOMEM); 171 } 172 173 trunk_size = 1 << buf->trunk_shift; 174 alloced_size = 0; 175 for (i = 0; i < ntrunk; i++) { 176 trunks[i].buf = dma_alloc_coherent(hr_dev->dev, trunk_size, 177 &trunks[i].map, gfp_flags); 178 if (!trunks[i].buf) 179 break; 180 181 alloced_size += trunk_size; 182 } 183 184 buf->ntrunks = i; 185 186 /* In nofail mode, it's only failed when the alloced size is 0 */ 187 if ((flags & HNS_ROCE_BUF_NOFAIL) ? i == 0 : i != ntrunk) { 188 for (i = 0; i < buf->ntrunks; i++) 189 dma_free_coherent(hr_dev->dev, trunk_size, 190 trunks[i].buf, trunks[i].map); 191 192 kfree(trunks); 193 kfree(buf); 194 return ERR_PTR(-ENOMEM); 195 } 196 197 buf->npages = DIV_ROUND_UP(alloced_size, page_size); 198 buf->trunk_list = trunks; 199 200 return buf; 201 } 202 203 int hns_roce_get_kmem_bufs(struct hns_roce_dev *hr_dev, dma_addr_t *bufs, 204 int buf_cnt, struct hns_roce_buf *buf, 205 unsigned int page_shift) 206 { 207 unsigned int offset, max_size; 208 int total = 0; 209 int i; 210 211 if (page_shift > buf->trunk_shift) { 212 dev_err(hr_dev->dev, "failed to check kmem buf shift %u > %u\n", 213 page_shift, buf->trunk_shift); 214 return -EINVAL; 215 } 216 217 offset = 0; 218 max_size = buf->ntrunks << buf->trunk_shift; 219 for (i = 0; i < buf_cnt && offset < max_size; i++) { 220 bufs[total++] = hns_roce_buf_dma_addr(buf, offset); 221 offset += (1 << page_shift); 222 } 223 224 return total; 225 } 226 227 int hns_roce_get_umem_bufs(struct hns_roce_dev *hr_dev, dma_addr_t *bufs, 228 int buf_cnt, struct ib_umem *umem, 229 unsigned int page_shift) 230 { 231 struct ib_block_iter biter; 232 int total = 0; 233 234 /* convert system page cnt to hw page cnt */ 235 rdma_umem_for_each_dma_block(umem, &biter, 1 << page_shift) { 236 bufs[total++] = rdma_block_iter_dma_address(&biter); 237 if (total >= buf_cnt) 238 goto done; 239 } 240 241 done: 242 return total; 243 } 244 245 void hns_roce_cleanup_bitmap(struct hns_roce_dev *hr_dev) 246 { 247 if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_XRC) 248 ida_destroy(&hr_dev->xrcd_ida.ida); 249 250 if (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_SRQ) 251 hns_roce_cleanup_srq_table(hr_dev); 252 hns_roce_cleanup_qp_table(hr_dev); 253 hns_roce_cleanup_cq_table(hr_dev); 254 ida_destroy(&hr_dev->mr_table.mtpt_ida.ida); 255 ida_destroy(&hr_dev->pd_ida.ida); 256 hns_roce_cleanup_uar_table(hr_dev); 257 } 258