From owner-svn-src-head@FreeBSD.ORG Fri Apr 9 18:02:19 2010 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 804361065670; Fri, 9 Apr 2010 18:02:19 +0000 (UTC) (envelope-from luigi@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 6E5E58FC0A; Fri, 9 Apr 2010 18:02:19 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o39I2JMk092039; Fri, 9 Apr 2010 18:02:19 GMT (envelope-from luigi@svn.freebsd.org) Received: (from luigi@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o39I2J0K092034; Fri, 9 Apr 2010 18:02:19 GMT (envelope-from luigi@svn.freebsd.org) Message-Id: <201004091802.o39I2J0K092034@svn.freebsd.org> From: Luigi Rizzo Date: Fri, 9 Apr 2010 18:02:19 +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: r206428 - head/sys/netinet/ipfw 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: Fri, 09 Apr 2010 18:02:19 -0000 Author: luigi Date: Fri Apr 9 18:02:19 2010 New Revision: 206428 URL: http://svn.freebsd.org/changeset/base/206428 Log: This commit enables partial operation of dummynet with kernels compiled with "options VIMAGE". As it is now, there is still a single instance of the pipes, and it is only usable from vnet0 (the main instance). Trying to use a pipe from a different vimage does not crash the system as it did before, but the traffic coming out from the pipe goes to the wrong place, and i still need to figure out where. Support for per-vimage pipes is almost there (just a matter of uncommenting the VNET_* definitions for dn_cfg, plus putting into the structure the remaining static variables), however i need first to figure out how init/uninit work, and also to understand where packets are ending up on exit from a pipe. In summary: vimage support for dummynet is not complete yet, but we are getting there. Modified: head/sys/netinet/ipfw/ip_dn_io.c head/sys/netinet/ipfw/ip_dn_private.h head/sys/netinet/ipfw/ip_dummynet.c Modified: head/sys/netinet/ipfw/ip_dn_io.c ============================================================================== --- head/sys/netinet/ipfw/ip_dn_io.c Fri Apr 9 17:32:38 2010 (r206427) +++ head/sys/netinet/ipfw/ip_dn_io.c Fri Apr 9 18:02:19 2010 (r206428) @@ -69,6 +69,7 @@ __FBSDID("$FreeBSD$"); */ struct dn_parms dn_cfg; +//VNET_DEFINE(struct dn_parms, _base_dn_cfg); static long tick_last; /* Last tick duration (usec). */ static long tick_delta; /* Last vs standard tick diff (usec). */ @@ -100,31 +101,34 @@ SYSCTL_DECL(_net_inet); SYSCTL_DECL(_net_inet_ip); SYSCTL_NODE(_net_inet_ip, OID_AUTO, dummynet, CTLFLAG_RW, 0, "Dummynet"); +/* wrapper to pass dn_cfg fields to SYSCTL_* */ +//#define DC(x) (&(VNET_NAME(_base_dn_cfg).x)) +#define DC(x) (&(dn_cfg.x)) /* parameters */ SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, hash_size, - CTLFLAG_RW, &dn_cfg.hash_size, 0, "Default hash table size"); + CTLFLAG_RW, DC(hash_size), 0, "Default hash table size"); SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, pipe_slot_limit, - CTLFLAG_RW, &dn_cfg.slot_limit, 0, + CTLFLAG_RW, DC(slot_limit), 0, "Upper limit in slots for pipe queue."); SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, pipe_byte_limit, - CTLFLAG_RW, &dn_cfg.byte_limit, 0, + CTLFLAG_RW, DC(byte_limit), 0, "Upper limit in bytes for pipe queue."); SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, io_fast, - CTLFLAG_RW, &dn_cfg.io_fast, 0, "Enable fast dummynet io."); + CTLFLAG_RW, DC(io_fast), 0, "Enable fast dummynet io."); SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, debug, - CTLFLAG_RW, &dn_cfg.debug, 0, "Dummynet debug level"); + CTLFLAG_RW, DC(debug), 0, "Dummynet debug level"); SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, expire, - CTLFLAG_RW, &dn_cfg.expire, 0, "Expire empty queues/pipes"); + CTLFLAG_RW, DC(expire), 0, "Expire empty queues/pipes"); SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, expire_cycle, - CTLFLAG_RD, &dn_cfg.expire_cycle, 0, "Expire cycle for queues/pipes"); + CTLFLAG_RD, DC(expire_cycle), 0, "Expire cycle for queues/pipes"); /* RED parameters */ SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, red_lookup_depth, - CTLFLAG_RD, &dn_cfg.red_lookup_depth, 0, "Depth of RED lookup table"); + CTLFLAG_RD, DC(red_lookup_depth), 0, "Depth of RED lookup table"); SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, red_avg_pkt_size, - CTLFLAG_RD, &dn_cfg.red_avg_pkt_size, 0, "RED Medium packet size"); + CTLFLAG_RD, DC(red_avg_pkt_size), 0, "RED Medium packet size"); SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, red_max_pkt_size, - CTLFLAG_RD, &dn_cfg.red_max_pkt_size, 0, "RED Max packet size"); + CTLFLAG_RD, DC(red_max_pkt_size), 0, "RED Max packet size"); /* time adjustment */ SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, tick_delta, @@ -142,13 +146,13 @@ SYSCTL_LONG(_net_inet_ip_dummynet, OID_A /* statistics */ SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, schk_count, - CTLFLAG_RD, &dn_cfg.schk_count, 0, "Number of schedulers"); + CTLFLAG_RD, DC(schk_count), 0, "Number of schedulers"); SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, si_count, - CTLFLAG_RD, &dn_cfg.si_count, 0, "Number of scheduler instances"); + CTLFLAG_RD, DC(si_count), 0, "Number of scheduler instances"); SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, fsk_count, - CTLFLAG_RD, &dn_cfg.fsk_count, 0, "Number of flowsets"); + CTLFLAG_RD, DC(fsk_count), 0, "Number of flowsets"); SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, queue_count, - CTLFLAG_RD, &dn_cfg.queue_count, 0, "Number of queues"); + CTLFLAG_RD, DC(queue_count), 0, "Number of queues"); SYSCTL_ULONG(_net_inet_ip_dummynet, OID_AUTO, io_pkt, CTLFLAG_RD, &io_pkt, 0, "Number of packets passed to dummynet."); @@ -158,7 +162,7 @@ SYSCTL_ULONG(_net_inet_ip_dummynet, OID_ SYSCTL_ULONG(_net_inet_ip_dummynet, OID_AUTO, io_pkt_drop, CTLFLAG_RD, &io_pkt_drop, 0, "Number of packets dropped by dummynet."); - +#undef DC SYSEND #endif @@ -496,6 +500,8 @@ dummynet_task(void *context, int pending struct timeval t; struct mq q = { NULL, NULL }; /* queue to accumulate results */ + CURVNET_SET(context); + DN_BH_WLOCK(); /* Update number of lost(coalesced) ticks. */ @@ -560,6 +566,7 @@ dummynet_task(void *context, int pending dn_reschedule(); if (q.head != NULL) dummynet_send(q.head); + CURVNET_RESTORE(); } /* Modified: head/sys/netinet/ipfw/ip_dn_private.h ============================================================================== --- head/sys/netinet/ipfw/ip_dn_private.h Fri Apr 9 17:32:38 2010 (r206427) +++ head/sys/netinet/ipfw/ip_dn_private.h Fri Apr 9 18:02:19 2010 (r206428) @@ -150,6 +150,8 @@ struct dn_parms { uint32_t expire; uint32_t expire_cycle; /* tick count */ + int init_done; + /* if the upper half is busy doing something long, * can set the busy flag and we will enqueue packets in * a queue for later processing. @@ -354,6 +356,8 @@ enum { }; extern struct dn_parms dn_cfg; +//VNET_DECLARE(struct dn_parms, _base_dn_cfg); +//#define dn_cfg VNET(_base_dn_cfg) int dummynet_io(struct mbuf **, int , struct ip_fw_args *); void dummynet_task(void *context, int pending); Modified: head/sys/netinet/ipfw/ip_dummynet.c ============================================================================== --- head/sys/netinet/ipfw/ip_dummynet.c Fri Apr 9 17:32:38 2010 (r206427) +++ head/sys/netinet/ipfw/ip_dummynet.c Fri Apr 9 18:02:19 2010 (r206428) @@ -2112,14 +2112,10 @@ ip_dn_ctl(struct sockopt *sopt) static void ip_dn_init(void) { - static int init_done = 0; - - if (init_done) + if (dn_cfg.init_done) return; - init_done = 1; - if (bootverbose) - printf("DUMMYNET with IPv6 initialized (100131)\n"); - + printf("DUMMYNET %p with IPv6 initialized (100409)\n", curvnet); + dn_cfg.init_done = 1; /* Set defaults here. MSVC does not accept initializers, * and this is also useful for vimages */ @@ -2156,10 +2152,8 @@ ip_dn_init(void) SLIST_INIT(&dn_cfg.schedlist); DN_LOCK_INIT(); - ip_dn_ctl_ptr = ip_dn_ctl; - ip_dn_io_ptr = dummynet_io; - TASK_INIT(&dn_task, 0, dummynet_task, NULL); + TASK_INIT(&dn_task, 0, dummynet_task, curvnet); dn_tq = taskqueue_create_fast("dummynet", M_NOWAIT, taskqueue_thread_enqueue, &dn_tq); taskqueue_start_threads(&dn_tq, 1, PI_NET, "dummynet"); @@ -2173,13 +2167,16 @@ ip_dn_init(void) #ifdef KLD_MODULE static void -ip_dn_destroy(void) +ip_dn_destroy(int last) { callout_drain(&dn_timeout); DN_BH_WLOCK(); - ip_dn_ctl_ptr = NULL; - ip_dn_io_ptr = NULL; + if (last) { + printf("%s removing last instance\n", __FUNCTION__); + ip_dn_ctl_ptr = NULL; + ip_dn_io_ptr = NULL; + } dummynet_flush(); DN_BH_WUNLOCK(); @@ -2204,13 +2201,15 @@ dummynet_modevent(module_t mod, int type return EEXIST ; } ip_dn_init(); + ip_dn_ctl_ptr = ip_dn_ctl; + ip_dn_io_ptr = dummynet_io; return 0; } else if (type == MOD_UNLOAD) { #if !defined(KLD_MODULE) printf("dummynet statically compiled, cannot unload\n"); return EINVAL ; #else - ip_dn_destroy(); + ip_dn_destroy(1 /* last */); return 0; #endif } else @@ -2288,8 +2287,24 @@ static moduledata_t dummynet_mod = { "dummynet", dummynet_modevent, NULL }; -DECLARE_MODULE(dummynet, dummynet_mod, - SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY-1); +#define DN_SI_SUB SI_SUB_PROTO_IFATTACHDOMAIN +#define DN_MODEV_ORD (SI_ORDER_ANY - 128) /* after ipfw */ +DECLARE_MODULE(dummynet, dummynet_mod, DN_SI_SUB, DN_MODEV_ORD); MODULE_DEPEND(dummynet, ipfw, 2, 2, 2); MODULE_VERSION(dummynet, 1); + +/* + * Starting up. Done in order after dummynet_modevent() has been called. + * VNET_SYSINIT is also called for each existing vnet and each new vnet. + */ +//VNET_SYSINIT(vnet_dn_init, DN_SI_SUB, DN_MODEV_ORD+2, ip_dn_init, NULL); + +/* + * Shutdown handlers up shop. These are done in REVERSE ORDER, but still + * after dummynet_modevent() has been called. Not called on reboot. + * VNET_SYSUNINIT is also called for each exiting vnet as it exits. + * or when the module is unloaded. + */ +//VNET_SYSUNINIT(vnet_dn_uninit, DN_SI_SUB, DN_MODEV_ORD+2, ip_dn_destroy, NULL); + /* end of file */