The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/mlx4/mlx4_core/mlx4_pd.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 2006, 2007 Cisco Systems, Inc.  All rights reserved.
    3  * Copyright (c) 2005, 2014 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/errno.h>
   35 #include <linux/module.h>
   36 #include <linux/io-mapping.h>
   37 
   38 #include <linux/page.h>
   39 
   40 #include "mlx4.h"
   41 #include "icm.h"
   42 
   43 enum {
   44         MLX4_NUM_RESERVED_UARS = 8
   45 };
   46 
   47 int mlx4_pd_alloc(struct mlx4_dev *dev, u32 *pdn)
   48 {
   49         struct mlx4_priv *priv = mlx4_priv(dev);
   50 
   51         *pdn = mlx4_bitmap_alloc(&priv->pd_bitmap);
   52         if (*pdn == -1)
   53                 return -ENOMEM;
   54 
   55         return 0;
   56 }
   57 EXPORT_SYMBOL_GPL(mlx4_pd_alloc);
   58 
   59 void mlx4_pd_free(struct mlx4_dev *dev, u32 pdn)
   60 {
   61         mlx4_bitmap_free(&mlx4_priv(dev)->pd_bitmap, pdn, MLX4_USE_RR);
   62 }
   63 EXPORT_SYMBOL_GPL(mlx4_pd_free);
   64 
   65 int __mlx4_xrcd_alloc(struct mlx4_dev *dev, u32 *xrcdn)
   66 {
   67         struct mlx4_priv *priv = mlx4_priv(dev);
   68 
   69         *xrcdn = mlx4_bitmap_alloc(&priv->xrcd_bitmap);
   70         if (*xrcdn == -1)
   71                 return -ENOMEM;
   72 
   73         return 0;
   74 }
   75 
   76 int mlx4_xrcd_alloc(struct mlx4_dev *dev, u32 *xrcdn)
   77 {
   78         u64 out_param;
   79         int err;
   80 
   81         if (mlx4_is_mfunc(dev)) {
   82                 err = mlx4_cmd_imm(dev, 0, &out_param,
   83                                    RES_XRCD, RES_OP_RESERVE,
   84                                    MLX4_CMD_ALLOC_RES,
   85                                    MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
   86                 if (err)
   87                         return err;
   88 
   89                 *xrcdn = get_param_l(&out_param);
   90                 return 0;
   91         }
   92         return __mlx4_xrcd_alloc(dev, xrcdn);
   93 }
   94 EXPORT_SYMBOL_GPL(mlx4_xrcd_alloc);
   95 
   96 void __mlx4_xrcd_free(struct mlx4_dev *dev, u32 xrcdn)
   97 {
   98         mlx4_bitmap_free(&mlx4_priv(dev)->xrcd_bitmap, xrcdn, MLX4_USE_RR);
   99 }
  100 
  101 void mlx4_xrcd_free(struct mlx4_dev *dev, u32 xrcdn)
  102 {
  103         u64 in_param = 0;
  104         int err;
  105 
  106         if (mlx4_is_mfunc(dev)) {
  107                 set_param_l(&in_param, xrcdn);
  108                 err = mlx4_cmd(dev, in_param, RES_XRCD,
  109                                RES_OP_RESERVE, MLX4_CMD_FREE_RES,
  110                                MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
  111                 if (err)
  112                         mlx4_warn(dev, "Failed to release xrcdn %d\n", xrcdn);
  113         } else
  114                 __mlx4_xrcd_free(dev, xrcdn);
  115 }
  116 EXPORT_SYMBOL_GPL(mlx4_xrcd_free);
  117 
  118 int mlx4_init_pd_table(struct mlx4_dev *dev)
  119 {
  120         struct mlx4_priv *priv = mlx4_priv(dev);
  121 
  122         return mlx4_bitmap_init(&priv->pd_bitmap, dev->caps.num_pds,
  123                                 (1 << NOT_MASKED_PD_BITS) - 1,
  124                                  dev->caps.reserved_pds, 0);
  125 }
  126 
  127 void mlx4_cleanup_pd_table(struct mlx4_dev *dev)
  128 {
  129         mlx4_bitmap_cleanup(&mlx4_priv(dev)->pd_bitmap);
  130 }
  131 
  132 int mlx4_init_xrcd_table(struct mlx4_dev *dev)
  133 {
  134         struct mlx4_priv *priv = mlx4_priv(dev);
  135 
  136         return mlx4_bitmap_init(&priv->xrcd_bitmap, (1 << 16),
  137                                 (1 << 16) - 1, dev->caps.reserved_xrcds + 1, 0);
  138 }
  139 
  140 void mlx4_cleanup_xrcd_table(struct mlx4_dev *dev)
  141 {
  142         mlx4_bitmap_cleanup(&mlx4_priv(dev)->xrcd_bitmap);
  143 }
  144 
  145 int mlx4_uar_alloc(struct mlx4_dev *dev, struct mlx4_uar *uar)
  146 {
  147         int offset;
  148 
  149         uar->index = mlx4_bitmap_alloc(&mlx4_priv(dev)->uar_table.bitmap);
  150         if (uar->index == -1)
  151                 return -ENOMEM;
  152 
  153         if (mlx4_is_slave(dev))
  154                 offset = uar->index % ((int)pci_resource_len(dev->persist->pdev,
  155                                                              2) /
  156                                        dev->caps.uar_page_size);
  157         else
  158                 offset = uar->index;
  159         uar->pfn = (pci_resource_start(dev->persist->pdev, 2) >> PAGE_SHIFT)
  160                     + offset;
  161         uar->map = NULL;
  162         return 0;
  163 }
  164 EXPORT_SYMBOL_GPL(mlx4_uar_alloc);
  165 
  166 void mlx4_uar_free(struct mlx4_dev *dev, struct mlx4_uar *uar)
  167 {
  168         mlx4_bitmap_free(&mlx4_priv(dev)->uar_table.bitmap, uar->index, MLX4_USE_RR);
  169 }
  170 EXPORT_SYMBOL_GPL(mlx4_uar_free);
  171 
  172 int mlx4_bf_alloc(struct mlx4_dev *dev, struct mlx4_bf *bf, int node)
  173 {
  174         struct mlx4_priv *priv = mlx4_priv(dev);
  175         struct mlx4_uar *uar;
  176         int err = 0;
  177         int idx;
  178 
  179         if (!priv->bf_mapping)
  180                 return -ENOMEM;
  181 
  182         mutex_lock(&priv->bf_mutex);
  183         if (!list_empty(&priv->bf_list))
  184                 uar = list_entry(priv->bf_list.next, struct mlx4_uar, bf_list);
  185         else {
  186                 if (mlx4_bitmap_avail(&priv->uar_table.bitmap) < MLX4_NUM_RESERVED_UARS) {
  187                         err = -ENOMEM;
  188                         goto out;
  189                 }
  190                 uar = kmalloc_node(sizeof(*uar), GFP_KERNEL, node);
  191                 if (!uar) {
  192                         uar = kmalloc(sizeof(*uar), GFP_KERNEL);
  193                         if (!uar) {
  194                                 err = -ENOMEM;
  195                                 goto out;
  196                         }
  197                 }
  198                 err = mlx4_uar_alloc(dev, uar);
  199                 if (err)
  200                         goto free_kmalloc;
  201 
  202                 uar->map = ioremap(uar->pfn << PAGE_SHIFT, PAGE_SIZE);
  203                 if (!uar->map) {
  204                         err = -ENOMEM;
  205                         goto free_uar;
  206                 }
  207 
  208                 uar->bf_map = io_mapping_map_wc(priv->bf_mapping,
  209                                                 uar->index << PAGE_SHIFT,
  210                                                 PAGE_SIZE);
  211                 if (!uar->bf_map) {
  212                         err = -ENOMEM;
  213                         goto unamp_uar;
  214                 }
  215                 uar->free_bf_bmap = 0;
  216                 list_add(&uar->bf_list, &priv->bf_list);
  217         }
  218 
  219         idx = ffz(uar->free_bf_bmap);
  220         uar->free_bf_bmap |= 1 << idx;
  221         bf->uar = uar;
  222         bf->offset = 0;
  223         bf->buf_size = dev->caps.bf_reg_size / 2;
  224         bf->reg = uar->bf_map + idx * dev->caps.bf_reg_size;
  225         if (uar->free_bf_bmap == (1 << dev->caps.bf_regs_per_page) - 1)
  226                 list_del_init(&uar->bf_list);
  227 
  228         goto out;
  229 
  230 unamp_uar:
  231         bf->uar = NULL;
  232         iounmap(uar->map);
  233 
  234 free_uar:
  235         mlx4_uar_free(dev, uar);
  236 
  237 free_kmalloc:
  238         kfree(uar);
  239 
  240 out:
  241         mutex_unlock(&priv->bf_mutex);
  242         return err;
  243 }
  244 EXPORT_SYMBOL_GPL(mlx4_bf_alloc);
  245 
  246 void mlx4_bf_free(struct mlx4_dev *dev, struct mlx4_bf *bf)
  247 {
  248         struct mlx4_priv *priv = mlx4_priv(dev);
  249         int idx;
  250 
  251         if (!bf->uar || !bf->uar->bf_map)
  252                 return;
  253 
  254         mutex_lock(&priv->bf_mutex);
  255         idx = (bf->reg - bf->uar->bf_map) / dev->caps.bf_reg_size;
  256         bf->uar->free_bf_bmap &= ~(1 << idx);
  257         if (!bf->uar->free_bf_bmap) {
  258                 if (!list_empty(&bf->uar->bf_list))
  259                         list_del(&bf->uar->bf_list);
  260 
  261                 io_mapping_unmap(bf->uar->bf_map);
  262                 iounmap(bf->uar->map);
  263                 mlx4_uar_free(dev, bf->uar);
  264                 kfree(bf->uar);
  265         } else if (list_empty(&bf->uar->bf_list))
  266                 list_add(&bf->uar->bf_list, &priv->bf_list);
  267 
  268         mutex_unlock(&priv->bf_mutex);
  269 }
  270 EXPORT_SYMBOL_GPL(mlx4_bf_free);
  271 
  272 int mlx4_init_uar_table(struct mlx4_dev *dev)
  273 {
  274         int num_reserved_uar = mlx4_get_num_reserved_uar(dev);
  275 
  276         mlx4_dbg(dev, "uar_page_shift = %d", dev->uar_page_shift);
  277         mlx4_dbg(dev, "Effective reserved_uars=%d", dev->caps.reserved_uars);
  278 
  279         if (dev->caps.num_uars <= num_reserved_uar) {
  280                 mlx4_err(dev, "Only %d UAR pages (need more than %d)\n",
  281                          dev->caps.num_uars, num_reserved_uar);
  282                 mlx4_err(dev, "Increase firmware log2_uar_bar_megabytes?\n");
  283                 return -ENODEV;
  284         }
  285 
  286         return mlx4_bitmap_init(&mlx4_priv(dev)->uar_table.bitmap,
  287                                 dev->caps.num_uars, dev->caps.num_uars - 1,
  288                                 dev->caps.reserved_uars, 0);
  289 }
  290 
  291 void mlx4_cleanup_uar_table(struct mlx4_dev *dev)
  292 {
  293         mlx4_bitmap_cleanup(&mlx4_priv(dev)->uar_table.bitmap);
  294 }

Cache object: 26aaca0df92ea52d294e50ee060b3b83


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.