| // SPDX-License-Identifier: GPL-2.0 | |
| #ifndef _LINUX_MM_SLOT_H | |
| #define _LINUX_MM_SLOT_H | |
| #include <linux/hashtable.h> | |
| #include <linux/slab.h> | |
| /* | |
| * struct mm_slot - hash lookup from mm to mm_slot | |
| * @hash: link to the mm_slots hash list | |
| * @mm_node: link into the mm_slots list | |
| * @mm: the mm that this information is valid for | |
| */ | |
| struct mm_slot { | |
| struct hlist_node hash; | |
| struct list_head mm_node; | |
| struct mm_struct *mm; | |
| }; | |
| #define mm_slot_entry(ptr, type, member) \ | |
| container_of(ptr, type, member) | |
| static inline void *mm_slot_alloc(struct kmem_cache *cache) | |
| { | |
| if (!cache) /* initialization failed */ | |
| return NULL; | |
| return kmem_cache_zalloc(cache, GFP_KERNEL); | |
| } | |
| static inline void mm_slot_free(struct kmem_cache *cache, void *objp) | |
| { | |
| kmem_cache_free(cache, objp); | |
| } | |
| /* | |
| * Note: mm_slot_lookup and mm_slot_insert cannot be converted to static inline | |
| * functions because the hash helpers (hash_for_each_possible and hash_add) rely | |
| * on the actual array argument 'hashtable' for sizeof() instead of pointers. | |
| */ | |
| #define mm_slot_lookup(_hashtable, _mm) \ | |
| ({ \ | |
| struct mm_slot *tmp_slot, *mm_slot = NULL; \ | |
| \ | |
| hash_for_each_possible(_hashtable, tmp_slot, hash, (unsigned long)_mm) \ | |
| if (_mm == tmp_slot->mm) { \ | |
| mm_slot = tmp_slot; \ | |
| break; \ | |
| } \ | |
| \ | |
| mm_slot; \ | |
| }) | |
| #define mm_slot_insert(_hashtable, _mm, _mm_slot) \ | |
| ({ \ | |
| _mm_slot->mm = _mm; \ | |
| hash_add(_hashtable, &_mm_slot->hash, (unsigned long)_mm); \ | |
| }) | |
| static inline void mm_slot_remove(struct mm_slot *slot) | |
| { | |
| hash_del(&slot->hash); | |
| list_del(&slot->mm_node); | |
| } | |
| #endif /* _LINUX_MM_SLOT_H */ |