summaryrefslogtreecommitdiffstats
path: root/sys/kern/subr_hibernate.c
diff options
context:
space:
mode:
authorariane <ariane@openbsd.org>2011-07-08 18:34:46 +0000
committerariane <ariane@openbsd.org>2011-07-08 18:34:46 +0000
commitf0898735a3c4dec3414add3e8be85de599e05c34 (patch)
tree1c68b636f538612553c3f5cfb51ed7c877b7bfb4 /sys/kern/subr_hibernate.c
parentChange pig allocator to a highest-address selection. (diff)
downloadwireguard-openbsd-f0898735a3c4dec3414add3e8be85de599e05c34.tar.xz
wireguard-openbsd-f0898735a3c4dec3414add3e8be85de599e05c34.zip
Put in RLE logic for hibernate compressor.
These have the potential to compress 1MB of physmem into 1 byte. This works by noting the page is not in use and therefor skipping it. Needed by mlarkin@ for hibernate. No callers yet.
Diffstat (limited to 'sys/kern/subr_hibernate.c')
-rw-r--r--sys/kern/subr_hibernate.c35
1 files changed, 34 insertions, 1 deletions
diff --git a/sys/kern/subr_hibernate.c b/sys/kern/subr_hibernate.c
index 8c8c4ccfd46..c622e1a2cb8 100644
--- a/sys/kern/subr_hibernate.c
+++ b/sys/kern/subr_hibernate.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: subr_hibernate.c,v 1.4 2011/07/08 18:31:16 ariane Exp $ */
+/* $OpenBSD: subr_hibernate.c,v 1.5 2011/07/08 18:34:46 ariane Exp $ */
/*
* Copyright (c) 2011 Ariane van der Steldt <ariane@stack.nl>
@@ -451,3 +451,36 @@ found:
uvm_unlock_fpageq();
return 0;
}
+
+/*
+ * Physmem RLE compression support.
+ *
+ * Given a physical page address, it will return the number of pages
+ * starting at the address, that are free.
+ * Returns 0 if the page at addr is not free.
+ */
+psize_t
+uvm_page_rle(paddr_t addr)
+{
+ struct vm_page *pg, *pg_end;
+ struct vm_physseg *vmp;
+ int pseg_idx, off_idx;
+
+ pseg_idx = vm_physseg_find(atop(addr), &off_idx);
+ if (pseg_idx == -1)
+ return 0;
+
+ vmp = &vm_physmem[pseg_idx];
+ pg = &vmp->pgs[off_idx];
+ if (!(pg->pg_flags & PQ_FREE))
+ return 0;
+
+ /*
+ * Search for the first non-free page after pg.
+ * Note that the page may not be the first page in a free pmemrange,
+ * therefore pg->fpgsz cannot be used.
+ */
+ for (pg_end = pg; pg_end <= vmp->lastpg &&
+ (pg_end->pg_flags & PQ_FREE) == PQ_FREE; pg_end++);
+ return pg_end - pg;
+}