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 8 struct 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 } 23 EXPORT_SYMBOL(ib_mr_pool_get); 24 25 void 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 } 34 EXPORT_SYMBOL(ib_mr_pool_put); 35 36 int ib_mr_pool_init(struct ib_qp *qp, struct list_head *list, int nr, 37 enum ib_mr_type type, u32 max_num_sg) 38 { 39 struct ib_mr *mr; 40 unsigned long flags; 41 int ret, i; 42 43 for (i = 0; i < nr; i++) { 44 mr = ib_alloc_mr(qp->pd, type, max_num_sg); 45 if (IS_ERR(mr)) { 46 ret = PTR_ERR(mr); 47 goto out; 48 } 49 50 spin_lock_irqsave(&qp->mr_lock, flags); 51 list_add_tail(&mr->qp_entry, list); 52 spin_unlock_irqrestore(&qp->mr_lock, flags); 53 } 54 55 return 0; 56 out: 57 ib_mr_pool_destroy(qp, list); 58 return ret; 59 } 60 EXPORT_SYMBOL(ib_mr_pool_init); 61 62 void ib_mr_pool_destroy(struct ib_qp *qp, struct list_head *list) 63 { 64 struct ib_mr *mr; 65 unsigned long flags; 66 67 spin_lock_irqsave(&qp->mr_lock, flags); 68 while (!list_empty(list)) { 69 mr = list_first_entry(list, struct ib_mr, qp_entry); 70 list_del(&mr->qp_entry); 71 72 spin_unlock_irqrestore(&qp->mr_lock, flags); 73 ib_dereg_mr(mr); 74 spin_lock_irqsave(&qp->mr_lock, flags); 75 } 76 spin_unlock_irqrestore(&qp->mr_lock, flags); 77 } 78 EXPORT_SYMBOL(ib_mr_pool_destroy); 79