From 6f9838a6a5b80e0253bdc8fb194ad6f15eb655f5 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Sun, 16 Jan 2022 19:25:11 +0000 Subject: [PATCH] kernel: make Page.txtflush into an array 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. --- sys/src/9/bcm/mmu.c | 5 ++--- sys/src/9/bcm64/mmu.c | 5 ++--- sys/src/9/cycv/mmu.c | 6 +++--- sys/src/9/kw/mmu.c | 4 ++-- sys/src/9/mtx/mmu.c | 4 ++-- sys/src/9/omap/mmu.c | 4 ++-- sys/src/9/pc/dat.h | 3 +++ sys/src/9/pc/mem.h | 5 ----- sys/src/9/pc64/dat.h | 3 +++ sys/src/9/port/devsegment.c | 2 +- sys/src/9/port/fault.c | 9 +++------ sys/src/9/port/page.c | 3 +-- sys/src/9/port/portdat.h | 11 ++++++++++- sys/src/9/port/segment.c | 3 +-- sys/src/9/port/userinit.c | 2 +- sys/src/9/ppc/mmu.c | 4 ++-- sys/src/9/sgi/mmu.c | 4 ++-- sys/src/9/teg2/mmu.c | 5 +++-- sys/src/9/zynq/mmu.c | 6 +++--- 19 files changed, 46 insertions(+), 42 deletions(-) diff --git a/sys/src/9/bcm/mmu.c b/sys/src/9/bcm/mmu.c index 655d847ae..7a1e7bc02 100644 --- a/sys/src/9/bcm/mmu.c +++ b/sys/src/9/bcm/mmu.c @@ -254,11 +254,10 @@ putmmu(uintptr va, uintptr pa, Page* page) /* clear out the current entry */ mmuinvalidateaddr(PPN(va)); - if((page->txtflush & (1<machno)) != 0){ - /* pio() sets PG_TXTFLUSH whenever a text pg has been written */ + if(needtxtflush(page)){ cachedwbse((void*)(page->pa|KZERO), BY2PG); cacheiinvse((void*)page->va, BY2PG); - page->txtflush &= ~(1<machno); + donetxtflush(page); } //checkmmu(va, PPN(pa)); splx(s); diff --git a/sys/src/9/bcm64/mmu.c b/sys/src/9/bcm64/mmu.c index e619f7f36..636d265a5 100644 --- a/sys/src/9/bcm64/mmu.c +++ b/sys/src/9/bcm64/mmu.c @@ -460,11 +460,10 @@ putmmu(uintptr va, uintptr pa, Page *pg) flushasidva((uvlong)up->asid<<48 | va>>12); *pte = pa | PTEPAGE | PTEUSER | PTEPXN | PTENG | PTEAF | (((pa & PTEMA(7)) == PTECACHED)? PTESH(SHARE_INNER): PTESH(SHARE_OUTER)); - if(pg->txtflush & (1UL<machno)){ - /* pio() sets PG_TXTFLUSH whenever a text pg has been written */ + if(needtxtflush(pg)){ cachedwbinvse(kmap(pg), BY2PG); cacheiinvse((void*)va, BY2PG); - pg->txtflush &= ~(1UL<machno); + donetxtflush(pg); } splx(s); } diff --git a/sys/src/9/cycv/mmu.c b/sys/src/9/cycv/mmu.c index 213a88178..e85821f54 100644 --- a/sys/src/9/cycv/mmu.c +++ b/sys/src/9/cycv/mmu.c @@ -168,14 +168,14 @@ putmmu(uintptr va, uintptr pa, Page *pg) old = *e; *e = pa | L2VALID | L2USER | L2LOCAL; tmpunmap(l2); - splx(s); if((old & L2VALID) != 0) flushpg((void *) va); - if(pg->txtflush & (1<machno)){ + if(needtxtflush(pg)){ cleandse((void *) va, (void *) (va + BY2PG)); invalise((void *) va, (void *) (va + BY2PG)); - pg->txtflush &= ~(1<machno); + donetxtflush(pg); } + splx(s); } void diff --git a/sys/src/9/kw/mmu.c b/sys/src/9/kw/mmu.c index 0696bff35..bd4636fe7 100644 --- a/sys/src/9/kw/mmu.c +++ b/sys/src/9/kw/mmu.c @@ -345,9 +345,9 @@ putmmu(uintptr va, uintptr pa, Page* page) * rather than direct mapped. */ cachedwbinv(); - if(page->txtflush){ + if(needtxtflush(page)){ cacheiinv(); - page->txtflush = 0; + donetxtflush(page); } //print("putmmu %#p %#p %#p\n", va, pa, PPN(pa)|x); } diff --git a/sys/src/9/mtx/mmu.c b/sys/src/9/mtx/mmu.c index 7afd68a3f..62cb0d9aa 100644 --- a/sys/src/9/mtx/mmu.c +++ b/sys/src/9/mtx/mmu.c @@ -218,10 +218,10 @@ putmmu(uintptr va, uintptr pa, Page *pg) q[1] = pa; sync(); - if(pg->txtflush & (1<machno)){ + if(needtxtflush(pg)){ dcflush((void*)pg->va, BY2PG); icflush((void*)pg->va, BY2PG); - pg->txtflush &= ~(1<machno); + donetxtflush(pg); } } diff --git a/sys/src/9/omap/mmu.c b/sys/src/9/omap/mmu.c index 12383c962..188771bd8 100644 --- a/sys/src/9/omap/mmu.c +++ b/sys/src/9/omap/mmu.c @@ -322,9 +322,9 @@ putmmu(uintptr va, uintptr pa, Page* page) * rather than direct mapped. */ cachedwbinv(); - if(page->txtflush){ + if(needtxtflush(page)){ cacheiinv(); - page->txtflush = 0; + donetxtflush(page); } //print("putmmu %#p %#p %#p\n", va, pa, PPN(pa)|x); } diff --git a/sys/src/9/pc/dat.h b/sys/src/9/pc/dat.h index 63789fcee..fa83b2662 100644 --- a/sys/src/9/pc/dat.h +++ b/sys/src/9/pc/dat.h @@ -159,6 +159,9 @@ struct PMMU void *vmx; }; +#define inittxtflush(p) +#define settxtflush(p,c) + #include "../port/portdat.h" typedef struct { diff --git a/sys/src/9/pc/mem.h b/sys/src/9/pc/mem.h index ef646db7d..83dafb8cb 100644 --- a/sys/src/9/pc/mem.h +++ b/sys/src/9/pc/mem.h @@ -21,11 +21,6 @@ #define BLOCKALIGN 8 #define FPalign 16 -/* - * In 32-bit mode, the MAXMACH limit is 32 without - * changing the way active.machs is defined and used - * (unfortunately, it is also used in the port code). - */ #define MAXMACH 32 /* max # cpus system can run */ #define KSTACK 4096 /* Size of kernel stack */ diff --git a/sys/src/9/pc64/dat.h b/sys/src/9/pc64/dat.h index cfa07a0c5..7fc4c96fa 100644 --- a/sys/src/9/pc64/dat.h +++ b/sys/src/9/pc64/dat.h @@ -169,6 +169,9 @@ struct PMMU void *vmx; }; +#define inittxtflush(p) +#define settxtflush(p,c) + #include "../port/portdat.h" typedef struct { diff --git a/sys/src/9/port/devsegment.c b/sys/src/9/port/devsegment.c index dfbd34fbf..d24e0b72e 100644 --- a/sys/src/9/port/devsegment.c +++ b/sys/src/9/port/devsegment.c @@ -523,7 +523,7 @@ fixedseg(uintptr va, ulong len) p->ref = 1; p->va = va; p->modref = 0; - p->txtflush = ~0; + settxtflush(p, 1); k = kmap(p); memset((void*)VA(k), 0, BY2PG); diff --git a/sys/src/9/port/fault.c b/sys/src/9/port/fault.c index 6e317a6e0..719b64f46 100644 --- a/sys/src/9/port/fault.c +++ b/sys/src/9/port/fault.c @@ -135,8 +135,7 @@ retry: } done: putpage(new); - if(s->flushme) - (*p)->txtflush = ~0; + settxtflush(*p, s->flushme); } static int @@ -202,8 +201,7 @@ fixfault(Segment *s, uintptr addr, int read) new = newpage(0, &s, addr); if(s == nil) return -1; - if(s->flushme) - new->txtflush = ~0; + settxtflush(new, s->flushme); *pg = new; copypage(old, *pg); putpage(old); @@ -242,8 +240,7 @@ mapphys(Segment *s, uintptr addr, int attr) pg.ref = 1; pg.va = addr; pg.pa = s->pseg->pa+(addr-s->base); - if(s->flushme) - pg.txtflush = ~0; + settxtflush(&pg, s->flushme); mmuphys = PPN(pg.pa) | PTEVALID; if((attr & SG_RONLY) == 0) diff --git a/sys/src/9/port/page.c b/sys/src/9/port/page.c index f907aca5b..869a8733e 100644 --- a/sys/src/9/port/page.c +++ b/sys/src/9/port/page.c @@ -227,7 +227,7 @@ newpage(int clear, Segment **s, uintptr va) p->ref = 1; p->va = va; p->modref = 0; - p->txtflush = 0; + inittxtflush(p); if(clear) { k = kmap(p); @@ -345,7 +345,6 @@ cachedel(Image *i, uintptr daddr) } } - Pte* ptecpy(Pte *old) { diff --git a/sys/src/9/port/portdat.h b/sys/src/9/port/portdat.h index dc3c5bd66..5bb641f7f 100644 --- a/sys/src/9/port/portdat.h +++ b/sys/src/9/port/portdat.h @@ -329,10 +329,19 @@ struct Page uintptr va; /* Virtual address for user */ uintptr daddr; /* Disc address on swap */ Image *image; /* Associated text or swap image */ - ulong txtflush; /* Flush icache for putmmu */ ushort refage; /* Swap reference age */ char modref; /* Simulated modify/reference bits */ char color; /* Cache coloring */ + +#ifndef inittxtflush + /* Flush icache bitmap for putmmu() */ + ulong txtflush[(MAXMACH+31)/32]; + +#define inittxtflush(p) memset((p)->txtflush, 0, sizeof((p)->txtflush)) +#define settxtflush(p, c) if(c) memset((p)->txtflush, ~0, sizeof((p)->txtflush)) +#define needtxtflush(p) ((p)->txtflush[m->machno>>5] & (1 << (m->machno&0x1F))) +#define donetxtflush(p) ((p)->txtflush[m->machno>>5] &= ~(1 << (m->machno&0x1F))) +#endif }; struct Swapalloc diff --git a/sys/src/9/port/segment.c b/sys/src/9/port/segment.c index bc3e61cb7..b16be0f43 100644 --- a/sys/src/9/port/segment.c +++ b/sys/src/9/port/segment.c @@ -718,8 +718,7 @@ segflush(void *va, uintptr len) pg = &pte->pages[off/BY2PG]; pe = pg + len/BY2PG; while(pg < pe) { - if(!pagedout(*pg)) - (*pg)->txtflush = ~0; + settxtflush(*pg, !pagedout(*pg)); pg++; } } diff --git a/sys/src/9/port/userinit.c b/sys/src/9/port/userinit.c index 89a19c1c9..01354b94a 100644 --- a/sys/src/9/port/userinit.c +++ b/sys/src/9/port/userinit.c @@ -52,7 +52,7 @@ proc0(void*) k = kmap(p); memmove((void*)VA(k), initcode, sizeof(initcode)); kunmap(k); - p->txtflush = ~0; + settxtflush(p, 1); segpage(up->seg[TSEG], p); up->seg[TSEG]->flushme = 1; diff --git a/sys/src/9/ppc/mmu.c b/sys/src/9/ppc/mmu.c index 59e59c229..cc7f28380 100644 --- a/sys/src/9/ppc/mmu.c +++ b/sys/src/9/ppc/mmu.c @@ -245,10 +245,10 @@ putmmu(uintptr va, uintptr pa, Page *pg) q[0] = ptehi; q[1] = pa; - if(pg->txtflush & (1<machno)){ + if(needtxtflush(pg)){ dcflush((void*)pg->va, BY2PG); icflush((void*)pg->va, BY2PG); - pg->txtflush &= ~(1<machno); + donetxtflush(pg); } } diff --git a/sys/src/9/sgi/mmu.c b/sys/src/9/sgi/mmu.c index 84330f9c3..32d6a0758 100644 --- a/sys/src/9/sgi/mmu.c +++ b/sys/src/9/sgi/mmu.c @@ -389,9 +389,9 @@ putmmu(ulong tlbvirt, ulong tlbphys, Page *pg) x = gettlbp(tlbvirt, tlbent); if(x < 0) x = getrandom(); puttlbx(x, entry->virt, entry->phys0, entry->phys1, PGSZ); - if(pg->txtflush & (1<machno)){ + if(needtxtflush(pg)){ icflush((void*)pg->va, BY2PG); - pg->txtflush &= ~(1<machno); + donetxtflush(pg); } splx(s); } diff --git a/sys/src/9/teg2/mmu.c b/sys/src/9/teg2/mmu.c index 6005e5065..bdafac19d 100644 --- a/sys/src/9/teg2/mmu.c +++ b/sys/src/9/teg2/mmu.c @@ -574,10 +574,11 @@ putmmu(uintptr va, uintptr pa, Page* page) */ l1cache->wb(); - if(page->txtflush & (1<machno)){ + if(needtxtflush(page)){ cacheiinv(); - page->txtflush &= ~(1<machno); + donetxtflush(page); } + if (Debug) iprint("putmmu %#p %#p %#p\n", va, pa, PPN(pa)|x); } diff --git a/sys/src/9/zynq/mmu.c b/sys/src/9/zynq/mmu.c index 9b4c67d4c..ab3c7c871 100644 --- a/sys/src/9/zynq/mmu.c +++ b/sys/src/9/zynq/mmu.c @@ -176,14 +176,14 @@ putmmu(uintptr va, uintptr pa, Page *pg) old = *e; *e = pa | L2VALID | L2USER | L2LOCAL; tmpunmap(l2); - splx(s); if((old & L2VALID) != 0) flushpg((void *) va); - if(pg->txtflush & (1<machno)){ + if(needtxtflush(pg)){ cleandse((void *) va, (void *) (va + BY2PG)); invalise((void *) va, (void *) (va + BY2PG)); - pg->txtflush &= ~(1<machno); + donetxtflush(pg); } + splx(s); } void