First in a series of changes to remove the now-unused Giant compatibility

framework for non-MPSAFE network protocols:

- Remove debug_mpsafenet variable, sysctl, and tunable.
- Remove NET_NEEDS_GIANT() and associate SYSINITSs used by it to force
  debug.mpsafenet=0 if non-MPSAFE protocols are compiled into the kernel.
- Remove logic to automatically flag interrupt handlers as non-MPSAFE if
  debug.mpsafenet is set for an INTR_TYPE_NET handler.
- Remove logic to automatically flag netisr handlers as non-MPSAFE if
  debug.mpsafenet is set.
- Remove references in a few subsystems, including NFS and Cronyx drivers,
  which keyed off debug_mpsafenet to determine various aspects of their own
  locking behavior.
- Convert NET_LOCK_GIANT(), NET_UNLOCK_GIANT(), and NET_ASSERT_GIANT into
  no-op's, as their entire behavior was determined by the value in
  debug_mpsafenet.
- Alias NET_CALLOUT_MPSAFE to CALLOUT_MPSAFE.

Many remaining references to NET_.*_GIANT() and NET_CALLOUT_MPSAFE are still
present in subsystems, and will be removed in followup commits.

Reviewed by:	bz, jhb
Approved by:	re (kensmith)
This commit is contained in:
Robert Watson 2007-07-27 11:59:57 +00:00
parent 9be70a793e
commit 33d2bb9ca3
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=171613
15 changed files with 14 additions and 174 deletions

View File

@ -504,7 +504,7 @@ ath_rate_attach(struct ath_softc *sc)
if (asc == NULL)
return NULL;
asc->arc.arc_space = sizeof(struct amrr_node);
callout_init(&asc->timer, debug_mpsafenet ? CALLOUT_MPSAFE : 0);
callout_init(&asc->timer, CALLOUT_MPSAFE);
ath_rate_sysctlattach(sc);
return &asc->arc;

View File

@ -478,7 +478,7 @@ ath_rate_attach(struct ath_softc *sc)
if (osc == NULL)
return NULL;
osc->arc.arc_space = sizeof(struct onoe_node);
callout_init(&osc->timer, debug_mpsafenet ? CALLOUT_MPSAFE : 0);
callout_init(&osc->timer, CALLOUT_MPSAFE);
ath_rate_sysctlattach(sc);
return &osc->arc;

View File

@ -2604,13 +2604,6 @@ static int ce_modevent (module_t mod, int type, void *unused)
#if __FreeBSD_version < 500000
dev = makedev (CDEV_MAJOR, 0);
#endif
#if __FreeBSD_version >= 501114
if (!debug_mpsafenet && ce_mpsafenet) {
printf ("WORNING! Network stack is not MPSAFE. "
"Turning off debug.ce.mpsafenet.\n");
ce_mpsafenet = 0;
}
#endif
#if __FreeBSD_version >= 502103
if (ce_mpsafenet)
ce_cdevsw.d_flags &= ~D_NEEDGIANT;

View File

@ -2265,11 +2265,6 @@ static int cp_modevent (module_t mod, int type, void *unused)
{
static int load_count = 0;
if (!debug_mpsafenet && cp_mpsafenet) {
printf ("WORNING! Network stack is not MPSAFE. "
"Turning off debug.cp.mpsafenet.\n");
cp_mpsafenet = 0;
}
if (cp_mpsafenet)
cp_cdevsw.d_flags &= ~D_NEEDGIANT;

View File

@ -2206,11 +2206,6 @@ static int ct_modevent (module_t mod, int type, void *unused)
{
static int load_count = 0;
if (!debug_mpsafenet && ct_mpsafenet) {
printf ("WORNING! Network stack is not MPSAFE. "
"Turning off debug.ct.mpsafenet.\n");
ct_mpsafenet = 0;
}
if (ct_mpsafenet)
ct_cdevsw.d_flags &= ~D_NEEDGIANT;

View File

@ -2523,11 +2523,6 @@ static int cx_modevent (module_t mod, int type, void *unused)
{
static int load_count = 0;
if (!debug_mpsafenet && cx_mpsafenet) {
printf ("WORNING! Network stack is not MPSAFE. "
"Turning off debug.cx.mpsafenet.\n");
cx_mpsafenet = 0;
}
if (cx_mpsafenet)
cx_cdevsw.d_flags &= ~D_NEEDGIANT;

View File

@ -3464,9 +3464,6 @@ bus_setup_intr(device_t dev, struct resource *r, int flags,
int error;
if (dev->parent != NULL) {
if ((flags &~ INTR_ENTROPY) == (INTR_TYPE_NET | INTR_MPSAFE) &&
!debug_mpsafenet)
flags &= ~INTR_MPSAFE;
error = BUS_SETUP_INTR(dev->parent, dev, r, flags,
filter, handler, arg, cookiep);
if (error == 0) {

View File

@ -211,13 +211,8 @@ domaininit(void *dummy)
if (max_linkhdr < 16) /* XXX */
max_linkhdr = 16;
if (debug_mpsafenet) {
callout_init(&pffast_callout, CALLOUT_MPSAFE);
callout_init(&pfslow_callout, CALLOUT_MPSAFE);
} else {
callout_init(&pffast_callout, 0);
callout_init(&pfslow_callout, 0);
}
callout_init(&pffast_callout, CALLOUT_MPSAFE);
callout_init(&pfslow_callout, CALLOUT_MPSAFE);
mtx_lock(&dom_mtx);
KASSERT(domain_init_status == 0, ("domaininit called too late!"));

View File

@ -2694,9 +2694,7 @@ void
if_start(struct ifnet *ifp)
{
NET_ASSERT_GIANT();
if ((ifp->if_flags & IFF_NEEDSGIANT) != 0 && debug_mpsafenet != 0) {
if (ifp->if_flags & IFF_NEEDSGIANT) {
if (mtx_owned(&Giant))
(*(ifp)->if_start)(ifp);
else
@ -2711,11 +2709,6 @@ if_start_deferred(void *context, int pending)
{
struct ifnet *ifp;
/*
* This code must be entered with Giant, and should never run if
* we're not running with debug.mpsafenet.
*/
KASSERT(debug_mpsafenet != 0, ("if_start_deferred: debug.mpsafenet"));
GIANT_REQUIRED;
ifp = context;

View File

@ -922,7 +922,7 @@ ether_ifattach(struct ifnet *ifp, const u_int8_t *lla)
break;
if (i != ifp->if_addrlen)
if_printf(ifp, "Ethernet address: %6D\n", lla, ":");
if (debug_mpsafenet && (ifp->if_flags & IFF_NEEDSGIANT) != 0)
if (ifp->if_flags & IFF_NEEDSGIANT)
if_printf(ifp, "if_start running deferred for Giant\n");
}

View File

@ -56,24 +56,6 @@
#include <net/if_var.h>
#include <net/netisr.h>
/*
* debug_mpsafenet controls network subsystem-wide use of the Giant lock,
* from system calls down to interrupt handlers. It can be changed only via
* a tunable at boot, not at run-time, due to the complexity of unwinding.
* The compiled default is set via a kernel option; right now, the default
* unless otherwise specified is to run the network stack without Giant.
*/
#ifdef NET_WITH_GIANT
int debug_mpsafenet = 0;
#else
int debug_mpsafenet = 1;
#endif
int debug_mpsafenet_toolatetotwiddle = 0;
TUNABLE_INT("debug.mpsafenet", &debug_mpsafenet);
SYSCTL_INT(_debug, OID_AUTO, mpsafenet, CTLFLAG_RD, &debug_mpsafenet, 0,
"Enable/disable MPSAFE network support");
volatile unsigned int netisr; /* scheduling bits for network */
struct netisr {
@ -84,78 +66,6 @@ struct netisr {
static void *net_ih;
/*
* Not all network code is currently capable of running MPSAFE; however,
* most of it is. Since those sections that are not are generally optional
* components not shipped with default kernels, we provide a basic way to
* determine whether MPSAFE operation is permitted: based on a default of
* yes, we permit non-MPSAFE components to use a registration call to
* identify that they require Giant. If the system is early in the boot
* process still, then we change the debug_mpsafenet setting to choose a
* non-MPSAFE execution mode (degraded). If it's too late for that (since
* the setting cannot be changed at run time), we generate a console warning
* that the configuration may be unsafe.
*/
static int mpsafe_warn_count;
/*
* Function call implementing registration of a non-MPSAFE network component.
*/
void
net_warn_not_mpsafe(const char *component)
{
/*
* If we're running with Giant over the network stack, there is no
* problem.
*/
if (!debug_mpsafenet)
return;
/*
* If it's not too late to change the MPSAFE setting for the network
* stack, do so now. This effectively suppresses warnings by
* components registering later.
*/
if (!debug_mpsafenet_toolatetotwiddle) {
debug_mpsafenet = 0;
printf("WARNING: debug.mpsafenet forced to 0 as %s requires "
"Giant\n", component);
return;
}
/*
* We must run without Giant, so generate a console warning with some
* information with what to do about it. The system may be operating
* unsafely, however.
*/
printf("WARNING: Network stack Giant-free, but %s requires Giant.\n",
component);
if (mpsafe_warn_count == 0)
printf(" Consider adding 'options NET_WITH_GIANT' or "
"setting debug.mpsafenet=0\n");
mpsafe_warn_count++;
}
/*
* This sysinit is run after any pre-loaded or compiled-in components have
* announced that they require Giant, but before any modules loaded at
* run-time.
*/
static void
net_mpsafe_toolate(void *arg)
{
debug_mpsafenet_toolatetotwiddle = 1;
if (!debug_mpsafenet)
printf("WARNING: MPSAFE network stack disabled, expect "
"reduced performance.\n");
}
SYSINIT(net_mpsafe_toolate, SI_SUB_SETTINGS, SI_ORDER_ANY, net_mpsafe_toolate,
NULL);
void
legacy_setsoftnet(void)
{
@ -170,8 +80,6 @@ netisr_register(int num, netisr_t *handler, struct ifqueue *inq, int flags)
("bad isr %d", num));
netisrs[num].ni_handler = handler;
netisrs[num].ni_queue = inq;
if ((flags & NETISR_MPSAFE) && !debug_mpsafenet)
flags &= ~NETISR_MPSAFE;
netisrs[num].ni_flags = flags;
}

View File

@ -549,10 +549,7 @@ nfsrv_modevent(module_t mod, int type, void *data)
nfsrv_initcache(); /* Init the server request cache */
NFSD_LOCK();
nfsrv_init(0); /* Init server data structures */
if (debug_mpsafenet)
callout_init(&nfsrv_callout, CALLOUT_MPSAFE);
else
callout_init(&nfsrv_callout, 0);
callout_init(&nfsrv_callout, CALLOUT_MPSAFE);
NFSD_UNLOCK();
nfsrv_timer(0);

View File

@ -561,16 +561,10 @@ nfssvc_nfsd(struct thread *td)
nfsd->nfsd_slp = NULL;
nfsrv_slpderef(slp);
}
KASSERT(!(debug_mpsafenet == 0 && !mtx_owned(&Giant)),
("nfssvc_nfsd(): debug.mpsafenet=0 && !Giant"));
KASSERT(!(debug_mpsafenet == 1 && mtx_owned(&Giant)),
("nfssvc_nfsd(): debug.mpsafenet=1 && Giant"));
mtx_assert(&Giant, MA_NOTOWNED);
}
done:
KASSERT(!(debug_mpsafenet == 0 && !mtx_owned(&Giant)),
("nfssvc_nfsd(): debug.mpsafenet=0 && !Giant"));
KASSERT(!(debug_mpsafenet == 1 && mtx_owned(&Giant)),
("nfssvc_nfsd(): debug.mpsafenet=1 && Giant"));
mtx_assert(&Giant, MA_NOTOWNED);
TAILQ_REMOVE(&nfsd_head, nfsd, nfsd_chain);
splx(s);
free((caddr_t)nfsd, M_NFSD);

View File

@ -343,11 +343,6 @@ struct tunable_str {
#define TUNABLE_STR_FETCH(path, var, size) \
getenv_string((path), (var), (size))
void net_warn_not_mpsafe(const char *component);
#define NET_NEEDS_GIANT(component) \
SYSINIT(__CONCAT(__net_warn_not_mpsafe_, __LINE__), \
SI_SUB_SETTINGS, SI_ORDER_SECOND, net_warn_not_mpsafe, component);
struct intr_config_hook {
TAILQ_ENTRY(intr_config_hook) ich_links;
void (*ich_func)(void *arg);

View File

@ -397,35 +397,18 @@ do { \
} while (0)
/*
* Network MPSAFE temporary workarounds. When debug_mpsafenet
* is 1 the network is assumed to operate without Giant on the
* input path and protocols that require Giant must collect it
* on entry. When 0 Giant is grabbed in the network interface
* ISR's and in the netisr path and there is no need to grab
* the Giant lock. Note that, unlike PICKUP_GIANT() and
* DROP_GIANT(), these macros directly wrap mutex operations
* without special recursion handling.
*
* This mechanism is intended as temporary until everything of
* importance is properly locked. Note: the semantics for
* NET_{LOCK,UNLOCK}_GIANT() are not the same as DROP_GIANT()
* and PICKUP_GIANT(), as they are plain mutex operations
* without a recursion counter.
* With the advent of fine-grained locking, the Giant lock is no longer
* required around the network stack. These macros exist for historical
* reasons, allowing conditional acquisition of Giant based on a debugging
* setting, and will be removed.
*/
extern int debug_mpsafenet; /* defined in net/netisr.c */
#define NET_LOCK_GIANT() do { \
if (!debug_mpsafenet) \
mtx_lock(&Giant); \
} while (0)
#define NET_UNLOCK_GIANT() do { \
if (!debug_mpsafenet) \
mtx_unlock(&Giant); \
} while (0)
#define NET_ASSERT_GIANT() do { \
if (!debug_mpsafenet) \
mtx_assert(&Giant, MA_OWNED); \
} while (0)
#define NET_CALLOUT_MPSAFE (debug_mpsafenet ? CALLOUT_MPSAFE : 0)
#define NET_CALLOUT_MPSAFE CALLOUT_MPSAFE
struct mtx_args {
struct mtx *ma_mtx;