Thu Jul 14 06:44:50 2016 UTC ()
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


(snj)
diff -r1.38.8.1 -r1.38.8.1.2.1 src/sys/kern/kern_softint.c

cvs diff -r1.38.8.1 -r1.38.8.1.2.1 src/sys/kern/kern_softint.c (expand / switch to unified diff)

--- src/sys/kern/kern_softint.c 2013/02/08 19:32:07 1.38.8.1
+++ src/sys/kern/kern_softint.c 2016/07/14 06:44:50 1.38.8.1.2.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: kern_softint.c,v 1.38.8.1 2013/02/08 19:32:07 riz Exp $ */ 1/* $NetBSD: kern_softint.c,v 1.38.8.1.2.1 2016/07/14 06:44:50 snj Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2007, 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 2007, 2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Doran. 8 * by Andrew Doran.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -166,27 +166,27 @@ @@ -166,27 +166,27 @@
166 * If a soft interrupt handler blocks and is resumed, it resumes 166 * If a soft interrupt handler blocks and is resumed, it resumes
167 * execution as a normal LWP (kthread) and gains VM context. Only 167 * execution as a normal LWP (kthread) and gains VM context. Only
168 * when it has completed and is ready to fire again will it 168 * when it has completed and is ready to fire again will it
169 * interrupt other threads. 169 * interrupt other threads.
170 * 170 *
171 * Future directions 171 * Future directions
172 * 172 *
173 * Provide a cheap way to direct software interrupts to remote 173 * Provide a cheap way to direct software interrupts to remote
174 * CPUs. Provide a way to enqueue work items into the handler 174 * CPUs. Provide a way to enqueue work items into the handler
175 * record, removing additional spl calls (see subr_workqueue.c).  175 * record, removing additional spl calls (see subr_workqueue.c).
176 */ 176 */
177 177
178#include <sys/cdefs.h> 178#include <sys/cdefs.h>
179__KERNEL_RCSID(0, "$NetBSD: kern_softint.c,v 1.38.8.1 2013/02/08 19:32:07 riz Exp $"); 179__KERNEL_RCSID(0, "$NetBSD: kern_softint.c,v 1.38.8.1.2.1 2016/07/14 06:44:50 snj Exp $");
180 180
181#include <sys/param.h> 181#include <sys/param.h>
182#include <sys/proc.h> 182#include <sys/proc.h>
183#include <sys/intr.h> 183#include <sys/intr.h>
184#include <sys/mutex.h> 184#include <sys/mutex.h>
185#include <sys/kthread.h> 185#include <sys/kthread.h>
186#include <sys/evcnt.h> 186#include <sys/evcnt.h>
187#include <sys/cpu.h> 187#include <sys/cpu.h>
188#include <sys/xcall.h> 188#include <sys/xcall.h>
189#include <sys/pserialize.h> 189#include <sys/pserialize.h>
190 190
191#include <net/netisr.h> 191#include <net/netisr.h>
192 192
@@ -414,28 +414,28 @@ softint_disestablish(void *arg) @@ -414,28 +414,28 @@ softint_disestablish(void *arg)
414 */ 414 */
415 where = xc_broadcast(0, (xcfunc_t)nullop, NULL, NULL); 415 where = xc_broadcast(0, (xcfunc_t)nullop, NULL, NULL);
416 xc_wait(where); 416 xc_wait(where);
417 417
418 for (;;) { 418 for (;;) {
419 /* Collect flag values from each CPU. */ 419 /* Collect flag values from each CPU. */
420 flags = 0; 420 flags = 0;
421 for (CPU_INFO_FOREACH(cii, ci)) { 421 for (CPU_INFO_FOREACH(cii, ci)) {
422 sc = ci->ci_data.cpu_softcpu; 422 sc = ci->ci_data.cpu_softcpu;
423 sh = (softhand_t *)((uint8_t *)sc + offset); 423 sh = (softhand_t *)((uint8_t *)sc + offset);
424 KASSERT(sh->sh_func != NULL); 424 KASSERT(sh->sh_func != NULL);
425 flags |= sh->sh_flags; 425 flags |= sh->sh_flags;
426 } 426 }
427 /* Inactive on all CPUs? */ 427 /* Neither pending nor active on all CPUs? */
428 if ((flags & SOFTINT_ACTIVE) == 0) { 428 if ((flags & (SOFTINT_PENDING | SOFTINT_ACTIVE)) == 0) {
429 break; 429 break;
430 } 430 }
431 /* Oops, still active. Wait for it to clear. */ 431 /* Oops, still active. Wait for it to clear. */
432 (void)kpause("softdis", false, 1, NULL); 432 (void)kpause("softdis", false, 1, NULL);
433 } 433 }
434 434
435 /* Clear the handler on each CPU. */ 435 /* Clear the handler on each CPU. */
436 mutex_enter(&softint_lock); 436 mutex_enter(&softint_lock);
437 for (CPU_INFO_FOREACH(cii, ci)) { 437 for (CPU_INFO_FOREACH(cii, ci)) {
438 sc = ci->ci_data.cpu_softcpu; 438 sc = ci->ci_data.cpu_softcpu;
439 sh = (softhand_t *)((uint8_t *)sc + offset); 439 sh = (softhand_t *)((uint8_t *)sc + offset);
440 KASSERT(sh->sh_func != NULL); 440 KASSERT(sh->sh_func != NULL);
441 sh->sh_func = NULL; 441 sh->sh_func = NULL;