Module Name: src Committed By: snj Date: Thu Jul 14 06:56:03 UTC 2016
Modified Files: src/sys/kern [netbsd-6]: kern_softint.c Log Message: Pull up following revision(s) (requested by knakahara in ticket #1356): sys/kern/kern_softint.c: revision 1.42 fix the following softint parallel operation problem. (0) softint handler "handler A" is established (1) CPU#X does softint_schedule() for "handler A" - the softhand_t is set SOFTINT_PENDING flag - the softhand_t is NOT set SOFTINT_ACTIVE flag yet (2) CPU#X begins other H/W interrupt processing (3) CPU#Y does softint_disestablish() for "handler A" - waits until softhand_t's SOFTINT_ACTIVE of all CPUs is clear - the softhand_t is set not SOFTINT_ACTIVE but SOFTINT_PENDING, so CPU#Y does not wait - unset the function of "handler A" (4) CPU#X does softint_execute() - the function of "handler A" is already clear, so panic To generate a diff of this commit: cvs rdiff -u -r1.38.8.1 -r1.38.8.2 src/sys/kern/kern_softint.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/kern_softint.c diff -u src/sys/kern/kern_softint.c:1.38.8.1 src/sys/kern/kern_softint.c:1.38.8.2 --- src/sys/kern/kern_softint.c:1.38.8.1 Fri Feb 8 19:32:07 2013 +++ src/sys/kern/kern_softint.c Thu Jul 14 06:56:03 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_softint.c,v 1.38.8.1 2013/02/08 19:32:07 riz Exp $ */ +/* $NetBSD: kern_softint.c,v 1.38.8.2 2016/07/14 06:56:03 snj Exp $ */ /*- * Copyright (c) 2007, 2008 The NetBSD Foundation, Inc. @@ -176,7 +176,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_softint.c,v 1.38.8.1 2013/02/08 19:32:07 riz Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_softint.c,v 1.38.8.2 2016/07/14 06:56:03 snj Exp $"); #include <sys/param.h> #include <sys/proc.h> @@ -424,8 +424,8 @@ softint_disestablish(void *arg) KASSERT(sh->sh_func != NULL); flags |= sh->sh_flags; } - /* Inactive on all CPUs? */ - if ((flags & SOFTINT_ACTIVE) == 0) { + /* Neither pending nor active on all CPUs? */ + if ((flags & (SOFTINT_PENDING | SOFTINT_ACTIVE)) == 0) { break; } /* Oops, still active. Wait for it to clear. */