0001
0002
0003
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);