Currently, mmap() fails with `-EINVAL` when both MAP_DROPPABLE and MAP_PRIVATE are specified. This behavior might be inconsistent, as the implementation of MAP_DROPPABLE under the hood already includes the semantics of MAP_PRIVATE. So, IMO, whether MAP_PRIVATE is explicitly specified or not, it should work as expected. For example, when mmap() is called with `MAP_DROPPABLE | MAP_ANONYMOUS`, it creates a private anonymous mapping. Users can verify this behavior via `/proc/self/smaps`, where the resulting VMA is marked with the `dp` (MAP_DROPPABLE) flag, and the `Private_*` fields confirm private memory semantics. The output for a 2MiB mapping with these flags might look like: ``` f433ace00000-f433ad000000 rw-p 00000000 00:00 0 Size: 2048 kB KernelPageSize: 4 kB MMUPageSize: 4 kB Rss: 2048 kB Pss: 2048 kB Pss_Dirty: 2048 kB Shared_Clean: 0 kB Shared_Dirty: 0 kB Private_Clean: 0 kB Private_Dirty: 2048 kB Referenced: 2048 kB Anonymous: 2048 kB ... VmFlags: rd wr mr mw me nr wf dd dp ``` This patch changes mmap() to allow the combination of `MAP_DROPPABLE | MAP_PRIVATE`. For mmap(), at least one of MAP_PRIVATE or MAP_SHARED could be explicitly specified, regardless of the combination with other `MAP_*` flags. Fixes: 9651fcedf7b9 ("mm: add MAP_DROPPABLE for designating always lazily freeable mappings") Signed-off-by: Mingzhe Yang <mingzhe.yang@xxxxxx> Signed-off-by: Lance Yang <ioworker0@xxxxxxxxx> --- mm/mmap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mm/mmap.c b/mm/mmap.c index cda01071c7b1..840889b5bfb2 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -504,6 +504,7 @@ unsigned long do_mmap(struct file *file, unsigned long addr, vm_flags |= VM_SHARED | VM_MAYSHARE; break; case MAP_DROPPABLE: + case MAP_DROPPABLE | MAP_PRIVATE: if (VM_DROPPABLE == VM_NONE) return -ENOTSUPP; /* -- 2.45.2