Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

HEADS UP: struct thread changed (Fwd: svn commit: r194012)

5 views
Skip to first unread message

Marko Zec

unread,
Jun 11, 2009, 1:43:57 PM6/11/09
to
--Boundary-00=_kpTMKq6v65aiW9y
Content-Type: text/plain;
charset="us-ascii"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

Note that svn r194012 changed the layout of struct thread, but because of
__FreeBSD_version number shortage a version bump has not been performed at
this time. Nevertheless, be advised that both the kernel and the modules
have to be rebuilt.

Discussed with: rwatson, bz, julian

Cheers,

Marko

--Boundary-00=_kpTMKq6v65aiW9y
Content-Type: message/rfc822;
name="forwarded message"
Content-Transfer-Encoding: 7bit
Content-Description: Marko Zec <z...@freebsd.org>: svn commit: r194012 - in
head: . sys/netgraph sys/sys
Content-Disposition: inline

Return-Path: <owner-src-...@freebsd.org>
Received: from fruitcake.ICSI.Berkeley.EDU (fruitcake.ICSI.Berkeley.EDU
[192.150.186.11])
by imunes.tel.fer.hr (8.13.8/8.13.8) with ESMTP id n5BGp7f2036400
for <ma...@imunes.tel.fer.hr>; Thu, 11 Jun 2009 18:51:08 +0200 (CEST)
(envelope-from owner-src-...@freebsd.org)
Received: from mx2.freebsd.org (mx2.freebsd.org [69.147.83.53])
by fruitcake.ICSI.Berkeley.EDU (8.12.11.20060614/8.12.11) with ESMTP id
n5BGp6Jb021022
for <z...@icsi.berkeley.edu>; Thu, 11 Jun 2009 09:51:07 -0700 (PDT)
Received: from hub.freebsd.org (hub.freebsd.org [IPv6:2001:4f8:fff6::36])
by mx2.freebsd.org (Postfix) with ESMTP id CAEDC158C4E
for <z...@icsi.berkeley.edu>; Thu, 11 Jun 2009 16:50:59 +0000 (UTC)
(envelope-from owner-src-...@FreeBSD.org)
Received: by hub.freebsd.org (Postfix)
id D5B4F1065789; Thu, 11 Jun 2009 16:50:56 +0000 (UTC)
Delivered-To: z...@freebsd.org
Received: by hub.freebsd.org (Postfix, from userid 538)
id 2C14110656AE; Thu, 11 Jun 2009 16:50:56 +0000 (UTC)
Delivered-To: src-com...@freebsd.org
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
by hub.freebsd.org (Postfix) with ESMTP id 724651065696;
Thu, 11 Jun 2009 16:50:50 +0000 (UTC) (envelope-from z...@FreeBSD.org)
Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c])
by mx1.freebsd.org (Postfix) with ESMTP id 5F05A8FC08;
Thu, 11 Jun 2009 16:50:50 +0000 (UTC) (envelope-from z...@FreeBSD.org)
Received: from svn.freebsd.org (localhost [127.0.0.1])
by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n5BGookv053454;
Thu, 11 Jun 2009 16:50:50 GMT (envelope-from z...@svn.freebsd.org)
Received: (from zec@localhost)
by svn.freebsd.org (8.14.3/8.14.3/Submit) id n5BGonnn053446;
Thu, 11 Jun 2009 16:50:49 GMT (envelope-from z...@svn.freebsd.org)
Message-Id: <200906111650....@svn.freebsd.org>
From: Marko Zec <z...@freebsd.org>
Date: Thu, 11 Jun 2009 16:50:49 +0000 (UTC)
To: src-com...@freebsd.org, svn-s...@freebsd.org,
svn-sr...@freebsd.org
Subject: svn commit: r194012 - in head: . sys/netgraph sys/sys
X-SVN-Group: head
MIME-Version: 1.0
Content-Type: text/plain;
charset=UTF-8
Content-Transfer-Encoding: 8bit
Sender: owner-src-...@freebsd.org
Precedence: bulk
X-Loop: FreeBSD.ORG
X-Spam-Status: No, score=0.0 required=5.1 tests=none autolearn=failed
version=3.1.6
X-Spam-Checker-Version: SpamAssassin 3.1.6 (2006-10-03) on imunes.tel.fer.hr
X-UIDL: ]-a"!E]R!!~?D!!AYK"!

Author: zec
Date: Thu Jun 11 16:50:49 2009
New Revision: 194012
URL: http://svn.freebsd.org/changeset/base/194012

Log:
Introduce a mechanism for detecting calls from outbound path of the
network stack when reentering the inbound path from netgraph, and
force queueing of mbufs at the outbound netgraph node.

The mechanism relies on two components. First, in netgraph nodes
where outbound path of the network stack calls into netgraph, the
current thread has to be appropriately marked using the new
NG_OUTBOUND_THREAD_REF() macro before proceeding to call further
into the netgraph topology, and unmarked using the
NG_OUTBOUND_THREAD_UNREF() macro before returning to the caller.
Second, netgraph nodes which can potentially reenter the network
stack in the inbound path have to mark their inbound hooks using
NG_HOOK_SET_TO_INBOUND() macro. The netgraph framework will then
detect when there is a danger of a call graph looping back from
outbound to inbound path via netgraph, and defer handing off the
mbufs to the "inbound" node to a worker thread with a clean stack.

In this first pass only the most obvious netgraph nodes have been
updated to ensure no outbound to inbound calls can occur. Nodes
such as ng_ipfw, ng_gif etc. should be further examined whether a
potential for outbound to inbound call looping exists.

This commit changes the layout of struct thread, but due to
__FreeBSD_version number shortage a version bump has been omitted
at this time, nevertheless kernel and modules have to be rebuilt.

Reviewed by: julian, rwatson, bz
Approved by: julian (mentor)

Modified:
head/UPDATING
head/sys/netgraph/netgraph.h
head/sys/netgraph/ng_base.c
head/sys/netgraph/ng_eiface.c
head/sys/netgraph/ng_ether.c
head/sys/netgraph/ng_iface.c
head/sys/netgraph/ng_ip_input.c
head/sys/sys/proc.h

Modified: head/UPDATING
==============================================================================
--- head/UPDATING Thu Jun 11 16:48:59 2009 (r194011)
+++ head/UPDATING Thu Jun 11 16:50:49 2009 (r194012)
@@ -22,6 +22,10 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.
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.

Modified: head/sys/netgraph/netgraph.h
==============================================================================
--- head/sys/netgraph/netgraph.h Thu Jun 11 16:48:59 2009 (r194011)
+++ head/sys/netgraph/netgraph.h Thu Jun 11 16:50:49 2009 (r194012)
@@ -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'
#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(ho
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 *
}

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 * fi
#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 * fi
#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, \

Modified: head/sys/netgraph/ng_base.c
==============================================================================
--- head/sys/netgraph/ng_base.c Thu Jun 11 16:48:59 2009 (r194011)
+++ head/sys/netgraph/ng_base.c Thu Jun 11 16:50:49 2009 (r194012)
@@ -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

Modified: head/sys/netgraph/ng_eiface.c
==============================================================================
--- head/sys/netgraph/ng_eiface.c Thu Jun 11 16:48:59 2009 (r194011)
+++ head/sys/netgraph/ng_eiface.c Thu Jun 11 16:50:49 2009 (r194012)
@@ -261,7 +261,9 @@ ng_eiface_start2(node_p node, hook_p hoo
* 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 ho
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);

Modified: head/sys/netgraph/ng_ether.c
==============================================================================
--- head/sys/netgraph/ng_ether.c Thu Jun 11 16:48:59 2009 (r194011)
+++ head/sys/netgraph/ng_ether.c Thu Jun 11 16:50:49 2009 (r194012)
@@ -282,7 +282,9 @@ ng_ether_output(struct ifnet *ifp, struc
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 hoo
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);

Modified: head/sys/netgraph/ng_iface.c
==============================================================================
--- head/sys/netgraph/ng_iface.c Thu Jun 11 16:48:59 2009 (r194011)
+++ head/sys/netgraph/ng_iface.c Thu Jun 11 16:50:49 2009 (r194012)
@@ -482,9 +482,10 @@ ng_iface_send(struct ifnet *ifp, struct
/* 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 hoo
return (EISCONN);
*hookptr = hook;
NG_HOOK_HI_STACK(hook);
+ NG_HOOK_SET_TO_INBOUND(hook);
return (0);
}

Modified: head/sys/netgraph/ng_ip_input.c
==============================================================================
--- head/sys/netgraph/ng_ip_input.c Thu Jun 11 16:48:59 2009 (r194011)
+++ head/sys/netgraph/ng_ip_input.c Thu Jun 11 16:50:49 2009 (r194012)
@@ -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;
}

Modified: head/sys/sys/proc.h
==============================================================================
--- head/sys/sys/proc.h Thu Jun 11 16:48:59 2009 (r194011)
+++ head/sys/sys/proc.h Thu Jun 11 16:50:49 2009 (r194012)
@@ -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


--Boundary-00=_kpTMKq6v65aiW9y
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
freebsd...@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-curre...@freebsd.org"
--Boundary-00=_kpTMKq6v65aiW9y--

0 new messages