From owner-p4-projects@FreeBSD.ORG Wed Jun 10 17:38:53 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id E84781065673; Wed, 10 Jun 2009 17:38:52 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A79BC1065672 for ; Wed, 10 Jun 2009 17:38:52 +0000 (UTC) (envelope-from zec@fer.hr) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 956758FC13 for ; Wed, 10 Jun 2009 17:38:52 +0000 (UTC) (envelope-from zec@fer.hr) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n5AHcqj3017799 for ; Wed, 10 Jun 2009 17:38:52 GMT (envelope-from zec@fer.hr) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n5AHcpYP017797 for perforce@freebsd.org; Wed, 10 Jun 2009 17:38:51 GMT (envelope-from zec@fer.hr) Date: Wed, 10 Jun 2009 17:38:51 GMT Message-Id: <200906101738.n5AHcpYP017797@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to zec@fer.hr using -f From: Marko Zec To: Perforce Change Reviews Cc: Subject: PERFORCE change 164019 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 10 Jun 2009 17:38:54 -0000 http://perforce.freebsd.org/chv.cgi?CH=164019 Change 164019 by zec@zec_tpx32 on 2009/06/10 17:38:06 Detect calls from outbound path of the network stack when reentering the inbound path from netgraph, and in such cases queue netisrs, instead of direct dispatching them. Affected files ... .. //depot/projects/vimage-commit2/src/sys/netgraph/netgraph.h#26 edit .. //depot/projects/vimage-commit2/src/sys/netgraph/ng_base.c#34 edit .. //depot/projects/vimage-commit2/src/sys/netgraph/ng_eiface.c#24 edit .. //depot/projects/vimage-commit2/src/sys/netgraph/ng_ether.c#16 edit .. //depot/projects/vimage-commit2/src/sys/netgraph/ng_iface.c#22 edit .. //depot/projects/vimage-commit2/src/sys/netgraph/ng_ip_input.c#3 edit .. //depot/projects/vimage-commit2/src/sys/sys/proc.h#19 edit Differences ... ==== //depot/projects/vimage-commit2/src/sys/netgraph/netgraph.h#26 (text+ko) ==== @@ -1205,6 +1205,20 @@ #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, \ ==== //depot/projects/vimage-commit2/src/sys/netgraph/ng_base.c#34 (text+ko) ==== @@ -2219,9 +2219,8 @@ */ if ((flags & NG_QUEUE) || (hook && (hook->hk_flags & HK_QUEUE))) { queue = 1; - } else if (hook && (hook->hk_flags & HK_TO_INBOUND) /* && - (curthread->td_flags & TDF_NG_OUTBOUND) */) { -printf("ng queuing: td_flags = %X\n", curthread->td_flags); + } else if (hook && (hook->hk_flags & HK_TO_INBOUND) && + curthread->td_ng_outbound) { queue = 1; } else { queue = 0; ==== //depot/projects/vimage-commit2/src/sys/netgraph/ng_eiface.c#24 (text+ko) ==== @@ -95,7 +95,6 @@ static ng_rcvmsg_t ng_eiface_rcvmsg; static ng_shutdown_t ng_eiface_rmnode; static ng_newhook_t ng_eiface_newhook; -static ng_connect_t ng_eiface_connect; static ng_rcvdata_t ng_eiface_rcvdata; static ng_disconnect_t ng_eiface_disconnect; @@ -108,7 +107,6 @@ .rcvmsg = ng_eiface_rcvmsg, .shutdown = ng_eiface_rmnode, .newhook = ng_eiface_newhook, - .connect = ng_eiface_connect, .rcvdata = ng_eiface_rcvdata, .disconnect = ng_eiface_disconnect, .cmdlist = ng_eiface_cmdlist @@ -263,7 +261,9 @@ * 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) @@ -416,6 +416,7 @@ 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); @@ -423,19 +424,6 @@ } /* - * Mark a hook as leading to inbound path of the network stack, so - * that framework can queue calls to us that arrived from the outbound - * path. - */ -static int -ng_eiface_connect(hook_p hook) -{ - - NG_HOOK_SET_TO_INBOUND(hook); - return (0); -} - -/* * Receive a control message */ static int ==== //depot/projects/vimage-commit2/src/sys/netgraph/ng_ether.c#16 (text+ko) ==== @@ -263,7 +263,9 @@ m_freem(m); return; } + NG_OUTBOUND_THREAD_REF(); NG_SEND_DATA_ONLY(error, priv->orphan, m); + NG_OUTBOUND_THREAD_UNREF(); } /* @@ -282,7 +284,9 @@ 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 +420,7 @@ 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); ==== //depot/projects/vimage-commit2/src/sys/netgraph/ng_iface.c#22 (text+ko) ==== @@ -482,9 +482,10 @@ /* 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 @@ return (EISCONN); *hookptr = hook; NG_HOOK_HI_STACK(hook); + NG_HOOK_SET_TO_INBOUND(hook); return (0); } ==== //depot/projects/vimage-commit2/src/sys/netgraph/ng_ip_input.c#3 (text+ko) ==== @@ -77,6 +77,7 @@ #include #include #include +#include #include #include #include @@ -120,7 +121,10 @@ 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; } ==== //depot/projects/vimage-commit2/src/sys/sys/proc.h#19 (text+ko) ==== @@ -235,6 +235,7 @@ 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 @@ -277,8 +278,8 @@ struct lpohead td_lprof[2]; /* (a) lock profiling objects. */ struct kdtrace_thread *td_dtrace; /* (*) DTrace-specific data. */ int td_errno; /* Error returned by last syscall. */ - struct vnet *td_vnet; /* (*) Effective vnet. */ - const char *td_vnet_lpush; /* (*) Debugging vnet push / pop. */ + struct vnet *td_vnet; /* (k) Effective vnet. */ + const char *td_vnet_lpush; /* (k) Debugging vnet push / pop. */ }; struct mtx *thread_lock_block(struct thread *); @@ -319,7 +320,7 @@ #define TDF_BOUNDARY 0x00000400 /* Thread suspended at user boundary */ #define TDF_ASTPENDING 0x00000800 /* Thread has some asynchronous events. */ #define TDF_TIMOFAIL 0x00001000 /* Timeout from sleep after we were awake. */ -#define TDF_NG_OUTBOUND 0x00002000 /* Thread called into ng from ntw stack. */ +#define TDF_UNUSED2000 0x00002000 /* --available-- */ #define TDF_UPIBLOCKED 0x00004000 /* Thread blocked on user PI mutex. */ #define TDF_NEEDSUSPCHK 0x00008000 /* Thread may need to suspend. */ #define TDF_NEEDRESCHED 0x00010000 /* Thread needs to yield. */