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_srq.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) 2007, 2008, 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 <dev/mlx4/cmd.h>
   35 #include <dev/mlx4/srq.h>
   36 #include <linux/module.h>
   37 #include <linux/gfp.h>
   38 #include <linux/rcupdate.h>
   39 
   40 #include "mlx4.h"
   41 #include "icm.h"
   42 
   43 void mlx4_srq_event(struct mlx4_dev *dev, u32 srqn, int event_type)
   44 {
   45         struct mlx4_srq_table *srq_table = &mlx4_priv(dev)->srq_table;
   46         struct mlx4_srq *srq;
   47 
   48         rcu_read_lock();
   49         srq = radix_tree_lookup(&srq_table->tree, srqn & (dev->caps.num_srqs - 1));
   50         rcu_read_unlock();
   51         if (srq)
   52                 atomic_inc(&srq->refcount);
   53         else {
   54                 mlx4_warn(dev, "Async event for bogus SRQ %08x\n", srqn);
   55                 return;
   56         }
   57 
   58         srq->event(srq, event_type);
   59 
   60         if (atomic_dec_and_test(&srq->refcount))
   61                 complete(&srq->free);
   62 }
   63 
   64 static int mlx4_SW2HW_SRQ(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox,
   65                           int srq_num)
   66 {
   67         return mlx4_cmd(dev, mailbox->dma, srq_num, 0,
   68                         MLX4_CMD_SW2HW_SRQ, MLX4_CMD_TIME_CLASS_A,
   69                         MLX4_CMD_WRAPPED);
   70 }
   71 
   72 static int mlx4_HW2SW_SRQ(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox,
   73                           int srq_num)
   74 {
   75         return mlx4_cmd_box(dev, 0, mailbox ? mailbox->dma : 0, srq_num,
   76                             mailbox ? 0 : 1, MLX4_CMD_HW2SW_SRQ,
   77                             MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
   78 }
   79 
   80 static int mlx4_ARM_SRQ(struct mlx4_dev *dev, int srq_num, int limit_watermark)
   81 {
   82         return mlx4_cmd(dev, limit_watermark, srq_num, 0, MLX4_CMD_ARM_SRQ,
   83                         MLX4_CMD_TIME_CLASS_B, MLX4_CMD_WRAPPED);
   84 }
   85 
   86 static int mlx4_QUERY_SRQ(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox,
   87                           int srq_num)
   88 {
   89         return mlx4_cmd_box(dev, 0, mailbox->dma, srq_num, 0, MLX4_CMD_QUERY_SRQ,
   90                             MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
   91 }
   92 
   93 int __mlx4_srq_alloc_icm(struct mlx4_dev *dev, int *srqn)
   94 {
   95         struct mlx4_srq_table *srq_table = &mlx4_priv(dev)->srq_table;
   96         int err;
   97 
   98 
   99         *srqn = mlx4_bitmap_alloc(&srq_table->bitmap);
  100         if (*srqn == -1)
  101                 return -ENOMEM;
  102 
  103         err = mlx4_table_get(dev, &srq_table->table, *srqn, GFP_KERNEL);
  104         if (err)
  105                 goto err_out;
  106 
  107         err = mlx4_table_get(dev, &srq_table->cmpt_table, *srqn, GFP_KERNEL);
  108         if (err)
  109                 goto err_put;
  110         return 0;
  111 
  112 err_put:
  113         mlx4_table_put(dev, &srq_table->table, *srqn);
  114 
  115 err_out:
  116         mlx4_bitmap_free(&srq_table->bitmap, *srqn, MLX4_NO_RR);
  117         return err;
  118 }
  119 
  120 static int mlx4_srq_alloc_icm(struct mlx4_dev *dev, int *srqn)
  121 {
  122         u64 out_param;
  123         int err;
  124 
  125         if (mlx4_is_mfunc(dev)) {
  126                 err = mlx4_cmd_imm(dev, 0, &out_param, RES_SRQ,
  127                                    RES_OP_RESERVE_AND_MAP,
  128                                    MLX4_CMD_ALLOC_RES,
  129                                    MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED);
  130                 if (!err)
  131                         *srqn = get_param_l(&out_param);
  132 
  133                 return err;
  134         }
  135         return __mlx4_srq_alloc_icm(dev, srqn);
  136 }
  137 
  138 void __mlx4_srq_free_icm(struct mlx4_dev *dev, int srqn)
  139 {
  140         struct mlx4_srq_table *srq_table = &mlx4_priv(dev)->srq_table;
  141 
  142         mlx4_table_put(dev, &srq_table->cmpt_table, srqn);
  143         mlx4_table_put(dev, &srq_table->table, srqn);
  144         mlx4_bitmap_free(&srq_table->bitmap, srqn, MLX4_NO_RR);
  145 }
  146 
  147 static void mlx4_srq_free_icm(struct mlx4_dev *dev, int srqn)
  148 {
  149         u64 in_param = 0;
  150 
  151         if (mlx4_is_mfunc(dev)) {
  152                 set_param_l(&in_param, srqn);
  153                 if (mlx4_cmd(dev, in_param, RES_SRQ, RES_OP_RESERVE_AND_MAP,
  154                              MLX4_CMD_FREE_RES,
  155                              MLX4_CMD_TIME_CLASS_A, MLX4_CMD_WRAPPED))
  156                         mlx4_warn(dev, "Failed freeing cq:%d\n", srqn);
  157                 return;
  158         }
  159         __mlx4_srq_free_icm(dev, srqn);
  160 }
  161 
  162 int mlx4_srq_alloc(struct mlx4_dev *dev, u32 pdn, u32 cqn, u16 xrcd,
  163                    struct mlx4_mtt *mtt, u64 db_rec, struct mlx4_srq *srq)
  164 {
  165         struct mlx4_srq_table *srq_table = &mlx4_priv(dev)->srq_table;
  166         struct mlx4_cmd_mailbox *mailbox;
  167         struct mlx4_srq_context *srq_context;
  168         u64 mtt_addr;
  169         int err;
  170 
  171         err = mlx4_srq_alloc_icm(dev, &srq->srqn);
  172         if (err)
  173                 return err;
  174 
  175         spin_lock_irq(&srq_table->lock);
  176         err = radix_tree_insert(&srq_table->tree, srq->srqn, srq);
  177         spin_unlock_irq(&srq_table->lock);
  178         if (err)
  179                 goto err_icm;
  180 
  181         mailbox = mlx4_alloc_cmd_mailbox(dev);
  182         if (IS_ERR(mailbox)) {
  183                 err = PTR_ERR(mailbox);
  184                 goto err_radix;
  185         }
  186 
  187         srq_context = mailbox->buf;
  188         srq_context->state_logsize_srqn = cpu_to_be32((ilog2(srq->max) << 24) |
  189                                                       srq->srqn);
  190         srq_context->logstride          = srq->wqe_shift - 4;
  191         srq_context->xrcd               = cpu_to_be16(xrcd);
  192         srq_context->pg_offset_cqn      = cpu_to_be32(cqn & 0xffffff);
  193         srq_context->log_page_size      = mtt->page_shift - MLX4_ICM_PAGE_SHIFT;
  194 
  195         mtt_addr = mlx4_mtt_addr(dev, mtt);
  196         srq_context->mtt_base_addr_h    = mtt_addr >> 32;
  197         srq_context->mtt_base_addr_l    = cpu_to_be32(mtt_addr & 0xffffffff);
  198         srq_context->pd                 = cpu_to_be32(pdn);
  199         srq_context->db_rec_addr        = cpu_to_be64(db_rec);
  200 
  201         err = mlx4_SW2HW_SRQ(dev, mailbox, srq->srqn);
  202         mlx4_free_cmd_mailbox(dev, mailbox);
  203         if (err)
  204                 goto err_radix;
  205 
  206         atomic_set(&srq->refcount, 1);
  207         init_completion(&srq->free);
  208 
  209         return 0;
  210 
  211 err_radix:
  212         spin_lock_irq(&srq_table->lock);
  213         radix_tree_delete(&srq_table->tree, srq->srqn);
  214         spin_unlock_irq(&srq_table->lock);
  215 
  216 err_icm:
  217         mlx4_srq_free_icm(dev, srq->srqn);
  218         return err;
  219 }
  220 EXPORT_SYMBOL_GPL(mlx4_srq_alloc);
  221 
  222 void mlx4_srq_free(struct mlx4_dev *dev, struct mlx4_srq *srq)
  223 {
  224         struct mlx4_srq_table *srq_table = &mlx4_priv(dev)->srq_table;
  225         int err;
  226 
  227         err = mlx4_HW2SW_SRQ(dev, NULL, srq->srqn);
  228         if (err)
  229                 mlx4_warn(dev, "HW2SW_SRQ failed (%d) for SRQN %06x\n", err, srq->srqn);
  230 
  231         spin_lock_irq(&srq_table->lock);
  232         radix_tree_delete(&srq_table->tree, srq->srqn);
  233         spin_unlock_irq(&srq_table->lock);
  234 
  235         if (atomic_dec_and_test(&srq->refcount))
  236                 complete(&srq->free);
  237         wait_for_completion(&srq->free);
  238 
  239         mlx4_srq_free_icm(dev, srq->srqn);
  240 }
  241 EXPORT_SYMBOL_GPL(mlx4_srq_free);
  242 
  243 int mlx4_srq_arm(struct mlx4_dev *dev, struct mlx4_srq *srq, int limit_watermark)
  244 {
  245         return mlx4_ARM_SRQ(dev, srq->srqn, limit_watermark);
  246 }
  247 EXPORT_SYMBOL_GPL(mlx4_srq_arm);
  248 
  249 int mlx4_srq_query(struct mlx4_dev *dev, struct mlx4_srq *srq, int *limit_watermark)
  250 {
  251         struct mlx4_cmd_mailbox *mailbox;
  252         struct mlx4_srq_context *srq_context;
  253         int err;
  254 
  255         mailbox = mlx4_alloc_cmd_mailbox(dev);
  256         if (IS_ERR(mailbox))
  257                 return PTR_ERR(mailbox);
  258 
  259         srq_context = mailbox->buf;
  260 
  261         err = mlx4_QUERY_SRQ(dev, mailbox, srq->srqn);
  262         if (err)
  263                 goto err_out;
  264         *limit_watermark = be16_to_cpu(srq_context->limit_watermark);
  265 
  266 err_out:
  267         mlx4_free_cmd_mailbox(dev, mailbox);
  268         return err;
  269 }
  270 EXPORT_SYMBOL_GPL(mlx4_srq_query);
  271 
  272 int mlx4_init_srq_table(struct mlx4_dev *dev)
  273 {
  274         struct mlx4_srq_table *srq_table = &mlx4_priv(dev)->srq_table;
  275         int err;
  276 
  277         spin_lock_init(&srq_table->lock);
  278         INIT_RADIX_TREE(&srq_table->tree, GFP_ATOMIC);
  279         if (mlx4_is_slave(dev))
  280                 return 0;
  281 
  282         err = mlx4_bitmap_init(&srq_table->bitmap, dev->caps.num_srqs,
  283                                dev->caps.num_srqs - 1, dev->caps.reserved_srqs, 0);
  284         if (err)
  285                 return err;
  286 
  287         return 0;
  288 }
  289 
  290 void mlx4_cleanup_srq_table(struct mlx4_dev *dev)
  291 {
  292         if (mlx4_is_slave(dev))
  293                 return;
  294         mlx4_bitmap_cleanup(&mlx4_priv(dev)->srq_table.bitmap);
  295 }
  296 
  297 struct mlx4_srq *mlx4_srq_lookup(struct mlx4_dev *dev, u32 srqn)
  298 {
  299         struct mlx4_srq_table *srq_table = &mlx4_priv(dev)->srq_table;
  300         struct mlx4_srq *srq;
  301 
  302         rcu_read_lock();
  303         srq = radix_tree_lookup(&srq_table->tree,
  304                                 srqn & (dev->caps.num_srqs - 1));
  305         rcu_read_unlock();
  306 
  307         return srq;
  308 }
  309 EXPORT_SYMBOL_GPL(mlx4_srq_lookup);

Cache object: e7cacff006c39d0a3cf23886e1f1d4a6


[ 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.