Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/i386/i386 postpone freeing PTPs until TLBs are flushed
details: https://anonhg.NetBSD.org/src/rev/b3319b293bc0
branches: trunk
changeset: 556743:b3319b293bc0
user: yamt <yamt%NetBSD.org@localhost>
date: Fri Dec 26 11:50:51 2003 +0000
description:
postpone freeing PTPs until TLBs are flushed
to avoid loading invalid TLB entries. from Stephan Uphoff.
for more details,
see "i386 pmap bug" thread on port-i386@ around Feb, 2003.
diffstat:
sys/arch/i386/i386/pmap.c | 34 +++++++++++++++++++++++++++++-----
1 files changed, 29 insertions(+), 5 deletions(-)
diffs (113 lines):
diff -r 9922c2239995 -r b3319b293bc0 sys/arch/i386/i386/pmap.c
--- a/sys/arch/i386/i386/pmap.c Fri Dec 26 11:43:24 2003 +0000
+++ b/sys/arch/i386/i386/pmap.c Fri Dec 26 11:50:51 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.c,v 1.166 2003/12/10 18:13:32 drochner Exp $ */
+/* $NetBSD: pmap.c,v 1.167 2003/12/26 11:50:51 yamt Exp $ */
/*
*
@@ -60,7 +60,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.166 2003/12/10 18:13:32 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.167 2003/12/26 11:50:51 yamt Exp $");
#include "opt_cputype.h"
#include "opt_user_ldt.h"
@@ -2344,11 +2344,14 @@
vaddr_t blkendva;
struct vm_page *ptp;
int32_t cpumask = 0;
+ TAILQ_HEAD(, vm_page) empty_ptps;
/*
* we lock in the pmap => pv_head direction
*/
+ TAILQ_INIT(&empty_ptps);
+
PMAP_MAP_TO_HEAD_LOCK();
ptes = pmap_map_ptes(pmap); /* locks pmap */
@@ -2421,12 +2424,17 @@
TAILQ_FIRST(&pmap->pm_obj.memq);
ptp->wire_count = 0;
ptp->flags |= PG_ZERO;
- uvm_pagefree(ptp);
+ /* Postpone free to shootdown */
+ uvm_pagerealloc(ptp, NULL, 0);
+ TAILQ_INSERT_TAIL(&empty_ptps, ptp, listq);
}
}
pmap_tlb_shootnow(cpumask);
pmap_unmap_ptes(pmap); /* unlock pmap */
PMAP_MAP_TO_HEAD_UNLOCK();
+ /* Now we can free unused ptps */
+ TAILQ_FOREACH(ptp, &empty_ptps, listq)
+ uvm_pagefree(ptp);
return;
}
@@ -2512,13 +2520,18 @@
pmap->pm_ptphint = pmap->pm_obj.memq.tqh_first;
ptp->wire_count = 0;
ptp->flags |= PG_ZERO;
- uvm_pagefree(ptp);
+ /* Postpone free to shootdown */
+ uvm_pagerealloc(ptp, NULL, 0);
+ TAILQ_INSERT_TAIL(&empty_ptps, ptp, listq);
}
}
pmap_tlb_shootnow(cpumask);
pmap_unmap_ptes(pmap);
PMAP_MAP_TO_HEAD_UNLOCK();
+ /* Now we can free unused ptps */
+ TAILQ_FOREACH(ptp, &empty_ptps, listq)
+ uvm_pagefree(ptp);
}
/*
@@ -2536,6 +2549,8 @@
struct pv_entry *pve, *npve, *killlist = NULL;
pt_entry_t *ptes, opte;
int32_t cpumask = 0;
+ TAILQ_HEAD(, vm_page) empty_ptps;
+ struct vm_page *ptp;
#ifdef DIAGNOSTIC
int bank, off;
@@ -2550,6 +2565,8 @@
return;
}
+ TAILQ_INIT(&empty_ptps);
+
/* set pv_head => pmap locking */
PMAP_HEAD_TO_MAP_LOCK();
@@ -2614,7 +2631,10 @@
pve->pv_pmap->pm_obj.memq.tqh_first;
pve->pv_ptp->wire_count = 0;
pve->pv_ptp->flags |= PG_ZERO;
- uvm_pagefree(pve->pv_ptp);
+ /* Free only after the shootdown */
+ uvm_pagerealloc(pve->pv_ptp, NULL, 0);
+ TAILQ_INSERT_TAIL(&empty_ptps, pve->pv_ptp,
+ listq);
}
}
pmap_unmap_ptes(pve->pv_pmap); /* unlocks pmap */
@@ -2626,6 +2646,10 @@
simple_unlock(&pvh->pvh_lock);
PMAP_HEAD_TO_MAP_UNLOCK();
pmap_tlb_shootnow(cpumask);
+
+ /* Now we can free unused ptps */
+ TAILQ_FOREACH(ptp, &empty_ptps, listq)
+ uvm_pagefree(ptp);
}
/*
Home |
Main Index |
Thread Index |
Old Index