1 /* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
2 /*
3  * Copyright (c) 2016 Mellanox Technologies Ltd. All rights reserved.
4  * Copyright (c) 2015 System Fabric Works, Inc. All rights reserved.
5  */
6 
7 #ifndef RXE_POOL_H
8 #define RXE_POOL_H
9 
10 enum rxe_pool_flags {
11 	RXE_POOL_INDEX		= BIT(1),
12 	RXE_POOL_KEY		= BIT(2),
13 	RXE_POOL_NO_ALLOC	= BIT(4),
14 };
15 
16 enum rxe_elem_type {
17 	RXE_TYPE_UC,
18 	RXE_TYPE_PD,
19 	RXE_TYPE_AH,
20 	RXE_TYPE_SRQ,
21 	RXE_TYPE_QP,
22 	RXE_TYPE_CQ,
23 	RXE_TYPE_MR,
24 	RXE_TYPE_MW,
25 	RXE_TYPE_MC_GRP,
26 	RXE_TYPE_MC_ELEM,
27 	RXE_NUM_TYPES,		/* keep me last */
28 };
29 
30 struct rxe_pool_elem {
31 	struct rxe_pool		*pool;
32 	void			*obj;
33 	struct kref		ref_cnt;
34 	struct list_head	list;
35 
36 	/* only used if keyed */
37 	struct rb_node		key_node;
38 
39 	/* only used if indexed */
40 	struct rb_node		index_node;
41 	u32			index;
42 };
43 
44 struct rxe_pool {
45 	struct rxe_dev		*rxe;
46 	const char		*name;
47 	rwlock_t		pool_lock; /* protects pool add/del/search */
48 	void			(*cleanup)(struct rxe_pool_elem *obj);
49 	enum rxe_pool_flags	flags;
50 	enum rxe_elem_type	type;
51 
52 	unsigned int		max_elem;
53 	atomic_t		num_elem;
54 	size_t			elem_size;
55 	size_t			elem_offset;
56 
57 	/* only used if indexed */
58 	struct {
59 		struct rb_root		tree;
60 		unsigned long		*table;
61 		u32			last;
62 		u32			max_index;
63 		u32			min_index;
64 	} index;
65 
66 	/* only used if keyed */
67 	struct {
68 		struct rb_root		tree;
69 		size_t			key_offset;
70 		size_t			key_size;
71 	} key;
72 };
73 
74 /* initialize a pool of objects with given limit on
75  * number of elements. gets parameters from rxe_type_info
76  * pool elements will be allocated out of a slab cache
77  */
78 int rxe_pool_init(struct rxe_dev *rxe, struct rxe_pool *pool,
79 		  enum rxe_elem_type type, u32 max_elem);
80 
81 /* free resources from object pool */
82 void rxe_pool_cleanup(struct rxe_pool *pool);
83 
84 /* allocate an object from pool holding and not holding the pool lock */
85 void *rxe_alloc_locked(struct rxe_pool *pool);
86 
87 void *rxe_alloc(struct rxe_pool *pool);
88 
89 /* connect already allocated object to pool */
90 int __rxe_add_to_pool(struct rxe_pool *pool, struct rxe_pool_elem *elem);
91 
92 #define rxe_add_to_pool(pool, obj) __rxe_add_to_pool(pool, &(obj)->elem)
93 
94 /* assign an index to an indexed object and insert object into
95  *  pool's rb tree holding and not holding the pool_lock
96  */
97 int __rxe_add_index_locked(struct rxe_pool_elem *elem);
98 
99 #define rxe_add_index_locked(obj) __rxe_add_index_locked(&(obj)->elem)
100 
101 int __rxe_add_index(struct rxe_pool_elem *elem);
102 
103 #define rxe_add_index(obj) __rxe_add_index(&(obj)->elem)
104 
105 /* drop an index and remove object from rb tree
106  * holding and not holding the pool_lock
107  */
108 void __rxe_drop_index_locked(struct rxe_pool_elem *elem);
109 
110 #define rxe_drop_index_locked(obj) __rxe_drop_index_locked(&(obj)->elem)
111 
112 void __rxe_drop_index(struct rxe_pool_elem *elem);
113 
114 #define rxe_drop_index(obj) __rxe_drop_index(&(obj)->elem)
115 
116 /* assign a key to a keyed object and insert object into
117  * pool's rb tree holding and not holding pool_lock
118  */
119 int __rxe_add_key_locked(struct rxe_pool_elem *elem, void *key);
120 
121 #define rxe_add_key_locked(obj, key) __rxe_add_key_locked(&(obj)->elem, key)
122 
123 int __rxe_add_key(struct rxe_pool_elem *elem, void *key);
124 
125 #define rxe_add_key(obj, key) __rxe_add_key(&(obj)->elem, key)
126 
127 /* remove elem from rb tree holding and not holding the pool_lock */
128 void __rxe_drop_key_locked(struct rxe_pool_elem *elem);
129 
130 #define rxe_drop_key_locked(obj) __rxe_drop_key_locked(&(obj)->elem)
131 
132 void __rxe_drop_key(struct rxe_pool_elem *elem);
133 
134 #define rxe_drop_key(obj) __rxe_drop_key(&(obj)->elem)
135 
136 /* lookup an indexed object from index holding and not holding the pool_lock.
137  * takes a reference on object
138  */
139 void *rxe_pool_get_index_locked(struct rxe_pool *pool, u32 index);
140 
141 void *rxe_pool_get_index(struct rxe_pool *pool, u32 index);
142 
143 /* lookup keyed object from key holding and not holding the pool_lock.
144  * takes a reference on the objecti
145  */
146 void *rxe_pool_get_key_locked(struct rxe_pool *pool, void *key);
147 
148 void *rxe_pool_get_key(struct rxe_pool *pool, void *key);
149 
150 /* cleanup an object when all references are dropped */
151 void rxe_elem_release(struct kref *kref);
152 
153 /* take a reference on an object */
154 #define rxe_add_ref(obj) kref_get(&(obj)->elem.ref_cnt)
155 
156 /* drop a reference on an object */
157 #define rxe_drop_ref(obj) kref_put(&(obj)->elem.ref_cnt, rxe_elem_release)
158 
159 #endif /* RXE_POOL_H */
160