tech-kern archive

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

kpreempt_disable and lwp migration



Hello tech-kern,

It seems that kpreempt_disable() does not prevent a lwp from
migrating. The assumption that it does is in some places in
NetBSD.

This came up as I am using a non-MPSAFE filesystem (LFS), and had
panics in x86 pmap's pmap_extract, which states it makes this assumption
in a comment:

        kpreempt_disable();
        ci = l->l_cpu;
        if (__predict_true(!ci->ci_want_pmapload && ci->ci_pmap == pmap) ||
            pmap == pmap_kernel()) {
                /*
                 * no need to lock, because it's pmap_kernel() or our
                 * own pmap and is active.  if a user pmap, the caller
                 * will hold the vm_map write/read locked and so prevent
                 * entries from disappearing while we are here.  ptps
                 * can disappear via pmap_remove() and pmap_protect(),
                 * but they are called with the vm_map write locked.

My personal opinion is that allowing lwp migration with preemption
explicitly disabled is a headache for reasoning about races and
that we should consider disallowing this.

Most notably, using curcpu() is a headache.

I'm not sure how this affects other archs which don't allow kernel
preemption.

I think the following diff will do it, thoughts?

Thanks.

Index: kern_cpu.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_cpu.c,v
retrieving revision 1.71
diff -u -r1.71 kern_cpu.c
--- kern_cpu.c	29 Aug 2015 12:24:00 -0000	1.71
+++ kern_cpu.c	17 Jun 2017 18:15:18 -0000
@@ -374,7 +374,8 @@
 		struct cpu_info *mci;
 
 		lwp_lock(l);
-		if (l->l_cpu != ci || (l->l_pflag & (LP_BOUND | LP_INTR))) {
+		if (l->l_cpu != ci || (l->l_pflag & (LP_BOUND | LP_INTR)) ||
+		    l->l_nopreempt) {
 			lwp_unlock(l);
 			continue;
 		}



Home | Main Index | Thread Index | Old Index