NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

port-sh3/56381: Infinite loop in pmap_page_protect()



>Number:         56381
>Category:       port-sh3
>Synopsis:       Infinite loop in pmap_page_protect()
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    port-sh3-maintainer
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Aug 30 01:50:00 +0000 2021
>Originator:     Rin Okuyama
>Release:        9.99.88
>Organization:
Department of Physics, Meiji University
>Environment:
NetBSD hdlu 9.99.88 NetBSD 9.99.88 (GENERIC) #2: Thu Aug 26 20:34:10 JST 2021  rin@latipes:/sys/arch/landisk/compile/GENERIC landisk
>Description:
Sometimes kernel is trapped into infinite loop in pmap_page_protect(),
where the user cannot do anything but entering DDB from console.

This patch seems to work around the problem:

----
RCS file: /home/netbsd/src/sys/arch/sh3/sh3/pmap.c,v
retrieving revision 1.85
diff -p -u -r1.85 pmap.c
--- sys/arch/sh3/sh3/pmap.c	26 Jul 2021 21:43:11 -0000	1.85
+++ sys/arch/sh3/sh3/pmap.c	24 Aug 2021 04:35:22 -0000
@@ -723,10 +723,28 @@ pmap_page_protect(struct vm_page *pg, vm
 	default:
 		/* Remove all */
 		s = splvm();
+#if 0 /* XXXRO */
 		while ((pv = SLIST_FIRST(&pvh->pvh_head)) != NULL) {
 			va = pv->pv_va;
 			pmap_remove(pv->pv_pmap, va, va + PAGE_SIZE);
 		}
+#else
+		while ((pv = SLIST_FIRST(&pvh->pvh_head)) != NULL) {
+			pt_entry_t *pte;
+			pmap = pv->pv_pmap;
+			va = pv->pv_va;
+			while ((pte = __pmap_pte_lookup(pmap, va)) == NULL ||
+			    *pte == 0) {
+				pv = SLIST_NEXT(pv, pv_link);
+				if (pv == NULL)
+					goto out;
+				pmap = pv->pv_pmap;
+				va = pv->pv_va;
+			}
+			pmap_remove(pmap, va, va + PAGE_SIZE);
+		}
+ out:
+#endif
 		splx(s);
 	}
 }
----

Note that similar check for pte and *pte is already done for
pmap_extract(). However,

(1) this may cause memory leak for pv, and moreover,

(2) I'm afraid that (pte == NULL || *pte == 0) indicates that
    pmap_enter() is partially executed at when pmap_remove() is invoked.

Also,

(3) usage of SLIST, and internal interfaces around pmap_remove() seems
    suboptimal.

Although, (3) should be addressed after the main problem is fixed.
>How-To-Repeat:
Make pkgsrc's for few hours to one day on landisk.
>Fix:
Workaround is provided above, but probably not a correct fix...



Home | Main Index | Thread Index | Old Index