From owner-svn-src-all@FreeBSD.ORG Sat Jun 15 05:57:30 2013 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id 81C5BB48; Sat, 15 Jun 2013 05:57:30 +0000 (UTC) (envelope-from lstewart@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 749521AAA; Sat, 15 Jun 2013 05:57:30 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r5F5vUpb042856; Sat, 15 Jun 2013 05:57:30 GMT (envelope-from lstewart@svn.freebsd.org) Received: (from lstewart@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r5F5vTmj042854; Sat, 15 Jun 2013 05:57:29 GMT (envelope-from lstewart@svn.freebsd.org) Message-Id: <201306150557.r5F5vTmj042854@svn.freebsd.org> From: Lawrence Stewart Date: Sat, 15 Jun 2013 05:57:29 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r251774 - head/sys/kern X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 15 Jun 2013 05:57:30 -0000 Author: lstewart Date: Sat Jun 15 05:57:29 2013 New Revision: 251774 URL: http://svnweb.freebsd.org/changeset/base/251774 Log: Add a private KPI between hhook and khelp that allows khelp modules to insert hook functions into hhook points which register after the modules were loaded - potentially useful during boot or if hhook points are dynamically registered. MFC after: 1 week Modified: head/sys/kern/kern_hhook.c head/sys/kern/kern_khelp.c Modified: head/sys/kern/kern_hhook.c ============================================================================== --- head/sys/kern/kern_hhook.c Sat Jun 15 05:04:14 2013 (r251773) +++ head/sys/kern/kern_hhook.c Sat Jun 15 05:57:29 2013 (r251774) @@ -74,6 +74,7 @@ static uint32_t n_hhookheads; /* Private function prototypes. */ static void hhook_head_destroy(struct hhook_head *hhh); +void khelp_new_hhook_registered(struct hhook_head *hhh, uint32_t flags); #define HHHLIST_LOCK() mtx_lock(&hhook_head_list_lock) #define HHHLIST_UNLOCK() mtx_unlock(&hhook_head_list_lock) @@ -311,12 +312,7 @@ hhook_head_register(int32_t hhook_type, tmphhh->hhh_nhooks = 0; STAILQ_INIT(&tmphhh->hhh_hooks); HHH_LOCK_INIT(tmphhh); - - if (hhh != NULL) { - refcount_init(&tmphhh->hhh_refcount, 1); - *hhh = tmphhh; - } else - refcount_init(&tmphhh->hhh_refcount, 0); + refcount_init(&tmphhh->hhh_refcount, 1); HHHLIST_LOCK(); if (flags & HHOOK_HEADISINVNET) { @@ -331,6 +327,13 @@ hhook_head_register(int32_t hhook_type, n_hhookheads++; HHHLIST_UNLOCK(); + khelp_new_hhook_registered(tmphhh, flags); + + if (hhh != NULL) + *hhh = tmphhh; + else + refcount_release(&tmphhh->hhh_refcount); + return (0); } Modified: head/sys/kern/kern_khelp.c ============================================================================== --- head/sys/kern/kern_khelp.c Sat Jun 15 05:04:14 2013 (r251773) +++ head/sys/kern/kern_khelp.c Sat Jun 15 05:57:29 2013 (r251774) @@ -40,7 +40,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include @@ -52,8 +51,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include - static struct rwlock khelp_list_lock; RW_SYSINIT(khelplistlock, &khelp_list_lock, "helper list lock"); @@ -61,6 +58,7 @@ static TAILQ_HEAD(helper_head, helper) h /* Private function prototypes. */ static inline void khelp_remove_osd(struct helper *h, struct osd *hosd); +void khelp_new_hhook_registered(struct hhook_head *hhh, uint32_t flags); #define KHELP_LIST_WLOCK() rw_wlock(&khelp_list_lock) #define KHELP_LIST_WUNLOCK() rw_wunlock(&khelp_list_lock) @@ -289,6 +287,36 @@ khelp_remove_hhook(struct hookinfo *hki) return (error); } +/* + * Private KPI between hhook and khelp that allows khelp modules to insert hook + * functions into hhook points which register after the modules were loaded. + */ +void +khelp_new_hhook_registered(struct hhook_head *hhh, uint32_t flags) +{ + struct helper *h; + int error, i; + + KHELP_LIST_RLOCK(); + TAILQ_FOREACH(h, &helpers, h_next) { + for (i = 0; i < h->h_nhooks; i++) { + if (hhh->hhh_type != h->h_hooks[i].hook_type || + hhh->hhh_id != h->h_hooks[i].hook_id) + continue; + error = hhook_add_hook(hhh, &h->h_hooks[i], flags); + if (error) { + printf("%s: \"%s\" khelp module unable to " + "hook type %d id %d due to error %d\n", + __func__, h->h_name, + h->h_hooks[i].hook_type, + h->h_hooks[i].hook_id, error); + error = 0; + } + } + } + KHELP_LIST_RUNLOCK(); +} + int khelp_modevent(module_t mod, int event_type, void *data) { @@ -348,95 +376,3 @@ khelp_modevent(module_t mod, int event_t return (error); } - -/* - * This function is called in two separate situations: - * - * - When the kernel is booting, it is called directly by the SYSINIT framework - * to allow Khelp modules which were compiled into the kernel or loaded by the - * boot loader to insert their non-virtualised hook functions into the kernel. - * - * - When the kernel is booting or a vnet is created, this function is also - * called indirectly through khelp_vnet_init() by the vnet initialisation code. - * In this situation, Khelp modules are able to insert their virtualised hook - * functions into the virtualised hook points in the vnet which is being - * initialised. In the case where the kernel is not compiled with "options - * VIMAGE", this step is still run once at boot, but the hook functions get - * transparently inserted into the standard unvirtualised network stack. - */ -static void -khelp_init(const void *vnet) -{ - struct helper *h; - int error, i, vinit; - int32_t htype, hid; - - error = 0; - vinit = vnet != NULL; - - KHELP_LIST_RLOCK(); - TAILQ_FOREACH(h, &helpers, h_next) { - for (i = 0; i < h->h_nhooks && !error; i++) { - htype = h->h_hooks[i].hook_type; - hid = h->h_hooks[i].hook_id; - - /* - * If we're doing a virtualised init (vinit != 0) and - * the hook point is virtualised, or we're doing a plain - * sysinit at boot and the hook point is not - * virtualised, insert the hook. - */ - if ((hhook_head_is_virtualised_lookup(htype, hid) == - HHOOK_HEADISINVNET && vinit) || - (!hhook_head_is_virtualised_lookup(htype, hid) && - !vinit)) { - error = hhook_add_hook_lookup(&h->h_hooks[i], - HHOOK_NOWAIT); - } - } - - if (error) { - /* Remove any helper's hooks we successfully added. */ - for (i--; i >= 0; i--) - hhook_remove_hook_lookup(&h->h_hooks[i]); - - printf("%s: Failed to add hooks for helper \"%s\" (%p)", - __func__, h->h_name, h); - if (vinit) - printf(" to vnet %p.\n", vnet); - else - printf(".\n"); - - error = 0; - } - } - KHELP_LIST_RUNLOCK(); -} - -/* - * Vnet created and being initialised. - */ -static void -khelp_vnet_init(const void *unused __unused) -{ - - khelp_init(TD_TO_VNET(curthread)); -} - - -/* - * As the kernel boots, allow Khelp modules which were compiled into the kernel - * or loaded by the boot loader to insert their non-virtualised hook functions - * into the kernel. - */ -SYSINIT(khelp_init, SI_SUB_PROTO_END, SI_ORDER_FIRST, khelp_init, NULL); - -/* - * When a vnet is created and being initialised, we need to insert the helper - * hook functions for all currently registered Khelp modules into the vnet's - * helper hook points. The hhook KPI provides a mechanism for subsystems which - * export helper hook points to clean up on vnet shutdown, so we don't need a - * VNET_SYSUNINIT for Khelp. - */ -VNET_SYSINIT(khelp_vnet_init, SI_SUB_PROTO_END, SI_ORDER_FIRST, - khelp_vnet_init, NULL);