Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

mm: add mk_vma_flags() bitmap flag macro helper

This patch introduces the mk_vma_flags() macro helper to allow easy
manipulation of VMA flags utilising the new bitmap representation
implemented of VMA flags defined by the vma_flags_t type.

It is a variadic macro which provides a bitwise-or'd representation of all
of each individual VMA flag specified.

Note that, while we maintain VM_xxx flags for backwards compatibility
until the conversion is complete, we define VMA flags of type vma_flag_t
using VMA_xxx_BIT to avoid confusing the two.

This helper macro therefore can be used thusly:

vma_flags_t flags = mk_vma_flags(VMA_READ_BIT, VMA_WRITE_BIT);

Testing has demonstrated that the compiler optimises this code such that
it generates the same assembly utilising this macro as it does if the
flags were specified manually, for instance:

vma_flags_t get_flags(void)
{
return mk_vma_flags(VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT);
}

Generates the same code as:

vma_flags_t get_flags(void)
{
vma_flags_t flags;

vma_flags_clear_all(&flags);
vma_flag_set(&flags, VMA_READ_BIT);
vma_flag_set(&flags, VMA_WRITE_BIT);
vma_flag_set(&flags, VMA_EXEC_BIT);

return flags;
}

And:

vma_flags_t get_flags(void)
{
vma_flags_t flags;
unsigned long *bitmap = ACCESS_PRIVATE(&flags, __vma_flags);

*bitmap = 1UL << (__force int)VMA_READ_BIT;
*bitmap |= 1UL << (__force int)VMA_WRITE_BIT;
*bitmap |= 1UL << (__force int)VMA_EXEC_BIT;

return flags;
}

That is:

get_flags:
movl $7, %eax
ret

Link: https://lkml.kernel.org/r/fde00df6ff7fb8c4b42cc0defa5a4924c7a1943a.1769097829.git.lorenzo.stoakes@oracle.com
Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Suggested-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Pedro Falcato <pfalcato@suse.de>
Reviewed-by: Liam R. Howlett <Liam.Howlett@oracle.com>
Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
Cc: Barry Song <baohua@kernel.org>
Cc: David Hildenbrand <david@kernel.org>
Cc: Dev Jain <dev.jain@arm.com>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Zi Yan <ziy@nvidia.com>
Cc: Damien Le Moal <dlemoal@kernel.org>
Cc: "Darrick J. Wong" <djwong@kernel.org>
Cc: Jarkko Sakkinen <jarkko@kernel.org>
Cc: Yury Norov <ynorov@nvidia.com>
Cc: Chris Mason <clm@fb.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Lorenzo Stoakes and committed by
Andrew Morton
1c628004 e388d312

+33
+33
include/linux/mm.h
··· 2 2 #ifndef _LINUX_MM_H 3 3 #define _LINUX_MM_H 4 4 5 + #include <linux/args.h> 5 6 #include <linux/errno.h> 6 7 #include <linux/mmdebug.h> 7 8 #include <linux/gfp.h> ··· 1026 1025 1027 1026 return false; 1028 1027 } 1028 + 1029 + /* Set an individual VMA flag in flags, non-atomically. */ 1030 + static inline void vma_flag_set(vma_flags_t *flags, vma_flag_t bit) 1031 + { 1032 + unsigned long *bitmap = flags->__vma_flags; 1033 + 1034 + __set_bit((__force int)bit, bitmap); 1035 + } 1036 + 1037 + static inline vma_flags_t __mk_vma_flags(size_t count, const vma_flag_t *bits) 1038 + { 1039 + vma_flags_t flags; 1040 + int i; 1041 + 1042 + vma_flags_clear_all(&flags); 1043 + for (i = 0; i < count; i++) 1044 + vma_flag_set(&flags, bits[i]); 1045 + return flags; 1046 + } 1047 + 1048 + /* 1049 + * Helper macro which bitwise-or combines the specified input flags into a 1050 + * vma_flags_t bitmap value. E.g.: 1051 + * 1052 + * vma_flags_t flags = mk_vma_flags(VMA_IO_BIT, VMA_PFNMAP_BIT, 1053 + * VMA_DONTEXPAND_BIT, VMA_DONTDUMP_BIT); 1054 + * 1055 + * The compiler cleverly optimises away all of the work and this ends up being 1056 + * equivalent to aggregating the values manually. 1057 + */ 1058 + #define mk_vma_flags(...) __mk_vma_flags(COUNT_ARGS(__VA_ARGS__), \ 1059 + (const vma_flag_t []){__VA_ARGS__}) 1029 1060 1030 1061 static inline void vma_set_anonymous(struct vm_area_struct *vma) 1031 1062 {