1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0
2f08c3bdfSopenharmony_ci/*
3f08c3bdfSopenharmony_ci * Copyright (C) 2010  Red Hat, Inc.
4f08c3bdfSopenharmony_ci */
5f08c3bdfSopenharmony_ci
6f08c3bdfSopenharmony_ci/*\
7f08c3bdfSopenharmony_ci * [Description]
8f08c3bdfSopenharmony_ci *
9f08c3bdfSopenharmony_ci * This is a reproducer copied from one of LKML patch submission
10f08c3bdfSopenharmony_ci * which subject is
11f08c3bdfSopenharmony_ci *
12f08c3bdfSopenharmony_ci * [PATCH] mlock: revert the optimization for dirtying pages and triggering writeback.
13f08c3bdfSopenharmony_ci * url see https://www.spinics.net/lists/kernel/msg1141090.html
14f08c3bdfSopenharmony_ci *
15f08c3bdfSopenharmony_ci * "In 5ecfda0, we do some optimization in mlock, but it causes
16f08c3bdfSopenharmony_ci * a very basic test case(attached below) of mlock to fail. So
17f08c3bdfSopenharmony_ci * this patch revert it with some tiny modification so that it
18f08c3bdfSopenharmony_ci * apply successfully with the lastest 38-rc2 kernel."
19f08c3bdfSopenharmony_ci *
20f08c3bdfSopenharmony_ci * This bug was fixed by kernel
21f08c3bdfSopenharmony_ci * commit fdf4c587a7 ("mlock: operate on any regions with protection != PROT_NONE")
22f08c3bdfSopenharmony_ci *
23f08c3bdfSopenharmony_ci * As this case does, mmaps a file with PROT_WRITE permissions but without
24f08c3bdfSopenharmony_ci * PROT_READ, so attempt to not unnecessarity break COW during mlock ended up
25f08c3bdfSopenharmony_ci * causing mlock to fail with a permission problem on unfixed kernel.
26f08c3bdfSopenharmony_ci */
27f08c3bdfSopenharmony_ci
28f08c3bdfSopenharmony_ci#include <sys/mman.h>
29f08c3bdfSopenharmony_ci#include <stdio.h>
30f08c3bdfSopenharmony_ci#include <sys/types.h>
31f08c3bdfSopenharmony_ci#include "tst_test.h"
32f08c3bdfSopenharmony_ci#include "tst_safe_macros.h"
33f08c3bdfSopenharmony_ci
34f08c3bdfSopenharmony_cistatic int fd = -1, file_len = 40960;
35f08c3bdfSopenharmony_cistatic char *testfile = "test_mlock";
36f08c3bdfSopenharmony_ci
37f08c3bdfSopenharmony_cistatic void verify_mlock(void)
38f08c3bdfSopenharmony_ci{
39f08c3bdfSopenharmony_ci	char *buf;
40f08c3bdfSopenharmony_ci
41f08c3bdfSopenharmony_ci	buf = SAFE_MMAP(NULL, file_len, PROT_WRITE, MAP_SHARED, fd, 0);
42f08c3bdfSopenharmony_ci	TST_EXP_PASS(mlock(buf, file_len), "mlock(%p, %d)", buf, file_len);
43f08c3bdfSopenharmony_ci	SAFE_MUNLOCK(buf, file_len);
44f08c3bdfSopenharmony_ci	SAFE_MUNMAP(buf, file_len);
45f08c3bdfSopenharmony_ci}
46f08c3bdfSopenharmony_ci
47f08c3bdfSopenharmony_cistatic void setup(void)
48f08c3bdfSopenharmony_ci{
49f08c3bdfSopenharmony_ci	fd = SAFE_OPEN(testfile, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
50f08c3bdfSopenharmony_ci	SAFE_FTRUNCATE(fd, file_len);
51f08c3bdfSopenharmony_ci}
52f08c3bdfSopenharmony_ci
53f08c3bdfSopenharmony_cistatic void cleanup(void)
54f08c3bdfSopenharmony_ci{
55f08c3bdfSopenharmony_ci	if (fd > -1)
56f08c3bdfSopenharmony_ci		SAFE_CLOSE(fd);
57f08c3bdfSopenharmony_ci}
58f08c3bdfSopenharmony_ci
59f08c3bdfSopenharmony_cistatic struct tst_test test = {
60f08c3bdfSopenharmony_ci	.needs_tmpdir = 1,
61f08c3bdfSopenharmony_ci	.setup = setup,
62f08c3bdfSopenharmony_ci	.cleanup = cleanup,
63f08c3bdfSopenharmony_ci	.test_all = verify_mlock,
64f08c3bdfSopenharmony_ci	.tags = (const struct tst_tag[]) {
65f08c3bdfSopenharmony_ci		{"linux-git", "fdf4c587a793"},
66f08c3bdfSopenharmony_ci		{}
67f08c3bdfSopenharmony_ci	}
68f08c3bdfSopenharmony_ci};
69