NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: port-arm/53173: (earmv7hf) "go test net/http" locks up the machine
The following reply was made to PR port-arm/53173; it has been noted by GNATS.
From: Manuel Bouyer <bouyer%antioche.eu.org@localhost>
To: bsiegert%NetBSD.org@localhost
Cc: gnats-bugs%NetBSD.org@localhost
Subject: Re: port-arm/53173: (earmv7hf) "go test net/http" locks up the
machine
Date: Fri, 19 Apr 2019 18:12:23 +0200
--cWoXeonUoKmBZSoM
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
hello,
can you see if the attached patch fixes the issue for you ?
I had similar lock up on network load, and it should fix it.
--
Manuel Bouyer <bouyer%antioche.eu.org@localhost>
NetBSD: 26 ans d'experience feront toujours la difference
--
--cWoXeonUoKmBZSoM
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=diff
Index: arm32/pmap.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/arm32/pmap.c,v
retrieving revision 1.371
diff -u -p -u -r1.371 pmap.c
--- arm32/pmap.c 28 Oct 2018 14:59:17 -0000 1.371
+++ arm32/pmap.c 19 Apr 2019 15:55:30 -0000
@@ -217,6 +217,10 @@
#include <arm/locore.h>
+#ifdef DDB
+#include <arm/db_machdep.h>
+#endif
+
__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.371 2018/10/28 14:59:17 skrll Exp $");
//#define PMAP_DEBUG
@@ -516,7 +520,8 @@ static size_t cnptes;
#endif
vaddr_t memhook; /* used by mem.c & others */
kmutex_t memlock __cacheline_aligned; /* used by mem.c & others */
-kmutex_t pmap_lock __cacheline_aligned;
+kmutex_t pmap_pg_lock __cacheline_aligned;
+kmutex_t kpm_lock __cacheline_aligned;
extern void *msgbufaddr;
int pmap_kmpages;
/*
@@ -538,9 +543,14 @@ vaddr_t pmap_directlimit;
static inline void
pmap_acquire_pmap_lock(pmap_t pm)
{
+#if defined(MULTIPROCESSOR) && defined(DDB)
+ if (__predict_false(db_onproc != NULL))
+ return;
+#endif
+
if (pm == pmap_kernel()) {
#ifdef MULTIPROCESSOR
- KERNEL_LOCK(1, NULL);
+ mutex_enter(&kpm_lock);
#endif
} else {
mutex_enter(pm->pm_lock);
@@ -550,9 +560,13 @@ pmap_acquire_pmap_lock(pmap_t pm)
static inline void
pmap_release_pmap_lock(pmap_t pm)
{
+#if defined(MULTIPROCESSOR) && defined(DDB)
+ if (__predict_false(db_onproc != NULL))
+ return;
+#endif
if (pm == pmap_kernel()) {
#ifdef MULTIPROCESSOR
- KERNEL_UNLOCK_ONE(NULL);
+ mutex_exit(&kpm_lock);
#endif
} else {
mutex_exit(pm->pm_lock);
@@ -562,20 +576,20 @@ pmap_release_pmap_lock(pmap_t pm)
static inline void
pmap_acquire_page_lock(struct vm_page_md *md)
{
- mutex_enter(&pmap_lock);
+ mutex_enter(&pmap_pg_lock);
}
static inline void
pmap_release_page_lock(struct vm_page_md *md)
{
- mutex_exit(&pmap_lock);
+ mutex_exit(&pmap_pg_lock);
}
#ifdef DIAGNOSTIC
static inline int
pmap_page_locked_p(struct vm_page_md *md)
{
- return mutex_owned(&pmap_lock);
+ return mutex_owned(&pmap_pg_lock);
}
#endif
@@ -3057,6 +3071,10 @@ pmap_enter(pmap_t pm, vaddr_t va, paddr_
#else
const bool vector_page_p = (va == vector_page);
#endif
+ struct pmap_page *pp = pmap_pv_tracked(pa);
+ struct pv_entry *new_pv = NULL;
+ struct pv_entry *old_pv = NULL;
+ int error = 0;
UVMHIST_FUNC(__func__); UVMHIST_CALLED(maphist);
@@ -3072,6 +3090,12 @@ pmap_enter(pmap_t pm, vaddr_t va, paddr_
* test for a managed page by checking pg != NULL.
*/
pg = pmap_initialized ? PHYS_TO_VM_PAGE(pa) : NULL;
+ /*
+ * if we may need a new pv entry allocate if now, as we can't do it
+ * with the kernel_pmap locked
+ */
+ if (pg || pp)
+ new_pv = pool_get(&pmap_pv_pool, PR_NOWAIT);
nflags = 0;
if (prot & VM_PROT_WRITE)
@@ -3095,7 +3119,8 @@ pmap_enter(pmap_t pm, vaddr_t va, paddr_
if (l2b == NULL) {
if (flags & PMAP_CANFAIL) {
pmap_release_pmap_lock(pm);
- return (ENOMEM);
+ error = ENOMEM;
+ goto free_pv;
}
panic("pmap_enter: failed to allocate L2 bucket");
}
@@ -3118,8 +3143,6 @@ pmap_enter(pmap_t pm, vaddr_t va, paddr_
} else
opg = NULL;
- struct pmap_page *pp = pmap_pv_tracked(pa);
-
if (pg || pp) {
KASSERT((pg != NULL) != (pp != NULL));
struct vm_page_md *md = (pg != NULL) ? VM_PAGE_TO_MD(pg) :
@@ -3228,9 +3251,10 @@ pmap_enter(pmap_t pm, vaddr_t va, paddr_
}
#endif
} else {
- pmap_release_page_lock(md);
- pv = pool_get(&pmap_pv_pool, PR_NOWAIT);
+ pv = new_pv;
+ new_pv = NULL;
if (pv == NULL) {
+ pmap_release_page_lock(md);
pmap_release_pmap_lock(pm);
if ((flags & PMAP_CANFAIL) == 0)
panic("pmap_enter: "
@@ -3241,7 +3265,6 @@ pmap_enter(pmap_t pm, vaddr_t va, paddr_
0, 0, 0, 0);
return (ENOMEM);
}
- pmap_acquire_page_lock(md);
}
pmap_enter_pv(md, pa, pv, pm, va, nflags);
@@ -3278,9 +3301,9 @@ pmap_enter(pmap_t pm, vaddr_t va, paddr_
paddr_t opa = VM_PAGE_TO_PHYS(opg);
pmap_acquire_page_lock(omd);
- struct pv_entry *pv = pmap_remove_pv(omd, opa, pm, va);
+ old_pv = pmap_remove_pv(omd, opa, pm, va);
pmap_vac_me_harder(omd, opa, pm, 0);
- oflags = pv->pv_flags;
+ oflags = old_pv->pv_flags;
pmap_release_page_lock(omd);
#ifdef PMAP_CACHE_VIVT
@@ -3288,7 +3311,6 @@ pmap_enter(pmap_t pm, vaddr_t va, paddr_
pmap_cache_wbinv_page(pm, va, true, oflags);
}
#endif
- pool_put(&pmap_pv_pool, pv);
}
}
@@ -3390,7 +3412,13 @@ pmap_enter(pmap_t pm, vaddr_t va, paddr_
pmap_release_pmap_lock(pm);
- return (0);
+
+ if (old_pv)
+ pool_put(&pmap_pv_pool, old_pv);
+free_pv:
+ if (new_pv)
+ pool_put(&pmap_pv_pool, new_pv);
+ return (error);
}
/*
@@ -3425,6 +3453,7 @@ pmap_remove(pmap_t pm, vaddr_t sva, vadd
/*
* we lock in the pmap => pv_head direction
*/
+
pmap_acquire_pmap_lock(pm);
#ifndef ARM_MMU_EXTENDED
@@ -3463,6 +3492,7 @@ pmap_remove(pmap_t pm, vaddr_t sva, vadd
for (;sva < next_bucket;
sva += PAGE_SIZE, ptep += PAGE_SIZE / L2_S_SIZE) {
pt_entry_t opte = *ptep;
+ struct pv_entry *opv = NULL;
if (opte == 0) {
/* Nothing here, move along */
@@ -3480,17 +3510,15 @@ pmap_remove(pmap_t pm, vaddr_t sva, vadd
*/
if (pg != NULL) {
struct vm_page_md *md = VM_PAGE_TO_MD(pg);
- struct pv_entry *pv;
pmap_acquire_page_lock(md);
- pv = pmap_remove_pv(md, pa, pm, sva);
+ opv = pmap_remove_pv(md, pa, pm, sva);
pmap_vac_me_harder(md, pa, pm, 0);
pmap_release_page_lock(md);
- if (pv != NULL) {
+ if (opv != NULL) {
if (pm->pm_remove_all == false) {
- flags = pv->pv_flags;
+ flags = opv->pv_flags;
}
- pool_put(&pmap_pv_pool, pv);
}
}
mappings += PAGE_SIZE / L2_S_SIZE;
@@ -3503,7 +3531,7 @@ pmap_remove(pmap_t pm, vaddr_t sva, vadd
*/
l2pte_reset(ptep);
PTE_SYNC_CURRENT(pm, ptep);
- continue;
+ goto free_opv;
}
#ifdef ARM_MMU_EXTENDED
@@ -3545,6 +3573,12 @@ pmap_remove(pmap_t pm, vaddr_t sva, vadd
}
}
#endif
+free_opv:
+ if (opv) {
+ pmap_release_pmap_lock(pm);
+ pool_put(&pmap_pv_pool, opv);
+ pmap_acquire_pmap_lock(pm);
+ }
}
#ifndef ARM_MMU_EXTENDED
@@ -3807,7 +3841,6 @@ pmap_kremove(vaddr_t va, vsize_t len)
#ifdef UVMHIST
u_int total_mappings = 0;
#endif
-
PMAPCOUNT(kenter_unmappings);
UVMHIST_FUNC(__func__); UVMHIST_CALLED(maphist);
@@ -3815,15 +3848,15 @@ pmap_kremove(vaddr_t va, vsize_t len)
UVMHIST_LOG(maphist, " (va=%#jx, len=%#jx)", va, len, 0, 0);
const vaddr_t eva = va + len;
+ pmap_t kpm = pmap_kernel();
- pmap_acquire_pmap_lock(pmap_kernel());
+ pmap_acquire_pmap_lock(kpm);
while (va < eva) {
vaddr_t next_bucket = L2_NEXT_BUCKET_VA(va);
if (next_bucket > eva)
next_bucket = eva;
- pmap_t kpm = pmap_kernel();
struct l2_bucket * const l2b = pmap_get_l2_bucket(kpm, va);
KDASSERT(l2b != NULL);
@@ -3879,7 +3912,7 @@ pmap_kremove(vaddr_t va, vsize_t len)
total_mappings += mappings;
#endif
}
- pmap_release_pmap_lock(pmap_kernel());
+ pmap_release_pmap_lock(kpm);
cpu_cpwait();
UVMHIST_LOG(maphist, " <--- done (%ju mappings removed)",
total_mappings, 0, 0, 0);
@@ -5904,7 +5937,7 @@ pmap_growkernel(vaddr_t maxkvaddr)
* whoops! we need to add kernel PTPs
*/
- s = splhigh(); /* to be safe */
+ s = splvm(); /* to be safe */
mutex_enter(kpm->pm_lock);
/* Map 1MB at a time */
@@ -6147,15 +6180,8 @@ pmap_bootstrap(vaddr_t vstart, vaddr_t v
#endif
VPRINTF("locks ");
-#if defined(PMAP_CACHE_VIPT) && !defined(ARM_MMU_EXTENDED)
- if (arm_cache_prefer_mask != 0) {
- mutex_init(&pmap_lock, MUTEX_DEFAULT, IPL_VM);
- } else {
-#endif
- mutex_init(&pmap_lock, MUTEX_DEFAULT, IPL_NONE);
-#if defined(PMAP_CACHE_VIPT) && !defined(ARM_MMU_EXTENDED)
- }
-#endif
+ mutex_init(&pmap_pg_lock, MUTEX_DEFAULT, IPL_VM);
+ mutex_init(&kpm_lock, MUTEX_DEFAULT, IPL_VM);
mutex_init(&pm->pm_obj_lock, MUTEX_DEFAULT, IPL_NONE);
uvm_obj_init(&pm->pm_obj, NULL, false, 1);
uvm_obj_setlock(&pm->pm_obj, &pm->pm_obj_lock);
--cWoXeonUoKmBZSoM--
Home |
Main Index |
Thread Index |
Old Index