Skip to content

Commit 1c62800

Browse files
ljskernelakpm00
authored andcommitted
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>
1 parent e388d31 commit 1c62800

1 file changed

Lines changed: 33 additions & 0 deletions

File tree

include/linux/mm.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#ifndef _LINUX_MM_H
33
#define _LINUX_MM_H
44

5+
#include <linux/args.h>
56
#include <linux/errno.h>
67
#include <linux/mmdebug.h>
78
#include <linux/gfp.h>
@@ -1026,6 +1027,38 @@ static inline bool vma_test_atomic_flag(struct vm_area_struct *vma, vma_flag_t b
10261027
return false;
10271028
}
10281029

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

0 commit comments

Comments
 (0)