2 * Copyright (c) 2016 Mellanox Technologies Ltd. All rights reserved.
3 * Copyright (c) 2015 System Fabric Works, Inc. All rights reserved.
5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
15 * - Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
19 * - Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
37 /* info about object pools
38 * note that mr and mw share a single index space
39 * so that one can map an lkey to the correct type of object
41 struct rxe_type_info rxe_type_info
[RXE_NUM_TYPES
] = {
44 .size
= sizeof(struct rxe_ucontext
),
45 .flags
= RXE_POOL_NO_ALLOC
,
49 .size
= sizeof(struct rxe_pd
),
50 .flags
= RXE_POOL_NO_ALLOC
,
54 .size
= sizeof(struct rxe_ah
),
55 .flags
= RXE_POOL_ATOMIC
| RXE_POOL_NO_ALLOC
,
59 .size
= sizeof(struct rxe_srq
),
60 .flags
= RXE_POOL_INDEX
| RXE_POOL_NO_ALLOC
,
61 .min_index
= RXE_MIN_SRQ_INDEX
,
62 .max_index
= RXE_MAX_SRQ_INDEX
,
66 .size
= sizeof(struct rxe_qp
),
67 .cleanup
= rxe_qp_cleanup
,
68 .flags
= RXE_POOL_INDEX
,
69 .min_index
= RXE_MIN_QP_INDEX
,
70 .max_index
= RXE_MAX_QP_INDEX
,
74 .size
= sizeof(struct rxe_cq
),
75 .flags
= RXE_POOL_NO_ALLOC
,
76 .cleanup
= rxe_cq_cleanup
,
80 .size
= sizeof(struct rxe_mem
),
81 .cleanup
= rxe_mem_cleanup
,
82 .flags
= RXE_POOL_INDEX
,
83 .max_index
= RXE_MAX_MR_INDEX
,
84 .min_index
= RXE_MIN_MR_INDEX
,
88 .size
= sizeof(struct rxe_mem
),
89 .flags
= RXE_POOL_INDEX
,
90 .max_index
= RXE_MAX_MW_INDEX
,
91 .min_index
= RXE_MIN_MW_INDEX
,
95 .size
= sizeof(struct rxe_mc_grp
),
96 .cleanup
= rxe_mc_cleanup
,
97 .flags
= RXE_POOL_KEY
,
98 .key_offset
= offsetof(struct rxe_mc_grp
, mgid
),
99 .key_size
= sizeof(union ib_gid
),
101 [RXE_TYPE_MC_ELEM
] = {
102 .name
= "rxe-mc_elem",
103 .size
= sizeof(struct rxe_mc_elem
),
104 .flags
= RXE_POOL_ATOMIC
,
108 static inline const char *pool_name(struct rxe_pool
*pool
)
110 return rxe_type_info
[pool
->type
].name
;
113 static inline struct kmem_cache
*pool_cache(struct rxe_pool
*pool
)
115 return rxe_type_info
[pool
->type
].cache
;
118 static void rxe_cache_clean(size_t cnt
)
121 struct rxe_type_info
*type
;
123 for (i
= 0; i
< cnt
; i
++) {
124 type
= &rxe_type_info
[i
];
125 if (!(type
->flags
& RXE_POOL_NO_ALLOC
)) {
126 kmem_cache_destroy(type
->cache
);
132 int rxe_cache_init(void)
137 struct rxe_type_info
*type
;
139 for (i
= 0; i
< RXE_NUM_TYPES
; i
++) {
140 type
= &rxe_type_info
[i
];
141 size
= ALIGN(type
->size
, RXE_POOL_ALIGN
);
142 if (!(type
->flags
& RXE_POOL_NO_ALLOC
)) {
144 kmem_cache_create(type
->name
, size
,
146 RXE_POOL_CACHE_FLAGS
, NULL
);
148 pr_err("Unable to init kmem cache for %s\n",
164 void rxe_cache_exit(void)
166 rxe_cache_clean(RXE_NUM_TYPES
);
169 static int rxe_pool_init_index(struct rxe_pool
*pool
, u32 max
, u32 min
)
174 if ((max
- min
+ 1) < pool
->max_elem
) {
175 pr_warn("not enough indices for max_elem\n");
180 pool
->max_index
= max
;
181 pool
->min_index
= min
;
183 size
= BITS_TO_LONGS(max
- min
+ 1) * sizeof(long);
184 pool
->table
= kmalloc(size
, GFP_KERNEL
);
190 pool
->table_size
= size
;
191 bitmap_zero(pool
->table
, max
- min
+ 1);
199 struct rxe_pool
*pool
,
200 enum rxe_elem_type type
,
201 unsigned int max_elem
)
204 size_t size
= rxe_type_info
[type
].size
;
206 memset(pool
, 0, sizeof(*pool
));
210 pool
->max_elem
= max_elem
;
211 pool
->elem_size
= ALIGN(size
, RXE_POOL_ALIGN
);
212 pool
->flags
= rxe_type_info
[type
].flags
;
213 pool
->tree
= RB_ROOT
;
214 pool
->cleanup
= rxe_type_info
[type
].cleanup
;
216 atomic_set(&pool
->num_elem
, 0);
218 kref_init(&pool
->ref_cnt
);
220 rwlock_init(&pool
->pool_lock
);
222 if (rxe_type_info
[type
].flags
& RXE_POOL_INDEX
) {
223 err
= rxe_pool_init_index(pool
,
224 rxe_type_info
[type
].max_index
,
225 rxe_type_info
[type
].min_index
);
230 if (rxe_type_info
[type
].flags
& RXE_POOL_KEY
) {
231 pool
->key_offset
= rxe_type_info
[type
].key_offset
;
232 pool
->key_size
= rxe_type_info
[type
].key_size
;
235 pool
->state
= RXE_POOL_STATE_VALID
;
241 static void rxe_pool_release(struct kref
*kref
)
243 struct rxe_pool
*pool
= container_of(kref
, struct rxe_pool
, ref_cnt
);
245 pool
->state
= RXE_POOL_STATE_INVALID
;
249 static void rxe_pool_put(struct rxe_pool
*pool
)
251 kref_put(&pool
->ref_cnt
, rxe_pool_release
);
254 void rxe_pool_cleanup(struct rxe_pool
*pool
)
258 write_lock_irqsave(&pool
->pool_lock
, flags
);
259 pool
->state
= RXE_POOL_STATE_INVALID
;
260 if (atomic_read(&pool
->num_elem
) > 0)
261 pr_warn("%s pool destroyed with unfree'd elem\n",
263 write_unlock_irqrestore(&pool
->pool_lock
, flags
);
268 static u32
alloc_index(struct rxe_pool
*pool
)
271 u32 range
= pool
->max_index
- pool
->min_index
+ 1;
273 index
= find_next_zero_bit(pool
->table
, range
, pool
->last
);
275 index
= find_first_zero_bit(pool
->table
, range
);
277 WARN_ON_ONCE(index
>= range
);
278 set_bit(index
, pool
->table
);
280 return index
+ pool
->min_index
;
283 static void insert_index(struct rxe_pool
*pool
, struct rxe_pool_entry
*new)
285 struct rb_node
**link
= &pool
->tree
.rb_node
;
286 struct rb_node
*parent
= NULL
;
287 struct rxe_pool_entry
*elem
;
291 elem
= rb_entry(parent
, struct rxe_pool_entry
, node
);
293 if (elem
->index
== new->index
) {
294 pr_warn("element already exists!\n");
298 if (elem
->index
> new->index
)
299 link
= &(*link
)->rb_left
;
301 link
= &(*link
)->rb_right
;
304 rb_link_node(&new->node
, parent
, link
);
305 rb_insert_color(&new->node
, &pool
->tree
);
310 static void insert_key(struct rxe_pool
*pool
, struct rxe_pool_entry
*new)
312 struct rb_node
**link
= &pool
->tree
.rb_node
;
313 struct rb_node
*parent
= NULL
;
314 struct rxe_pool_entry
*elem
;
319 elem
= rb_entry(parent
, struct rxe_pool_entry
, node
);
321 cmp
= memcmp((u8
*)elem
+ pool
->key_offset
,
322 (u8
*)new + pool
->key_offset
, pool
->key_size
);
325 pr_warn("key already exists!\n");
330 link
= &(*link
)->rb_left
;
332 link
= &(*link
)->rb_right
;
335 rb_link_node(&new->node
, parent
, link
);
336 rb_insert_color(&new->node
, &pool
->tree
);
341 void rxe_add_key(void *arg
, void *key
)
343 struct rxe_pool_entry
*elem
= arg
;
344 struct rxe_pool
*pool
= elem
->pool
;
347 write_lock_irqsave(&pool
->pool_lock
, flags
);
348 memcpy((u8
*)elem
+ pool
->key_offset
, key
, pool
->key_size
);
349 insert_key(pool
, elem
);
350 write_unlock_irqrestore(&pool
->pool_lock
, flags
);
353 void rxe_drop_key(void *arg
)
355 struct rxe_pool_entry
*elem
= arg
;
356 struct rxe_pool
*pool
= elem
->pool
;
359 write_lock_irqsave(&pool
->pool_lock
, flags
);
360 rb_erase(&elem
->node
, &pool
->tree
);
361 write_unlock_irqrestore(&pool
->pool_lock
, flags
);
364 void rxe_add_index(void *arg
)
366 struct rxe_pool_entry
*elem
= arg
;
367 struct rxe_pool
*pool
= elem
->pool
;
370 write_lock_irqsave(&pool
->pool_lock
, flags
);
371 elem
->index
= alloc_index(pool
);
372 insert_index(pool
, elem
);
373 write_unlock_irqrestore(&pool
->pool_lock
, flags
);
376 void rxe_drop_index(void *arg
)
378 struct rxe_pool_entry
*elem
= arg
;
379 struct rxe_pool
*pool
= elem
->pool
;
382 write_lock_irqsave(&pool
->pool_lock
, flags
);
383 clear_bit(elem
->index
- pool
->min_index
, pool
->table
);
384 rb_erase(&elem
->node
, &pool
->tree
);
385 write_unlock_irqrestore(&pool
->pool_lock
, flags
);
388 void *rxe_alloc(struct rxe_pool
*pool
)
390 struct rxe_pool_entry
*elem
;
393 might_sleep_if(!(pool
->flags
& RXE_POOL_ATOMIC
));
395 read_lock_irqsave(&pool
->pool_lock
, flags
);
396 if (pool
->state
!= RXE_POOL_STATE_VALID
) {
397 read_unlock_irqrestore(&pool
->pool_lock
, flags
);
400 kref_get(&pool
->ref_cnt
);
401 read_unlock_irqrestore(&pool
->pool_lock
, flags
);
403 if (!ib_device_try_get(&pool
->rxe
->ib_dev
))
406 if (atomic_inc_return(&pool
->num_elem
) > pool
->max_elem
)
409 elem
= kmem_cache_zalloc(pool_cache(pool
),
410 (pool
->flags
& RXE_POOL_ATOMIC
) ?
411 GFP_ATOMIC
: GFP_KERNEL
);
416 kref_init(&elem
->ref_cnt
);
421 atomic_dec(&pool
->num_elem
);
422 ib_device_put(&pool
->rxe
->ib_dev
);
428 int rxe_add_to_pool(struct rxe_pool
*pool
, struct rxe_pool_entry
*elem
)
432 might_sleep_if(!(pool
->flags
& RXE_POOL_ATOMIC
));
434 read_lock_irqsave(&pool
->pool_lock
, flags
);
435 if (pool
->state
!= RXE_POOL_STATE_VALID
) {
436 read_unlock_irqrestore(&pool
->pool_lock
, flags
);
439 kref_get(&pool
->ref_cnt
);
440 read_unlock_irqrestore(&pool
->pool_lock
, flags
);
442 if (!ib_device_try_get(&pool
->rxe
->ib_dev
))
445 if (atomic_inc_return(&pool
->num_elem
) > pool
->max_elem
)
449 kref_init(&elem
->ref_cnt
);
454 atomic_dec(&pool
->num_elem
);
455 ib_device_put(&pool
->rxe
->ib_dev
);
461 void rxe_elem_release(struct kref
*kref
)
463 struct rxe_pool_entry
*elem
=
464 container_of(kref
, struct rxe_pool_entry
, ref_cnt
);
465 struct rxe_pool
*pool
= elem
->pool
;
470 if (!(pool
->flags
& RXE_POOL_NO_ALLOC
))
471 kmem_cache_free(pool_cache(pool
), elem
);
472 atomic_dec(&pool
->num_elem
);
473 ib_device_put(&pool
->rxe
->ib_dev
);
477 void *rxe_pool_get_index(struct rxe_pool
*pool
, u32 index
)
479 struct rb_node
*node
= NULL
;
480 struct rxe_pool_entry
*elem
= NULL
;
483 read_lock_irqsave(&pool
->pool_lock
, flags
);
485 if (pool
->state
!= RXE_POOL_STATE_VALID
)
488 node
= pool
->tree
.rb_node
;
491 elem
= rb_entry(node
, struct rxe_pool_entry
, node
);
493 if (elem
->index
> index
)
494 node
= node
->rb_left
;
495 else if (elem
->index
< index
)
496 node
= node
->rb_right
;
498 kref_get(&elem
->ref_cnt
);
504 read_unlock_irqrestore(&pool
->pool_lock
, flags
);
505 return node
? elem
: NULL
;
508 void *rxe_pool_get_key(struct rxe_pool
*pool
, void *key
)
510 struct rb_node
*node
= NULL
;
511 struct rxe_pool_entry
*elem
= NULL
;
515 read_lock_irqsave(&pool
->pool_lock
, flags
);
517 if (pool
->state
!= RXE_POOL_STATE_VALID
)
520 node
= pool
->tree
.rb_node
;
523 elem
= rb_entry(node
, struct rxe_pool_entry
, node
);
525 cmp
= memcmp((u8
*)elem
+ pool
->key_offset
,
526 key
, pool
->key_size
);
529 node
= node
->rb_left
;
531 node
= node
->rb_right
;
537 kref_get(&elem
->ref_cnt
);
540 read_unlock_irqrestore(&pool
->pool_lock
, flags
);
541 return node
? elem
: NULL
;