From 29f60cace1a71edd730c60ddac8dfbd962741038 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Tue, 22 Dec 2020 16:29:55 +0100 Subject: kernel: avoid palloc lock during mmurelease() 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. --- sys/src/9/cycv/mmu.c | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) (limited to 'sys/src/9/cycv') diff --git a/sys/src/9/cycv/mmu.c b/sys/src/9/cycv/mmu.c index 8a449e70b..213a88178 100644 --- a/sys/src/9/cycv/mmu.c +++ b/sys/src/9/cycv/mmu.c @@ -197,23 +197,21 @@ flushmmu(void) void mmurelease(Proc *proc) { - Page *p, *n; + Page *p; - if(islo()) - panic("mmurelease: islo"); - l1switch(&m->l1, 0); - if(proc->kmaptable != nil){ + if((p = proc->kmaptable) != nil){ + if(p->ref != 1) + panic("mmurelease: kmap ref %ld", p->ref); if(proc->l1 == nil) panic("mmurelease: no l1"); - if(decref(proc->kmaptable) != 0) - panic("mmurelease: kmap ref %ld", proc->kmaptable->ref); if(proc->nkmap) panic("mmurelease: nkmap %d", proc->nkmap); - if(PPN(proc->l1->va[L1X(KMAP)]) != proc->kmaptable->pa) - panic("mmurelease: bad kmap l2 %#.8lux kmap %#.8lux", proc->l1->va[L1X(KMAP)], proc->kmaptable->pa); + if(PPN(proc->l1->va[L1X(KMAP)]) != p->pa) + panic("mmurelease: bad kmap l2 %#.8lux kmap %#.8lux", proc->l1->va[L1X(KMAP)], p->pa); proc->l1->va[L1X(KMAP)] = 0; - pagechainhead(proc->kmaptable); + p->next = proc->mmufree; + proc->mmufree = p; proc->kmaptable = nil; } if(proc->l1 != nil){ @@ -221,14 +219,7 @@ mmurelease(Proc *proc) l1free(proc->l1); proc->l1 = nil; } - for(p = proc->mmufree; p != nil; p = n){ - n = p->next; - if(decref(p) != 0) - panic("mmurelease: p->ref %ld", p->ref); - pagechainhead(p); - } - if(proc->mmufree != nil) - pagechaindone(); + freepages(proc->mmufree, nil, 0); proc->mmufree = nil; } -- cgit v1.2.3