summaryrefslogtreecommitdiff
path: root/sys/src/9/port/page.c
AgeCommit message (Collapse)Author
2023-04-08kernel: Clear secrets on rebootcinap_lenrek
The idea is that when we reboot, we zero out memory written by processes that have the private flag set (such as factotum and keyfs), and also clear the secrmem pool, which contains TLS keys and the state of the random number generator. This is so the newly booted kernel or firmware will not find these secret keys in memory.
2022-01-16kernel: make Page.txtflush into an arraycinap_lenrek
To avoid a MAXMACH limit of 32 and make txtflush into an array for the bitmap. Provide portable macros for testing and clearing the bits: needtxtflush(), donetxtflush(). On pc/pc64, define inittxtflush()/settxtflush() as no-op macros, avoiding the storage overhead of the txtflush array alltogether.
2021-04-02kernel: get rid of physical page bank array and use conf.mem[] insteadcinap_lenrek
We can take advantage of the fact that xinit() allocates kernel memory from conf.mem[] banks always at the beginning of a bank, so the separate palloc.mem[] array can be eleminated as we can calculate the amount of non-kernel memory like: upages = cm->npage - (PGROUND(cm->klimit - cm->kbase)/BY2PG) for the number of reserved kernel pages, we provide the new function: ulong nkpages(Confmem*) This eleminates the error case of running out of slots in the array and avoids wasting memory in ports that have simple memory configurations (compared to pc/pc64).
2020-12-22kernel: avoid palloc lock during mmurelease()cinap_lenrek
Previously, mmurelease() was always called with palloc spinlock held. This is unneccesary for some mmurelease() implementations as they wont release pages to the palloc pool. This change removes pagechainhead() and pagechaindone() and replaces them with just freepages() call, which aquires the palloc lock internally as needed. freepages() avoids holding the palloc lock while walking the linked list of pages, avoding some lock contention.
2020-05-31kernel: remove unused segment argument in freepte()cinap_lenrek
2020-05-10kernel: fix checkpages() and segflush() on SG_PHYSICAL type segmentscinap_lenrek
do not touch s->map on SG_PHYSICAL type segments as they do not have a pte map (s->mapsize == 0 && s->map == nil). also remove the SG_PHYSICAL switch in freepte(), this is never reached.
2020-04-26kernel: improve page reclaimation strategy and lockingcinap_lenrek
when reclaiming pages from an image, always reclaim all the hash chains equally. that way, we avoid being biased towards the chains at the start of the Image.pghash[] array. images can be in two states: active or inactive. inactive images are the ones which are not used by program while active ones aare. when reclaiming pages, we should try to reclaim pages from inactive images first and only if that set becomes exhausted attempt to release text pages and attempt to reclaim pages from active images. when we run out of Image structures, it makes only sense to reclaim pages from inactive images, as reclaiming pages from active ones will never free any Image structures. change putimage() to require a image already locked and make it unlock the image. this avoids many pointless unlock()/lock() sequences as all callers of putimage() already had the image locked.
2019-05-01kernel: get rid of checkpagerefs() debuggingcinap_lenrek
was only implemented by the pc kernel. does not account pages used by the mount cache.
2019-05-01kernel: export freepages() function so it can be used in mmurelease()cinap_lenrek
2017-04-04kernel: fix memory leak in checkpagerefs() debug function (thanks aiju)cinap_lenrek
2015-07-09kernel: various cleanups of imagereclaim(), pagereclaim(), freepages(), ↵cinap_lenrek
putimage() imagereclaim(), pagereclaim(): - move imagereclaim() and pagereclaim() declarations to portfns.h - consistently use ulong type for page counts - name number of pages to free "pages" instead of "min" - check for pages == 0 on entry freepages(): - move pagechaindone() call to wakeup newpage() consumers inside palloc critical section. putimage(): - use long type for refcount
2015-06-18kernel: ignore memory pages with singular kernel addressescinap_lenrek
addresses va's of 0 and -BY2PG cause trouble with some memmove()/memset() implementations and possibly other code because of the nil pointer and end pointers wrapping to zero.
2015-06-15kernel: add pagechaindone() to wakeup processes waiting for memorycinap_lenrek
we keep the details about palloc in page.c, providing pagechaindone() for mmu code to be called after a series of pagechainhead() calls.
2015-06-15kernel: implement separate wait queues for page allocationcinap_lenrek
give kernel processes and local disk file servers (procs having noswap flag set) a clear advantage for page allocation under starved condition by giving them ther own wait queue so they get readied as soon as pages become available.
2015-03-16kernel: get rid of auxpage() and preserve cache index bits in Page.va in ↵cinap_lenrek
mount cache the mount cache uses Page.va to store cached range offset and limit, but mips kernel uses cache index bits from Page.va to maintain page coloring. Page.va was not initialized by auxpage(). this change removes auxpage() which was primarily used only by the mount cache and use newpage() with cache file offset page as va so we will get a page of the right color. mount cache keeps the index bits intact by only using the top and buttom PGSHIFT bits of Page.va for the range offset/limit.
2015-03-10kernel: fix integer overflow in syssegflush(), segment code cleanupcinap_lenrek
mcountseg(), mfreeseg(): use Pte.first/last pointers when possible and avoid constructs like s->map[i]->pages[j]. freepte(): do not zero entries in freepte(), the segment is going away and here is no point in zeroing page pointers. hoist common code at the top avoiding duplication. segpage(), fixfault(): avoid load after store for Pte** pointer. fixfault(): return -1 in default case to avoid the "used but not set" warning for mmuphys and get rid of the useless initialization. syssegflush(): due to len being unsigned, the pe = PGROUND(pe) can make "chunk" bigger than len causing a overflow. rewrite the function and deal with page alignment and errors at the beginning. syssegflush(), segpage(), fixfault(), putseg(), relocateseg(), mcountseg(), mfreeseg(): keep naming consistent.
2015-03-03kernel: fix physical segment handlingcinap_lenrek
ignore physical segments in mcountseg() and mfreeseg(). physical segments are not backed by user pages, and doing putpage() on physical segment pages in mfreeseg() is an error. do now allow physical segemnts to be resized. the segment size is only checked in segattach() to be within the physical segment! ignore physical segments in portcountpagerefs() as pagenumber() does not work on the malloced page structures of a physical segment. get rid of Physseg.pgalloc() and Physseg.pgfree() indirection as this was never used and if theres a need to do more efficient allocation, it should be done in a portable way.
2015-02-07kernel: make pagereclaim() a bit less stupidcinap_lenrek
put recently used pages at the head of ther image hash chains, and reclaim pages from the tail first.
2015-02-07kernel: reduce Page structure size by changing Page.cachectl[]cinap_lenrek
there are no kernels currently that do page coloring, so the only use of cachectl[] is flushing the icache (on arm and ppc). on pc64, cachectl consumes 32 bytes in each page resulting in over 200 megabytes of overhead for 32gb of ram with 4K pages. this change removes cachectl[] and adds txtflush ulong that is set to ~0 by pio() to instruct putmmu() to flush the icache.
2014-06-22kernel: new pagecache, remove Lock from page, use cmpswap for Ref instead of ↵cinap_lenrek
Lock make the Page stucture less than half its original size by getting rid of the Lock and the lru. The Lock was required to coordinate the unchaining of pages that where both cached and on the lru freelist. now pages have a single next pointer that is used for palloc.head freelist xor for page cache hash chains in Image.pghash[]. cached pages are not on the freelist anymore, but will be reclaimed from images by the pager when the freelist runs out of pages. each Image has its own 512 hash chains for cached page lookup. That is 2MB worth of pages and there should be no collisions for most text images. page reclaiming can be done without holding palloc.lock as the Image is the owner of the page hash chains protected by the Image's lock. reclaiming Image structures can be done quickly by only reclaiming pages from inactive images, that is images which are not currently in use by segments. the Ref structure has no Lock anymore. Only a single long that is atomically incremented or decremnted using cmpswap(). there are various other changes as a consequence code. and lots of pikeshedding, sorry.
2014-06-01pc64: allocate palloc.pages from upagescinap_lenrek
the palloc.pages array takes arround 5% of the upages which gives us: 16GB = ~0.8GB 32GB = ~1.6GB 64GB = ~3.2GB we only have 2GB of address space above KZERO so this will not work for long. instead, pageinit() was altered to accept a preallocated memory in palloc.pages. and preallocpages() in pc64/main.c allocates the in upages memory, mapping it in the VMAP area (which has 512GB). the drawback is that we cannot poke at Page structures now from /proc/n/mem as the VMAP area is not accessible from it.
2014-04-15kernel: fix printing wrong memory sizes in pageinit(), overflowed on amd64 ↵cinap_lenrek
(thanks aram)
2014-03-02kernel: getting rid of duppage() (thanks charles)cinap_lenrek
simplifying paging code by getting rid of duppage(). instead, fixfault() now always makes a copy of the shared/cached page and leaves the cache alone. newpage() uncaches pages as neccesary. thanks charles forsyth for the suggestion. from http://9fans.net/archive/2014/03/26: > It isn't needed at all. When a cached page is written, it's trying hard to > replace the page in the cache by a new copy, > to return the previously cached page. Instead, I copy the cached page and > return the copy, which is what it already > does in another instance. ...
2014-02-24kernel: keep cached pages continuous at the end of the page list on ↵cinap_lenrek
imagereclaim() imagereclaim() sabotaged itself by breaking the invariant that cached pages are kept at the end of the page list. once we made a hole of uncached pages, we would stop reclaiming cached pages before it as the loop breaks once it hits a uncached page. (we iterate backwards from the tail to the head of the pagelist until pages have been reclaimed or we hit a uncached page). the solution is to move pages to the head of the pagelist after removing them from the image cache.
2014-01-20kernel: apply uintptr for ulong when a pointer is storedcinap_lenrek
this change is in preparation for amd64. the systab calling convention was also changed to return uintptr (as segattach returns a pointer) and the arguments are now passed as va_list which handles amd64 arguments properly (all arguments are passed in 64bit quantities on the stack, tho the upper part will not be initialized when the element is smaller than 8 bytes). this is partial. xalloc needs to be converted in the future.
2013-11-08kernel: make image cache not hold onto the channel, remove nocache flagcinap_lenrek
the image cache should not hold onto the text file channel when not neccesary. now, the image keeps track of the number of page cache references in Image.pgref. if the number of page cache references and Image.ref are equal, this means all the references to this image are from the page cache. so no segments are using this image. in that case, we can close the channel, but keep the Image in the hash table. when attachimage() finds our image, it will check if Image.c is nil and reattach the channel to the image before it is used. the Image.nocache flag isnt needed anymore.
2013-10-25kernel: disable freelist page caching for executables run from uncached mountcinap_lenrek
the image cache has the property of keeping a channel for the executable binary arround which prevents the mountpoint from going away. this can easily be reproduced by running: @{rfork n; ramfs; cp /bin/echo /tmp; /tmp/echo} observe how ramfs stays arround until the image is reclaimed. the echo binary is also cached but is unreachable from any namespace. we now restrict the caching to mounts that use the client cache (-C flag) only. this should always be the case for /bin. places where this isnt the case might observe a performance regression.
2012-10-16kernel: duppage cleanupcinap_lenrek
remove the sched() call and retry loop from duppage() and just drop the page lock, then reacquire it after lock(&palloc).
2012-10-16kernel: cachedel() lock order, lookpage, cleanupcinap_lenrek
the lock order of page.Lock -> palloc.hashlock was violated in cachedel() which is called from the pager. change the code to do it in the right oder to prevent deadlock. change lookpage to retry on false hit. i assume that a false hit means: a) we'r low on memory -> cached page got uncached/reused b) duppage() got called on the page, meaning theres another cached copy in the image now. paging in is expensive compared to the hashtable lookup, so i think retrying is better. cleanup fixfault, adding comments.
2012-02-16kernel: remove duppage debug, add comments, cleanupcinap_lenrek
2012-02-16kernel: duppage checkingcinap_lenrek
2011-08-24fix kernel: pio()/mfreeseg() racecinap_lenrek
2011-03-30Import sources from 2011-03-30 iso image - libTaru Karttunen
2011-03-30Import sources from 2011-03-30 iso imageTaru Karttunen