svn commit: r231696 - in stable/8/sys: kern netgraph
Gleb Smirnoff
glebius at FreeBSD.org
Tue Feb 14 17:35:45 UTC 2012
Author: glebius
Date: Tue Feb 14 17:35:44 2012
New Revision: 231696
URL: http://svn.freebsd.org/changeset/base/231696
Log:
Merge netgraph related fixes and enhancements from head/. Revisions
merged: r223754,224031,226829,229003,230213,230480, 230486-230487,231585.
r223754 to ng_base:
- Use refcount(9) API to manage node and hook refcounting.
r224031 to ng_socket:
In ng_attach_cntl() first allocate things that may fail, and then
do the rest of initialization. This simplifies code and fixes
a double free in failure scenario.
r226829 to ng_base:
- If KDB & NETGRAPH_DEBUG are on, print traces on discovered failed
invariants.
- Reduce tautology in NETGRAPH_DEBUG output.
r229003 to ng_base:
style(9), whitespace and spelling nits.
r230213 to ng_socket:
Remove some disabled NOTYET code. Probability of enabling it is low,
if anyone wants, he/she can take it from svn.
r230480 to ng_base:
Convert locks that protect name hash, ID hash and typelist from
mutex(9) to rwlock(9) based locks.
While here remove dropping lock when processing NGM_LISTNODES,
and NGM_LISTTYPES generic commands. We don't need to drop it
since memory allocation is done with M_NOWAIT.
r230486 to hashinit(9):
Convert panic()s to KASSERT()s. This is an optimisation for
hashdestroy() since in absence of INVARIANTS a compiler
will drop the entire for() cycle.
r230487,r231585 to ng_socket:
Provide a findhook method for ng_socket(4). The node stores a
hash with names of its hooks. It starts with size of 16, and
grows when number of hooks reaches twice the current size. A
failure to grow (memory is allocated with M_NOWAIT) isn't
fatal, however.
Tested by: Eugene Grosbein, Mike Tancsa
Modified:
stable/8/sys/kern/kern_subr.c
stable/8/sys/netgraph/netgraph.h
stable/8/sys/netgraph/ng_base.c
stable/8/sys/netgraph/ng_socket.c
stable/8/sys/netgraph/ng_socketvar.h
Directory Properties:
stable/8/sys/ (props changed)
Modified: stable/8/sys/kern/kern_subr.c
==============================================================================
--- stable/8/sys/kern/kern_subr.c Tue Feb 14 17:18:45 2012 (r231695)
+++ stable/8/sys/kern/kern_subr.c Tue Feb 14 17:35:44 2012 (r231696)
@@ -373,9 +373,7 @@ hashinit_flags(int elements, struct mall
LIST_HEAD(generic, generic) *hashtbl;
int i;
- if (elements <= 0)
- panic("hashinit: bad elements");
-
+ KASSERT(elements > 0, ("%s: bad elements", __func__));
/* Exactly one of HASH_WAITOK and HASH_NOWAIT must be set. */
KASSERT((flags & HASH_WAITOK) ^ (flags & HASH_NOWAIT),
("Bad flags (0x%x) passed to hashinit_flags", flags));
@@ -416,8 +414,7 @@ hashdestroy(void *vhashtbl, struct mallo
hashtbl = vhashtbl;
for (hp = hashtbl; hp <= &hashtbl[hashmask]; hp++)
- if (!LIST_EMPTY(hp))
- panic("hashdestroy: hash not empty");
+ KASSERT(LIST_EMPTY(hp), ("%s: hash not empty", __func__));
free(hashtbl, type);
}
@@ -436,8 +433,7 @@ phashinit(int elements, struct malloc_ty
LIST_HEAD(generic, generic) *hashtbl;
int i;
- if (elements <= 0)
- panic("phashinit: bad elements");
+ KASSERT(elements > 0, ("%s: bad elements", __func__));
for (i = 1, hashsize = primes[1]; hashsize <= elements;) {
i++;
if (i == NPRIMES)
Modified: stable/8/sys/netgraph/netgraph.h
==============================================================================
--- stable/8/sys/netgraph/netgraph.h Tue Feb 14 17:18:45 2012 (r231695)
+++ stable/8/sys/netgraph/netgraph.h Tue Feb 14 17:35:44 2012 (r231696)
@@ -53,9 +53,11 @@
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/mutex.h>
+#include <sys/refcount.h>
#ifdef HAVE_KERNEL_OPTION_HEADERS
#include "opt_netgraph.h"
+#include "opt_kdb.h"
#endif
/* debugging options */
@@ -137,7 +139,7 @@ struct ng_hook {
* If you can't do it with these you probably shouldn;t be doing it.
*/
void ng_unref_hook(hook_p hook); /* don't move this */
-#define _NG_HOOK_REF(hook) atomic_add_int(&(hook)->hk_refs, 1)
+#define _NG_HOOK_REF(hook) refcount_acquire(&(hook)->hk_refs)
#define _NG_HOOK_NAME(hook) ((hook)->hk_name)
#define _NG_HOOK_UNREF(hook) ng_unref_hook(hook)
#define _NG_HOOK_SET_PRIVATE(hook, val) do {(hook)->hk_private = val;} while (0)
@@ -189,7 +191,7 @@ static __inline void
_chkhook(hook_p hook, char *file, int line)
{
if (hook->hk_magic != HK_MAGIC) {
- printf("Accessing freed hook ");
+ printf("Accessing freed ");
dumphook(hook, file, line);
}
hook->lastline = line;
@@ -400,7 +402,7 @@ int ng_unref_node(node_p node); /* don't
#define _NG_NODE_NAME(node) ((node)->nd_name + 0)
#define _NG_NODE_HAS_NAME(node) ((node)->nd_name[0] + 0)
#define _NG_NODE_ID(node) ((node)->nd_ID + 0)
-#define _NG_NODE_REF(node) atomic_add_int(&(node)->nd_refs, 1)
+#define _NG_NODE_REF(node) refcount_acquire(&(node)->nd_refs)
#define _NG_NODE_UNREF(node) ng_unref_node(node)
#define _NG_NODE_SET_PRIVATE(node, val) do {(node)->nd_private = val;} while (0)
#define _NG_NODE_PRIVATE(node) ((node)->nd_private)
@@ -457,7 +459,7 @@ static __inline void
_chknode(node_p node, char *file, int line)
{
if (node->nd_magic != ND_MAGIC) {
- printf("Accessing freed node ");
+ printf("Accessing freed ");
dumpnode(node, file, line);
}
node->lastline = line;
Modified: stable/8/sys/netgraph/ng_base.c
==============================================================================
--- stable/8/sys/netgraph/ng_base.c Tue Feb 14 17:18:45 2012 (r231695)
+++ stable/8/sys/netgraph/ng_base.c Tue Feb 14 17:35:44 2012 (r231696)
@@ -1,7 +1,3 @@
-/*
- * ng_base.c
- */
-
/*-
* Copyright (c) 1996-1999 Whistle Communications, Inc.
* All rights reserved.
@@ -54,6 +50,7 @@
#include <sys/kernel.h>
#include <sys/ktr.h>
#include <sys/limits.h>
+#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/queue.h>
@@ -61,6 +58,7 @@
#include <sys/syslog.h>
#include <sys/refcount.h>
#include <sys/proc.h>
+#include <sys/rwlock.h>
#include <sys/unistd.h>
#include <sys/kthread.h>
#include <sys/smp.h>
@@ -167,19 +165,28 @@ static struct mtx ng_worklist_mtx; /*
/* List of installed types */
static LIST_HEAD(, ng_type) ng_typelist;
-static struct mtx ng_typelist_mtx;
+static struct rwlock ng_typelist_lock;
+#define TYPELIST_RLOCK() rw_rlock(&ng_typelist_lock)
+#define TYPELIST_RUNLOCK() rw_runlock(&ng_typelist_lock)
+#define TYPELIST_WLOCK() rw_wlock(&ng_typelist_lock)
+#define TYPELIST_WUNLOCK() rw_wunlock(&ng_typelist_lock)
/* Hash related definitions */
/* XXX Don't need to initialise them because it's a LIST */
static VNET_DEFINE(LIST_HEAD(, ng_node), ng_ID_hash[NG_ID_HASH_SIZE]);
#define V_ng_ID_hash VNET(ng_ID_hash)
-static struct mtx ng_idhash_mtx;
+static struct rwlock ng_idhash_lock;
+#define IDHASH_RLOCK() rw_rlock(&ng_idhash_lock)
+#define IDHASH_RUNLOCK() rw_runlock(&ng_idhash_lock)
+#define IDHASH_WLOCK() rw_wlock(&ng_idhash_lock)
+#define IDHASH_WUNLOCK() rw_wunlock(&ng_idhash_lock)
+
/* Method to find a node.. used twice so do it here */
#define NG_IDHASH_FN(ID) ((ID) % (NG_ID_HASH_SIZE))
#define NG_IDHASH_FIND(ID, node) \
do { \
- mtx_assert(&ng_idhash_mtx, MA_OWNED); \
+ rw_assert(&ng_idhash_lock, RA_LOCKED); \
LIST_FOREACH(node, &V_ng_ID_hash[NG_IDHASH_FN(ID)], \
nd_idnodes) { \
if (NG_NODE_IS_VALID(node) \
@@ -192,7 +199,6 @@ static struct mtx ng_idhash_mtx;
static VNET_DEFINE(LIST_HEAD(, ng_node), ng_name_hash[NG_NAME_HASH_SIZE]);
#define V_ng_name_hash VNET(ng_name_hash)
-static struct mtx ng_namehash_mtx;
#define NG_NAMEHASH(NAME, HASH) \
do { \
u_char h = 0; \
@@ -202,6 +208,11 @@ static struct mtx ng_namehash_mtx;
(HASH) = h % (NG_NAME_HASH_SIZE); \
} while (0)
+static struct rwlock ng_namehash_lock;
+#define NAMEHASH_RLOCK() rw_rlock(&ng_namehash_lock)
+#define NAMEHASH_RUNLOCK() rw_runlock(&ng_namehash_lock)
+#define NAMEHASH_WLOCK() rw_wlock(&ng_namehash_lock)
+#define NAMEHASH_WUNLOCK() rw_wunlock(&ng_namehash_lock)
/* Internal functions */
static int ng_add_hook(node_p node, const char *name, hook_p * hookp);
@@ -330,18 +341,18 @@ ng_alloc_node(void)
#define NG_FREE_HOOK(hook) \
do { \
- mtx_lock(&ng_nodelist_mtx); \
+ mtx_lock(&ng_nodelist_mtx); \
LIST_INSERT_HEAD(&ng_freehooks, hook, hk_hooks); \
hook->hk_magic = 0; \
- mtx_unlock(&ng_nodelist_mtx); \
+ mtx_unlock(&ng_nodelist_mtx); \
} while (0)
#define NG_FREE_NODE(node) \
do { \
- mtx_lock(&ng_nodelist_mtx); \
+ mtx_lock(&ng_nodelist_mtx); \
LIST_INSERT_HEAD(&ng_freenodes, node, nd_nodes); \
node->nd_magic = 0; \
- mtx_unlock(&ng_nodelist_mtx); \
+ mtx_unlock(&ng_nodelist_mtx); \
} while (0)
#else /* NETGRAPH_DEBUG */ /*----------------------------------------------*/
@@ -651,12 +662,12 @@ ng_make_node_common(struct ng_type *type
LIST_INIT(&node->nd_hooks);
/* Link us into the name hash. */
- mtx_lock(&ng_namehash_mtx);
+ NAMEHASH_WLOCK();
LIST_INSERT_HEAD(&V_ng_name_hash[0], node, nd_nodes);
- mtx_unlock(&ng_namehash_mtx);
+ NAMEHASH_WUNLOCK();
/* get an ID and put us in the hash chain */
- mtx_lock(&ng_idhash_mtx);
+ IDHASH_WLOCK();
for (;;) { /* wrap protection, even if silly */
node_p node2 = NULL;
node->nd_ID = V_nextID++; /* 137/sec for 1 year before wrap */
@@ -667,9 +678,9 @@ ng_make_node_common(struct ng_type *type
break;
}
}
- LIST_INSERT_HEAD(&V_ng_ID_hash[NG_IDHASH_FN(node->nd_ID)],
- node, nd_idnodes);
- mtx_unlock(&ng_idhash_mtx);
+ LIST_INSERT_HEAD(&V_ng_ID_hash[NG_IDHASH_FN(node->nd_ID)], node,
+ nd_idnodes);
+ IDHASH_WUNLOCK();
/* Done */
*nodepp = node;
@@ -771,33 +782,39 @@ ng_rmnode(node_p node, hook_p dummy1, vo
/*
* Remove a reference to the node, possibly the last.
* deadnode always acts as it it were the last.
+ *
+ * XXX: in head this function is void, since it isn't
+ * safe to trust its value. But for API compatibility
+ * here it is left int, and in case of non-last reference
+ * count it returns a large positive value.
*/
int
ng_unref_node(node_p node)
{
- int v;
- if (node == &ng_deadnode) {
+ if (node == &ng_deadnode)
return (0);
- }
-
- v = atomic_fetchadd_int(&node->nd_refs, -1);
- if (v == 1) { /* we were the last */
+ if (refcount_release(&node->nd_refs)) { /* we were the last */
- mtx_lock(&ng_namehash_mtx);
node->nd_type->refs--; /* XXX maybe should get types lock? */
+ NAMEHASH_WLOCK();
LIST_REMOVE(node, nd_nodes);
- mtx_unlock(&ng_namehash_mtx);
+ NAMEHASH_WUNLOCK();
- mtx_lock(&ng_idhash_mtx);
+ IDHASH_WLOCK();
LIST_REMOVE(node, nd_idnodes);
- mtx_unlock(&ng_idhash_mtx);
+ IDHASH_WUNLOCK();
mtx_destroy(&node->nd_input_queue.q_mtx);
NG_FREE_NODE(node);
+
+ /* XXX */
+ return (0);
}
- return (v - 1);
+
+ /* XXX */
+ return (42);
}
/************************************************************************
@@ -807,11 +824,11 @@ static node_p
ng_ID2noderef(ng_ID_t ID)
{
node_p node;
- mtx_lock(&ng_idhash_mtx);
+ IDHASH_RLOCK();
NG_IDHASH_FIND(ID, node);
if(node)
NG_NODE_REF(node);
- mtx_unlock(&ng_idhash_mtx);
+ IDHASH_RUNLOCK();
return(node);
}
@@ -826,7 +843,7 @@ ng_node2ID(node_p node)
************************************************************************/
/*
- * Assign a node a name. Once assigned, the name cannot be changed.
+ * Assign a node a name.
*/
int
ng_name_node(node_p node, const char *name)
@@ -860,10 +877,10 @@ ng_name_node(node_p node, const char *na
/* Update name hash. */
NG_NAMEHASH(name, hash);
- mtx_lock(&ng_namehash_mtx);
+ NAMEHASH_WLOCK();
LIST_REMOVE(node, nd_nodes);
LIST_INSERT_HEAD(&V_ng_name_hash[hash], node, nd_nodes);
- mtx_unlock(&ng_namehash_mtx);
+ NAMEHASH_WUNLOCK();
return (0);
}
@@ -898,16 +915,15 @@ ng_name2noderef(node_p here, const char
/* Find node by name */
NG_NAMEHASH(name, hash);
- mtx_lock(&ng_namehash_mtx);
- LIST_FOREACH(node, &V_ng_name_hash[hash], nd_nodes) {
+ NAMEHASH_RLOCK();
+ LIST_FOREACH(node, &V_ng_name_hash[hash], nd_nodes)
if (NG_NODE_IS_VALID(node) &&
(strcmp(NG_NODE_NAME(node), name) == 0)) {
+ NG_NODE_REF(node);
break;
}
- }
- if (node)
- NG_NODE_REF(node);
- mtx_unlock(&ng_namehash_mtx);
+ NAMEHASH_RUNLOCK();
+
return (node);
}
@@ -923,27 +939,21 @@ ng_decodeidname(const char *name)
u_long val;
/* Check for proper length, brackets, no leading junk */
- if ((len < 3)
- || (name[0] != '[')
- || (name[len - 1] != ']')
- || (!isxdigit(name[1]))) {
+ if ((len < 3) || (name[0] != '[') || (name[len - 1] != ']') ||
+ (!isxdigit(name[1])))
return ((ng_ID_t)0);
- }
/* Decode number */
val = strtoul(name + 1, &eptr, 16);
- if ((eptr - name != len - 1)
- || (val == ULONG_MAX)
- || (val == 0)) {
+ if ((eptr - name != len - 1) || (val == ULONG_MAX) || (val == 0))
return ((ng_ID_t)0);
- }
- return (ng_ID_t)val;
+
+ return ((ng_ID_t)val);
}
/*
* Remove a name from a node. This should only be called
* when shutting down and removing the node.
- * IF we allow name changing this may be more resurrected.
*/
void
ng_unname(node_p node)
@@ -963,15 +973,11 @@ ng_unname(node_p node)
void
ng_unref_hook(hook_p hook)
{
- int v;
- if (hook == &ng_deadhook) {
+ if (hook == &ng_deadhook)
return;
- }
-
- v = atomic_fetchadd_int(&hook->hk_refs, -1);
- if (v == 1) { /* we were the last */
+ if (refcount_release(&hook->hk_refs)) { /* we were the last */
if (_NG_HOOK_NODE(hook)) /* it'll probably be ng_deadnode */
_NG_NODE_UNREF((_NG_HOOK_NODE(hook)));
NG_FREE_HOOK(hook);
@@ -1051,8 +1057,8 @@ ng_findhook(node_p node, const char *nam
if (node->nd_type->findhook != NULL)
return (*node->nd_type->findhook)(node, name);
LIST_FOREACH(hook, &node->nd_hooks, hk_hooks) {
- if (NG_HOOK_IS_VALID(hook)
- && (strcmp(NG_HOOK_NAME(hook), name) == 0))
+ if (NG_HOOK_IS_VALID(hook) &&
+ (strcmp(NG_HOOK_NAME(hook), name) == 0))
return (hook);
}
return (NULL);
@@ -1188,12 +1194,12 @@ ng_newtype(struct ng_type *tp)
const size_t namelen = strlen(tp->name);
/* Check version and type name fields */
- if ((tp->version != NG_ABI_VERSION)
- || (namelen == 0)
- || (namelen >= NG_TYPESIZ)) {
+ if ((tp->version != NG_ABI_VERSION) || (namelen == 0) ||
+ (namelen >= NG_TYPESIZ)) {
TRAP_ERROR();
if (tp->version != NG_ABI_VERSION) {
- printf("Netgraph: Node type rejected. ABI mismatch. Suggest recompile\n");
+ printf("Netgraph: Node type rejected. ABI mismatch. "
+ "Suggest recompile\n");
}
return (EINVAL);
}
@@ -1206,10 +1212,10 @@ ng_newtype(struct ng_type *tp)
/* Link in new type */
- mtx_lock(&ng_typelist_mtx);
+ TYPELIST_WLOCK();
LIST_INSERT_HEAD(&ng_typelist, tp, types);
tp->refs = 1; /* first ref is linked list */
- mtx_unlock(&ng_typelist_mtx);
+ TYPELIST_WUNLOCK();
return (0);
}
@@ -1227,9 +1233,9 @@ ng_rmtype(struct ng_type *tp)
}
/* Unlink type */
- mtx_lock(&ng_typelist_mtx);
+ TYPELIST_WLOCK();
LIST_REMOVE(tp, types);
- mtx_unlock(&ng_typelist_mtx);
+ TYPELIST_WUNLOCK();
return (0);
}
@@ -1241,12 +1247,12 @@ ng_findtype(const char *typename)
{
struct ng_type *type;
- mtx_lock(&ng_typelist_mtx);
+ TYPELIST_RLOCK();
LIST_FOREACH(type, &ng_typelist, types) {
if (strcmp(type->name, typename) == 0)
break;
}
- mtx_unlock(&ng_typelist_mtx);
+ TYPELIST_RUNLOCK();
return (type);
}
@@ -1641,8 +1647,8 @@ ng_path_parse(char *addr, char **nodep,
* return the destination node.
*/
int
-ng_path2noderef(node_p here, const char *address,
- node_p *destp, hook_p *lasthook)
+ng_path2noderef(node_p here, const char *address, node_p *destp,
+ hook_p *lasthook)
{
char fullpath[NG_PATHSIZ];
char *nodename, *path;
@@ -1721,10 +1727,9 @@ ng_path2noderef(node_p here, const char
mtx_lock(&ng_topo_mtx);
/* Can't get there from here... */
- if (hook == NULL
- || NG_HOOK_PEER(hook) == NULL
- || NG_HOOK_NOT_VALID(hook)
- || NG_HOOK_NOT_VALID(NG_HOOK_PEER(hook))) {
+ if (hook == NULL || NG_HOOK_PEER(hook) == NULL ||
+ NG_HOOK_NOT_VALID(hook) ||
+ NG_HOOK_NOT_VALID(NG_HOOK_PEER(hook))) {
TRAP_ERROR();
NG_NODE_UNREF(node);
mtx_unlock(&ng_topo_mtx);
@@ -1888,9 +1893,9 @@ ng_dequeue(node_p node, int *rw)
long t = ngq->q_flags;
if (t & WRITER_ACTIVE) {
/* There is writer, reader can't proceed. */
- CTR4(KTR_NET, "%20s: node [%x] (%p) queued reader "
- "can't proceed; queue flags 0x%lx", __func__,
- node->nd_ID, node, t);
+ CTR4(KTR_NET, "%20s: node [%x] (%p) queued "
+ "reader can't proceed; queue flags 0x%lx",
+ __func__, node->nd_ID, node, t);
return (NULL);
}
if (atomic_cmpset_acq_int(&ngq->q_flags, t,
@@ -1906,9 +1911,9 @@ ng_dequeue(node_p node, int *rw)
*rw = NGQRW_W;
} else {
/* There is somebody other, writer can't proceed. */
- CTR4(KTR_NET, "%20s: node [%x] (%p) queued writer "
- "can't proceed; queue flags 0x%lx", __func__,
- node->nd_ID, node, ngq->q_flags);
+ CTR4(KTR_NET, "%20s: node [%x] (%p) queued writer can't "
+ "proceed; queue flags 0x%lx", __func__, node->nd_ID, node,
+ ngq->q_flags);
return (NULL);
}
@@ -1920,10 +1925,9 @@ ng_dequeue(node_p node, int *rw)
STAILQ_REMOVE_HEAD(&ngq->queue, el_next);
if (STAILQ_EMPTY(&ngq->queue))
atomic_clear_int(&ngq->q_flags, OP_PENDING);
- CTR6(KTR_NET, "%20s: node [%x] (%p) returning item %p as %s; "
- "queue flags 0x%lx", __func__,
- node->nd_ID, node, item, *rw ? "WRITER" : "READER" ,
- ngq->q_flags);
+ CTR6(KTR_NET, "%20s: node [%x] (%p) returning item %p as %s; queue "
+ "flags 0x%lx", __func__, node->nd_ID, node, item, *rw ? "WRITER" :
+ "READER", ngq->q_flags);
return (item);
}
@@ -1947,7 +1951,7 @@ ng_queue_rw(node_p node, item_p item, i
CTR5(KTR_NET, "%20s: node [%x] (%p) queued item %p as %s", __func__,
node->nd_ID, node, item, rw ? "WRITER" : "READER" );
-
+
/*
* We can take the worklist lock with the node locked
* BUT NOT THE REVERSE!
@@ -1965,12 +1969,12 @@ ng_acquire_read(node_p node, item_p item
("%s: working on deadnode", __func__));
/* Reader needs node without writer and pending items. */
- while (1) {
+ for (;;) {
long t = node->nd_input_queue.q_flags;
if (t & NGQ_RMASK)
break; /* Node is not ready for reader. */
- if (atomic_cmpset_acq_int(&node->nd_input_queue.q_flags,
- t, t + READER_INCREMENT)) {
+ if (atomic_cmpset_acq_int(&node->nd_input_queue.q_flags, t,
+ t + READER_INCREMENT)) {
/* Successfully grabbed node */
CTR4(KTR_NET, "%20s: node [%x] (%p) acquired item %p",
__func__, node->nd_ID, node, item);
@@ -1993,8 +1997,8 @@ ng_acquire_write(node_p node, item_p ite
("%s: working on deadnode", __func__));
/* Writer needs completely idle node. */
- if (atomic_cmpset_acq_int(&node->nd_input_queue.q_flags,
- 0, WRITER_ACTIVE)) {
+ if (atomic_cmpset_acq_int(&node->nd_input_queue.q_flags, 0,
+ WRITER_ACTIVE)) {
/* Successfully grabbed node */
CTR4(KTR_NET, "%20s: node [%x] (%p) acquired item %p",
__func__, node->nd_ID, node, item);
@@ -2038,11 +2042,10 @@ ng_upgrade_write(node_p node, item_p ite
ng_apply_item(node, item, 0);
/*
- * Having acted on the item, atomically
- * down grade back to READER and finish up
+ * Having acted on the item, atomically
+ * downgrade back to READER and finish up.
*/
- atomic_add_int(&ngq->q_flags,
- READER_INCREMENT - WRITER_ACTIVE);
+ atomic_add_int(&ngq->q_flags, READER_INCREMENT - WRITER_ACTIVE);
/* Our caller will call ng_leave_read() */
return;
@@ -2210,11 +2213,10 @@ ng_snd_item(item_p item, int flags)
size_t st, su, sl;
GET_STACK_USAGE(st, su);
sl = st - su;
- if ((sl * 4 < st) ||
- ((sl * 2 < st) && ((node->nd_flags & NGF_HI_STACK) ||
- (hook && (hook->hk_flags & HK_HI_STACK))))) {
+ if ((sl * 4 < st) || ((sl * 2 < st) &&
+ ((node->nd_flags & NGF_HI_STACK) || (hook &&
+ (hook->hk_flags & HK_HI_STACK)))))
queue = 1;
- }
#endif
}
@@ -2316,10 +2318,10 @@ ng_apply_item(node_p node, item_p item,
}
/*
* If no receive method, just silently drop it.
- * Give preference to the hook over-ride method
+ * Give preference to the hook over-ride method.
*/
- if ((!(rcvdata = hook->hk_rcvdata))
- && (!(rcvdata = NG_HOOK_NODE(hook)->nd_type->rcvdata))) {
+ if ((!(rcvdata = hook->hk_rcvdata)) &&
+ (!(rcvdata = NG_HOOK_NODE(hook)->nd_type->rcvdata))) {
error = 0;
NG_FREE_ITEM(item);
break;
@@ -2539,8 +2541,8 @@ ng_generic_msg(node_p here, item_p item,
hook_p hook;
/* Get response struct */
- NG_MKRESPONSE(resp, msg, sizeof(*hl)
- + (nhooks * sizeof(struct linkinfo)), M_NOWAIT);
+ NG_MKRESPONSE(resp, msg, sizeof(*hl) +
+ (nhooks * sizeof(struct linkinfo)), M_NOWAIT);
if (resp == NULL) {
error = ENOMEM;
break;
@@ -2588,7 +2590,7 @@ ng_generic_msg(node_p here, item_p item,
node_p node;
int num = 0, i;
- mtx_lock(&ng_namehash_mtx);
+ NAMEHASH_RLOCK();
/* Count number of nodes */
for (i = 0; i < NG_NAME_HASH_SIZE; i++) {
LIST_FOREACH(node, &V_ng_name_hash[i], nd_nodes) {
@@ -2598,12 +2600,12 @@ ng_generic_msg(node_p here, item_p item,
}
}
}
- mtx_unlock(&ng_namehash_mtx);
/* Get response struct */
- NG_MKRESPONSE(resp, msg, sizeof(*nl)
- + (num * sizeof(struct nodeinfo)), M_NOWAIT);
+ NG_MKRESPONSE(resp, msg, sizeof(*nl) +
+ (num * sizeof(struct nodeinfo)), M_NOWAIT);
if (resp == NULL) {
+ NAMEHASH_RUNLOCK();
error = ENOMEM;
break;
}
@@ -2611,7 +2613,6 @@ ng_generic_msg(node_p here, item_p item,
/* Cycle through the linked list of nodes */
nl->numnames = 0;
- mtx_lock(&ng_namehash_mtx);
for (i = 0; i < NG_NAME_HASH_SIZE; i++) {
LIST_FOREACH(node, &V_ng_name_hash[i], nd_nodes) {
struct nodeinfo *const np =
@@ -2621,20 +2622,17 @@ ng_generic_msg(node_p here, item_p item,
continue;
if (!unnamed && (! NG_NODE_HAS_NAME(node)))
continue;
- if (nl->numnames >= num) {
- log(LOG_ERR, "%s: number of nodes changed\n",
- __func__);
- break;
- }
if (NG_NODE_HAS_NAME(node))
strcpy(np->name, NG_NODE_NAME(node));
strcpy(np->type, node->nd_type->name);
np->id = ng_node2ID(node);
np->hooks = node->nd_numhooks;
+ KASSERT(nl->numnames < num, ("%s: no space",
+ __func__));
nl->numnames++;
}
}
- mtx_unlock(&ng_namehash_mtx);
+ NAMEHASH_RUNLOCK();
break;
}
@@ -2644,17 +2642,16 @@ ng_generic_msg(node_p here, item_p item,
struct ng_type *type;
int num = 0;
- mtx_lock(&ng_typelist_mtx);
+ TYPELIST_RLOCK();
/* Count number of types */
- LIST_FOREACH(type, &ng_typelist, types) {
+ LIST_FOREACH(type, &ng_typelist, types)
num++;
- }
- mtx_unlock(&ng_typelist_mtx);
/* Get response struct */
- NG_MKRESPONSE(resp, msg, sizeof(*tl)
- + (num * sizeof(struct typeinfo)), M_NOWAIT);
+ NG_MKRESPONSE(resp, msg, sizeof(*tl) +
+ (num * sizeof(struct typeinfo)), M_NOWAIT);
if (resp == NULL) {
+ TYPELIST_RUNLOCK();
error = ENOMEM;
break;
}
@@ -2662,20 +2659,15 @@ ng_generic_msg(node_p here, item_p item,
/* Cycle through the linked list of types */
tl->numtypes = 0;
- mtx_lock(&ng_typelist_mtx);
LIST_FOREACH(type, &ng_typelist, types) {
struct typeinfo *const tp = &tl->typeinfo[tl->numtypes];
- if (tl->numtypes >= num) {
- log(LOG_ERR, "%s: number of %s changed\n",
- __func__, "types");
- break;
- }
strcpy(tp->type_name, type->name);
tp->numnodes = type->refs - 1; /* don't count list */
+ KASSERT(tl->numtypes < num, ("%s: no space", __func__));
tl->numtypes++;
}
- mtx_unlock(&ng_typelist_mtx);
+ TYPELIST_RUNLOCK();
break;
}
@@ -2708,16 +2700,16 @@ ng_generic_msg(node_p here, item_p item,
bcopy(binary, ascii, sizeof(*binary));
/* Find command by matching typecookie and command number */
- for (c = here->nd_type->cmdlist;
- c != NULL && c->name != NULL; c++) {
- if (binary->header.typecookie == c->cookie
- && binary->header.cmd == c->cmd)
+ for (c = here->nd_type->cmdlist; c != NULL && c->name != NULL;
+ c++) {
+ if (binary->header.typecookie == c->cookie &&
+ binary->header.cmd == c->cmd)
break;
}
if (c == NULL || c->name == NULL) {
for (c = ng_generic_cmds; c->name != NULL; c++) {
- if (binary->header.typecookie == c->cookie
- && binary->header.cmd == c->cmd)
+ if (binary->header.typecookie == c->cookie &&
+ binary->header.cmd == c->cmd)
break;
}
if (c->name == NULL) {
@@ -2811,8 +2803,8 @@ ng_generic_msg(node_p here, item_p item,
if (argstype == NULL) {
bufSize = 0;
} else {
- if ((error = ng_parse(argstype, ascii->data,
- &off, (u_char *)binary->data, &bufSize)) != 0) {
+ if ((error = ng_parse(argstype, ascii->data, &off,
+ (u_char *)binary->data, &bufSize)) != 0) {
NG_FREE_MSG(resp);
break;
}
@@ -2843,7 +2835,7 @@ ng_generic_msg(node_p here, item_p item,
}
/*
* Sometimes a generic message may be statically allocated
- * to avoid problems with allocating when in tight memeory situations.
+ * to avoid problems with allocating when in tight memory situations.
* Don't free it if it is so.
* I break them appart here, because erros may cause a free if the item
* in which case we'd be doing it twice.
@@ -2877,7 +2869,7 @@ SYSCTL_INT(_net_graph, OID_AUTO, maxdata
#ifdef NETGRAPH_DEBUG
static TAILQ_HEAD(, ng_item) ng_itemlist = TAILQ_HEAD_INITIALIZER(ng_itemlist);
-static int allocated; /* number of items malloc'd */
+static int allocated; /* number of items malloc'd */
#endif
/*
@@ -2895,7 +2887,7 @@ ng_alloc_item(int type, int flags)
KASSERT(((type & ~NGQF_TYPE) == 0),
("%s: incorrect item type: %d", __func__, type));
- item = uma_zalloc((type == NGQF_DATA)?ng_qdzone:ng_qzone,
+ item = uma_zalloc((type == NGQF_DATA) ? ng_qdzone : ng_qzone,
((flags & NG_WAITOK) ? M_WAITOK : M_NOWAIT) | M_ZERO);
if (item) {
@@ -2951,8 +2943,8 @@ ng_free_item(item_p item)
allocated--;
mtx_unlock(&ngq_mtx);
#endif
- uma_zfree(((item->el_flags & NGQF_TYPE) == NGQF_DATA)?
- ng_qdzone:ng_qzone, item);
+ uma_zfree(((item->el_flags & NGQF_TYPE) == NGQF_DATA) ?
+ ng_qdzone : ng_qzone, item);
}
/*
@@ -2997,51 +2989,40 @@ int
ng_mod_event(module_t mod, int event, void *data)
{
struct ng_type *const type = data;
- int s, error = 0;
+ int error = 0;
switch (event) {
case MOD_LOAD:
/* Register new netgraph node type */
- s = splnet();
- if ((error = ng_newtype(type)) != 0) {
- splx(s);
+ if ((error = ng_newtype(type)) != 0)
break;
- }
/* Call type specific code */
if (type->mod_event != NULL)
if ((error = (*type->mod_event)(mod, event, data))) {
- mtx_lock(&ng_typelist_mtx);
+ TYPELIST_WLOCK();
type->refs--; /* undo it */
LIST_REMOVE(type, types);
- mtx_unlock(&ng_typelist_mtx);
+ TYPELIST_WUNLOCK();
}
- splx(s);
break;
case MOD_UNLOAD:
- s = splnet();
if (type->refs > 1) { /* make sure no nodes exist! */
error = EBUSY;
} else {
- if (type->refs == 0) {
- /* failed load, nothing to undo */
- splx(s);
+ if (type->refs == 0) /* failed load, nothing to undo */
break;
- }
if (type->mod_event != NULL) { /* check with type */
error = (*type->mod_event)(mod, event, data);
- if (error != 0) { /* type refuses.. */
- splx(s);
+ if (error != 0) /* type refuses.. */
break;
- }
}
- mtx_lock(&ng_typelist_mtx);
+ TYPELIST_WLOCK();
LIST_REMOVE(type, types);
- mtx_unlock(&ng_typelist_mtx);
+ TYPELIST_WUNLOCK();
}
- splx(s);
break;
default:
@@ -3054,7 +3035,7 @@ ng_mod_event(module_t mod, int event, vo
return (error);
}
-#ifdef VIMAGE
+#ifdef VIMAGE
static void
vnet_netgraph_uninit(const void *unused __unused)
{
@@ -3063,7 +3044,7 @@ vnet_netgraph_uninit(const void *unused
do {
/* Find a node to kill */
- mtx_lock(&ng_namehash_mtx);
+ NAMEHASH_RLOCK();
for (i = 0; i < NG_NAME_HASH_SIZE; i++) {
LIST_FOREACH(node, &V_ng_name_hash[i], nd_nodes) {
if (node != &ng_deadnode) {
@@ -3074,14 +3055,14 @@ vnet_netgraph_uninit(const void *unused
if (node != NULL)
break;
}
- mtx_unlock(&ng_namehash_mtx);
+ NAMEHASH_RUNLOCK();
/* Attempt to kill it only if it is a regular node */
if (node != NULL) {
if (node == last_killed) {
/* This should never happen */
- printf("ng node %s needs"
- "NGF_REALLY_DIE\n", node->nd_name);
+ printf("ng node %s needs NGF_REALLY_DIE\n",
+ node->nd_name);
if (node->nd_flags & NGF_REALLY_DIE)
panic("ng node %s won't die",
node->nd_name);
@@ -3112,12 +3093,9 @@ ngb_mod_event(module_t mod, int event, v
case MOD_LOAD:
/* Initialize everything. */
NG_WORKLIST_LOCK_INIT();
- mtx_init(&ng_typelist_mtx, "netgraph types mutex", NULL,
- MTX_DEF);
- mtx_init(&ng_idhash_mtx, "netgraph idhash mutex", NULL,
- MTX_DEF);
- mtx_init(&ng_namehash_mtx, "netgraph namehash mutex", NULL,
- MTX_DEF);
+ rw_init(&ng_typelist_lock, "netgraph types");
+ rw_init(&ng_idhash_lock, "netgraph idhash");
+ rw_init(&ng_namehash_lock, "netgraph namehash");
mtx_init(&ng_topo_mtx, "netgraph topology mutex", NULL,
MTX_DEF);
#ifdef NETGRAPH_DEBUG
@@ -3129,8 +3107,9 @@ ngb_mod_event(module_t mod, int event, v
ng_qzone = uma_zcreate("NetGraph items", sizeof(struct ng_item),
NULL, NULL, NULL, NULL, UMA_ALIGN_CACHE, 0);
uma_zone_set_max(ng_qzone, maxalloc);
- ng_qdzone = uma_zcreate("NetGraph data items", sizeof(struct ng_item),
- NULL, NULL, NULL, NULL, UMA_ALIGN_CACHE, 0);
+ ng_qdzone = uma_zcreate("NetGraph data items",
+ sizeof(struct ng_item), NULL, NULL, NULL, NULL,
+ UMA_ALIGN_CACHE, 0);
uma_zone_set_max(ng_qdzone, maxdata);
/* Autoconfigure number of threads. */
if (numthreads <= 0)
@@ -3176,6 +3155,9 @@ dumphook (hook_p hook, char *file, int l
hook->lastfile, hook->lastline);
if (line) {
printf(" problem discovered at file %s, line %d\n", file, line);
+#ifdef KDB
+ kdb_backtrace();
+#endif
}
}
@@ -3190,6 +3172,9 @@ dumpnode(node_p node, char *file, int li
node->lastfile, node->lastline);
if (line) {
printf(" problem discovered at file %s, line %d\n", file, line);
+#ifdef KDB
+ kdb_backtrace();
+#endif
}
}
@@ -3365,7 +3350,7 @@ ng_worklist_add(node_p node)
* then put us on.
*/
node->nd_input_queue.q_flags2 |= NGQ2_WORKQ;
- NG_NODE_REF(node); /* XXX fafe in mutex? */
+ NG_NODE_REF(node); /* XXX safe in mutex? */
NG_WORKLIST_LOCK();
STAILQ_INSERT_TAIL(&ng_worklist, node, nd_input_queue.q_work);
NG_WORKLIST_UNLOCK();
@@ -3493,8 +3478,7 @@ ng_address_hook(node_p here, item_p item
* that the peer node is present, though maybe invalid.
*/
mtx_lock(&ng_topo_mtx);
- if ((hook == NULL) ||
- NG_HOOK_NOT_VALID(hook) ||
+ if ((hook == NULL) || NG_HOOK_NOT_VALID(hook) ||
NG_HOOK_NOT_VALID(peer = NG_HOOK_PEER(hook)) ||
NG_NODE_NOT_VALID(peernode = NG_PEER_NODE(hook))) {
NG_FREE_ITEM(item);
@@ -3786,4 +3770,3 @@ ng_macro_test(item_p item)
NG_FWD_MSG_HOOK(error, node, item, hook, retaddr);
}
#endif /* TESTING */
-
Modified: stable/8/sys/netgraph/ng_socket.c
==============================================================================
--- stable/8/sys/netgraph/ng_socket.c Tue Feb 14 17:18:45 2012 (r231695)
+++ stable/8/sys/netgraph/ng_socket.c Tue Feb 14 17:35:44 2012 (r231696)
@@ -51,6 +51,7 @@
#include <sys/param.h>
#include <sys/domain.h>
+#include <sys/hash.h>
#include <sys/kernel.h>
#include <sys/linker.h>
#include <sys/lock.h>
@@ -64,9 +65,6 @@
#include <sys/socketvar.h>
#include <sys/syscallsubr.h>
#include <sys/sysctl.h>
-#ifdef NOTYET
-#include <sys/vnode.h>
-#endif
#include <net/vnet.h>
@@ -115,6 +113,7 @@ static ng_rcvmsg_t ngs_rcvmsg;
static ng_shutdown_t ngs_shutdown;
static ng_newhook_t ngs_newhook;
static ng_connect_t ngs_connect;
+static ng_findhook_t ngs_findhook;
static ng_rcvdata_t ngs_rcvdata;
static ng_disconnect_t ngs_disconnect;
@@ -124,9 +123,6 @@ static int ng_attach_cntl(struct socket
static int ng_attach_common(struct socket *so, int type);
static void ng_detach_common(struct ngpcb *pcbp, int type);
static void ng_socket_free_priv(struct ngsock *priv);
-#ifdef NOTYET
-static int ng_internalize(struct mbuf *m, struct thread *p);
-#endif
static int ng_connect_data(struct sockaddr *nam, struct ngpcb *pcbp);
static int ng_bind(struct sockaddr *nam, struct ngpcb *pcbp);
@@ -143,6 +139,7 @@ static struct ng_type typestruct = {
.shutdown = ngs_shutdown,
.newhook = ngs_newhook,
.connect = ngs_connect,
+ .findhook = ngs_findhook,
.rcvdata = ngs_rcvdata,
.disconnect = ngs_disconnect,
};
@@ -209,19 +206,10 @@ ngc_send(struct socket *so, int flags, s
int len, error = 0;
struct ng_apply_info apply;
-#ifdef NOTYET
- if (control && (error = ng_internalize(control, td))) {
- if (pcbp->sockdata == NULL) {
- error = ENOTCONN;
- goto release;
- }
- }
-#else /* NOTYET */
if (control) {
error = EINVAL;
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-all
mailing list