···41074107 * mas_wr_append: Attempt to append41084108 * @wr_mas: the maple write state41094109 *41104110+ * This is currently unsafe in rcu mode since the end of the node may be cached41114111+ * by readers while the node contents may be updated which could result in41124112+ * inaccurate information.41134113+ *41104114 * Return: True if appended, false otherwise41114115 */41124116static inline bool mas_wr_append(struct ma_wr_state *wr_mas,···41194115 unsigned char end = wr_mas->node_end;41204116 struct ma_state *mas = wr_mas->mas;41214117 unsigned char node_pivots = mt_pivots[wr_mas->type];41184118+41194119+ if (mt_in_rcu(mas->tree))41204120+ return false;4122412141234122 if (mas->offset != wr_mas->node_end)41244123 return false;
+1-1
mm/huge_memory.c
···16071607 * If other processes are mapping this folio, we couldn't discard16081608 * the folio unless they all do MADV_FREE so let's skip the folio.16091609 */16101610- if (folio_mapcount(folio) != 1)16101610+ if (folio_estimated_sharers(folio) != 1)16111611 goto out;1612161216131613 if (!folio_trylock(folio))
+3-3
mm/madvise.c
···383383 folio = pfn_folio(pmd_pfn(orig_pmd));384384385385 /* Do not interfere with other mappings of this folio */386386- if (folio_mapcount(folio) != 1)386386+ if (folio_estimated_sharers(folio) != 1)387387 goto huge_unlock;388388389389 if (pageout_anon_only_filter && !folio_test_anon(folio))···459459 if (folio_test_large(folio)) {460460 int err;461461462462- if (folio_mapcount(folio) != 1)462462+ if (folio_estimated_sharers(folio) != 1)463463 break;464464 if (pageout_anon_only_filter && !folio_test_anon(folio))465465 break;···683683 if (folio_test_large(folio)) {684684 int err;685685686686- if (folio_mapcount(folio) != 1)686686+ if (folio_estimated_sharers(folio) != 1)687687 break;688688 if (!folio_trylock(folio))689689 break;
+4-2
mm/shmem.c
···806806 XA_STATE(xas, &mapping->i_pages, start);807807 struct page *page;808808 unsigned long swapped = 0;809809+ unsigned long max = end - 1;809810810811 rcu_read_lock();811811- xas_for_each(&xas, page, end - 1) {812812+ xas_for_each(&xas, page, max) {812813 if (xas_retry(&xas, page))813814 continue;814815 if (xa_is_value(page))815816 swapped++;816816-817817+ if (xas.xa_index == max)818818+ break;817819 if (need_resched()) {818820 xas_pause(&xas);819821 cond_resched_rcu();
···44#include <stdio.h>55#include <stdbool.h>66#include <linux/kernel.h>77+#include <linux/magic.h>78#include <linux/mman.h>89#include <sys/mman.h>910#include <sys/shm.h>1011#include <sys/syscall.h>1212+#include <sys/vfs.h>1113#include <unistd.h>1214#include <string.h>1315#include <fcntl.h>1416#include <errno.h>15171618#include "../kselftest.h"1919+2020+#define NR_TESTS 917211822static const char * const dev_files[] = {1923 "/dev/zero", "/dev/null", "/dev/urandom",···9591}96929793/*9494+ * fsync() is implemented via noop_fsync() on tmpfs. This makes the fsync()9595+ * test fail below, so we need to check for test file living on a tmpfs.9696+ */9797+static bool is_on_tmpfs(int fd)9898+{9999+ struct statfs statfs_buf;100100+101101+ if (fstatfs(fd, &statfs_buf))102102+ return false;103103+104104+ return statfs_buf.f_type == TMPFS_MAGIC;105105+}106106+107107+/*98108 * Open/create the file at filename, (optionally) write random data to it99109 * (exactly num_pages), then test the cachestat syscall on this file.100110 *101111 * If test_fsync == true, fsync the file, then check the number of dirty102112 * pages.103113 */104104-bool test_cachestat(const char *filename, bool write_random, bool create,105105- bool test_fsync, unsigned long num_pages, int open_flags,106106- mode_t open_mode)114114+static int test_cachestat(const char *filename, bool write_random, bool create,115115+ bool test_fsync, unsigned long num_pages,116116+ int open_flags, mode_t open_mode)107117{108118 size_t PS = sysconf(_SC_PAGESIZE);109119 int filesize = num_pages * PS;110110- bool ret = true;120120+ int ret = KSFT_PASS;111121 long syscall_ret;112122 struct cachestat cs;113123 struct cachestat_range cs_range = { 0, filesize };···130112131113 if (fd == -1) {132114 ksft_print_msg("Unable to create/open file.\n");133133- ret = false;115115+ ret = KSFT_FAIL;134116 goto out;135117 } else {136118 ksft_print_msg("Create/open %s\n", filename);···139121 if (write_random) {140122 if (!write_exactly(fd, filesize)) {141123 ksft_print_msg("Unable to access urandom.\n");142142- ret = false;124124+ ret = KSFT_FAIL;143125 goto out1;144126 }145127 }···150132151133 if (syscall_ret) {152134 ksft_print_msg("Cachestat returned non-zero.\n");153153- ret = false;135135+ ret = KSFT_FAIL;154136 goto out1;155137156138 } else {···160142 if (cs.nr_cache + cs.nr_evicted != num_pages) {161143 ksft_print_msg(162144 "Total number of cached and evicted pages is off.\n");163163- ret = false;145145+ ret = KSFT_FAIL;164146 }165147 }166148 }167149168150 if (test_fsync) {169169- if (fsync(fd)) {151151+ if (is_on_tmpfs(fd)) {152152+ ret = KSFT_SKIP;153153+ } else if (fsync(fd)) {170154 ksft_print_msg("fsync fails.\n");171171- ret = false;155155+ ret = KSFT_FAIL;172156 } else {173157 syscall_ret = syscall(cachestat_nr, fd, &cs_range, &cs, 0);174158···181161 print_cachestat(&cs);182162183163 if (cs.nr_dirty) {184184- ret = false;164164+ ret = KSFT_FAIL;185165 ksft_print_msg(186166 "Number of dirty should be zero after fsync.\n");187167 }188168 } else {189169 ksft_print_msg("Cachestat (after fsync) returned non-zero.\n");190190- ret = false;170170+ ret = KSFT_FAIL;191171 goto out1;192172 }193173 }···256236257237int main(void)258238{259259- int ret = 0;239239+ int ret;240240+241241+ ksft_print_header();242242+243243+ ret = syscall(__NR_cachestat, -1, NULL, NULL, 0);244244+ if (ret == -1 && errno == ENOSYS)245245+ ksft_exit_skip("cachestat syscall not available\n");246246+247247+ ksft_set_plan(NR_TESTS);248248+249249+ if (ret == -1 && errno == EBADF) {250250+ ksft_test_result_pass("bad file descriptor recognized\n");251251+ ret = 0;252252+ } else {253253+ ksft_test_result_fail("bad file descriptor ignored\n");254254+ ret = 1;255255+ }260256261257 for (int i = 0; i < 5; i++) {262258 const char *dev_filename = dev_files[i];263259264260 if (test_cachestat(dev_filename, false, false, false,265265- 4, O_RDONLY, 0400))261261+ 4, O_RDONLY, 0400) == KSFT_PASS)266262 ksft_test_result_pass("cachestat works with %s\n", dev_filename);267263 else {268264 ksft_test_result_fail("cachestat fails with %s\n", dev_filename);···287251 }288252289253 if (test_cachestat("tmpfilecachestat", true, true,290290- true, 4, O_CREAT | O_RDWR, 0400 | 0600))254254+ false, 4, O_CREAT | O_RDWR, 0600) == KSFT_PASS)291255 ksft_test_result_pass("cachestat works with a normal file\n");292256 else {293257 ksft_test_result_fail("cachestat fails with normal file\n");294258 ret = 1;259259+ }260260+261261+ switch (test_cachestat("tmpfilecachestat", true, true,262262+ true, 4, O_CREAT | O_RDWR, 0600)) {263263+ case KSFT_FAIL:264264+ ksft_test_result_fail("cachestat fsync fails with normal file\n");265265+ ret = KSFT_FAIL;266266+ break;267267+ case KSFT_PASS:268268+ ksft_test_result_pass("cachestat fsync works with a normal file\n");269269+ break;270270+ case KSFT_SKIP:271271+ ksft_test_result_skip("tmpfilecachestat is on tmpfs\n");272272+ break;295273 }296274297275 if (test_cachestat_shmem())