From owner-svn-src-head@FreeBSD.ORG Sun Apr 26 07:09:39 2009 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B8F8E106566B; Sun, 26 Apr 2009 07:09:39 +0000 (UTC) (envelope-from zec@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 9C6F18FC14; Sun, 26 Apr 2009 07:09:39 +0000 (UTC) (envelope-from zec@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 n3Q79dda075150; Sun, 26 Apr 2009 07:09:39 GMT (envelope-from zec@svn.freebsd.org) Received: (from zec@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n3Q79doO075148; Sun, 26 Apr 2009 07:09:39 GMT (envelope-from zec@svn.freebsd.org) Message-Id: <200904260709.n3Q79doO075148@svn.freebsd.org> From: Marko Zec Date: Sun, 26 Apr 2009 07:09:39 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r191508 - in head/sys: kern sys X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 26 Apr 2009 07:09:40 -0000 Author: zec Date: Sun Apr 26 07:09:39 2009 New Revision: 191508 URL: http://svn.freebsd.org/changeset/base/191508 Log: Extend the vnet module registration / initialization framework first introduced @ r190909 with a vnet module deregistration service. kldunloadable modules, which are currently using vnet_mod_register() to attach their per-vnet initialization routines to the vnet initialization framework, should call vnet_mod_deregister() before acknowledging MOD_UNLOAD requests in their mod_event handlers. Such changes to the existing code base will follow in subsequent commits. vnet_mod_deregister() does not check whether departing vnet modules are registered as prerequisites for another module(s), so it should be used with care. Currently I'm only aware of vnet modules which are leafs on module dependency graphs that are kldunloadable. This change also introduces per-vnet module destructor handler, which calls vnet's module cleanup function, which (if required) has to be registered in vnet module's vnet_modinfo_t structure .vmi_idetach field. Once options VIMAGE becomes operational, the framework will take care that module's cleanup function become invoked for each active vnet instance, and that the memory allocated for each instance gets freed. Currently calls to destructor handlers must always succeed. Modified: head/sys/kern/kern_vimage.c head/sys/sys/vimage.h Modified: head/sys/kern/kern_vimage.c ============================================================================== --- head/sys/kern/kern_vimage.c Sun Apr 26 03:55:08 2009 (r191507) +++ head/sys/kern/kern_vimage.c Sun Apr 26 07:09:39 2009 (r191508) @@ -47,6 +47,7 @@ static TAILQ_HEAD(vnet_modlink_head, vne static TAILQ_HEAD(vnet_modpending_head, vnet_modlink) vnet_modpending_head; static void vnet_mod_complete_registration(struct vnet_modlink *); static int vnet_mod_constructor(struct vnet_modlink *); +static int vnet_mod_destructor(struct vnet_modlink *); void vnet_mod_register(const struct vnet_modinfo *vmi) @@ -144,6 +145,37 @@ vnet_mod_complete_registration(struct vn } while (vml_iter != NULL); } +void +vnet_mod_deregister(const struct vnet_modinfo *vmi) +{ + + vnet_mod_deregister_multi(vmi, NULL, NULL); +} + +void +vnet_mod_deregister_multi(const struct vnet_modinfo *vmi, void *iarg, + char *iname) +{ + VNET_ITERATOR_DECL(vnet_iter); + struct vnet_modlink *vml; + + TAILQ_FOREACH(vml, &vnet_modlink_head, vml_mod_le) + if (vml->vml_modinfo == vmi && vml->vml_iarg == iarg) + break; + if (vml == NULL) + panic("cannot deregister unregistered vnet module %s", + vmi->vmi_name); + + VNET_FOREACH(vnet_iter) { + CURVNET_SET_QUIET(vnet_iter); + vnet_mod_destructor(vml); + CURVNET_RESTORE(); + } + + TAILQ_REMOVE(&vnet_modlink_head, vml, vml_mod_le); + free(vml, M_VIMAGE); +} + static int vnet_mod_constructor(struct vnet_modlink *vml) { const struct vnet_modinfo *vmi = vml->vml_modinfo; @@ -153,16 +185,18 @@ static int vnet_mod_constructor(struct v if (vml->vml_iarg) printf("/%s", vml->vml_iname); printf(": "); - if (vmi->vmi_struct_size) - printf("malloc(%zu); ", vmi->vmi_struct_size); +#ifdef VIMAGE + if (vmi->vmi_size) + printf("malloc(%zu); ", vmi->vmi_size); +#endif if (vmi->vmi_iattach != NULL) printf("iattach()"); printf("\n"); #endif #ifdef VIMAGE - if (vmi->vmi_struct_size) { - void *mem = malloc(vmi->vmi_struct_size, M_VNET, + if (vmi->vmi_size) { + void *mem = malloc(vmi->vmi_size, M_VNET, M_NOWAIT | M_ZERO); if (mem == NULL) /* XXX should return error, not panic. */ panic("vi_alloc: malloc for %s\n", vmi->vmi_name); @@ -176,6 +210,41 @@ static int vnet_mod_constructor(struct v return (0); } + +static int +vnet_mod_destructor(struct vnet_modlink *vml) +{ + const struct vnet_modinfo *vmi = vml->vml_modinfo; + +#ifdef DEBUG_ORDERING + printf("destroying vnet_%s", vmi->vmi_name); + if (vml->vml_iarg) + printf("/%s", vml->vml_iname); + printf(": "); + if (vmi->vmi_idetach != NULL) + printf("idetach(); "); +#ifdef VIMAGE + if (vmi->vmi_size) + printf("free()"); +#endif + printf("\n"); +#endif + + if (vmi->vmi_idetach) + vmi->vmi_idetach(vml->vml_iarg); + +#ifdef VIMAGE + if (vmi->vmi_size) { + if (curvnet->mod_data[vmi->vmi_id] == NULL) + panic("vi_destroy: %s\n", vmi->vmi_name); + free(curvnet->mod_data[vmi->vmi_id], M_VNET); + curvnet->mod_data[vmi->vmi_id] = NULL; + } +#endif + + return (0); +} + /* * vi_symlookup() attempts to resolve name to address queries for * variables which have been moved from global namespace to virtualization Modified: head/sys/sys/vimage.h ============================================================================== --- head/sys/sys/vimage.h Sun Apr 26 03:55:08 2009 (r191507) +++ head/sys/sys/vimage.h Sun Apr 26 07:09:39 2009 (r191508) @@ -121,6 +121,8 @@ struct vnet_modlink { int vi_symlookup(struct kld_sym_lookup *, char *); void vnet_mod_register(const struct vnet_modinfo *); void vnet_mod_register_multi(const struct vnet_modinfo *, void *, char *); +void vnet_mod_deregister(const struct vnet_modinfo *); +void vnet_mod_deregister_multi(const struct vnet_modinfo *, void *, char *); #endif /* !VIMAGE_GLOBALS */