at v2.6.26-rc7 355 lines 8.6 kB view raw
1/* 2 * Copyright (c) 2006, 2007 Cisco Systems, Inc. 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: 9 * 10 * Redistribution and use in source and binary forms, with or 11 * without modification, are permitted provided that the following 12 * conditions are met: 13 * 14 * - Redistributions of source code must retain the above 15 * copyright notice, this list of conditions and the following 16 * disclaimer. 17 * 18 * - Redistributions in binary form must reproduce the above 19 * copyright notice, this list of conditions and the following 20 * disclaimer in the documentation and/or other materials 21 * provided with the distribution. 22 * 23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 * SOFTWARE. 31 */ 32 33#include <linux/errno.h> 34#include <linux/slab.h> 35#include <linux/bitmap.h> 36#include <linux/dma-mapping.h> 37#include <linux/vmalloc.h> 38 39#include "mlx4.h" 40 41u32 mlx4_bitmap_alloc(struct mlx4_bitmap *bitmap) 42{ 43 u32 obj; 44 45 spin_lock(&bitmap->lock); 46 47 obj = find_next_zero_bit(bitmap->table, bitmap->max, bitmap->last); 48 if (obj >= bitmap->max) { 49 bitmap->top = (bitmap->top + bitmap->max) & bitmap->mask; 50 obj = find_first_zero_bit(bitmap->table, bitmap->max); 51 } 52 53 if (obj < bitmap->max) { 54 set_bit(obj, bitmap->table); 55 bitmap->last = (obj + 1) & (bitmap->max - 1); 56 obj |= bitmap->top; 57 } else 58 obj = -1; 59 60 spin_unlock(&bitmap->lock); 61 62 return obj; 63} 64 65void mlx4_bitmap_free(struct mlx4_bitmap *bitmap, u32 obj) 66{ 67 obj &= bitmap->max - 1; 68 69 spin_lock(&bitmap->lock); 70 clear_bit(obj, bitmap->table); 71 bitmap->last = min(bitmap->last, obj); 72 bitmap->top = (bitmap->top + bitmap->max) & bitmap->mask; 73 spin_unlock(&bitmap->lock); 74} 75 76int mlx4_bitmap_init(struct mlx4_bitmap *bitmap, u32 num, u32 mask, u32 reserved) 77{ 78 int i; 79 80 /* num must be a power of 2 */ 81 if (num != roundup_pow_of_two(num)) 82 return -EINVAL; 83 84 bitmap->last = 0; 85 bitmap->top = 0; 86 bitmap->max = num; 87 bitmap->mask = mask; 88 spin_lock_init(&bitmap->lock); 89 bitmap->table = kzalloc(BITS_TO_LONGS(num) * sizeof (long), GFP_KERNEL); 90 if (!bitmap->table) 91 return -ENOMEM; 92 93 for (i = 0; i < reserved; ++i) 94 set_bit(i, bitmap->table); 95 96 return 0; 97} 98 99void mlx4_bitmap_cleanup(struct mlx4_bitmap *bitmap) 100{ 101 kfree(bitmap->table); 102} 103 104/* 105 * Handling for queue buffers -- we allocate a bunch of memory and 106 * register it in a memory region at HCA virtual address 0. If the 107 * requested size is > max_direct, we split the allocation into 108 * multiple pages, so we don't require too much contiguous memory. 109 */ 110 111int mlx4_buf_alloc(struct mlx4_dev *dev, int size, int max_direct, 112 struct mlx4_buf *buf) 113{ 114 dma_addr_t t; 115 116 if (size <= max_direct) { 117 buf->nbufs = 1; 118 buf->npages = 1; 119 buf->page_shift = get_order(size) + PAGE_SHIFT; 120 buf->direct.buf = dma_alloc_coherent(&dev->pdev->dev, 121 size, &t, GFP_KERNEL); 122 if (!buf->direct.buf) 123 return -ENOMEM; 124 125 buf->direct.map = t; 126 127 while (t & ((1 << buf->page_shift) - 1)) { 128 --buf->page_shift; 129 buf->npages *= 2; 130 } 131 132 memset(buf->direct.buf, 0, size); 133 } else { 134 int i; 135 136 buf->nbufs = (size + PAGE_SIZE - 1) / PAGE_SIZE; 137 buf->npages = buf->nbufs; 138 buf->page_shift = PAGE_SHIFT; 139 buf->page_list = kzalloc(buf->nbufs * sizeof *buf->page_list, 140 GFP_KERNEL); 141 if (!buf->page_list) 142 return -ENOMEM; 143 144 for (i = 0; i < buf->nbufs; ++i) { 145 buf->page_list[i].buf = 146 dma_alloc_coherent(&dev->pdev->dev, PAGE_SIZE, 147 &t, GFP_KERNEL); 148 if (!buf->page_list[i].buf) 149 goto err_free; 150 151 buf->page_list[i].map = t; 152 153 memset(buf->page_list[i].buf, 0, PAGE_SIZE); 154 } 155 156 if (BITS_PER_LONG == 64) { 157 struct page **pages; 158 pages = kmalloc(sizeof *pages * buf->nbufs, GFP_KERNEL); 159 if (!pages) 160 goto err_free; 161 for (i = 0; i < buf->nbufs; ++i) 162 pages[i] = virt_to_page(buf->page_list[i].buf); 163 buf->direct.buf = vmap(pages, buf->nbufs, VM_MAP, PAGE_KERNEL); 164 kfree(pages); 165 if (!buf->direct.buf) 166 goto err_free; 167 } 168 } 169 170 return 0; 171 172err_free: 173 mlx4_buf_free(dev, size, buf); 174 175 return -ENOMEM; 176} 177EXPORT_SYMBOL_GPL(mlx4_buf_alloc); 178 179void mlx4_buf_free(struct mlx4_dev *dev, int size, struct mlx4_buf *buf) 180{ 181 int i; 182 183 if (buf->nbufs == 1) 184 dma_free_coherent(&dev->pdev->dev, size, buf->direct.buf, 185 buf->direct.map); 186 else { 187 if (BITS_PER_LONG == 64) 188 vunmap(buf->direct.buf); 189 190 for (i = 0; i < buf->nbufs; ++i) 191 if (buf->page_list[i].buf) 192 dma_free_coherent(&dev->pdev->dev, PAGE_SIZE, 193 buf->page_list[i].buf, 194 buf->page_list[i].map); 195 kfree(buf->page_list); 196 } 197} 198EXPORT_SYMBOL_GPL(mlx4_buf_free); 199 200static struct mlx4_db_pgdir *mlx4_alloc_db_pgdir(struct device *dma_device) 201{ 202 struct mlx4_db_pgdir *pgdir; 203 204 pgdir = kzalloc(sizeof *pgdir, GFP_KERNEL); 205 if (!pgdir) 206 return NULL; 207 208 bitmap_fill(pgdir->order1, MLX4_DB_PER_PAGE / 2); 209 pgdir->bits[0] = pgdir->order0; 210 pgdir->bits[1] = pgdir->order1; 211 pgdir->db_page = dma_alloc_coherent(dma_device, PAGE_SIZE, 212 &pgdir->db_dma, GFP_KERNEL); 213 if (!pgdir->db_page) { 214 kfree(pgdir); 215 return NULL; 216 } 217 218 return pgdir; 219} 220 221static int mlx4_alloc_db_from_pgdir(struct mlx4_db_pgdir *pgdir, 222 struct mlx4_db *db, int order) 223{ 224 int o; 225 int i; 226 227 for (o = order; o <= 1; ++o) { 228 i = find_first_bit(pgdir->bits[o], MLX4_DB_PER_PAGE >> o); 229 if (i < MLX4_DB_PER_PAGE >> o) 230 goto found; 231 } 232 233 return -ENOMEM; 234 235found: 236 clear_bit(i, pgdir->bits[o]); 237 238 i <<= o; 239 240 if (o > order) 241 set_bit(i ^ 1, pgdir->bits[order]); 242 243 db->u.pgdir = pgdir; 244 db->index = i; 245 db->db = pgdir->db_page + db->index; 246 db->dma = pgdir->db_dma + db->index * 4; 247 db->order = order; 248 249 return 0; 250} 251 252int mlx4_db_alloc(struct mlx4_dev *dev, struct mlx4_db *db, int order) 253{ 254 struct mlx4_priv *priv = mlx4_priv(dev); 255 struct mlx4_db_pgdir *pgdir; 256 int ret = 0; 257 258 mutex_lock(&priv->pgdir_mutex); 259 260 list_for_each_entry(pgdir, &priv->pgdir_list, list) 261 if (!mlx4_alloc_db_from_pgdir(pgdir, db, order)) 262 goto out; 263 264 pgdir = mlx4_alloc_db_pgdir(&(dev->pdev->dev)); 265 if (!pgdir) { 266 ret = -ENOMEM; 267 goto out; 268 } 269 270 list_add(&pgdir->list, &priv->pgdir_list); 271 272 /* This should never fail -- we just allocated an empty page: */ 273 WARN_ON(mlx4_alloc_db_from_pgdir(pgdir, db, order)); 274 275out: 276 mutex_unlock(&priv->pgdir_mutex); 277 278 return ret; 279} 280EXPORT_SYMBOL_GPL(mlx4_db_alloc); 281 282void mlx4_db_free(struct mlx4_dev *dev, struct mlx4_db *db) 283{ 284 struct mlx4_priv *priv = mlx4_priv(dev); 285 int o; 286 int i; 287 288 mutex_lock(&priv->pgdir_mutex); 289 290 o = db->order; 291 i = db->index; 292 293 if (db->order == 0 && test_bit(i ^ 1, db->u.pgdir->order0)) { 294 clear_bit(i ^ 1, db->u.pgdir->order0); 295 ++o; 296 } 297 i >>= o; 298 set_bit(i, db->u.pgdir->bits[o]); 299 300 if (bitmap_full(db->u.pgdir->order1, MLX4_DB_PER_PAGE / 2)) { 301 dma_free_coherent(&(dev->pdev->dev), PAGE_SIZE, 302 db->u.pgdir->db_page, db->u.pgdir->db_dma); 303 list_del(&db->u.pgdir->list); 304 kfree(db->u.pgdir); 305 } 306 307 mutex_unlock(&priv->pgdir_mutex); 308} 309EXPORT_SYMBOL_GPL(mlx4_db_free); 310 311int mlx4_alloc_hwq_res(struct mlx4_dev *dev, struct mlx4_hwq_resources *wqres, 312 int size, int max_direct) 313{ 314 int err; 315 316 err = mlx4_db_alloc(dev, &wqres->db, 1); 317 if (err) 318 return err; 319 320 *wqres->db.db = 0; 321 322 err = mlx4_buf_alloc(dev, size, max_direct, &wqres->buf); 323 if (err) 324 goto err_db; 325 326 err = mlx4_mtt_init(dev, wqres->buf.npages, wqres->buf.page_shift, 327 &wqres->mtt); 328 if (err) 329 goto err_buf; 330 331 err = mlx4_buf_write_mtt(dev, &wqres->mtt, &wqres->buf); 332 if (err) 333 goto err_mtt; 334 335 return 0; 336 337err_mtt: 338 mlx4_mtt_cleanup(dev, &wqres->mtt); 339err_buf: 340 mlx4_buf_free(dev, size, &wqres->buf); 341err_db: 342 mlx4_db_free(dev, &wqres->db); 343 344 return err; 345} 346EXPORT_SYMBOL_GPL(mlx4_alloc_hwq_res); 347 348void mlx4_free_hwq_res(struct mlx4_dev *dev, struct mlx4_hwq_resources *wqres, 349 int size) 350{ 351 mlx4_mtt_cleanup(dev, &wqres->mtt); 352 mlx4_buf_free(dev, size, &wqres->buf); 353 mlx4_db_free(dev, &wqres->db); 354} 355EXPORT_SYMBOL_GPL(mlx4_free_hwq_res);