diff options
-rw-r--r-- | UPDATING | 4 | ||||
-rw-r--r-- | sys/netgraph/netgraph.h | 33 | ||||
-rw-r--r-- | sys/netgraph/ng_base.c | 6 | ||||
-rw-r--r-- | sys/netgraph/ng_eiface.c | 3 | ||||
-rw-r--r-- | sys/netgraph/ng_ether.c | 3 | ||||
-rw-r--r-- | sys/netgraph/ng_iface.c | 6 | ||||
-rw-r--r-- | sys/netgraph/ng_ip_input.c | 6 | ||||
-rw-r--r-- | sys/sys/proc.h | 1 |
8 files changed, 56 insertions, 6 deletions
@@ -22,6 +22,10 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.x IS SLOW: to maximize performance. (To disable malloc debugging, run ln -s aj /etc/malloc.conf.) +20090611: + The layout of struct thread has changed. Kernel and modules + need to be rebuilt. + 20090608: The layout of structs ifnet, domain, protosw and vnet_net has changed. Kernel modules need to be rebuilt. diff --git a/sys/netgraph/netgraph.h b/sys/netgraph/netgraph.h index 7276427..5a0418e 100644 --- a/sys/netgraph/netgraph.h +++ b/sys/netgraph/netgraph.h @@ -130,6 +130,7 @@ struct ng_hook { #define HK_FORCE_WRITER 0x0004 /* Incoming data queued as a writer */ #define HK_DEAD 0x0008 /* This is the dead hook.. don't free */ #define HK_HI_STACK 0x0010 /* Hook has hi stack usage */ +#define HK_TO_INBOUND 0x0020 /* Hook on ntw. stack inbound path. */ /* * Public Methods for hook @@ -150,6 +151,8 @@ void ng_unref_hook(hook_p hook); /* don't move this */ #define _NG_HOOK_FORCE_WRITER(hook) \ do { hook->hk_flags |= HK_FORCE_WRITER; } while (0) #define _NG_HOOK_FORCE_QUEUE(hook) do { hook->hk_flags |= HK_QUEUE; } while (0) +#define _NG_HOOK_SET_TO_INBOUND(hook) \ + do { hook->hk_flags |= HK_TO_INBOUND; } while (0) #define _NG_HOOK_HI_STACK(hook) do { hook->hk_flags |= HK_HI_STACK; } while (0) /* Some shortcuts */ @@ -176,8 +179,11 @@ static __inline int _ng_hook_is_valid(hook_p hook, char * file, int line); static __inline node_p _ng_hook_node(hook_p hook, char * file, int line); static __inline hook_p _ng_hook_peer(hook_p hook, char * file, int line); static __inline void _ng_hook_force_writer(hook_p hook, char * file, - int line); -static __inline void _ng_hook_force_queue(hook_p hook, char * file, int line); + int line); +static __inline void _ng_hook_force_queue(hook_p hook, char * file, + int line); +static __inline void _ng_hook_set_to_inbound(hook_p hook, char * file, + int line); static __inline void _chkhook(hook_p hook, char *file, int line) @@ -282,6 +288,13 @@ _ng_hook_force_queue(hook_p hook, char * file, int line) } static __inline void +_ng_hook_set_to_inbound(hook_p hook, char * file, int line) +{ + _chkhook(hook, file, line); + _NG_HOOK_SET_TO_INBOUND(hook); +} + +static __inline void _ng_hook_hi_stack(hook_p hook, char * file, int line) { _chkhook(hook, file, line); @@ -302,6 +315,7 @@ _ng_hook_hi_stack(hook_p hook, char * file, int line) #define NG_HOOK_PEER(hook) _ng_hook_peer(hook, _NN_) #define NG_HOOK_FORCE_WRITER(hook) _ng_hook_force_writer(hook, _NN_) #define NG_HOOK_FORCE_QUEUE(hook) _ng_hook_force_queue(hook, _NN_) +#define NG_HOOK_SET_TO_INBOUND(hook) _ng_hook_set_to_inbound(hook, _NN_) #define NG_HOOK_HI_STACK(hook) _ng_hook_hi_stack(hook, _NN_) #else /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ @@ -319,6 +333,7 @@ _ng_hook_hi_stack(hook_p hook, char * file, int line) #define NG_HOOK_PEER(hook) _NG_HOOK_PEER(hook) #define NG_HOOK_FORCE_WRITER(hook) _NG_HOOK_FORCE_WRITER(hook) #define NG_HOOK_FORCE_QUEUE(hook) _NG_HOOK_FORCE_QUEUE(hook) +#define NG_HOOK_SET_TO_INBOUND(hook) _NG_HOOK_SET_TO_INBOUND(hook) #define NG_HOOK_HI_STACK(hook) _NG_HOOK_HI_STACK(hook) #endif /* NETGRAPH_DEBUG */ /*----------------------------------------------*/ @@ -1189,6 +1204,20 @@ typedef void *meta_p; #define NG_ID_HASH_SIZE 128 /* most systems wont need even this many */ #define NG_NAME_HASH_SIZE 128 /* most systems wont need even this many */ +/* + * Mark the current thread when called from the outbound path of the + * network stack, in order to enforce queuing on ng nodes calling into + * the inbound network stack path. + */ +#define NG_OUTBOUND_THREAD_REF() \ + curthread->td_ng_outbound++ +#define NG_OUTBOUND_THREAD_UNREF() \ + do { \ + curthread->td_ng_outbound--; \ + KASSERT(curthread->td_ng_outbound >= 0, \ + ("%s: negative td_ng_outbound", __func__)); \ + } while (0) + /* Virtualization macros */ #define INIT_VNET_NETGRAPH(vnet) \ INIT_FROM_VNET(vnet, VNET_MOD_NETGRAPH, \ diff --git a/sys/netgraph/ng_base.c b/sys/netgraph/ng_base.c index 39084b5..a495701 100644 --- a/sys/netgraph/ng_base.c +++ b/sys/netgraph/ng_base.c @@ -2213,11 +2213,15 @@ ng_snd_item(item_p item, int flags) } /* - * If sender or receiver requests queued delivery or stack usage + * If sender or receiver requests queued delivery, or call graph + * loops back from outbound to inbound path, or stack usage * level is dangerous - enqueue message. */ if ((flags & NG_QUEUE) || (hook && (hook->hk_flags & HK_QUEUE))) { queue = 1; + } else if (hook && (hook->hk_flags & HK_TO_INBOUND) && + curthread->td_ng_outbound) { + queue = 1; } else { queue = 0; #ifdef GET_STACK_USAGE diff --git a/sys/netgraph/ng_eiface.c b/sys/netgraph/ng_eiface.c index 615d10d..5474798 100644 --- a/sys/netgraph/ng_eiface.c +++ b/sys/netgraph/ng_eiface.c @@ -261,7 +261,9 @@ ng_eiface_start2(node_p node, hook_p hook, void *arg1, int arg2) * Send packet; if hook is not connected, mbuf will get * freed. */ + NG_OUTBOUND_THREAD_REF(); NG_SEND_DATA_ONLY(error, priv->ether, m); + NG_OUTBOUND_THREAD_UNREF(); /* Update stats */ if (error == 0) @@ -414,6 +416,7 @@ ng_eiface_newhook(node_p node, hook_p hook, const char *name) return (EISCONN); priv->ether = hook; NG_HOOK_SET_PRIVATE(hook, &priv->ether); + NG_HOOK_SET_TO_INBOUND(hook); if_link_state_change(ifp, LINK_STATE_UP); diff --git a/sys/netgraph/ng_ether.c b/sys/netgraph/ng_ether.c index 679c4e9..d009e00 100644 --- a/sys/netgraph/ng_ether.c +++ b/sys/netgraph/ng_ether.c @@ -282,7 +282,9 @@ ng_ether_output(struct ifnet *ifp, struct mbuf **mp) return (0); /* Send it out "upper" hook */ + NG_OUTBOUND_THREAD_REF(); NG_SEND_DATA_ONLY(error, priv->upper, *mp); + NG_OUTBOUND_THREAD_UNREF(); return (error); } @@ -416,6 +418,7 @@ ng_ether_newhook(node_p node, hook_p hook, const char *name) if (strcmp(name, NG_ETHER_HOOK_UPPER) == 0) { hookptr = &priv->upper; NG_HOOK_SET_RCVDATA(hook, ng_ether_rcv_upper); + NG_HOOK_SET_TO_INBOUND(hook); } else if (strcmp(name, NG_ETHER_HOOK_LOWER) == 0) { hookptr = &priv->lower; NG_HOOK_SET_RCVDATA(hook, ng_ether_rcv_lower); diff --git a/sys/netgraph/ng_iface.c b/sys/netgraph/ng_iface.c index 385750c..d6e3d64 100644 --- a/sys/netgraph/ng_iface.c +++ b/sys/netgraph/ng_iface.c @@ -482,9 +482,10 @@ ng_iface_send(struct ifnet *ifp, struct mbuf *m, sa_family_t sa) /* Copy length before the mbuf gets invalidated. */ len = m->m_pkthdr.len; - /* Send packet. If hook is not connected, - mbuf will get freed. */ + /* Send packet. If hook is not connected, mbuf will get freed. */ + NG_OUTBOUND_THREAD_REF(); NG_SEND_DATA_ONLY(error, *get_hook_from_iffam(priv, iffam), m); + NG_OUTBOUND_THREAD_UNREF(); /* Update stats. */ if (error == 0) { @@ -610,6 +611,7 @@ ng_iface_newhook(node_p node, hook_p hook, const char *name) return (EISCONN); *hookptr = hook; NG_HOOK_HI_STACK(hook); + NG_HOOK_SET_TO_INBOUND(hook); return (0); } diff --git a/sys/netgraph/ng_ip_input.c b/sys/netgraph/ng_ip_input.c index 416bc12..af0254b 100644 --- a/sys/netgraph/ng_ip_input.c +++ b/sys/netgraph/ng_ip_input.c @@ -77,6 +77,7 @@ #include <sys/malloc.h> #include <sys/mbuf.h> #include <sys/socket.h> +#include <sys/proc.h> #include <net/if.h> #include <net/if_types.h> #include <net/if_var.h> @@ -120,7 +121,10 @@ ngipi_rcvdata(hook_p hook, item_p item) NGI_GET_M(item, m); NG_FREE_ITEM(item); - netisr_dispatch(NETISR_IP, m); + if (curthread->td_ng_outbound) + netisr_queue(NETISR_IP, m); + else + netisr_dispatch(NETISR_IP, m); return 0; } diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 96f811d..1dd82ed 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -235,6 +235,7 @@ struct thread { char td_name[MAXCOMLEN + 1]; /* (*) Thread name. */ struct file *td_fpop; /* (k) file referencing cdev under op */ int td_dbgflags; /* (c) Userland debugger flags */ + int td_ng_outbound; /* (k) Thread entered ng from above. */ struct osd td_osd; /* (k) Object specific data. */ #define td_endzero td_base_pri |