filemap.c (5c68005083d620b1499fc81926a514d39ae8b88c) | filemap.c (cf264e1329fb0307e044f7675849f9f38b44c11a) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * linux/mm/filemap.c 4 * 5 * Copyright (C) 1994-1999 Linus Torvalds 6 */ 7 8/* --- 8 unchanged lines hidden (view full) --- 17#include <linux/sched/signal.h> 18#include <linux/uaccess.h> 19#include <linux/capability.h> 20#include <linux/kernel_stat.h> 21#include <linux/gfp.h> 22#include <linux/mm.h> 23#include <linux/swap.h> 24#include <linux/swapops.h> | 1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * linux/mm/filemap.c 4 * 5 * Copyright (C) 1994-1999 Linus Torvalds 6 */ 7 8/* --- 8 unchanged lines hidden (view full) --- 17#include <linux/sched/signal.h> 18#include <linux/uaccess.h> 19#include <linux/capability.h> 20#include <linux/kernel_stat.h> 21#include <linux/gfp.h> 22#include <linux/mm.h> 23#include <linux/swap.h> 24#include <linux/swapops.h> |
25#include <linux/syscalls.h> |
|
25#include <linux/mman.h> 26#include <linux/pagemap.h> 27#include <linux/file.h> 28#include <linux/uio.h> 29#include <linux/error-injection.h> 30#include <linux/hash.h> 31#include <linux/writeback.h> 32#include <linux/backing-dev.h> --- 20 unchanged lines hidden (view full) --- 53 54/* 55 * FIXME: remove all knowledge of the buffer layer from the core VM 56 */ 57#include <linux/buffer_head.h> /* for try_to_free_buffers */ 58 59#include <asm/mman.h> 60 | 26#include <linux/mman.h> 27#include <linux/pagemap.h> 28#include <linux/file.h> 29#include <linux/uio.h> 30#include <linux/error-injection.h> 31#include <linux/hash.h> 32#include <linux/writeback.h> 33#include <linux/backing-dev.h> --- 20 unchanged lines hidden (view full) --- 54 55/* 56 * FIXME: remove all knowledge of the buffer layer from the core VM 57 */ 58#include <linux/buffer_head.h> /* for try_to_free_buffers */ 59 60#include <asm/mman.h> 61 |
62#include "swap.h" 63 |
|
61/* 62 * Shared mappings implemented 30.11.1994. It's not fully working yet, 63 * though. 64 * 65 * Shared mappings now work. 15.8.1995 Bruno. 66 * 67 * finished 'unifying' the page and buffer cache and SMP-threaded the 68 * page-cache, 21.05.1999, Ingo Molnar <mingo@redhat.com> --- 4045 unchanged lines hidden (view full) --- 4114 if (folio_test_writeback(folio)) 4115 return false; 4116 4117 if (mapping && mapping->a_ops->release_folio) 4118 return mapping->a_ops->release_folio(folio, gfp); 4119 return try_to_free_buffers(folio); 4120} 4121EXPORT_SYMBOL(filemap_release_folio); | 64/* 65 * Shared mappings implemented 30.11.1994. It's not fully working yet, 66 * though. 67 * 68 * Shared mappings now work. 15.8.1995 Bruno. 69 * 70 * finished 'unifying' the page and buffer cache and SMP-threaded the 71 * page-cache, 21.05.1999, Ingo Molnar <mingo@redhat.com> --- 4045 unchanged lines hidden (view full) --- 4117 if (folio_test_writeback(folio)) 4118 return false; 4119 4120 if (mapping && mapping->a_ops->release_folio) 4121 return mapping->a_ops->release_folio(folio, gfp); 4122 return try_to_free_buffers(folio); 4123} 4124EXPORT_SYMBOL(filemap_release_folio); |
4125 4126#ifdef CONFIG_CACHESTAT_SYSCALL 4127/** 4128 * filemap_cachestat() - compute the page cache statistics of a mapping 4129 * @mapping: The mapping to compute the statistics for. 4130 * @first_index: The starting page cache index. 4131 * @last_index: The final page index (inclusive). 4132 * @cs: the cachestat struct to write the result to. 4133 * 4134 * This will query the page cache statistics of a mapping in the 4135 * page range of [first_index, last_index] (inclusive). The statistics 4136 * queried include: number of dirty pages, number of pages marked for 4137 * writeback, and the number of (recently) evicted pages. 4138 */ 4139static void filemap_cachestat(struct address_space *mapping, 4140 pgoff_t first_index, pgoff_t last_index, struct cachestat *cs) 4141{ 4142 XA_STATE(xas, &mapping->i_pages, first_index); 4143 struct folio *folio; 4144 4145 rcu_read_lock(); 4146 xas_for_each(&xas, folio, last_index) { 4147 unsigned long nr_pages; 4148 pgoff_t folio_first_index, folio_last_index; 4149 4150 if (xas_retry(&xas, folio)) 4151 continue; 4152 4153 if (xa_is_value(folio)) { 4154 /* page is evicted */ 4155 void *shadow = (void *)folio; 4156 bool workingset; /* not used */ 4157 int order = xa_get_order(xas.xa, xas.xa_index); 4158 4159 nr_pages = 1 << order; 4160 folio_first_index = round_down(xas.xa_index, 1 << order); 4161 folio_last_index = folio_first_index + nr_pages - 1; 4162 4163 /* Folios might straddle the range boundaries, only count covered pages */ 4164 if (folio_first_index < first_index) 4165 nr_pages -= first_index - folio_first_index; 4166 4167 if (folio_last_index > last_index) 4168 nr_pages -= folio_last_index - last_index; 4169 4170 cs->nr_evicted += nr_pages; 4171 4172#ifdef CONFIG_SWAP /* implies CONFIG_MMU */ 4173 if (shmem_mapping(mapping)) { 4174 /* shmem file - in swap cache */ 4175 swp_entry_t swp = radix_to_swp_entry(folio); 4176 4177 shadow = get_shadow_from_swap_cache(swp); 4178 } 4179#endif 4180 if (workingset_test_recent(shadow, true, &workingset)) 4181 cs->nr_recently_evicted += nr_pages; 4182 4183 goto resched; 4184 } 4185 4186 nr_pages = folio_nr_pages(folio); 4187 folio_first_index = folio_pgoff(folio); 4188 folio_last_index = folio_first_index + nr_pages - 1; 4189 4190 /* Folios might straddle the range boundaries, only count covered pages */ 4191 if (folio_first_index < first_index) 4192 nr_pages -= first_index - folio_first_index; 4193 4194 if (folio_last_index > last_index) 4195 nr_pages -= folio_last_index - last_index; 4196 4197 /* page is in cache */ 4198 cs->nr_cache += nr_pages; 4199 4200 if (folio_test_dirty(folio)) 4201 cs->nr_dirty += nr_pages; 4202 4203 if (folio_test_writeback(folio)) 4204 cs->nr_writeback += nr_pages; 4205 4206resched: 4207 if (need_resched()) { 4208 xas_pause(&xas); 4209 cond_resched_rcu(); 4210 } 4211 } 4212 rcu_read_unlock(); 4213} 4214 4215/* 4216 * The cachestat(2) system call. 4217 * 4218 * cachestat() returns the page cache statistics of a file in the 4219 * bytes range specified by `off` and `len`: number of cached pages, 4220 * number of dirty pages, number of pages marked for writeback, 4221 * number of evicted pages, and number of recently evicted pages. 4222 * 4223 * An evicted page is a page that is previously in the page cache 4224 * but has been evicted since. A page is recently evicted if its last 4225 * eviction was recent enough that its reentry to the cache would 4226 * indicate that it is actively being used by the system, and that 4227 * there is memory pressure on the system. 4228 * 4229 * `off` and `len` must be non-negative integers. If `len` > 0, 4230 * the queried range is [`off`, `off` + `len`]. If `len` == 0, 4231 * we will query in the range from `off` to the end of the file. 4232 * 4233 * The `flags` argument is unused for now, but is included for future 4234 * extensibility. User should pass 0 (i.e no flag specified). 4235 * 4236 * Currently, hugetlbfs is not supported. 4237 * 4238 * Because the status of a page can change after cachestat() checks it 4239 * but before it returns to the application, the returned values may 4240 * contain stale information. 4241 * 4242 * return values: 4243 * zero - success 4244 * -EFAULT - cstat or cstat_range points to an illegal address 4245 * -EINVAL - invalid flags 4246 * -EBADF - invalid file descriptor 4247 * -EOPNOTSUPP - file descriptor is of a hugetlbfs file 4248 */ 4249SYSCALL_DEFINE4(cachestat, unsigned int, fd, 4250 struct cachestat_range __user *, cstat_range, 4251 struct cachestat __user *, cstat, unsigned int, flags) 4252{ 4253 struct fd f = fdget(fd); 4254 struct address_space *mapping; 4255 struct cachestat_range csr; 4256 struct cachestat cs; 4257 pgoff_t first_index, last_index; 4258 4259 if (!f.file) 4260 return -EBADF; 4261 4262 if (copy_from_user(&csr, cstat_range, 4263 sizeof(struct cachestat_range))) { 4264 fdput(f); 4265 return -EFAULT; 4266 } 4267 4268 /* hugetlbfs is not supported */ 4269 if (is_file_hugepages(f.file)) { 4270 fdput(f); 4271 return -EOPNOTSUPP; 4272 } 4273 4274 if (flags != 0) { 4275 fdput(f); 4276 return -EINVAL; 4277 } 4278 4279 first_index = csr.off >> PAGE_SHIFT; 4280 last_index = 4281 csr.len == 0 ? ULONG_MAX : (csr.off + csr.len - 1) >> PAGE_SHIFT; 4282 memset(&cs, 0, sizeof(struct cachestat)); 4283 mapping = f.file->f_mapping; 4284 filemap_cachestat(mapping, first_index, last_index, &cs); 4285 fdput(f); 4286 4287 if (copy_to_user(cstat, &cs, sizeof(struct cachestat))) 4288 return -EFAULT; 4289 4290 return 0; 4291} 4292#endif /* CONFIG_CACHESTAT_SYSCALL */ |
|