Date: Sun, 16 Sep 2007 10:15:08 GMT From: Marko Zec <zec@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 126462 for review Message-ID: <200709161015.l8GAF8rL099593@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=126462 Change 126462 by zec@zec_tpx32 on 2007/09/16 10:14:47 Get rid of vimage_0, vnet_0, vprocg_0 and vcpu_0. Checking whether running in a default context should from now on be done exclusively using IS_DEFAULT_VIMAGE() or IS_DEFAULT_VNET() macros. All the structures are allocated now via vi_alloc() even for the "default" vimage at boot time. Each vimage / vnet / vprocg / vcpu structure now has an unique ID number, which is always 0 for "default" instances. Attempt to fix races in counting the number of processes per vprocg. Stop exposing the parent name of the vimage to the userland. A few cosmetic / style cleanups. Affected files ... .. //depot/projects/vimage/src/sys/dev/firewire/firewire.c#8 edit .. //depot/projects/vimage/src/sys/i386/i386/dump_machdep.c#3 edit .. //depot/projects/vimage/src/sys/i386/i386/minidump_machdep.c#4 edit .. //depot/projects/vimage/src/sys/kern/init_main.c#11 edit .. //depot/projects/vimage/src/sys/kern/kern_exit.c#6 edit .. //depot/projects/vimage/src/sys/kern/kern_linker.c#9 edit .. //depot/projects/vimage/src/sys/kern/kern_vimage.c#37 edit .. //depot/projects/vimage/src/sys/netinet/in_proto.c#8 edit .. //depot/projects/vimage/src/sys/netinet/tcp_hostcache.c#16 edit .. //depot/projects/vimage/src/sys/netinet/tcp_subr.c#32 edit .. //depot/projects/vimage/src/sys/netinet/tcp_var.h#16 edit .. //depot/projects/vimage/src/sys/netinet/vinet.h#19 edit .. //depot/projects/vimage/src/sys/sys/vimage.h#37 edit Differences ... ==== //depot/projects/vimage/src/sys/dev/firewire/firewire.c#8 (text+ko) ==== @@ -677,7 +677,7 @@ static void fw_reset_crom(struct firewire_comm *fc) { - INIT_VPROCG(&vprocg_0); + INIT_VPROCG(curthread->td_ucred->cr_vimage->v_procg); /* XXX */ struct crom_src_buf *buf; struct crom_src *src; struct crom_chunk *root; ==== //depot/projects/vimage/src/sys/i386/i386/dump_machdep.c#3 (text+ko) ==== @@ -112,7 +112,7 @@ mkdumpheader(struct kerneldumpheader *kdh, uint32_t archver, uint64_t dumplen, uint32_t blksz) { - INIT_VPROCG(vimage_0.v_procg); + INIT_VPROCG(curthread->td_ucred->cr_vimage->v_procg); /* XXX */ bzero(kdh, sizeof(*kdh)); strncpy(kdh->magic, KERNELDUMPMAGIC, sizeof(kdh->magic)); ==== //depot/projects/vimage/src/sys/i386/i386/minidump_machdep.c#4 (text) ==== @@ -86,7 +86,7 @@ mkdumpheader(struct kerneldumpheader *kdh, uint32_t archver, uint64_t dumplen, uint32_t blksz) { - INIT_VPROCG(vimage_0.v_procg); + INIT_VPROCG(curthread->td_ucred->cr_vimage->v_procg); bzero(kdh, sizeof(*kdh)); strncpy(kdh->magic, KERNELDUMPMAGIC, sizeof(kdh->magic)); ==== //depot/projects/vimage/src/sys/kern/init_main.c#11 (text+ko) ==== @@ -447,8 +447,9 @@ p->p_ucred->cr_ruidinfo = uifind(0); p->p_ucred->cr_prison = NULL; /* Don't jail it. */ #ifdef VIMAGE - p->p_ucred->cr_vimage = p->p_ucred->cr_rvimage = &vimage_0; - vprocg_0.nprocs = 1; + p->p_ucred->cr_vimage = LIST_FIRST(&vimage_head); + p->p_ucred->cr_rvimage = p->p_ucred->cr_vimage; + LIST_FIRST(&vprocg_head)->nprocs = 1; #endif #ifdef AUDIT audit_cred_kproc0(p->p_ucred); ==== //depot/projects/vimage/src/sys/kern/kern_exit.c#6 (text+ko) ==== @@ -173,21 +173,28 @@ } KASSERT(p->p_numthreads == 1, ("exit1: proc %p exiting with %d threads", p, p->p_numthreads)); + #ifdef VIMAGE /* * Switch back to vprocg of our parent so we can deliver * signals, otherwise we won't die - why?!? XXX * - * XXX real or effective vimage? - * XXX nprocs counting in vprocg? + * XXX is PROC_UNLOCK()/PROC_LOCK() sequence safe here? */ if (p->p_pptr && p->p_ucred->cr_vimage->v_procg != p->p_pptr->p_ucred->cr_vimage->v_procg) { - struct ucred *oldcred = p->p_ucred; + struct ucred *oldcred; setsugid(p); + crhold(p->p_pptr->p_ucred); + oldcred = p->p_ucred; p->p_ucred = p->p_pptr->p_ucred; - crhold(p->p_ucred); + PROC_UNLOCK(p); + sx_xlock(&allproc_lock); + oldcred->cr_vimage->v_procg->nprocs--; + p->p_ucred->cr_vimage->v_procg->nprocs++; + sx_xunlock(&allproc_lock); + PROC_LOCK(p); crfree(oldcred); } #endif ==== //depot/projects/vimage/src/sys/kern/kern_linker.c#9 (text+ko) ==== @@ -857,7 +857,7 @@ return (error); #ifdef VIMAGE - if (td->td_ucred->cr_vimage != &vimage_0) + if (!IS_DEFAULT_VIMAGE(td->td_ucred->cr_vimage)) return (EPERM); #endif @@ -929,9 +929,8 @@ return (error); /* XXX should suser catch this for us? */ - VNET_ASSERT(td->td_ucred->cr_vimage == &vimage_0); - /* XXX is this necessary at all? */ - VNET_ASSERT(td == curthread); + VNET_ASSERT(IS_DEFAULT_VIMAGE(td->td_ucred->cr_vimage)); + CURVNET_SET(td->td_ucred->cr_vimage->v_vnet); KLD_LOCK(); ==== //depot/projects/vimage/src/sys/kern/kern_vimage.c#37 (text+ko) ==== @@ -36,9 +36,11 @@ #include <sys/param.h> #include <sys/kernel.h> #include <sys/linker.h> +#include <sys/lock.h> #include <sys/malloc.h> +#include <sys/priv.h> #include <sys/sockio.h> -#include <sys/priv.h> +#include <sys/sx.h> #include <sys/vimage.h> #ifdef DDB @@ -58,10 +60,12 @@ MALLOC_DEFINE(M_VPROCG, "vprocg", "process group control block"); MALLOC_DEFINE(M_VCPU, "vcpu", "cpu resource control block"); +static struct vimage *vi_alloc(char *, int); static int vi_destroy(struct vimage *); 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 *); +static int vi_child_of(struct vimage *, struct vimage *); #ifdef VI_PREALLOC_SIZE /* @@ -100,12 +104,6 @@ #define vi_free(addr, type) free((addr), (type)) #endif /* VI_PREALLOC_SIZE */ -/* XXX those must vanish */ -struct vimage vimage_0; -struct vprocg vprocg_0; -struct vcpu vcpu_0; -struct vnet vnet_0; - struct vimage_list_head vimage_head; struct vnet_list_head vnet_head; struct vprocg_list_head vprocg_head; @@ -123,7 +121,12 @@ #define VNET_LIST_UNLOCK() \ mtx_unlock(&vnet_list_refc_mtx); -static int last_vi_id = 0; +static u_int last_vi_id = 0; +static u_int last_vnet_id = 0; +#if 0 +static u_int last_vprocg_id = 0; +static u_int last_vcpu_id = 0; +#endif static TAILQ_HEAD(vnet_modlink_head, vnet_modlink) vnet_modlink_head; static TAILQ_HEAD(vnet_modpending_head, vnet_modlink) vnet_modpending_head; @@ -169,7 +172,9 @@ break; /* Depencency found, we are done */ if (vml_iter == NULL) { #ifdef DEBUG_ORDERING - printf("dependency %d missing for vnet mod %s, postponing registration\n", vmi->vmi_dependson, vmi->vmi_name); + printf("dependency %d missing for vnet mod %s," + "postponing registration\n", + vmi->vmi_dependson, vmi->vmi_name); #endif /* DEBUG_ORDERING */ TAILQ_INSERT_TAIL(&vnet_modpending_head, vml, vml_mod_le); @@ -199,7 +204,10 @@ break; if (vml_iter != NULL) { #ifdef DEBUG_ORDERING - printf("vnet mod %s now registering, dependency %d loaded\n", vml_iter->vml_modinfo->vmi_name, vml->vml_modinfo->vmi_id); + printf("vnet mod %s now registering," + "dependency %d loaded\n", + vml_iter->vml_modinfo->vmi_name, + vml->vml_modinfo->vmi_id); #endif /* DEBUG_ORDERING */ TAILQ_REMOVE(&vnet_modpending_head, vml_iter, vml_mod_le); @@ -288,7 +296,7 @@ u_char eaddr[6]; if (vi_req == NULL || strcmp(vi_req->vi_name, "-") == 0) { - if (vip == &vimage_0) + if (IS_DEFAULT_VIMAGE(vip)) return (ENXIO); new_vnet = vip->vi_parent->v_vnet; } else @@ -313,7 +321,7 @@ struct ifnet *t_ifp; CURVNET_SET_QUIET(new_vnet); - t_ifp = ifunit(vi_req->vi_parent_name); + t_ifp = ifunit(vi_req->vi_if_xname); CURVNET_RESTORE(); if (t_ifp != NULL) return (EEXIST); @@ -372,9 +380,9 @@ snprintf(ifp->if_xname, IFNAMSIZ, "%s%d", ifp->if_dname, ifp->if_dunit); } else { - if (vi_req && strlen(vi_req->vi_parent_name) > 0) { + if (vi_req && strlen(vi_req->vi_if_xname) > 0) { snprintf(ifp->if_xname, IFNAMSIZ, "%s", - vi_req->vi_parent_name); + vi_req->vi_if_xname); } else { int unit = 0; struct ifnet *iter; @@ -480,12 +488,6 @@ vi_req->vi_id = vip_r->vi_id; bcopy(&vip_r->vi_name, &vi_req->vi_name, sizeof (vi_req->vi_name)); - if (vip_r->vi_parent) - bcopy(&vip_r->vi_parent->vi_name, - &vi_req->vi_parent_name, - sizeof (vi_req->vi_parent_name)); - else - vi_req->vi_parent_name[0] = 0; vi_req->vi_proc_count = vip_r->v_procg->nprocs; vi_req->vi_if_count = vip_r->v_vnet->ifccnt; vi_req->vi_sock_count = vip_r->v_vnet->sockcnt; @@ -515,21 +517,24 @@ newcred->cr_rvimage = vip_r; /* XXX */ p->p_ucred = newcred; PROC_UNLOCK(p); + sx_xlock(&allproc_lock); + oldcred->cr_vimage->v_procg->nprocs--; + p->p_ucred->cr_vimage->v_procg->nprocs++; + sx_xunlock(&allproc_lock); crfree(oldcred); break; } if (vi_req->req_action & VI_CREATE) { - vip_r = vi_alloc(vi_req->vi_name, vi_req->vi_maxsockets, - vi_req->vi_tsc_hashs, - vi_req->vi_tsc_buckl); + vip_r = vi_alloc(vi_req->vi_name, + vi_req->vi_maxsockets); if (vip_r == NULL) return (ENOMEM); vip_r->vi_parent = vip; } - if (vip == vip_r && vip != &vimage_0) + if (vip == vip_r && !IS_DEFAULT_VIMAGE(vip)) return (EPERM); } @@ -567,9 +572,7 @@ struct vimage * -vi_alloc(name, maxsock, tsc_hashs, tsc_buckl) - char *name; - int maxsock, tsc_hashs, tsc_buckl; +vi_alloc(char *name, int maxsock) { struct vimage *vip; struct vnet *vnet; @@ -596,6 +599,7 @@ if (vnet == NULL) panic("vi_alloc: malloc failed for vnet \"%s\"\n", name); vip->v_vnet = vnet; + vnet->vnet_id = last_vnet_id++; vnet->vnet_magic_n = VNET_MAGIC_N; vprocg = vi_malloc(sizeof(struct vprocg), M_VPROCG, M_NOWAIT | M_ZERO); @@ -646,6 +650,9 @@ struct vnet_modlink *vml; /* XXX Beware of races -> more locking to be done... */ + if (vprocg->nprocs != 0) + return (EBUSY); + if (vnet->sockcnt != 0) return (EBUSY); @@ -783,23 +790,13 @@ LIST_INIT(&vprocg_head); LIST_INIT(&vcpu_head); - LIST_INSERT_HEAD(&vimage_head, &vimage_0, vi_le); - LIST_INSERT_HEAD(&vnet_head, &vnet_0, vnet_le); - LIST_INSERT_HEAD(&vprocg_head, &vprocg_0, vprocg_le); - LIST_INSERT_HEAD(&vcpu_head, &vcpu_0, vcpu_le); - - sprintf(vimage_0.vi_name, "default"); - vimage_0.v_vnet = &vnet_0; - vimage_0.v_procg = &vprocg_0; - vimage_0.v_cpu = &vcpu_0; - - vnet_0.vnet_magic_n = VNET_MAGIC_N; - mtx_init(&vnet_list_refc_mtx, "vnet_list_refc_mtx", NULL, MTX_DEF); cv_init(&vnet_list_condvar, "vnet_list_condvar"); + vi_alloc("default", 0); + /* We MUST clear curvnet in vi_init_done before going SMP. */ - curvnet = &vnet_0; + curvnet = LIST_FIRST(&vnet_head); } static void @@ -824,7 +821,6 @@ SYSINIT(vimage_done, SI_SUB_VIMAGE_DONE, SI_ORDER_FIRST, vi_init_done, NULL) #ifdef VI_PREALLOC_SIZE - void * vi_malloc(unsigned long size, struct malloc_type *type, int flags) { @@ -845,7 +841,8 @@ /* Not (enough) free space in our pool, resort to malloc() */ if (vmt == NULL) { if (vi_mpool_fail_cnt == 0) - printf("vi_mpool exhausted, consider increasing VI_PREALLOC_SIZE\n"); + printf("vi_mpool exhausted," + "consider increasing VI_PREALLOC_SIZE\n"); vi_mpool_fail_cnt++; addr = malloc(size, type, flags); return addr; ==== //depot/projects/vimage/src/sys/netinet/in_proto.c#8 (text+ko) ==== @@ -130,6 +130,7 @@ .pr_ctlinput = tcp_ctlinput, .pr_ctloutput = tcp_ctloutput, .pr_init = tcp_init, + .pr_destroy = tcp_destroy, .pr_slowtimo = tcp_slowtimo, .pr_drain = tcp_drain, .pr_usrreqs = &tcp_usrreqs ==== //depot/projects/vimage/src/sys/netinet/tcp_hostcache.c#16 (text+ko) ==== @@ -105,10 +105,9 @@ #ifndef VIMAGE static struct tcp_hostcache tcp_hostcache; +static struct callout tcp_hc_callout; #endif -static struct callout tcp_hc_callout; - static struct hc_metrics *tcp_hc_lookup(struct in_conninfo *); static struct hc_metrics *tcp_hc_insert(struct in_conninfo *); static int sysctl_tcp_hc_list(SYSCTL_HANDLER_ARGS); @@ -222,16 +221,22 @@ NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); uma_zone_set_max(V_tcp_hostcache.zone, V_tcp_hostcache.cache_limit); -#ifdef VIMAGE - if (!IS_DEFAULT_VNET(curvnet)) - return; -#endif - /* * Set up periodic cache cleanup. */ - callout_init(&tcp_hc_callout, CALLOUT_MPSAFE); - callout_reset(&tcp_hc_callout, V_tcp_hostcache.prune * hz, tcp_hc_purge, 0); + callout_init(&V_tcp_hc_callout, CALLOUT_MPSAFE); + callout_reset(&V_tcp_hc_callout, V_tcp_hostcache.prune * hz, + tcp_hc_purge, curvnet); +} + +void +tcp_hc_destroy(void) +{ + INIT_VNET_INET(curvnet); + + /* XXX TODO walk the hashtable and free all entries */ + + callout_drain(&V_tcp_hc_callout); } /* @@ -638,12 +643,12 @@ static void tcp_hc_purge(void *arg) { + CURVNET_SET((struct vnet *) arg); + INIT_VNET_INET(curvnet); struct hc_metrics *hc_entry, *hc_next; int all = 0; int i; - VNET_ITERLOOP_BEGIN() - INIT_VNET_INET(vnet_iter); if (V_tcp_hostcache.purgeall) { all = 1; V_tcp_hostcache.purgeall = 0; @@ -665,11 +670,9 @@ } THC_UNLOCK(&V_tcp_hostcache.hashbase[i].hch_mtx); } - VNET_ITERLOOP_END(); + + callout_reset(&V_tcp_hc_callout, V_tcp_hostcache.prune * hz, + tcp_hc_purge, arg); - /* XXX Marko - FIXME! */ - CURVNET_SET(&vnet_0); - INIT_VNET_INET(&vnet_0); - callout_reset(&tcp_hc_callout, V_tcp_hostcache.prune * hz, tcp_hc_purge, 0); CURVNET_RESTORE(); } ==== //depot/projects/vimage/src/sys/netinet/tcp_subr.c#32 (text+ko) ==== @@ -387,6 +387,12 @@ } void +tcp_destroy(void) +{ + tcp_hc_destroy(); +} + +void tcp_fini(void *xtp) { ==== //depot/projects/vimage/src/sys/netinet/tcp_var.h#16 (text+ko) ==== @@ -547,6 +547,7 @@ void tcp_drain(void); void tcp_fasttimo(void); void tcp_init(void); +void tcp_destroy(void); void tcp_fini(void *); char *tcp_log_addrs(struct in_conninfo *, struct tcphdr *, void *, const void *); @@ -587,6 +588,7 @@ * All tcp_hc_* functions are IPv4 and IPv6 (via in_conninfo) */ void tcp_hc_init(void); +void tcp_hc_destroy(void); void tcp_hc_get(struct in_conninfo *, struct hc_metrics_lite *); u_long tcp_hc_getmtu(struct in_conninfo *); void tcp_hc_updatemtu(struct in_conninfo *, u_long); ==== //depot/projects/vimage/src/sys/netinet/vinet.h#19 (text+ko) ==== @@ -87,6 +87,7 @@ struct inpcbinfo _tcbinfo; struct tcpstat _tcpstat; /* tcp statistics */ struct tcp_hostcache _tcp_hostcache; + struct callout _tcp_hc_callout; struct tcp_syncache _tcp_syncache; TAILQ_HEAD(, tcptw) _twq_2msl; @@ -220,6 +221,7 @@ #define V_tcpstat VNET_INET(tcpstat) #define V_twq_2msl VNET_INET(twq_2msl) #define V_tcp_hostcache VNET_INET(tcp_hostcache) +#define V_tcp_hc_callout VNET_INET(tcp_hc_callout) #define V_tcp_syncache VNET_INET(tcp_syncache) #define V_tcp_sc_rst_sock_fail VNET_INET(tcp_sc_rst_sock_fail) ==== //depot/projects/vimage/src/sys/sys/vimage.h#37 (text+ko) ==== @@ -108,23 +108,25 @@ struct vnet { void *mod_data[VNET_MOD_MAX]; - LIST_ENTRY(vnet) vnet_le; + u_int vnet_ref; /* reference count */ + LIST_ENTRY(vnet) vnet_le; /* all vnets list */ + u_int vnet_id; /* ID num */ - int ifccnt; - int sockcnt; + u_int ifccnt; + u_int sockcnt; - int vnet_magic_n; + u_int vnet_magic_n; }; struct vnet_symmap { char *name; - int offset; - int size; + size_t offset; + size_t size; }; struct vnet_modinfo { - int vmi_id; - int vmi_dependson; + u_int vmi_id; + u_int vmi_dependson; char *vmi_name; vnet_attach_fn *vmi_iattach; vnet_detach_fn *vmi_idetach; @@ -298,28 +300,22 @@ const char *); void printcpuinfo(struct vprocg *); -struct vimage *vi_alloc(char *, int, int, int); void vi_cpu_acct(void *); int vi_td_ioctl(u_long, struct vi_req *, struct thread *); int vi_if_move(struct vi_req *, struct ifnet *, struct vimage *); -int vi_child_of(struct vimage *, struct vimage *); int vi_symlookup(struct kld_sym_lookup *, char *); struct vimage *vnet2vimage(struct vnet *); char *vnet_name(struct vnet *); -extern struct vimage vimage_0; LIST_HEAD(vimage_list_head, vimage); extern struct vimage_list_head vimage_head; -extern struct vprocg vprocg_0; LIST_HEAD(vprocg_list_head, vprocg); extern struct vprocg_list_head vprocg_head; -extern struct vcpu vcpu_0; LIST_HEAD(vcpu_list_head, vcpu); extern struct vcpu_list_head vcpu_head; -extern struct vnet vnet_0; LIST_HEAD(vnet_list_head, vnet); extern struct vnet_list_head vnet_head; extern int vnet_list_refc; @@ -337,14 +333,13 @@ mtx_unlock(&vnet_list_refc_mtx); \ cv_signal(&vnet_list_condvar); -#define IS_DEFAULT_VNET(arg) ((arg) == &vnet_0 ? 1 : 0) +#define IS_DEFAULT_VIMAGE(arg) ((arg)->vi_id == 0) +#define IS_DEFAULT_VNET(arg) ((arg)->vnet_id == 0) -/* - * XXX The stuff bellow needs a major cleanup / rewrite from scratch. - */ - struct vimage { - LIST_ENTRY(vimage) vi_le; + LIST_ENTRY(vimage) vi_le; /* all vimage list */ + LIST_ENTRY(vimage) vi_sibilings; /* vimages with same parent */ + LIST_HEAD(, vimage) vi_child_head; /* direct offspring list */ struct vimage *vi_parent; /* ptr to parent vimage */ u_int vi_id; /* ID num */ @@ -357,6 +352,8 @@ struct vprocg { LIST_ENTRY(vprocg) vprocg_le; + u_int vprocg_ref; /* reference count */ + u_int vprocg_id; /* ID num */ u_int nprocs; @@ -394,6 +391,8 @@ struct vcpu { LIST_ENTRY(vcpu) vcpu_le; + u_int vcpu_ref; /* reference count */ + u_int vcpu_id; /* ID num */ #if 0 u_int cp_time_avg[CPUSTATES]; @@ -418,8 +417,6 @@ u_int vi_cpu_weight; /* Prop. share scheduling priority */ int vi_intr_limit; /* Limit on CPU usage in intr ctx */ int vi_maxsockets; - int vi_tsc_hashs; - int vi_tsc_buckl; u_short vi_id; /* IDnum - but do we need it at all? */ u_short vi_proc_limit; /* max. number of processes */ u_short vi_proc_count; /* current number of processes */ @@ -427,9 +424,9 @@ u_short vi_child_count; /* current number of child vnets */ int vi_if_count; /* current number network interfaces */ int vi_sock_count; - char vi_name[MAXHOSTNAMELEN]; - char vi_parent_name[MAXHOSTNAMELEN]; + char vi_name[MAXPATHLEN]; char vi_chroot[MAXPATHLEN]; + char vi_if_xname[MAXPATHLEN]; /* XXX should be IFNAMSIZ */ int cp_time_avg[CPUSTATES]; struct loadavg averunnable; };
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200709161015.l8GAF8rL099593>
