Fri Jan 27 17:25:34 2017 UTC ()
Don't hold softnet_lock if NET_MPSAFE.

Some functions lock softnet_lock while waiting in pserialize_perform() in pfil_add_hook().
(e.g. key_timehandler(), etc)


(ryo)
diff -r1.5 -r1.6 src/sys/net/npf/npf_os.c

cvs diff -r1.5 -r1.6 src/sys/net/npf/npf_os.c (expand / switch to unified diff)

--- src/sys/net/npf/npf_os.c 2017/01/03 00:58:05 1.5
+++ src/sys/net/npf/npf_os.c 2017/01/27 17:25:34 1.6
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: npf_os.c,v 1.5 2017/01/03 00:58:05 rmind Exp $ */ 1/* $NetBSD: npf_os.c,v 1.6 2017/01/27 17:25:34 ryo Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2009-2016 The NetBSD Foundation, Inc. 4 * Copyright (c) 2009-2016 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This material is based upon work partially supported by The 7 * This material is based upon work partially supported by The
8 * NetBSD Foundation under a contract with Mindaugas Rasiukevicius. 8 * NetBSD Foundation under a contract with Mindaugas Rasiukevicius.
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.
@@ -25,27 +25,27 @@ @@ -25,27 +25,27 @@
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * NPF main: dynamic load/initialisation and unload routines. 33 * NPF main: dynamic load/initialisation and unload routines.
34 */ 34 */
35 35
36#ifdef _KERNEL 36#ifdef _KERNEL
37#include <sys/cdefs.h> 37#include <sys/cdefs.h>
38__KERNEL_RCSID(0, "$NetBSD: npf_os.c,v 1.5 2017/01/03 00:58:05 rmind Exp $"); 38__KERNEL_RCSID(0, "$NetBSD: npf_os.c,v 1.6 2017/01/27 17:25:34 ryo Exp $");
39 39
40#ifdef _KERNEL_OPT 40#ifdef _KERNEL_OPT
41#include "pf.h" 41#include "pf.h"
42#if NPF > 0 42#if NPF > 0
43#error "NPF and PF are mutually exclusive; please select one" 43#error "NPF and PF are mutually exclusive; please select one"
44#endif 44#endif
45#endif 45#endif
46 46
47#include <sys/param.h> 47#include <sys/param.h>
48#include <sys/types.h> 48#include <sys/types.h>
49 49
50#include <sys/conf.h> 50#include <sys/conf.h>
51#include <sys/kauth.h> 51#include <sys/kauth.h>
@@ -55,26 +55,27 @@ __KERNEL_RCSID(0, "$NetBSD: npf_os.c,v 1 @@ -55,26 +55,27 @@ __KERNEL_RCSID(0, "$NetBSD: npf_os.c,v 1
55#include <sys/socketvar.h> 55#include <sys/socketvar.h>
56#include <sys/uio.h> 56#include <sys/uio.h>
57 57
58#include <netinet/in.h> 58#include <netinet/in.h>
59#include <netinet6/in6_var.h> 59#include <netinet6/in6_var.h>
60#endif 60#endif
61 61
62#include "npf_impl.h" 62#include "npf_impl.h"
63#include "npfkern.h" 63#include "npfkern.h"
64 64
65#ifdef _KERNEL 65#ifdef _KERNEL
66#ifndef _MODULE 66#ifndef _MODULE
67#include "opt_modular.h" 67#include "opt_modular.h"
 68#include "opt_net_mpsafe.h"
68#endif 69#endif
69#include "ioconf.h" 70#include "ioconf.h"
70#endif 71#endif
71 72
72/* 73/*
73 * Module and device structures. 74 * Module and device structures.
74 */ 75 */
75#ifndef _MODULE 76#ifndef _MODULE
76/* 77/*
77 * Modular kernels load drivers too early, and we need percpu to be inited 78 * Modular kernels load drivers too early, and we need percpu to be inited
78 * So we make this misc; a better way would be to have early boot and late 79 * So we make this misc; a better way would be to have early boot and late
79 * boot drivers. 80 * boot drivers.
80 */ 81 */
@@ -386,28 +387,30 @@ npf_ifaddrhook(void *arg, u_long cmd, vo @@ -386,28 +387,30 @@ npf_ifaddrhook(void *arg, u_long cmd, vo
386 } 387 }
387 npf_ifaddr_sync(npf, ifa->ifa_ifp); 388 npf_ifaddr_sync(npf, ifa->ifa_ifp);
388} 389}
389 390
390/* 391/*
391 * npf_pfil_register: register pfil(9) hooks. 392 * npf_pfil_register: register pfil(9) hooks.
392 */ 393 */
393int 394int
394npf_pfil_register(bool init) 395npf_pfil_register(bool init)
395{ 396{
396 npf_t *npf = npf_getkernctx(); 397 npf_t *npf = npf_getkernctx();
397 int error = 0; 398 int error = 0;
398 399
 400#ifndef NET_MPSAFE
399 mutex_enter(softnet_lock); 401 mutex_enter(softnet_lock);
400 KERNEL_LOCK(1, NULL); 402 KERNEL_LOCK(1, NULL);
 403#endif
401 404
402 /* Init: interface re-config and attach/detach hook. */ 405 /* Init: interface re-config and attach/detach hook. */
403 if (!npf_ph_if) { 406 if (!npf_ph_if) {
404 npf_ph_if = pfil_head_get(PFIL_TYPE_IFNET, 0); 407 npf_ph_if = pfil_head_get(PFIL_TYPE_IFNET, 0);
405 if (!npf_ph_if) { 408 if (!npf_ph_if) {
406 error = ENOENT; 409 error = ENOENT;
407 goto out; 410 goto out;
408 } 411 }
409 412
410 error = pfil_add_ihook(npf_ifhook, NULL, 413 error = pfil_add_ihook(npf_ifhook, NULL,
411 PFIL_IFNET, npf_ph_if); 414 PFIL_IFNET, npf_ph_if);
412 KASSERT(error == 0); 415 KASSERT(error == 0);
413 416
@@ -442,56 +445,62 @@ npf_pfil_register(bool init) @@ -442,56 +445,62 @@ npf_pfil_register(bool init)
442 if (npf_ph_inet6) { 445 if (npf_ph_inet6) {
443 error = pfil_add_hook(npfkern_packet_handler, npf, 446 error = pfil_add_hook(npfkern_packet_handler, npf,
444 PFIL_ALL, npf_ph_inet6); 447 PFIL_ALL, npf_ph_inet6);
445 KASSERT(error == 0); 448 KASSERT(error == 0);
446 } 449 }
447 450
448 /* 451 /*
449 * It is necessary to re-sync all/any interface address tables, 452 * It is necessary to re-sync all/any interface address tables,
450 * since we did not listen for any changes. 453 * since we did not listen for any changes.
451 */ 454 */
452 npf_ifaddr_syncall(npf); 455 npf_ifaddr_syncall(npf);
453 pfil_registered = true; 456 pfil_registered = true;
454out: 457out:
 458#ifndef NET_MPSAFE
455 KERNEL_UNLOCK_ONE(NULL); 459 KERNEL_UNLOCK_ONE(NULL);
456 mutex_exit(softnet_lock); 460 mutex_exit(softnet_lock);
 461#endif
457 462
458 return error; 463 return error;
459} 464}
460 465
461/* 466/*
462 * npf_pfil_unregister: unregister pfil(9) hooks. 467 * npf_pfil_unregister: unregister pfil(9) hooks.
463 */ 468 */
464void 469void
465npf_pfil_unregister(bool fini) 470npf_pfil_unregister(bool fini)
466{ 471{
467 npf_t *npf = npf_getkernctx(); 472 npf_t *npf = npf_getkernctx();
468 473
 474#ifndef NET_MPSAFE
469 mutex_enter(softnet_lock); 475 mutex_enter(softnet_lock);
470 KERNEL_LOCK(1, NULL); 476 KERNEL_LOCK(1, NULL);
 477#endif
471 478
472 if (fini && npf_ph_if) { 479 if (fini && npf_ph_if) {
473 (void)pfil_remove_ihook(npf_ifhook, NULL, 480 (void)pfil_remove_ihook(npf_ifhook, NULL,
474 PFIL_IFNET, npf_ph_if); 481 PFIL_IFNET, npf_ph_if);
475 (void)pfil_remove_ihook(npf_ifaddrhook, NULL, 482 (void)pfil_remove_ihook(npf_ifaddrhook, NULL,
476 PFIL_IFADDR, npf_ph_if); 483 PFIL_IFADDR, npf_ph_if);
477 } 484 }
478 if (npf_ph_inet) { 485 if (npf_ph_inet) {
479 (void)pfil_remove_hook(npfkern_packet_handler, npf, 486 (void)pfil_remove_hook(npfkern_packet_handler, npf,
480 PFIL_ALL, npf_ph_inet); 487 PFIL_ALL, npf_ph_inet);
481 } 488 }
482 if (npf_ph_inet6) { 489 if (npf_ph_inet6) {
483 (void)pfil_remove_hook(npfkern_packet_handler, npf, 490 (void)pfil_remove_hook(npfkern_packet_handler, npf,
484 PFIL_ALL, npf_ph_inet6); 491 PFIL_ALL, npf_ph_inet6);
485 } 492 }
486 pfil_registered = false; 493 pfil_registered = false;
487 494
 495#ifndef NET_MPSAFE
488 KERNEL_UNLOCK_ONE(NULL); 496 KERNEL_UNLOCK_ONE(NULL);
489 mutex_exit(softnet_lock); 497 mutex_exit(softnet_lock);
 498#endif
490} 499}
491 500
492bool 501bool
493npf_pfil_registered_p(void) 502npf_pfil_registered_p(void)
494{ 503{
495 return pfil_registered; 504 return pfil_registered;
496} 505}
497#endif 506#endif