mr_pool.c (1928B)
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);