Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (c) 2016 HGST, a Western Digital Company.
0004  */
0005 #include <rdma/ib_verbs.h>
0006 #include <rdma/mr_pool.h>
0007 
0008 struct ib_mr *ib_mr_pool_get(struct ib_qp *qp, struct list_head *list)
0009 {
0010     struct ib_mr *mr;
0011     unsigned long flags;
0012 
0013     spin_lock_irqsave(&qp->mr_lock, flags);
0014     mr = list_first_entry_or_null(list, struct ib_mr, qp_entry);
0015     if (mr) {
0016         list_del(&mr->qp_entry);
0017         qp->mrs_used++;
0018     }
0019     spin_unlock_irqrestore(&qp->mr_lock, flags);
0020 
0021     return mr;
0022 }
0023 EXPORT_SYMBOL(ib_mr_pool_get);
0024 
0025 void ib_mr_pool_put(struct ib_qp *qp, struct list_head *list, struct ib_mr *mr)
0026 {
0027     unsigned long flags;
0028 
0029     spin_lock_irqsave(&qp->mr_lock, flags);
0030     list_add(&mr->qp_entry, list);
0031     qp->mrs_used--;
0032     spin_unlock_irqrestore(&qp->mr_lock, flags);
0033 }
0034 EXPORT_SYMBOL(ib_mr_pool_put);
0035 
0036 int ib_mr_pool_init(struct ib_qp *qp, struct list_head *list, int nr,
0037         enum ib_mr_type type, u32 max_num_sg, u32 max_num_meta_sg)
0038 {
0039     struct ib_mr *mr;
0040     unsigned long flags;
0041     int ret, i;
0042 
0043     for (i = 0; i < nr; i++) {
0044         if (type == IB_MR_TYPE_INTEGRITY)
0045             mr = ib_alloc_mr_integrity(qp->pd, max_num_sg,
0046                            max_num_meta_sg);
0047         else
0048             mr = ib_alloc_mr(qp->pd, type, max_num_sg);
0049         if (IS_ERR(mr)) {
0050             ret = PTR_ERR(mr);
0051             goto out;
0052         }
0053 
0054         spin_lock_irqsave(&qp->mr_lock, flags);
0055         list_add_tail(&mr->qp_entry, list);
0056         spin_unlock_irqrestore(&qp->mr_lock, flags);
0057     }
0058 
0059     return 0;
0060 out:
0061     ib_mr_pool_destroy(qp, list);
0062     return ret;
0063 }
0064 EXPORT_SYMBOL(ib_mr_pool_init);
0065 
0066 void ib_mr_pool_destroy(struct ib_qp *qp, struct list_head *list)
0067 {
0068     struct ib_mr *mr;
0069     unsigned long flags;
0070 
0071     spin_lock_irqsave(&qp->mr_lock, flags);
0072     while (!list_empty(list)) {
0073         mr = list_first_entry(list, struct ib_mr, qp_entry);
0074         list_del(&mr->qp_entry);
0075 
0076         spin_unlock_irqrestore(&qp->mr_lock, flags);
0077         ib_dereg_mr(mr);
0078         spin_lock_irqsave(&qp->mr_lock, flags);
0079     }
0080     spin_unlock_irqrestore(&qp->mr_lock, flags);
0081 }
0082 EXPORT_SYMBOL(ib_mr_pool_destroy);