2 * Copyright (c) 2013-2015, Mellanox Technologies, Ltd. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 #include <linux/errno.h>
29 #include <linux/slab.h>
31 #include <linux/dma-mapping.h>
32 #include <linux/vmalloc.h>
33 #include <dev/mlx5/driver.h>
35 #include "mlx5_core.h"
37 /* Handling for queue buffers -- we allocate a bunch of memory and
38 * register it in a memory region at HCA virtual address 0. If the
39 * requested size is > max_direct, we split the allocation into
40 * multiple pages, so we don't require too much contiguous memory.
43 static void *mlx5_dma_zalloc_coherent_node(struct mlx5_core_dev *dev,
44 size_t size, dma_addr_t *dma_handle,
49 cpu_handle = dma_zalloc_coherent(&dev->pdev->dev, size,
50 dma_handle, GFP_KERNEL);
54 int mlx5_buf_alloc_node(struct mlx5_core_dev *dev, int size, int max_direct,
55 struct mlx5_buf *buf, int node)
60 if (size <= max_direct) {
63 buf->page_shift = (u8)get_order(size) + PAGE_SHIFT;
64 buf->direct.buf = mlx5_dma_zalloc_coherent_node(dev, size,
71 while (t & ((1 << buf->page_shift) - 1)) {
78 buf->direct.buf = NULL;
79 buf->nbufs = (size + PAGE_SIZE - 1) / PAGE_SIZE;
80 buf->npages = buf->nbufs;
81 buf->page_shift = PAGE_SHIFT;
82 buf->page_list = kcalloc(buf->nbufs, sizeof(*buf->page_list),
85 for (i = 0; i < buf->nbufs; i++) {
86 buf->page_list[i].buf =
87 mlx5_dma_zalloc_coherent_node(dev, PAGE_SIZE,
90 buf->page_list[i].map = t;
93 if (BITS_PER_LONG == 64) {
96 pages = kmalloc(sizeof(*pages) * (buf->nbufs + 1),
98 for (i = 0; i < buf->nbufs; i++)
99 pages[i] = virt_to_page(buf->page_list[i].buf);
100 pages[buf->nbufs] = pages[0];
101 buf->direct.buf = vmap(pages, buf->nbufs + 1, VM_MAP,
104 if (!buf->direct.buf)
112 mlx5_buf_free(dev, buf);
117 int mlx5_buf_alloc(struct mlx5_core_dev *dev, int size, int max_direct,
118 struct mlx5_buf *buf)
120 return mlx5_buf_alloc_node(dev, size, max_direct,
121 buf, dev->priv.numa_node);
123 EXPORT_SYMBOL_GPL(mlx5_buf_alloc);
126 void mlx5_buf_free(struct mlx5_core_dev *dev, struct mlx5_buf *buf)
129 dma_free_coherent(&dev->pdev->dev, buf->size, buf->direct.buf,
133 if (BITS_PER_LONG == 64 && buf->direct.buf)
134 vunmap(buf->direct.buf);
136 for (i = 0; i < buf->nbufs; i++)
137 if (buf->page_list[i].buf)
138 dma_free_coherent(&dev->pdev->dev, PAGE_SIZE,
139 buf->page_list[i].buf,
140 buf->page_list[i].map);
141 kfree(buf->page_list);
144 EXPORT_SYMBOL_GPL(mlx5_buf_free);
146 static struct mlx5_db_pgdir *mlx5_alloc_db_pgdir(struct mlx5_core_dev *dev,
149 struct mlx5_db_pgdir *pgdir;
151 pgdir = kzalloc(sizeof(*pgdir), GFP_KERNEL);
153 bitmap_fill(pgdir->bitmap, MLX5_DB_PER_PAGE);
155 pgdir->db_page = mlx5_dma_zalloc_coherent_node(dev, PAGE_SIZE,
156 &pgdir->db_dma, node);
157 if (!pgdir->db_page) {
165 static int mlx5_alloc_db_from_pgdir(struct mlx5_db_pgdir *pgdir,
171 i = find_first_bit(pgdir->bitmap, MLX5_DB_PER_PAGE);
172 if (i >= MLX5_DB_PER_PAGE)
175 __clear_bit(i, pgdir->bitmap);
179 offset = db->index * L1_CACHE_BYTES;
180 db->db = pgdir->db_page + offset / sizeof(*pgdir->db_page);
181 db->dma = pgdir->db_dma + offset;
189 int mlx5_db_alloc_node(struct mlx5_core_dev *dev, struct mlx5_db *db, int node)
191 struct mlx5_db_pgdir *pgdir;
194 mutex_lock(&dev->priv.pgdir_mutex);
196 list_for_each_entry(pgdir, &dev->priv.pgdir_list, list)
197 if (!mlx5_alloc_db_from_pgdir(pgdir, db))
200 pgdir = mlx5_alloc_db_pgdir(dev, node);
206 list_add(&pgdir->list, &dev->priv.pgdir_list);
208 /* This should never fail -- we just allocated an empty page: */
209 WARN_ON(mlx5_alloc_db_from_pgdir(pgdir, db));
212 mutex_unlock(&dev->priv.pgdir_mutex);
216 EXPORT_SYMBOL_GPL(mlx5_db_alloc_node);
218 int mlx5_db_alloc(struct mlx5_core_dev *dev, struct mlx5_db *db)
220 return mlx5_db_alloc_node(dev, db, dev->priv.numa_node);
222 EXPORT_SYMBOL_GPL(mlx5_db_alloc);
224 void mlx5_db_free(struct mlx5_core_dev *dev, struct mlx5_db *db)
226 mutex_lock(&dev->priv.pgdir_mutex);
228 __set_bit(db->index, db->u.pgdir->bitmap);
230 if (bitmap_full(db->u.pgdir->bitmap, MLX5_DB_PER_PAGE)) {
231 dma_free_coherent(&(dev->pdev->dev), PAGE_SIZE,
232 db->u.pgdir->db_page, db->u.pgdir->db_dma);
233 list_del(&db->u.pgdir->list);
237 mutex_unlock(&dev->priv.pgdir_mutex);
239 EXPORT_SYMBOL_GPL(mlx5_db_free);
242 void mlx5_fill_page_array(struct mlx5_buf *buf, __be64 *pas)
247 for (i = 0; i < buf->npages; i++) {
249 addr = buf->direct.map + ((u64)i << buf->page_shift);
251 addr = buf->page_list[i].map;
253 pas[i] = cpu_to_be64(addr);
256 EXPORT_SYMBOL_GPL(mlx5_fill_page_array);