mirror of
https://github.com/RGBCube/serenity
synced 2025-07-10 04:37:35 +00:00
Kernel: Add a mode flag to sys$purge and allow purging clean inodes
This commit is contained in:
parent
c74cde918a
commit
1f31156173
7 changed files with 83 additions and 17 deletions
|
@ -404,20 +404,36 @@ int Process::sys$madvise(void* address, size_t size, int advice)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Process::sys$purge()
|
int Process::sys$purge(int mode)
|
||||||
{
|
{
|
||||||
NonnullRefPtrVector<PurgeableVMObject> vmobjects;
|
|
||||||
{
|
|
||||||
InterruptDisabler disabler;
|
|
||||||
MM.for_each_vmobject([&](auto& vmobject) {
|
|
||||||
if (vmobject.is_purgeable())
|
|
||||||
vmobjects.append(static_cast<PurgeableVMObject&>(vmobject));
|
|
||||||
return IterationDecision::Continue;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
int purged_page_count = 0;
|
int purged_page_count = 0;
|
||||||
for (auto& vmobject : vmobjects) {
|
if (mode & PURGE_ALL_VOLATILE) {
|
||||||
purged_page_count += vmobject.purge();
|
NonnullRefPtrVector<PurgeableVMObject> vmobjects;
|
||||||
|
{
|
||||||
|
InterruptDisabler disabler;
|
||||||
|
MM.for_each_vmobject([&](auto& vmobject) {
|
||||||
|
if (vmobject.is_purgeable())
|
||||||
|
vmobjects.append(static_cast<PurgeableVMObject&>(vmobject));
|
||||||
|
return IterationDecision::Continue;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
for (auto& vmobject : vmobjects) {
|
||||||
|
purged_page_count += vmobject.purge();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mode & PURGE_ALL_CLEAN_INODE) {
|
||||||
|
NonnullRefPtrVector<InodeVMObject> vmobjects;
|
||||||
|
{
|
||||||
|
InterruptDisabler disabler;
|
||||||
|
MM.for_each_vmobject([&](auto& vmobject) {
|
||||||
|
if (vmobject.is_inode())
|
||||||
|
vmobjects.append(static_cast<InodeVMObject&>(vmobject));
|
||||||
|
return IterationDecision::Continue;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
for (auto& vmobject : vmobjects) {
|
||||||
|
purged_page_count += vmobject.release_all_clean_pages();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return purged_page_count;
|
return purged_page_count;
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,7 +142,7 @@ public:
|
||||||
int sys$set_mmap_name(void*, size_t, const char*);
|
int sys$set_mmap_name(void*, size_t, const char*);
|
||||||
int sys$mprotect(void*, size_t, int prot);
|
int sys$mprotect(void*, size_t, int prot);
|
||||||
int sys$madvise(void*, size_t, int advice);
|
int sys$madvise(void*, size_t, int advice);
|
||||||
int sys$purge();
|
int sys$purge(int mode);
|
||||||
int sys$select(const Syscall::SC_select_params*);
|
int sys$select(const Syscall::SC_select_params*);
|
||||||
int sys$poll(pollfd*, int nfds, int timeout);
|
int sys$poll(pollfd*, int nfds, int timeout);
|
||||||
ssize_t sys$get_dir_entries(int fd, void*, ssize_t);
|
ssize_t sys$get_dir_entries(int fd, void*, ssize_t);
|
||||||
|
|
|
@ -467,3 +467,5 @@ struct ifreq {
|
||||||
|
|
||||||
#define AT_FDCWD -100
|
#define AT_FDCWD -100
|
||||||
|
|
||||||
|
#define PURGE_ALL_VOLATILE 0x1
|
||||||
|
#define PURGE_ALL_CLEAN_INODE 0x2
|
||||||
|
|
|
@ -39,7 +39,8 @@ InodeVMObject::~InodeVMObject()
|
||||||
size_t InodeVMObject::amount_clean() const
|
size_t InodeVMObject::amount_clean() const
|
||||||
{
|
{
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
for (int i = 0; i < m_dirty_pages.size(); ++i) {
|
ASSERT(page_count() == (size_t)m_dirty_pages.size());
|
||||||
|
for (size_t i = 0; i < page_count(); ++i) {
|
||||||
if (!m_dirty_pages.get(i) && m_physical_pages[i])
|
if (!m_dirty_pages.get(i) && m_physical_pages[i])
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
|
@ -125,3 +126,25 @@ void InodeVMObject::inode_contents_changed(Badge<Inode>, off_t offset, ssize_t s
|
||||||
region.remap();
|
region.remap();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int InodeVMObject::release_all_clean_pages()
|
||||||
|
{
|
||||||
|
LOCKER(m_paging_lock);
|
||||||
|
return release_all_clean_pages_impl();
|
||||||
|
}
|
||||||
|
|
||||||
|
int InodeVMObject::release_all_clean_pages_impl()
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
InterruptDisabler disabler;
|
||||||
|
for (size_t i = 0; i < page_count(); ++i) {
|
||||||
|
if (!m_dirty_pages.get(i) && m_physical_pages[i]) {
|
||||||
|
m_physical_pages[i] = nullptr;
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for_each_region([](auto& region) {
|
||||||
|
region.remap();
|
||||||
|
});
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@ public:
|
||||||
size_t amount_dirty() const;
|
size_t amount_dirty() const;
|
||||||
size_t amount_clean() const;
|
size_t amount_clean() const;
|
||||||
|
|
||||||
|
int release_all_clean_pages();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit InodeVMObject(Inode&);
|
explicit InodeVMObject(Inode&);
|
||||||
explicit InodeVMObject(const InodeVMObject&);
|
explicit InodeVMObject(const InodeVMObject&);
|
||||||
|
@ -29,6 +31,8 @@ private:
|
||||||
|
|
||||||
virtual bool is_inode() const override { return true; }
|
virtual bool is_inode() const override { return true; }
|
||||||
|
|
||||||
|
int release_all_clean_pages_impl();
|
||||||
|
|
||||||
NonnullRefPtr<Inode> m_inode;
|
NonnullRefPtr<Inode> m_inode;
|
||||||
Bitmap m_dirty_pages;
|
Bitmap m_dirty_pages;
|
||||||
};
|
};
|
||||||
|
|
|
@ -410,6 +410,10 @@ PageFaultResponse Region::handle_inode_fault(size_t page_index_in_region)
|
||||||
LOCKER(vmobject().m_paging_lock);
|
LOCKER(vmobject().m_paging_lock);
|
||||||
cli();
|
cli();
|
||||||
|
|
||||||
|
#ifdef PAGE_FAULT_DEBUG
|
||||||
|
dbg() << *current << " inode fault in " << name() << " page index: " << page_index_in_region;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!vmobject_physical_page_entry.is_null()) {
|
if (!vmobject_physical_page_entry.is_null()) {
|
||||||
#ifdef PAGE_FAULT_DEBUG
|
#ifdef PAGE_FAULT_DEBUG
|
||||||
dbgprintf("MM: page_in_from_inode() but page already present. Fine with me!\n");
|
dbgprintf("MM: page_in_from_inode() but page already present. Fine with me!\n");
|
||||||
|
|
|
@ -1,9 +1,26 @@
|
||||||
#include <stdio.h>
|
|
||||||
#include <Kernel/Syscall.h>
|
#include <Kernel/Syscall.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
int main(int, char**)
|
#define PURGE_ALL_VOLATILE 0x1
|
||||||
|
#define PURGE_ALL_CLEAN_INODE 0x2
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
int purged_page_count = syscall(SC_purge);
|
int mode = 0;
|
||||||
|
if (argc == 1) {
|
||||||
|
mode = PURGE_ALL_VOLATILE | PURGE_ALL_CLEAN_INODE;
|
||||||
|
} else {
|
||||||
|
if (!strcmp(argv[1], "-c")) {
|
||||||
|
mode = PURGE_ALL_CLEAN_INODE;
|
||||||
|
} else if (!strcmp(argv[1], "-v")) {
|
||||||
|
mode = PURGE_ALL_VOLATILE;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Unknown option: %s\n", argv[1]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int purged_page_count = syscall(SC_purge, mode);
|
||||||
printf("Purged page count: %d\n", purged_page_count);
|
printf("Purged page count: %d\n", purged_page_count);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue