Skip to content

Commit b5b4287

Browse files
charlie-rivospalmer-dabbelt
authored andcommitted
riscv: mm: Use hint address in mmap if available
On riscv it is guaranteed that the address returned by mmap is less than the hint address. Allow mmap to return an address all the way up to addr, if provided, rather than just up to the lower address space. This provides a performance benefit as well, allowing mmap to exit after checking that the address is in range rather than searching for a valid address. It is possible to provide an address that uses at most the same number of bits, however it is significantly more computationally expensive to provide that number rather than setting the max to be the hint address. There is the instruction clz/clzw in Zbb that returns the highest set bit which could be used to performantly implement this, but it would still be slower than the current implementation. At worst case, half of the address would not be able to be allocated when a hint address is provided. Signed-off-by: Charlie Jenkins <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent 556e2d1 commit b5b4287

File tree

1 file changed

+11
-16
lines changed

1 file changed

+11
-16
lines changed

arch/riscv/include/asm/processor.h

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,16 @@
1414

1515
#include <asm/ptrace.h>
1616

17-
#ifdef CONFIG_64BIT
18-
#define DEFAULT_MAP_WINDOW (UL(1) << (MMAP_VA_BITS - 1))
19-
#define STACK_TOP_MAX TASK_SIZE_64
20-
2117
#define arch_get_mmap_end(addr, len, flags) \
2218
({ \
2319
unsigned long mmap_end; \
2420
typeof(addr) _addr = (addr); \
25-
if ((_addr) == 0 || (IS_ENABLED(CONFIG_COMPAT) && is_compat_task())) \
21+
if ((_addr) == 0 || \
22+
(IS_ENABLED(CONFIG_COMPAT) && is_compat_task()) || \
23+
((_addr + len) > BIT(VA_BITS - 1))) \
2624
mmap_end = STACK_TOP_MAX; \
27-
else if ((_addr) >= VA_USER_SV57) \
28-
mmap_end = STACK_TOP_MAX; \
29-
else if ((((_addr) >= VA_USER_SV48)) && (VA_BITS >= VA_BITS_SV48)) \
30-
mmap_end = VA_USER_SV48; \
3125
else \
32-
mmap_end = VA_USER_SV39; \
26+
mmap_end = (_addr + len); \
3327
mmap_end; \
3428
})
3529

@@ -39,17 +33,18 @@
3933
typeof(addr) _addr = (addr); \
4034
typeof(base) _base = (base); \
4135
unsigned long rnd_gap = DEFAULT_MAP_WINDOW - (_base); \
42-
if ((_addr) == 0 || (IS_ENABLED(CONFIG_COMPAT) && is_compat_task())) \
36+
if ((_addr) == 0 || \
37+
(IS_ENABLED(CONFIG_COMPAT) && is_compat_task()) || \
38+
((_addr + len) > BIT(VA_BITS - 1))) \
4339
mmap_base = (_base); \
44-
else if (((_addr) >= VA_USER_SV57) && (VA_BITS >= VA_BITS_SV57)) \
45-
mmap_base = VA_USER_SV57 - rnd_gap; \
46-
else if ((((_addr) >= VA_USER_SV48)) && (VA_BITS >= VA_BITS_SV48)) \
47-
mmap_base = VA_USER_SV48 - rnd_gap; \
4840
else \
49-
mmap_base = VA_USER_SV39 - rnd_gap; \
41+
mmap_base = (_addr + len) - rnd_gap; \
5042
mmap_base; \
5143
})
5244

45+
#ifdef CONFIG_64BIT
46+
#define DEFAULT_MAP_WINDOW (UL(1) << (MMAP_VA_BITS - 1))
47+
#define STACK_TOP_MAX TASK_SIZE_64
5348
#else
5449
#define DEFAULT_MAP_WINDOW TASK_SIZE
5550
#define STACK_TOP_MAX TASK_SIZE

0 commit comments

Comments
 (0)