Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
fcbc329f
Commit
fcbc329f
authored
Aug 24, 2023
by
Andrew Morton
Browse files
Options
Browse Files
Download
Plain Diff
merge mm-hotfixes-stable into mm-stable to pick up depended-upon changes
parents
a644b0ab
e5548f85
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
80 additions
and
21 deletions
+80
-21
lib/maple_tree.c
lib/maple_tree.c
+7
-0
mm/huge_memory.c
mm/huge_memory.c
+1
-1
mm/madvise.c
mm/madvise.c
+3
-3
mm/shmem.c
mm/shmem.c
+4
-2
tools/testing/selftests/cachestat/test_cachestat.c
tools/testing/selftests/cachestat/test_cachestat.c
+65
-15
No files found.
lib/maple_tree.c
View file @
fcbc329f
...
...
@@ -4107,6 +4107,10 @@ static inline unsigned char mas_wr_new_end(struct ma_wr_state *wr_mas)
* mas_wr_append: Attempt to append
* @wr_mas: the maple write state
*
* This is currently unsafe in rcu mode since the end of the node may be cached
* by readers while the node contents may be updated which could result in
* inaccurate information.
*
* Return: True if appended, false otherwise
*/
static
inline
bool
mas_wr_append
(
struct
ma_wr_state
*
wr_mas
,
...
...
@@ -4116,6 +4120,9 @@ static inline bool mas_wr_append(struct ma_wr_state *wr_mas,
struct
ma_state
*
mas
=
wr_mas
->
mas
;
unsigned
char
node_pivots
=
mt_pivots
[
wr_mas
->
type
];
if
(
mt_in_rcu
(
mas
->
tree
))
return
false
;
if
(
mas
->
offset
!=
wr_mas
->
node_end
)
return
false
;
...
...
mm/huge_memory.c
View file @
fcbc329f
...
...
@@ -1607,7 +1607,7 @@ bool madvise_free_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma,
* If other processes are mapping this folio, we couldn't discard
* the folio unless they all do MADV_FREE so let's skip the folio.
*/
if
(
folio_
mapcount
(
folio
)
!=
1
)
if
(
folio_
estimated_sharers
(
folio
)
!=
1
)
goto
out
;
if
(
!
folio_trylock
(
folio
))
...
...
mm/madvise.c
View file @
fcbc329f
...
...
@@ -383,7 +383,7 @@ static int madvise_cold_or_pageout_pte_range(pmd_t *pmd,
folio
=
pfn_folio
(
pmd_pfn
(
orig_pmd
));
/* Do not interfere with other mappings of this folio */
if
(
folio_
mapcount
(
folio
)
!=
1
)
if
(
folio_
estimated_sharers
(
folio
)
!=
1
)
goto
huge_unlock
;
if
(
pageout_anon_only_filter
&&
!
folio_test_anon
(
folio
))
...
...
@@ -459,7 +459,7 @@ static int madvise_cold_or_pageout_pte_range(pmd_t *pmd,
if
(
folio_test_large
(
folio
))
{
int
err
;
if
(
folio_
mapcount
(
folio
)
!=
1
)
if
(
folio_
estimated_sharers
(
folio
)
!=
1
)
break
;
if
(
pageout_anon_only_filter
&&
!
folio_test_anon
(
folio
))
break
;
...
...
@@ -683,7 +683,7 @@ static int madvise_free_pte_range(pmd_t *pmd, unsigned long addr,
if
(
folio_test_large
(
folio
))
{
int
err
;
if
(
folio_
mapcount
(
folio
)
!=
1
)
if
(
folio_
estimated_sharers
(
folio
)
!=
1
)
break
;
if
(
!
folio_trylock
(
folio
))
break
;
...
...
mm/shmem.c
View file @
fcbc329f
...
...
@@ -806,14 +806,16 @@ unsigned long shmem_partial_swap_usage(struct address_space *mapping,
XA_STATE
(
xas
,
&
mapping
->
i_pages
,
start
);
struct
page
*
page
;
unsigned
long
swapped
=
0
;
unsigned
long
max
=
end
-
1
;
rcu_read_lock
();
xas_for_each
(
&
xas
,
page
,
end
-
1
)
{
xas_for_each
(
&
xas
,
page
,
max
)
{
if
(
xas_retry
(
&
xas
,
page
))
continue
;
if
(
xa_is_value
(
page
))
swapped
++
;
if
(
xas
.
xa_index
==
max
)
break
;
if
(
need_resched
())
{
xas_pause
(
&
xas
);
cond_resched_rcu
();
...
...
tools/testing/selftests/cachestat/test_cachestat.c
View file @
fcbc329f
...
...
@@ -4,10 +4,12 @@
#include <stdio.h>
#include <stdbool.h>
#include <linux/kernel.h>
#include <linux/magic.h>
#include <linux/mman.h>
#include <sys/mman.h>
#include <sys/shm.h>
#include <sys/syscall.h>
#include <sys/vfs.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
...
...
@@ -15,6 +17,8 @@
#include "../kselftest.h"
#define NR_TESTS 9
static
const
char
*
const
dev_files
[]
=
{
"/dev/zero"
,
"/dev/null"
,
"/dev/urandom"
,
"/proc/version"
,
"/proc"
...
...
@@ -90,6 +94,20 @@ bool write_exactly(int fd, size_t filesize)
return
ret
;
}
/*
* fsync() is implemented via noop_fsync() on tmpfs. This makes the fsync()
* test fail below, so we need to check for test file living on a tmpfs.
*/
static
bool
is_on_tmpfs
(
int
fd
)
{
struct
statfs
statfs_buf
;
if
(
fstatfs
(
fd
,
&
statfs_buf
))
return
false
;
return
statfs_buf
.
f_type
==
TMPFS_MAGIC
;
}
/*
* Open/create the file at filename, (optionally) write random data to it
* (exactly num_pages), then test the cachestat syscall on this file.
...
...
@@ -97,13 +115,13 @@ bool write_exactly(int fd, size_t filesize)
* If test_fsync == true, fsync the file, then check the number of dirty
* pages.
*/
bool
test_cachestat
(
const
char
*
filename
,
bool
write_random
,
bool
create
,
bool
test_fsync
,
unsigned
long
num_pages
,
int
open_flag
s
,
mode_t
open_mode
)
static
int
test_cachestat
(
const
char
*
filename
,
bool
write_random
,
bool
create
,
bool
test_fsync
,
unsigned
long
num_page
s
,
int
open_flags
,
mode_t
open_mode
)
{
size_t
PS
=
sysconf
(
_SC_PAGESIZE
);
int
filesize
=
num_pages
*
PS
;
bool
ret
=
true
;
int
ret
=
KSFT_PASS
;
long
syscall_ret
;
struct
cachestat
cs
;
struct
cachestat_range
cs_range
=
{
0
,
filesize
};
...
...
@@ -112,7 +130,7 @@ bool test_cachestat(const char *filename, bool write_random, bool create,
if
(
fd
==
-
1
)
{
ksft_print_msg
(
"Unable to create/open file.
\n
"
);
ret
=
false
;
ret
=
KSFT_FAIL
;
goto
out
;
}
else
{
ksft_print_msg
(
"Create/open %s
\n
"
,
filename
);
...
...
@@ -121,7 +139,7 @@ bool test_cachestat(const char *filename, bool write_random, bool create,
if
(
write_random
)
{
if
(
!
write_exactly
(
fd
,
filesize
))
{
ksft_print_msg
(
"Unable to access urandom.
\n
"
);
ret
=
false
;
ret
=
KSFT_FAIL
;
goto
out1
;
}
}
...
...
@@ -132,7 +150,7 @@ bool test_cachestat(const char *filename, bool write_random, bool create,
if
(
syscall_ret
)
{
ksft_print_msg
(
"Cachestat returned non-zero.
\n
"
);
ret
=
false
;
ret
=
KSFT_FAIL
;
goto
out1
;
}
else
{
...
...
@@ -142,15 +160,17 @@ bool test_cachestat(const char *filename, bool write_random, bool create,
if
(
cs
.
nr_cache
+
cs
.
nr_evicted
!=
num_pages
)
{
ksft_print_msg
(
"Total number of cached and evicted pages is off.
\n
"
);
ret
=
false
;
ret
=
KSFT_FAIL
;
}
}
}
if
(
test_fsync
)
{
if
(
fsync
(
fd
))
{
if
(
is_on_tmpfs
(
fd
))
{
ret
=
KSFT_SKIP
;
}
else
if
(
fsync
(
fd
))
{
ksft_print_msg
(
"fsync fails.
\n
"
);
ret
=
false
;
ret
=
KSFT_FAIL
;
}
else
{
syscall_ret
=
syscall
(
cachestat_nr
,
fd
,
&
cs_range
,
&
cs
,
0
);
...
...
@@ -161,13 +181,13 @@ bool test_cachestat(const char *filename, bool write_random, bool create,
print_cachestat
(
&
cs
);
if
(
cs
.
nr_dirty
)
{
ret
=
false
;
ret
=
KSFT_FAIL
;
ksft_print_msg
(
"Number of dirty should be zero after fsync.
\n
"
);
}
}
else
{
ksft_print_msg
(
"Cachestat (after fsync) returned non-zero.
\n
"
);
ret
=
false
;
ret
=
KSFT_FAIL
;
goto
out1
;
}
}
...
...
@@ -236,13 +256,29 @@ bool test_cachestat_shmem(void)
int
main
(
void
)
{
int
ret
=
0
;
int
ret
;
ksft_print_header
();
ret
=
syscall
(
__NR_cachestat
,
-
1
,
NULL
,
NULL
,
0
);
if
(
ret
==
-
1
&&
errno
==
ENOSYS
)
ksft_exit_skip
(
"cachestat syscall not available
\n
"
);
ksft_set_plan
(
NR_TESTS
);
if
(
ret
==
-
1
&&
errno
==
EBADF
)
{
ksft_test_result_pass
(
"bad file descriptor recognized
\n
"
);
ret
=
0
;
}
else
{
ksft_test_result_fail
(
"bad file descriptor ignored
\n
"
);
ret
=
1
;
}
for
(
int
i
=
0
;
i
<
5
;
i
++
)
{
const
char
*
dev_filename
=
dev_files
[
i
];
if
(
test_cachestat
(
dev_filename
,
false
,
false
,
false
,
4
,
O_RDONLY
,
0400
))
4
,
O_RDONLY
,
0400
)
==
KSFT_PASS
)
ksft_test_result_pass
(
"cachestat works with %s
\n
"
,
dev_filename
);
else
{
ksft_test_result_fail
(
"cachestat fails with %s
\n
"
,
dev_filename
);
...
...
@@ -251,13 +287,27 @@ int main(void)
}
if
(
test_cachestat
(
"tmpfilecachestat"
,
true
,
true
,
true
,
4
,
O_CREAT
|
O_RDWR
,
0400
|
0600
)
)
false
,
4
,
O_CREAT
|
O_RDWR
,
0600
)
==
KSFT_PASS
)
ksft_test_result_pass
(
"cachestat works with a normal file
\n
"
);
else
{
ksft_test_result_fail
(
"cachestat fails with normal file
\n
"
);
ret
=
1
;
}
switch
(
test_cachestat
(
"tmpfilecachestat"
,
true
,
true
,
true
,
4
,
O_CREAT
|
O_RDWR
,
0600
))
{
case
KSFT_FAIL
:
ksft_test_result_fail
(
"cachestat fsync fails with normal file
\n
"
);
ret
=
KSFT_FAIL
;
break
;
case
KSFT_PASS
:
ksft_test_result_pass
(
"cachestat fsync works with a normal file
\n
"
);
break
;
case
KSFT_SKIP
:
ksft_test_result_skip
(
"tmpfilecachestat is on tmpfs
\n
"
);
break
;
}
if
(
test_cachestat_shmem
())
ksft_test_result_pass
(
"cachestat works with a shmem file
\n
"
);
else
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment