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