linux/drivers/infiniband/core/mr_pool.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (c) 2016 HGST, a Western Digital Company.
   4 */
   5#include <rdma/ib_verbs.h>
   6#include <rdma/mr_pool.h>
   7
   8struct ib_mr *ib_mr_pool_get(struct ib_qp *qp, struct list_head *list)
   9{
  10        struct ib_mr *mr;
  11        unsigned long flags;
  12
  13        spin_lock_irqsave(&qp->mr_lock, flags);
  14        mr = list_first_entry_or_null(list, struct ib_mr, qp_entry);
  15        if (mr) {
  16                list_del(&mr->qp_entry);
  17                qp->mrs_used++;
  18        }
  19        spin_unlock_irqrestore(&qp->mr_lock, flags);
  20
  21        return mr;
  22}
  23EXPORT_SYMBOL(ib_mr_pool_get);
  24
  25void ib_mr_pool_put(struct ib_qp *qp, struct list_head *list, struct ib_mr *mr)
  26{
  27        unsigned long flags;
  28
  29        spin_lock_irqsave(&qp->mr_lock, flags);
  30        list_add(&mr->qp_entry, list);
  31        qp->mrs_used--;
  32        spin_unlock_irqrestore(&qp->mr_lock, flags);
  33}
  34EXPORT_SYMBOL(ib_mr_pool_put);
  35
  36int ib_mr_pool_init(struct ib_qp *qp, struct list_head *list, int nr,
  37                enum ib_mr_type type, u32 max_num_sg, u32 max_num_meta_sg)
  38{
  39        struct ib_mr *mr;
  40        unsigned long flags;
  41        int ret, i;
  42
  43        for (i = 0; i < nr; i++) {
  44                if (type == IB_MR_TYPE_INTEGRITY)
  45                        mr = ib_alloc_mr_integrity(qp->pd, max_num_sg,
  46                                                   max_num_meta_sg);
  47                else
  48                        mr = ib_alloc_mr(qp->pd, type, max_num_sg);
  49                if (IS_ERR(mr)) {
  50                        ret = PTR_ERR(mr);
  51                        goto out;
  52                }
  53
  54                spin_lock_irqsave(&qp->mr_lock, flags);
  55                list_add_tail(&mr->qp_entry, list);
  56                spin_unlock_irqrestore(&qp->mr_lock, flags);
  57        }
  58
  59        return 0;
  60out:
  61        ib_mr_pool_destroy(qp, list);
  62        return ret;
  63}
  64EXPORT_SYMBOL(ib_mr_pool_init);
  65
  66void ib_mr_pool_destroy(struct ib_qp *qp, struct list_head *list)
  67{
  68        struct ib_mr *mr;
  69        unsigned long flags;
  70
  71        spin_lock_irqsave(&qp->mr_lock, flags);
  72        while (!list_empty(list)) {
  73                mr = list_first_entry(list, struct ib_mr, qp_entry);
  74                list_del(&mr->qp_entry);
  75
  76                spin_unlock_irqrestore(&qp->mr_lock, flags);
  77                ib_dereg_mr(mr);
  78                spin_lock_irqsave(&qp->mr_lock, flags);
  79        }
  80        spin_unlock_irqrestore(&qp->mr_lock, flags);
  81}
  82EXPORT_SYMBOL(ib_mr_pool_destroy);
  83