1 | // SPDX-License-Identifier: GPL-2.0 |
2 | |
3 | #ifndef _LINUX_MM_SLOT_H |
4 | #define _LINUX_MM_SLOT_H |
5 | |
6 | #include <linux/hashtable.h> |
7 | #include <linux/slab.h> |
8 | |
9 | /* |
10 | * struct mm_slot - hash lookup from mm to mm_slot |
11 | * @hash: link to the mm_slots hash list |
12 | * @mm_node: link into the mm_slots list |
13 | * @mm: the mm that this information is valid for |
14 | */ |
15 | struct mm_slot { |
16 | struct hlist_node hash; |
17 | struct list_head mm_node; |
18 | struct mm_struct *mm; |
19 | }; |
20 | |
21 | #define mm_slot_entry(ptr, type, member) \ |
22 | container_of(ptr, type, member) |
23 | |
24 | static inline void *mm_slot_alloc(struct kmem_cache *cache) |
25 | { |
26 | if (!cache) /* initialization failed */ |
27 | return NULL; |
28 | return kmem_cache_zalloc(k: cache, GFP_KERNEL); |
29 | } |
30 | |
31 | static inline void mm_slot_free(struct kmem_cache *cache, void *objp) |
32 | { |
33 | kmem_cache_free(s: cache, objp); |
34 | } |
35 | |
36 | #define mm_slot_lookup(_hashtable, _mm) \ |
37 | ({ \ |
38 | struct mm_slot *tmp_slot, *mm_slot = NULL; \ |
39 | \ |
40 | hash_for_each_possible(_hashtable, tmp_slot, hash, (unsigned long)_mm) \ |
41 | if (_mm == tmp_slot->mm) { \ |
42 | mm_slot = tmp_slot; \ |
43 | break; \ |
44 | } \ |
45 | \ |
46 | mm_slot; \ |
47 | }) |
48 | |
49 | #define mm_slot_insert(_hashtable, _mm, _mm_slot) \ |
50 | ({ \ |
51 | _mm_slot->mm = _mm; \ |
52 | hash_add(_hashtable, &_mm_slot->hash, (unsigned long)_mm); \ |
53 | }) |
54 | |
55 | #endif /* _LINUX_MM_SLOT_H */ |
56 | |