From owner-svn-src-user@FreeBSD.ORG Sun Jan 10 00:46:38 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id BCF44106566B; Sun, 10 Jan 2010 00:46:38 +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 AA4408FC12; Sun, 10 Jan 2010 00:46:38 +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 o0A0kcna065664; Sun, 10 Jan 2010 00:46:38 GMT (envelope-from luigi@svn.freebsd.org) Received: (from luigi@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0A0kcCm065657; Sun, 10 Jan 2010 00:46:38 GMT (envelope-from luigi@svn.freebsd.org) Message-Id: <201001100046.o0A0kcCm065657@svn.freebsd.org> From: Luigi Rizzo Date: Sun, 10 Jan 2010 00:46:38 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r201967 - in user/luigi/ipfw3-head/sys/netinet: . ipfw X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 10 Jan 2010 00:46:38 -0000 Author: luigi Date: Sun Jan 10 00:46:38 2010 New Revision: 201967 URL: http://svn.freebsd.org/changeset/base/201967 Log: add a fifo scheduler Added: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c (contents, props changed) Modified: user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Modified: user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h Sun Jan 10 00:14:04 2010 (r201966) +++ user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h Sun Jan 10 00:46:38 2010 (r201967) @@ -84,16 +84,6 @@ enum { /* user flags */ DN_NOERROR = 0x0010, }; -/* kernel-side flags */ -enum { - DN_RECONFIGURE = 0x0001, /* (k) */ - DN_DELETE = 0x0004, /* (k) */ - DN_REENQUEUE = 0x0008, /* (k) */ - DN_ACTIVE = 0x0010, /* (k) */ -// DN_SCH_BUSY = 0x0020, /* (k) */ - DN_SCH_DELETE_DELAY_LINE = 0x0040, /* (k) */ -}; - typedef uint64_t dn_key; struct new_cmd { /* header for all sockopt */ Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h Sun Jan 10 00:14:04 2010 (r201966) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h Sun Jan 10 00:46:38 2010 (r201967) @@ -114,14 +114,14 @@ struct dn_sched { * drain_queue called to free all idle queues, or possibly all of * them (this is a subset of delete_scheduler_instance) */ - int (*enqueue)(void *s, struct dn_id *f, struct mbuf *m, + int (*enqueue)(struct new_sch_inst *s, void *f, struct mbuf *m, struct ipfw_flow_id *id); - struct mbuf * (*dequeue)(void *s); + struct mbuf * (*dequeue)(struct new_sch_inst *); int (*config)(char *command, void *sch, int reconfigure); int (*destroy)(void* sch); - int (*new_sched)(void *sch_priv, void *sch_t_priv); - int (*free_sched)(void *s); + int (*new_sched)(struct new_schk *s, struct new_sch_inst *si); + int (*free_sched)(struct new_sch_inst *si); int (*new_fs)(void *command, struct dn_id *g, int reconfigure); int (*free_fs)(struct dn_id *f); @@ -202,6 +202,21 @@ int dn_i_hash_id(struct ipfw_flow_id *id struct new_queue * dn_q_hash_id(struct ipfw_flow_id *id, int i, struct new_queue **rq, struct dn_id *f); +/* + * Function that need to be called before returning a packet from dequeue. + * Update queue statistic + */ +static __inline struct mbuf* +dn_return_packet(struct mbuf *pkt, struct new_queue *q) +{ + + q->head = pkt->m_nextpkt; + q->lenght--; + q->len_bytes -= pkt->m_pkthdr.len; + + return pkt; +} + int dn_sched_modevent(module_t mod, int cmd, void *arg); #define DECLARE_DNSCHED_MODULE(name, dnsched) \ Added: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c Sun Jan 10 00:46:38 2010 (r201967) @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2010 Riccardo Panicucci, Universita` di Pisa + * Copyright (c) 1998-2002 Luigi Rizzo, Universita` di Pisa + * All rights reserved + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include /* IFNAMSIZ, struct ifaddr, ifq head, lock.h mutex.h */ +#include +#include /* ip_len, ip_off */ +#include /* ip_len, ip_off */ +#include +#include +#include +#include +#include +#include +#include +#include + +#define DN_FIFO 1 +/* + * This file implements a FIFO scheduler. + * A FIFO scheduler is a simple scheduler algorithm that can be use to + * scheduling internet packets. + * The scheduler receive a packet (by enqueue() function) and put in in the + * unique queue that manages. + * When the scheduler can transmit, the first packet in the queue is sent + * out (First In First Out) + * The complexity of this algorithm is O(1), all flows use the same queue. + * + * No parameters are required to configure a FIFO scheduler or a + * FIFO flowset. + * + */ + +/* A scheduler instance of a FIFO scheduler requires only a queue. */ +struct fifo_si { + struct new_queue *q; +}; + +static int +fifo_enqueue(struct new_sch_inst *_si, void *f, + struct mbuf *m, struct ipfw_flow_id *id) +{ + /* + * The system pass to the enqueue() function 4 parameters: + * - s: scheduler instance which the packet belongs + * - f: flowset scheduler private data + * - m: the packet + * - id: flow id of the packet, the mask is applyed by system + * + * The scheduler should save all data needs into variables in the + * scheduler instance. In the FIFO scheduling algorithm there is only + * one queue, so a queue should be saved in the scheduler instance. + * When the first packet arrives, the queue doesn't exist and the + * scheduler must create it calling the dn_create_queue() function. + * To really enqueue the packet, the scheduler must call the + * dn_queue_packet() function that insert the packet in the queue passes. + * If for some reason (for example the queue is full) the packet can't + * be enqueued, dn_queue_packet() returns 1. + * + * See the enqueue() function for wf2q+ scheduler algorithm for + * another examples of enqueue() + */ + + /* Access to specific scheduler instance data */ + struct fifo_si *si = (struct fifo_si *)(_si+1); + struct new_queue *q = (struct new_queue *)f; + + if (si->q == NULL) { + si->q = q; + } else if (si->q != q) { + printf("%s queue changed from %p to %p?\n", + __FUNCTION__, si->q, q); + return 1; + } + /* Now the si->q is valid, so insert the packet in this queue */ + if (dn_queue_packet(si->q, m)) { + /* packet was dropped */ + return 1; + } + + /* Ok, the packet is now in the queue. + * The dequeue() function will be called when the scheduler + * instance has credit to transmit packets + */ + return 0; +} + +static struct mbuf * +fifo_dequeue(struct new_sch_inst *_si) +{ + /* + * The dequeue() function is called by the system when the scheduler + * instance can transmit packets. The dequeue() is called until the + * instance has credit and packet to send. + * If the scheduler wants to dequeue a packet, it should call the + * dn_return_packet() function, that take a packet pkt and the relative + * queue and update. + * If the queue is empty, no packet can be send and the dequeue() must + * return NULL. + */ + + /* Pointer to the packet to return , if exists*/ + struct mbuf *pkt; + + /* Accessing to scheduler instance private data */ + struct fifo_si *si = (struct fifo_si *)(_si + 1); + + struct new_queue *q = si->q; + + if (q == NULL) { + /* Queue is not valid, no packet to dequeue */ + return NULL; + } + + /* Take the first packet from the queue, if exists */ + pkt = q->head; + + if (pkt != NULL) { + /* Packet exists, return it */ + return dn_return_packet(pkt, q); + } + + /* No packets in queue, return NULL */ + return NULL; +} + +static int +fifo_new_sched(struct new_schk *s, struct new_sch_inst *_si) +{ + /* This scheduler instance only has a queue pointer. */ + struct fifo_si *si = (struct fifo_si *)(_si + 1); + + /* Initialize scheduler instance private data */ + si->q = NULL; + + return 0; +} + +static int +fifo_free_sched(struct new_sch_inst *_si) +{ + /* + * Delete a FIFO scheduler instance + * - Deallocate memory if the create_scheduler_instance() function + * allocate memory + * - Delete the queue if exists + */ + struct fifo_si *si = (struct fifo_si *)(_si + 1); + + if (si->q) + dn_delete_queue(si->q, 0); + + return 0; +} + +static int +drain_queue_fifo(void *s, int flag) +{ + /* + * Called by the system to free memory. + * Remove the queue if it is empty or if the DN_FORCE flag is set + */ + + struct fifo_si *si = (struct fifo_si *)s; + + if (si->q && (si->q->head == NULL || flag & DN_FORCE)) { + dn_delete_queue(si->q, 0); + si->q = NULL; + } + + return 0; +} + +/* + * FIFO scheduler descriptor + * contains the type of the scheduler, the name, the size of the various + * structures and function pointers. If a function is not implemented, + * the pointer is initialized to NULL + */ +static struct dn_sched fifo_desc = { + .type = DN_FIFO, + .name = "FIFO scheduler algorithm descriptor", + + .scheduler_i_size = sizeof(struct fifo_si), + .queue_size = sizeof(struct new_queue), + + .enqueue = fifo_enqueue, + .dequeue = fifo_dequeue, + + .new_sched = fifo_new_sched, + .free_sched = fifo_free_sched, + .drain_queue = drain_queue_fifo, +}; + +DECLARE_DNSCHED_MODULE(dn_fifo, &fifo_desc); Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Sun Jan 10 00:14:04 2010 (r201966) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Sun Jan 10 00:46:38 2010 (r201967) @@ -477,10 +477,12 @@ create_scheduler_instance(struct new_sch si->sched = s; /* XXX do we make assumption on this starting with dn_id ? */ - ret = s->fp->new_sched(si + 1, s + 1); - if (ret) { - msg = "new_sched error"; - goto error; + if (s->fp->new_sched) { + ret = s->fp->new_sched(s, si); + if (ret) { + msg = "new_sched error"; + goto error; + } } /* Initialize scheduler instance queues list */ @@ -1174,11 +1176,6 @@ dummynet_io(struct mbuf **m0, int dir, s if (sch == NULL) goto dropit; pipe = sch->pipe; - if (pipe == NULL) { /* should not happen ? */ - printf("%s strange, scheduler without a pipe\n", __FUNCTION__); - goto dropit; - } - sch_inst = find_scheduler(sch, fs, &(fwa->f_id)); if (sch_inst == NULL) goto dropit; Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h Sun Jan 10 00:14:04 2010 (r201966) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h Sun Jan 10 00:46:38 2010 (r201967) @@ -251,15 +251,16 @@ struct new_sch_inst { dn_key sched_time ; /* time pipe was scheduled in ready_heap */ dn_key idle_time; /* start of scheduler instance idle time */ }; -/* These values are in the flag field of a flowset - * Some of them are used only by kernel (k) - */ -enum flowset_flag { - DN_FS_DELETE = 0x0001, /* (k) */ - DN_FS_REENQUEUE = 0x0002, /* (k) */ - DN_FS_HAVE_MASK = 0x0004, - DN_FS_QSIZE_BYTES = 0x0008, - DN_FS_NOERROR = 0x0010, /* (k) do not report ENOBUFS on drops */ + +/* kernel-side flags */ +enum { + DN_RECONFIGURE = 0x0001, /* (k) */ + DN_DELETE = 0x0004, /* (k) */ + DN_REENQUEUE = 0x0008, /* (k) */ + DN_ACTIVE = 0x0010, /* (k) */ +// DN_SCH_BUSY = 0x0020, /* (k) */ + DN_SCH_DELETE_DELAY_LINE = 0x0040, /* (k) */ + DN_FORCE = 0x0080 }; extern struct dn_parms dn_cfg; Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Sun Jan 10 00:14:04 2010 (r201966) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Sun Jan 10 00:46:38 2010 (r201967) @@ -490,7 +490,7 @@ dn_fs_config(struct new_fsk *fs) free(fs->alg_fs, M_DUMMYNET); free(fs, M_DUMMYNET); } else - fs->kflags |= DN_FS_DELETE; + fs->kflags |= DN_DELETE; DN_S_UNLOCK(fs->ptr_sched); fs = newfs; fs->fp = s; From owner-svn-src-user@FreeBSD.ORG Sun Jan 10 00:47:42 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B1E9B106566B; Sun, 10 Jan 2010 00:47:42 +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 2F38E8FC0C; Sun, 10 Jan 2010 00:47:42 +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 o0A0lgfR065941; Sun, 10 Jan 2010 00:47:42 GMT (envelope-from luigi@svn.freebsd.org) Received: (from luigi@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0A0lgrq065939; Sun, 10 Jan 2010 00:47:42 GMT (envelope-from luigi@svn.freebsd.org) Message-Id: <201001100047.o0A0lgrq065939@svn.freebsd.org> From: Luigi Rizzo Date: Sun, 10 Jan 2010 00:47:42 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r201968 - user/luigi/ipfw3-head/sys/conf X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 10 Jan 2010 00:47:42 -0000 Author: luigi Date: Sun Jan 10 00:47:41 2010 New Revision: 201968 URL: http://svn.freebsd.org/changeset/base/201968 Log: add to the configuration Modified: user/luigi/ipfw3-head/sys/conf/files Modified: user/luigi/ipfw3-head/sys/conf/files ============================================================================== --- user/luigi/ipfw3-head/sys/conf/files Sun Jan 10 00:46:38 2010 (r201967) +++ user/luigi/ipfw3-head/sys/conf/files Sun Jan 10 00:47:41 2010 (r201968) @@ -2450,7 +2450,9 @@ netinet/in_proto.c optional inet \ netinet/in_rmx.c optional inet netinet/ip_divert.c optional inet ipdivert ipfirewall netinet/ipfw/dn_heap.c optional inet dummynet +netinet/ipfw/dn_sched_fifo.c optional inet dummynet netinet/ipfw/ip_dummynet.c optional inet dummynet +netinet/ipfw/ip_dn_io.c optional inet dummynet netinet/ip_ecn.c optional inet | inet6 netinet/ip_encap.c optional inet | inet6 netinet/ip_fastfwd.c optional inet From owner-svn-src-user@FreeBSD.ORG Sun Jan 10 02:31:06 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 8EAFE106566B; Sun, 10 Jan 2010 02:31:06 +0000 (UTC) (envelope-from kmacy@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 7D8478FC12; Sun, 10 Jan 2010 02:31:06 +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 o0A2V6Ku088773; Sun, 10 Jan 2010 02:31:06 GMT (envelope-from kmacy@svn.freebsd.org) Received: (from kmacy@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0A2V6NK088772; Sun, 10 Jan 2010 02:31:06 GMT (envelope-from kmacy@svn.freebsd.org) Message-Id: <201001100231.o0A2V6NK088772@svn.freebsd.org> From: Kip Macy Date: Sun, 10 Jan 2010 02:31:06 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r201969 - user/kmacy/releng_8_fcs_buf_xen/sys/dev/xen/console X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 10 Jan 2010 02:31:06 -0000 Author: kmacy Date: Sun Jan 10 02:31:06 2010 New Revision: 201969 URL: http://svn.freebsd.org/changeset/base/201969 Log: fix lock recursion Modified: user/kmacy/releng_8_fcs_buf_xen/sys/dev/xen/console/console.c Modified: user/kmacy/releng_8_fcs_buf_xen/sys/dev/xen/console/console.c ============================================================================== --- user/kmacy/releng_8_fcs_buf_xen/sys/dev/xen/console/console.c Sun Jan 10 00:47:41 2010 (r201968) +++ user/kmacy/releng_8_fcs_buf_xen/sys/dev/xen/console/console.c Sun Jan 10 02:31:06 2010 (r201969) @@ -177,9 +177,6 @@ static boolean_t xcons_putc(int c) { int force_flush = xc_mute || -#ifdef DDB - db_active || -#endif panicstr; /* we're not gonna recover, so force * flush */ @@ -386,15 +383,17 @@ xc_timeout(void *v) tp = (struct tty *)v; - tty_lock(tp); - while ((c = xccncheckc(NULL)) != -1) + while ((c = xccncheckc(NULL)) != -1) { + tty_lock(tp); ttydisc_rint(tp, c, 0); - + tty_unlock(tp); + } if (xc_start_needed) { xc_start_needed = FALSE; + tty_lock(tp); xcoutwakeup(tp); + tty_unlock(tp); } - tty_unlock(tp); callout_reset(&xc_callout, XC_POLLTIME, xc_timeout, tp); } From owner-svn-src-user@FreeBSD.ORG Sun Jan 10 02:33:34 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 63EED1065670; Sun, 10 Jan 2010 02:33:34 +0000 (UTC) (envelope-from kmacy@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 527298FC08; Sun, 10 Jan 2010 02:33:34 +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 o0A2XYM7089343; Sun, 10 Jan 2010 02:33:34 GMT (envelope-from kmacy@svn.freebsd.org) Received: (from kmacy@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0A2XYUp089341; Sun, 10 Jan 2010 02:33:34 GMT (envelope-from kmacy@svn.freebsd.org) Message-Id: <201001100233.o0A2XYUp089341@svn.freebsd.org> From: Kip Macy Date: Sun, 10 Jan 2010 02:33:34 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r201970 - user/kmacy/releng_8_fcs_buf_xen/sys/cddl/contrib/opensolaris/uts/common/fs/zfs X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 10 Jan 2010 02:33:34 -0000 Author: kmacy Date: Sun Jan 10 02:33:34 2010 New Revision: 201970 URL: http://svn.freebsd.org/changeset/base/201970 Log: - clear buf after it is removed - set object root to NULL if bp being removed is the last one Modified: user/kmacy/releng_8_fcs_buf_xen/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_bio.c Modified: user/kmacy/releng_8_fcs_buf_xen/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_bio.c ============================================================================== --- user/kmacy/releng_8_fcs_buf_xen/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_bio.c Sun Jan 10 02:31:06 2010 (r201969) +++ user/kmacy/releng_8_fcs_buf_xen/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_bio.c Sun Jan 10 02:33:34 2010 (r201970) @@ -571,6 +571,9 @@ zio_buf_blkno_remove_locked(vm_object_t state->zss_resident_count--; state->zss_generation++; + if (bp == state->zss_blkno_root) + state->zss_blkno_root = NULL; + #ifdef INVARIANTS bp->b_right = bp->b_left = NULL; #endif @@ -756,13 +759,14 @@ zio_buf_evict_overlap(vm_object_t object TAILQ_REMOVE(&clh, tmpbp, b_cluster.cluster_entry); evict: zio_buf_vm_object_evict(tmpbp); - tmpbp->b_bufobj = NULL; - tmpbp->b_flags &= ~B_VMIO; - tmpbp->b_blkno = tmpbp->b_lblkno = 0; /* * move buffer to the unmanaged tree */ zio_buf_blkno_remove_locked(object, tmpbp); + tmpbp->b_bufobj = NULL; + tmpbp->b_flags &= ~(B_VMIO|B_CACHE); + tmpbp->b_blkno = tmpbp->b_lblkno = 0; + tmpbp->b_state = NULL; } done: if (!(collisions == 1 && tmpbp != NULL && tmpbp->b_blkno == blkno && From owner-svn-src-user@FreeBSD.ORG Sun Jan 10 10:42:59 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 18B2D106566C; Sun, 10 Jan 2010 10:42:59 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 083198FC12; Sun, 10 Jan 2010 10:42:59 +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 o0AAgwDY097453; Sun, 10 Jan 2010 10:42:58 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0AAgwrt097451; Sun, 10 Jan 2010 10:42:58 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201001101042.o0AAgwrt097451@svn.freebsd.org> From: Ed Schouten Date: Sun, 10 Jan 2010 10:42:58 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r201992 - user/ed/utmpx/usr.sbin/ppp X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 10 Jan 2010 10:42:59 -0000 Author: ed Date: Sun Jan 10 10:42:58 2010 New Revision: 201992 URL: http://svn.freebsd.org/changeset/base/201992 Log: Just use an int instead of a time_t here. It only stores a boolean. Modified: user/ed/utmpx/usr.sbin/ppp/physical.h Modified: user/ed/utmpx/usr.sbin/ppp/physical.h ============================================================================== --- user/ed/utmpx/usr.sbin/ppp/physical.h Sun Jan 10 09:31:57 2010 (r201991) +++ user/ed/utmpx/usr.sbin/ppp/physical.h Sun Jan 10 10:42:58 2010 (r201992) @@ -97,7 +97,7 @@ struct physical { char *base; } name; - time_t Utmp; /* Are we in utmp ? */ + int Utmp; /* Are we in utmp ? */ pid_t session_owner; /* HUP this when closing the link */ struct device *handler; /* device specific handler */ From owner-svn-src-user@FreeBSD.ORG Sun Jan 10 12:31:36 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 4CBBE1065679; Sun, 10 Jan 2010 12:31:36 +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 3A2AC8FC18; Sun, 10 Jan 2010 12:31:36 +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 o0ACVaww025718; Sun, 10 Jan 2010 12:31:36 GMT (envelope-from luigi@svn.freebsd.org) Received: (from luigi@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0ACVaeh025713; Sun, 10 Jan 2010 12:31:36 GMT (envelope-from luigi@svn.freebsd.org) Message-Id: <201001101231.o0ACVaeh025713@svn.freebsd.org> From: Luigi Rizzo Date: Sun, 10 Jan 2010 12:31:36 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r201996 - in user/luigi/ipfw3-head/sys/netinet: . ipfw X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 10 Jan 2010 12:31:36 -0000 Author: luigi Date: Sun Jan 10 12:31:35 2010 New Revision: 201996 URL: http://svn.freebsd.org/changeset/base/201996 Log: another batch of changes Modified: user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Modified: user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h Sun Jan 10 12:03:53 2010 (r201995) +++ user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h Sun Jan 10 12:31:35 2010 (r201996) @@ -196,10 +196,11 @@ struct new_sch { /* * "queue N" and "pipe N" accept 1<=N<=65535. To map the values in * the same namespace (which we search through a hash table) we add - * an offset to 'pipe N' below. The value is not so important, but - * it should be known to userland as well so we can print it. + * an offset to 'pipe N' below. + * 'queue' -> 1..0x0ffff , 'pipe': 0x10001-0x1ffff */ -#define DN_PIPEOFFSET 1000000 +#define DN_MAXID 0x1ffff +#define DN_PIPEOFFSET 0x10000 /*---- old parameters ---*/ /* Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h Sun Jan 10 12:03:53 2010 (r201995) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h Sun Jan 10 12:31:35 2010 (r201996) @@ -47,27 +47,28 @@ struct dn_sched { /* * The following define the size of 4 optional data structures - * that may need to be allocated at runtime: + * that may need to be allocated at runtime, and are appended + * to each of the base data structures. */ /* + parameters attached to the template, e.g. * default queue sizes, weights, quantum size, and so on; */ - size_t scheduler_size; // sch_arg + size_t schk_len; /* + per-instance parameters, such as timestamps, * ccontainers for queues, etc; */ - size_t scheduler_i_size; // sch_runtime + size_t sch_inst_len; /* + per-flowset parameters, such as individual weights, * priorities, queue limits, slot sizes... */ - size_t flowset_size; // fs_arg + size_t fs_len; // fs_arg /* + per-queue parameters (what for ?) */ - size_t queue_size; // queue_arg + size_t queue_len; // queue_arg SLIST_ENTRY(dn_sched) next; /* Next scheduler in the list */ @@ -114,22 +115,27 @@ struct dn_sched { * drain_queue called to free all idle queues, or possibly all of * them (this is a subset of delete_scheduler_instance) */ - int (*enqueue)(struct new_sch_inst *s, void *f, struct mbuf *m, - struct ipfw_flow_id *id); + int (*enqueue)(struct new_sch_inst *, struct new_fsk *, + struct mbuf *, struct ipfw_flow_id *); struct mbuf * (*dequeue)(struct new_sch_inst *); - int (*config)(char *command, void *sch, int reconfigure); - int (*destroy)(void* sch); - int (*new_sched)(struct new_schk *s, struct new_sch_inst *si); - int (*free_sched)(struct new_sch_inst *si); + /* config or destroy the scheduler template */ + int (*config)(struct new_schk *, int reconfigure); + int (*destroy)(struct new_schk*); + + /* create, drain or destroy a new scheduler instance */ + int (*new_sched)(struct new_schk *, struct new_sch_inst *); + int (*drain_sched)(struct new_sch_inst *, int flag); + int (*free_sched)(struct new_sch_inst *); + /* create or destroy a flowset attached to this scheduler */ int (*new_fs)(void *command, struct dn_id *g, int reconfigure); - int (*free_fs)(struct dn_id *f); + int (*free_fs)(struct new_fsk *); + /* create or destroy a queue attached to this scheduler */ int (*new_queue)(struct new_queue *q, struct dn_id *f); int (*free_queue)(struct new_queue *q); - int (*drain_queue)(void *s, int flag); }; SLIST_HEAD(dn_sched_head, dn_sched); Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c Sun Jan 10 12:03:53 2010 (r201995) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c Sun Jan 10 12:31:35 2010 (r201996) @@ -63,7 +63,7 @@ struct fifo_si { }; static int -fifo_enqueue(struct new_sch_inst *_si, void *f, +fifo_enqueue(struct new_sch_inst *_si, struct new_fs *f, struct mbuf *m, struct ipfw_flow_id *id) { /* @@ -180,14 +180,14 @@ fifo_free_sched(struct new_sch_inst *_si } static int -drain_queue_fifo(void *s, int flag) +fifo_drain(struct new_sch_inst *_si, int flag) { /* * Called by the system to free memory. * Remove the queue if it is empty or if the DN_FORCE flag is set */ - struct fifo_si *si = (struct fifo_si *)s; + struct fifo_si *si = (struct fifo_si *)(_si + 1); if (si->q && (si->q->head == NULL || flag & DN_FORCE)) { dn_delete_queue(si->q, 0); @@ -207,15 +207,15 @@ static struct dn_sched fifo_desc = { .type = DN_FIFO, .name = "FIFO scheduler algorithm descriptor", - .scheduler_i_size = sizeof(struct fifo_si), - .queue_size = sizeof(struct new_queue), + .sch_inst_len = sizeof(struct fifo_si), + .queue_len = sizeof(struct new_queue), .enqueue = fifo_enqueue, .dequeue = fifo_dequeue, .new_sched = fifo_new_sched, .free_sched = fifo_free_sched, - .drain_queue = drain_queue_fifo, + .drain_sched = fifo_drain, }; DECLARE_DNSCHED_MODULE(dn_fifo, &fifo_desc); Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Sun Jan 10 12:03:53 2010 (r201995) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Sun Jan 10 12:31:35 2010 (r201996) @@ -461,7 +461,7 @@ create_scheduler_instance(struct new_sch struct new_sch_inst *si; int ret; const char *msg = "malloc failure"; - int l = sizeof(*si) + s->fp->scheduler_i_size; + int l = sizeof(*si) + s->fp->sch_inst_len; si = malloc(l, M_DUMMYNET, M_NOWAIT | M_ZERO); @@ -1111,13 +1111,22 @@ red_drops(struct dn_flow_set *fs, struct struct new_fsk * ipdn_locate_flowset(int fs_nr) { - struct new_fsk *fs; + struct new_fsk *fs = NULL; - SLIST_FOREACH(fs, &dn_cfg.fshash[HASH(fs_nr)], next) - if (fs->fs.fs_nr == fs_nr) - return (fs); + for (;;) { + SLIST_FOREACH(fs, &dn_cfg.fshash[HASH(fs_nr)], next) + if (fs->fs.fs_nr == fs_nr) + break; + if (!fs || fs->sched_id == dn_cfg.id) + break; + /* configuration changed, update */ + if (dn_fs_config(fs)) { + fs = NULL; + break; + } + } - return (NULL); + return (fs); } /* @@ -1138,7 +1147,7 @@ ipdn_locate_flowset(int fs_nr) int dummynet_io(struct mbuf **m0, int dir, struct ip_fw_args *fwa) { - struct mbuf *m = *m0, *head = NULL; + struct mbuf *m = *m0; struct dn_pkt_tag *pkt; struct m_tag *mtag; struct new_fsk *fs = NULL; @@ -1157,31 +1166,22 @@ dummynet_io(struct mbuf **m0, int dir, s /* find flowset and schedset, protected by the UH lock */ DUMMYNET_LOCK(); io_pkt++; + /* XXX locate_flowset could be optimised with a direct ref. */ fs = ipdn_locate_flowset(fs_id); if (fs == NULL) goto dropit; /* This queue/pipe does not exist! */ - if (fs->sched_id != dn_cfg.id) { /* fs->sched invalid, update */ - /* configuration changed, update */ - int ret = dn_fs_config(fs); - if (ret) - goto dropit; - /* find again, just in case things changed */ - fs = ipdn_locate_flowset(fs_id); - if (fs == NULL) - goto dropit; - } sch = fs->sched; - if (sch == NULL) + if (sch == NULL) /* should not happen */ goto dropit; - pipe = sch->pipe; + /* find_scheduler can be fast */ sch_inst = find_scheduler(sch, fs, &(fwa->f_id)); if (sch_inst == NULL) goto dropit; - /* Apply the flow_mask */ - do_mask(&fs->fs.flow_mask, &(fwa->f_id)); + if (fs->kflags & DN_HAVE_MASK) + do_mask(&fs->fs.flow_mask, &(fwa->f_id)); /* tag the mbuf */ mtag = m_tag_get(PACKET_TAG_DUMMYNET, @@ -1202,16 +1202,7 @@ dummynet_io(struct mbuf **m0, int dir, s now = curr_time; /* in case it changes, use the same value */ pkt->output_time = now; /* XXX rewritten when reaches head */ - /* - * - 'sch_inst + 1' is the pointer to scheduler instance's - * private data, 'fs->alg_fs' is the flowset's private data, - * 'm' is the packet, 'id' is the masked flowid of the packet - * - * NOTE: If the scheduler function wants really enqueue the - * packet, it must call the queue_packet() - */ - - ret = sch->fp->enqueue(sch_inst + 1, fs->alg_fs, m, &(fwa->f_id)); + ret = sch->fp->enqueue(sch_inst, fs, m, &(fwa->f_id)); if (ret) { /* packet was dropped by enqueue() */ *m0 = NULL; @@ -1225,6 +1216,7 @@ dummynet_io(struct mbuf **m0, int dir, s */ if (sch_inst->flags & DN_ACTIVE) goto done; + pipe = sch->pipe; sch_inst->numbytes = dn_cfg.io_fast ? pipe->bandwidth : 0; if (pipe->burst) { uint64_t burst = (now - sch_inst->idle_time) * @@ -1233,23 +1225,24 @@ dummynet_io(struct mbuf **m0, int dir, s burst = pipe->burst; sch_inst->numbytes += burst; } - head = serve_sched(sch_inst, now); + m = serve_sched(sch_inst, now); /* optimization -- pass it back to ipfw for immediate send */ - if (dn_cfg.io_fast && head == m && (dir & PROTO_LAYER2) == 0 ) { + if (dn_cfg.io_fast && m == *m0 && (dir & PROTO_LAYER2) == 0 ) { /* fast io */ io_pkt_fast++; printf("dummynet TEST: ** IOFAST **\n"); - if (m->m_nextpkt != NULL) + if (m->m_nextpkt != NULL) { printf("dummynet: fast io: pkt chain detected!\n"); - head = m->m_nextpkt = NULL; + m->m_nextpkt = NULL; + } } else { *m0 = NULL; + if (m) + dummynet_send(m); } done: DUMMYNET_UNLOCK(); - if (head != NULL) - dummynet_send(head); return 0; dropit: Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h Sun Jan 10 12:03:53 2010 (r201995) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h Sun Jan 10 12:31:35 2010 (r201996) @@ -152,9 +152,9 @@ struct new_schk { */ int inst_counter; - /* Pointer to the parent pipe, and generation number */ - int pipe_id; + /* Pointer to the parent pipe, always valid */ struct new_pipe *pipe; + struct new_id *private; /* per-scheduler data */ struct dn_id *cfg; /* extra config arguments */ Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Sun Jan 10 12:03:53 2010 (r201995) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Sun Jan 10 12:31:35 2010 (r201996) @@ -178,7 +178,8 @@ really_deletescheduler(struct new_schk * delete_scheduler_instance(sid); } } - s->fp->free_sched(s + 1); + if (s->fp->destroy) + s->fp->destroy(s); s->fp->ref_count--; DN_S_LOCK_DESTROY(s); if (s->sch_i_size > 0) @@ -495,7 +496,7 @@ dn_fs_config(struct new_fsk *fs) fs = newfs; fs->fp = s; fs->active_f = 0; - fs->alg_fs = malloc(fs->fp->flowset_size, M_DUMMYNET, M_NOWAIT); + fs->alg_fs = malloc(fs->fp->fs_len, M_DUMMYNET, M_NOWAIT); if (fs->alg_fs == NULL) { DN_S_UNLOCK(sch_t); printf("dummynet: no memory for new flowset ext\n"); @@ -643,7 +644,7 @@ config_pipe(struct new_pipe *p, struct d return EINVAL; } i = p->pipe_nr; - if (i <= 0 || i >= 2*DN_PIPEOFFSET) + if (i <= 0 || i > DN_MAXID) return EINVAL; /* * The config program passes parameters as follows: @@ -672,8 +673,19 @@ config_pipe(struct new_pipe *p, struct d return 0; } +static struct new_schk * +destroy_sched(struct new_schk *s) +{ + if (s->fp->destroy) + s->fp->destroy(s); + if (s->private) + free(s->private, M_DUMMYNET); + free(s, M_DUMMYNET); + return NULL; +} + /* - * Configure a scheduler possibly allocating it (and the pipe) + * Configure a scheduler possibly allocating it (and the pipe). * XXX check link to type etc. * XXX postpone call */ @@ -681,15 +693,15 @@ static int config_sched(struct new_sch *nsch, struct dn_id *arg) { struct new_schk *s; - int i; struct dn_sched *fp; + int i; if (nsch->oid.len != sizeof(*nsch)) { printf("%s: bad sched len\n", __FUNCTION__); return EINVAL; } i = nsch->sched_nr; - if (i <= 0 || i >= 2*DN_PIPEOFFSET) + if (i <= 0 || i > DN_MAXID) return EINVAL; /* XXX other sanity checks */ /* XXX make sure the type exists */ @@ -700,6 +712,8 @@ config_sched(struct new_sch *nsch, struc } DUMMYNET_LOCK(); s = locate_scheduler(i); + if (s && s->fp != fp) /* type changed */ + s = destroy_sched(s); if (s == NULL) { /* add a scheduler to the hash table */ s = malloc(sizeof(*s) + sizeof(struct new_pipe), @@ -707,14 +721,15 @@ config_sched(struct new_sch *nsch, struc if (s == NULL) return ENOMEM; s->pipe = (struct new_pipe *)(s+1); + s->fp = fp; /* XXX init pipe ? */ SLIST_INSERT_HEAD(&dn_cfg.schedhash[HASH(i)], s, next); } s->sch = *nsch; s->cfg = arg; - s->fp = fp; /* call init function */ - s->fp->new_sched(s, s+1); + if (s->fp->config) + s->fp->config(s, 0); reset_credit(s); dn_cfg.id++; DUMMYNET_UNLOCK(); @@ -735,7 +750,7 @@ config_fs(struct new_fs *nfs, struct dn_ return EINVAL; } i = nfs->fs_nr; - if (i <= 0 || i >= 2*DN_PIPEOFFSET) + if (i <= 0 || i > DN_MAXID) return EINVAL; /* XXX other sanity checks */ DUMMYNET_LOCK(); @@ -771,7 +786,7 @@ config_profile(struct new_profile *pf, s return EINVAL; } i = pf->pipe_nr; - if (i <= 0 || i >= 2*DN_PIPEOFFSET) + if (i <= 0 || i > DN_MAXID) return EINVAL; /* XXX other sanity checks */ DUMMYNET_LOCK(); From owner-svn-src-user@FreeBSD.ORG Sun Jan 10 13:15:59 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 1E2451065670; Sun, 10 Jan 2010 13:15:59 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 0CFBD8FC0C; Sun, 10 Jan 2010 13:15:59 +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 o0ADFwQI035538; Sun, 10 Jan 2010 13:15:58 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0ADFwg8035535; Sun, 10 Jan 2010 13:15:58 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201001101315.o0ADFwg8035535@svn.freebsd.org> From: Ed Schouten Date: Sun, 10 Jan 2010 13:15:58 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r201997 - in user/ed/utmpx/usr.bin: . lastcomm X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 10 Jan 2010 13:15:59 -0000 Author: ed Date: Sun Jan 10 13:15:58 2010 New Revision: 201997 URL: http://svn.freebsd.org/changeset/base/201997 Log: Make lastcomm build again and reconnect it to the build. Modified: user/ed/utmpx/usr.bin/Makefile user/ed/utmpx/usr.bin/lastcomm/lastcomm.c Modified: user/ed/utmpx/usr.bin/Makefile ============================================================================== --- user/ed/utmpx/usr.bin/Makefile Sun Jan 10 12:31:35 2010 (r201996) +++ user/ed/utmpx/usr.bin/Makefile Sun Jan 10 13:15:58 2010 (r201997) @@ -94,6 +94,7 @@ SUBDIR= alias \ ktrace \ ktrdump \ lam \ + lastcomm \ ldd \ leave \ less \ Modified: user/ed/utmpx/usr.bin/lastcomm/lastcomm.c ============================================================================== --- user/ed/utmpx/usr.bin/lastcomm/lastcomm.c Sun Jan 10 12:31:35 2010 (r201996) +++ user/ed/utmpx/usr.bin/lastcomm/lastcomm.c Sun Jan 10 13:15:58 2010 (r201997) @@ -59,7 +59,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include "pathnames.h" /*XXX*/#include @@ -154,11 +153,11 @@ main(int argc, char *argv[]) if (*argv && !requested(argv, &ab)) continue; - (void)printf("%-*.*s %-7s %-*s %-*s", + (void)printf("%-*.*s %-7s %-*s %-8s", AC_COMM_LEN, AC_COMM_LEN, ab.ac_comm, flagbits(ab.ac_flagx), - UT_NAMESIZE, user_from_uid(ab.ac_uid, 0), - UT_LINESIZE, getdev(ab.ac_tty)); + MAXLOGNAME, user_from_uid(ab.ac_uid, 0), + getdev(ab.ac_tty)); /* user + system time */ From owner-svn-src-user@FreeBSD.ORG Sun Jan 10 13:30:48 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 1D581106566B; Sun, 10 Jan 2010 13:30:48 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 07D568FC1A; Sun, 10 Jan 2010 13:30:48 +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 o0ADUlgq038855; Sun, 10 Jan 2010 13:30:47 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0ADUkPf038833; Sun, 10 Jan 2010 13:30:46 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201001101330.o0ADUkPf038833@svn.freebsd.org> From: Ed Schouten Date: Sun, 10 Jan 2010 13:30:46 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r201998 - in user/ed/utmpx: . contrib/gcc/config/mips contrib/one-true-awk contrib/tcp_wrappers etc games/fortune/datfiles games/pom gnu/lib/libgcc gnu/usr.bin/binutils gnu/usr.bin/binu... X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 10 Jan 2010 13:30:48 -0000 Author: ed Date: Sun Jan 10 13:30:45 2010 New Revision: 201998 URL: http://svn.freebsd.org/changeset/base/201998 Log: Merge with HEAD. Added: user/ed/utmpx/include/semaphore.h - copied unchanged from r201997, head/include/semaphore.h user/ed/utmpx/lib/libc/gen/sem_new.c - copied unchanged from r201997, head/lib/libc/gen/sem_new.c user/ed/utmpx/lib/libc/mips/gen/hardfloat/ - copied from r201997, head/lib/libc/mips/gen/hardfloat/ user/ed/utmpx/share/man/man3/pthread_affinity_np.3 - copied unchanged from r201997, head/share/man/man3/pthread_affinity_np.3 user/ed/utmpx/share/man/man3/pthread_attr_affinity_np.3 - copied unchanged from r201997, head/share/man/man3/pthread_attr_affinity_np.3 user/ed/utmpx/sys/boot/efi/libefi/efipart.c - copied unchanged from r201997, head/sys/boot/efi/libefi/efipart.c user/ed/utmpx/sys/conf/ldscript.mips.mips64 - copied unchanged from r201997, head/sys/conf/ldscript.mips.mips64 user/ed/utmpx/sys/conf/ldscript.mips.octeon1.32 - copied unchanged from r201997, head/sys/conf/ldscript.mips.octeon1.32 user/ed/utmpx/sys/conf/ldscript.mips.octeon1.64 - copied unchanged from r201997, head/sys/conf/ldscript.mips.octeon1.64 user/ed/utmpx/sys/conf/ldscript.mips.octeon1.n32 - copied unchanged from r201997, head/sys/conf/ldscript.mips.octeon1.n32 user/ed/utmpx/sys/dev/flash/mx25l.c - copied unchanged from r201997, head/sys/dev/flash/mx25l.c user/ed/utmpx/sys/dev/flash/mx25lreg.h - copied unchanged from r201997, head/sys/dev/flash/mx25lreg.h - copied from r201997, head/sys/dev/siba/siba/ - copied from r201997, head/sys/mips/atheros/ - copied from r201997, head/sys/mips/cavium/ user/ed/utmpx/sys/mips/conf/AR71XX - copied unchanged from r201997, head/sys/mips/conf/AR71XX user/ed/utmpx/sys/mips/conf/AR71XX.hints - copied unchanged from r201997, head/sys/mips/conf/AR71XX.hints user/ed/utmpx/sys/mips/conf/MALTA64 - copied unchanged from r201997, head/sys/mips/conf/MALTA64 user/ed/utmpx/sys/mips/conf/OCTEON1 - copied unchanged from r201997, head/sys/mips/conf/OCTEON1 user/ed/utmpx/sys/mips/conf/OCTEON1-32 - copied unchanged from r201997, head/sys/mips/conf/OCTEON1-32 user/ed/utmpx/sys/mips/conf/OCTEON1.hints - copied unchanged from r201997, head/sys/mips/conf/OCTEON1.hints user/ed/utmpx/sys/mips/conf/SWARM - copied unchanged from r201997, head/sys/mips/conf/SWARM user/ed/utmpx/sys/mips/conf/SWARM.hints - copied unchanged from r201997, head/sys/mips/conf/SWARM.hints user/ed/utmpx/sys/mips/conf/XLR - copied unchanged from r201997, head/sys/mips/conf/XLR user/ed/utmpx/sys/mips/mips/ptrace_machdep.c - copied unchanged from r201997, head/sys/mips/mips/ptrace_machdep.c - copied from r201997, head/sys/mips/rmi/ - copied from r201997, head/sys/mips/sibyte/ user/ed/utmpx/tools/regression/posixsem2/ - copied from r201997, head/tools/regression/posixsem2/ user/ed/utmpx/tools/regression/usr.bin/make/sysmk/ - copied from r201997, head/tools/regression/usr.bin/make/sysmk/ user/ed/utmpx/usr.sbin/traceroute/findsaddr-udp.c - copied unchanged from r201997, head/usr.sbin/traceroute/findsaddr-udp.c Directory Properties: user/ed/utmpx/sys/dev/siba/siba/ (props changed) user/ed/utmpx/sys/mips/atheros/ (props changed) user/ed/utmpx/sys/mips/cavium/ (props changed) user/ed/utmpx/sys/mips/rmi/ (props changed) user/ed/utmpx/sys/mips/sibyte/ (props changed) Deleted: user/ed/utmpx/contrib/one-true-awk/mac.code user/ed/utmpx/lib/libc/mips/gen/fpgetmask.c user/ed/utmpx/lib/libc/mips/gen/fpgetround.c user/ed/utmpx/lib/libc/mips/gen/fpgetsticky.c user/ed/utmpx/lib/libc/mips/gen/fpsetmask.c user/ed/utmpx/lib/libc/mips/gen/fpsetround.c user/ed/utmpx/lib/libc/mips/gen/fpsetsticky.c user/ed/utmpx/sys/boot/efi/libefi/efifs.c user/ed/utmpx/sys/mips/sentry5/siba_cc.c user/ed/utmpx/sys/mips/sentry5/siba_mips.c user/ed/utmpx/sys/mips/sentry5/siba_sdram.c user/ed/utmpx/sys/sys/semaphore.h user/ed/utmpx/usr.bin/awk/b.c.diff user/ed/utmpx/usr.bin/awk/main.c.diff user/ed/utmpx/usr.bin/awk/run.c.diff Modified: user/ed/utmpx/Makefile user/ed/utmpx/ObsoleteFiles.inc user/ed/utmpx/UPDATING user/ed/utmpx/contrib/gcc/config/mips/freebsd.h user/ed/utmpx/contrib/one-true-awk/FIXES user/ed/utmpx/contrib/one-true-awk/b.c user/ed/utmpx/contrib/one-true-awk/lib.c user/ed/utmpx/contrib/one-true-awk/main.c user/ed/utmpx/contrib/one-true-awk/makefile user/ed/utmpx/contrib/one-true-awk/maketab.c user/ed/utmpx/contrib/one-true-awk/proctab.c user/ed/utmpx/contrib/one-true-awk/proto.h user/ed/utmpx/contrib/one-true-awk/run.c user/ed/utmpx/contrib/tcp_wrappers/hosts_access.c user/ed/utmpx/etc/rc.firewall user/ed/utmpx/games/fortune/datfiles/fortunes user/ed/utmpx/games/fortune/datfiles/fortunes-o.real user/ed/utmpx/games/pom/pom.6 user/ed/utmpx/games/pom/pom.c user/ed/utmpx/gnu/lib/libgcc/Makefile user/ed/utmpx/gnu/usr.bin/binutils/Makefile.inc0 user/ed/utmpx/gnu/usr.bin/binutils/ld/Makefile.mips user/ed/utmpx/gnu/usr.bin/cc/Makefile.tgt user/ed/utmpx/include/Makefile user/ed/utmpx/include/dirent.h user/ed/utmpx/include/strings.h user/ed/utmpx/kerberos5/usr.bin/kdestroy/Makefile user/ed/utmpx/kerberos5/usr.bin/kpasswd/Makefile user/ed/utmpx/lib/libc/Makefile user/ed/utmpx/lib/libc/gen/Makefile.inc user/ed/utmpx/lib/libc/gen/Symbol.map user/ed/utmpx/lib/libc/gen/_pthread_stubs.c user/ed/utmpx/lib/libc/gen/opendir.c user/ed/utmpx/lib/libc/gen/scandir.c user/ed/utmpx/lib/libc/gen/sem.c user/ed/utmpx/lib/libc/gen/sem_init.3 user/ed/utmpx/lib/libc/gen/sem_open.3 user/ed/utmpx/lib/libc/include/libc_private.h user/ed/utmpx/lib/libc/mips/Symbol.map user/ed/utmpx/lib/libc/mips/sys/brk.S user/ed/utmpx/lib/libc/rpc/getnetpath.c user/ed/utmpx/lib/libc/rpc/svc_auth_des.c user/ed/utmpx/lib/libc/stdio/getc.3 user/ed/utmpx/lib/libc/stdtime/localtime.c user/ed/utmpx/lib/libc/sys/cpuset.2 user/ed/utmpx/lib/libc/sys/cpuset_getaffinity.2 user/ed/utmpx/lib/libc/sys/sendfile.2 user/ed/utmpx/lib/libstand/dosfs.c user/ed/utmpx/lib/libthr/arch/mips/include/pthread_md.h user/ed/utmpx/lib/libthr/pthread.map user/ed/utmpx/lib/libthr/thread/thr_init.c user/ed/utmpx/lib/libthr/thread/thr_private.h user/ed/utmpx/lib/libthr/thread/thr_sem.c user/ed/utmpx/release/doc/share/misc/dev.archlist.txt user/ed/utmpx/sbin/dumpfs/dumpfs.c user/ed/utmpx/sbin/fsck_ffs/fsutil.c user/ed/utmpx/sbin/fsck_ffs/main.c user/ed/utmpx/sbin/fsck_ffs/pass1.c user/ed/utmpx/sbin/geom/class/raid3/geom_raid3.c user/ed/utmpx/sbin/geom/class/raid3/graid3.8 user/ed/utmpx/sbin/geom/class/stripe/geom_stripe.c user/ed/utmpx/share/man/man3/Makefile user/ed/utmpx/share/man/man3/pthread.3 user/ed/utmpx/share/man/man3/pthread_attr.3 user/ed/utmpx/share/man/man4/bridge.4 user/ed/utmpx/share/man/man4/carp.4 user/ed/utmpx/share/man/man4/faith.4 user/ed/utmpx/share/man/man4/uart.4 user/ed/utmpx/share/man/man7/security.7 user/ed/utmpx/share/man/man9/VFS.9 user/ed/utmpx/share/man/man9/VFS_CHECKEXP.9 user/ed/utmpx/share/man/man9/VFS_FHTOVP.9 user/ed/utmpx/share/man/man9/sleepqueue.9 user/ed/utmpx/share/mk/bsd.libnames.mk user/ed/utmpx/sys/amd64/amd64/sys_machdep.c user/ed/utmpx/sys/amd64/conf/DEFAULTS user/ed/utmpx/sys/amd64/conf/Makefile user/ed/utmpx/sys/arm/conf/DEFAULTS user/ed/utmpx/sys/boot/common/bootstrap.h user/ed/utmpx/sys/boot/common/dev_net.c user/ed/utmpx/sys/boot/efi/include/efilib.h user/ed/utmpx/sys/boot/efi/libefi/Makefile user/ed/utmpx/sys/boot/ia64/efi/conf.c user/ed/utmpx/sys/boot/ia64/efi/main.c user/ed/utmpx/sys/boot/ia64/efi/version user/ed/utmpx/sys/boot/sparc64/loader/Makefile user/ed/utmpx/sys/boot/zfs/zfsimpl.c user/ed/utmpx/sys/cam/ata/ata_xpt.c user/ed/utmpx/sys/cam/scsi/scsi_ses.c user/ed/utmpx/sys/cam/scsi/scsi_targ_bh.c user/ed/utmpx/sys/cddl/boot/zfs/zfsimpl.h user/ed/utmpx/sys/cddl/boot/zfs/zfssubr.c user/ed/utmpx/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c user/ed/utmpx/sys/compat/linux/linux_futex.c user/ed/utmpx/sys/conf/Makefile.mips user/ed/utmpx/sys/conf/NOTES user/ed/utmpx/sys/conf/files user/ed/utmpx/sys/conf/files.mips user/ed/utmpx/sys/conf/kern.mk user/ed/utmpx/sys/conf/ldscript.mips user/ed/utmpx/sys/conf/makeLINT.mk user/ed/utmpx/sys/conf/options user/ed/utmpx/sys/conf/options.mips user/ed/utmpx/sys/contrib/ngatm/netnatm/api/cc_conn.c user/ed/utmpx/sys/ddb/db_ps.c user/ed/utmpx/sys/dev/aac/aac.c user/ed/utmpx/sys/dev/acpi_support/acpi_ibm.c user/ed/utmpx/sys/dev/agp/agp.c user/ed/utmpx/sys/dev/amd/amd.c user/ed/utmpx/sys/dev/amr/amr.c user/ed/utmpx/sys/dev/arcmsr/arcmsr.c user/ed/utmpx/sys/dev/ata/ata-all.c user/ed/utmpx/sys/dev/ata/ata-raid.c user/ed/utmpx/sys/dev/ata/chipsets/ata-ahci.c user/ed/utmpx/sys/dev/ata/chipsets/ata-ati.c user/ed/utmpx/sys/dev/ata/chipsets/ata-siliconimage.c user/ed/utmpx/sys/dev/ath/ath_hal/ar5211/ar5211_reset.c user/ed/utmpx/sys/dev/ath/ath_hal/ar5212/ar5212_interrupts.c user/ed/utmpx/sys/dev/ath/ath_hal/ar5416/ar5416_interrupts.c user/ed/utmpx/sys/dev/bktr/bktr_i2c.c user/ed/utmpx/sys/dev/cardbus/cardbus.c user/ed/utmpx/sys/dev/cs/if_cs.c user/ed/utmpx/sys/dev/cxgb/common/cxgb_t3_hw.c user/ed/utmpx/sys/dev/cxgb/cxgb_sge.c user/ed/utmpx/sys/dev/de/if_de.c user/ed/utmpx/sys/dev/dpt/dpt.h user/ed/utmpx/sys/dev/dpt/dpt_scsi.c user/ed/utmpx/sys/dev/e1000/if_em.c user/ed/utmpx/sys/dev/ep/if_ep.c user/ed/utmpx/sys/dev/ex/if_ex.c user/ed/utmpx/sys/dev/fatm/if_fatm.c user/ed/utmpx/sys/dev/firewire/sbp.c user/ed/utmpx/sys/dev/hatm/if_hatm.c user/ed/utmpx/sys/dev/hptmv/entry.c user/ed/utmpx/sys/dev/if_ndis/if_ndis.c user/ed/utmpx/sys/dev/if_ndis/if_ndis_usb.c user/ed/utmpx/sys/dev/iir/iir.c user/ed/utmpx/sys/dev/iir/iir_pci.c user/ed/utmpx/sys/dev/iscsi/initiator/isc_sm.c user/ed/utmpx/sys/dev/isp/isp.c user/ed/utmpx/sys/dev/isp/isp_library.c user/ed/utmpx/sys/dev/iwn/if_iwn.c user/ed/utmpx/sys/dev/iwn/if_iwnvar.h user/ed/utmpx/sys/dev/ixgbe/ixgbe.c user/ed/utmpx/sys/dev/jme/if_jme.c user/ed/utmpx/sys/dev/lmc/if_lmc.c user/ed/utmpx/sys/dev/malo/if_malo.c user/ed/utmpx/sys/dev/mge/if_mge.c user/ed/utmpx/sys/dev/mly/mly.c user/ed/utmpx/sys/dev/mxge/if_mxge.c user/ed/utmpx/sys/dev/patm/if_patm_intr.c user/ed/utmpx/sys/dev/pci/pci.c user/ed/utmpx/sys/dev/pci/pci_private.h user/ed/utmpx/sys/dev/pdq/if_fea.c user/ed/utmpx/sys/dev/safe/safe.c user/ed/utmpx/sys/dev/sound/pci/maestro3.c user/ed/utmpx/sys/dev/ste/if_ste.c user/ed/utmpx/sys/dev/trm/trm.c user/ed/utmpx/sys/dev/usb/controller/musb_otg.c user/ed/utmpx/sys/dev/usb/controller/uhci.c user/ed/utmpx/sys/dev/usb/quirk/usb_quirk.c user/ed/utmpx/sys/dev/usb/serial/u3g.c user/ed/utmpx/sys/dev/usb/storage/umass.c user/ed/utmpx/sys/dev/usb/usb_device.c user/ed/utmpx/sys/dev/usb/usb_msctest.c user/ed/utmpx/sys/dev/usb/usb_msctest.h user/ed/utmpx/sys/dev/usb/usbdevs user/ed/utmpx/sys/fs/procfs/procfs_status.c user/ed/utmpx/sys/fs/smbfs/smbfs_smb.c user/ed/utmpx/sys/fs/tmpfs/tmpfs_vfsops.c user/ed/utmpx/sys/geom/geom_slice.c user/ed/utmpx/sys/geom/mirror/g_mirror.c user/ed/utmpx/sys/geom/part/g_part.c user/ed/utmpx/sys/geom/raid3/g_raid3.c user/ed/utmpx/sys/geom/uzip/g_uzip.c user/ed/utmpx/sys/gnu/fs/xfs/FreeBSD/xfs_vnops.c user/ed/utmpx/sys/i386/conf/DEFAULTS user/ed/utmpx/sys/i386/conf/Makefile user/ed/utmpx/sys/i386/conf/PAE user/ed/utmpx/sys/i386/i386/locore.s user/ed/utmpx/sys/i386/i386/pmap.c user/ed/utmpx/sys/i386/include/pmap.h user/ed/utmpx/sys/i386/xen/locore.s user/ed/utmpx/sys/i386/xen/pmap.c user/ed/utmpx/sys/ia64/conf/DEFAULTS user/ed/utmpx/sys/ia64/conf/Makefile user/ed/utmpx/sys/isa/pnp.c user/ed/utmpx/sys/kern/kern_clock.c user/ed/utmpx/sys/kern/kern_cpu.c user/ed/utmpx/sys/kern/kern_fail.c user/ed/utmpx/sys/kern/kern_lock.c user/ed/utmpx/sys/kern/kern_mib.c user/ed/utmpx/sys/kern/kern_umtx.c user/ed/utmpx/sys/kern/sched_4bsd.c user/ed/utmpx/sys/kern/subr_firmware.c user/ed/utmpx/sys/kern/subr_sleepqueue.c user/ed/utmpx/sys/kern/subr_turnstile.c user/ed/utmpx/sys/kern/tty.c user/ed/utmpx/sys/kern/tty_compat.c user/ed/utmpx/sys/kern/tty_pts.c user/ed/utmpx/sys/kern/uipc_sem.c user/ed/utmpx/sys/mips/adm5120/if_admsw.c user/ed/utmpx/sys/mips/conf/DEFAULTS user/ed/utmpx/sys/mips/include/sysarch.h user/ed/utmpx/sys/mips/mips/elf_machdep.c user/ed/utmpx/sys/modules/crypto/Makefile user/ed/utmpx/sys/net/flowtable.c user/ed/utmpx/sys/net/if_bridge.c user/ed/utmpx/sys/net/if_epair.c user/ed/utmpx/sys/net/if_ethersubr.c user/ed/utmpx/sys/net/if_lagg.c user/ed/utmpx/sys/net80211/ieee80211_node.c user/ed/utmpx/sys/net80211/ieee80211_var.h user/ed/utmpx/sys/netgraph/ng_ether.c user/ed/utmpx/sys/netgraph/ng_ipfw.c user/ed/utmpx/sys/netinet/if_ether.c user/ed/utmpx/sys/netinet/in.c user/ed/utmpx/sys/netinet/ip_carp.c user/ed/utmpx/sys/netinet/ip_divert.c user/ed/utmpx/sys/netinet/ip_divert.h user/ed/utmpx/sys/netinet/ip_dummynet.h user/ed/utmpx/sys/netinet/ip_var.h user/ed/utmpx/sys/netinet/ipfw/ip_dummynet.c user/ed/utmpx/sys/netinet/ipfw/ip_fw2.c user/ed/utmpx/sys/netinet/ipfw/ip_fw_dynamic.c user/ed/utmpx/sys/netinet/ipfw/ip_fw_log.c user/ed/utmpx/sys/netinet/ipfw/ip_fw_nat.c user/ed/utmpx/sys/netinet/ipfw/ip_fw_pfil.c user/ed/utmpx/sys/netinet/ipfw/ip_fw_private.h user/ed/utmpx/sys/netinet/ipfw/ip_fw_sockopt.c user/ed/utmpx/sys/netinet/ipfw/ip_fw_table.c user/ed/utmpx/sys/netinet/libalias/alias_db.c user/ed/utmpx/sys/netinet/libalias/alias_mod.c user/ed/utmpx/sys/netinet/raw_ip.c user/ed/utmpx/sys/netinet/sctp_asconf.c user/ed/utmpx/sys/netinet/sctputil.c user/ed/utmpx/sys/netinet6/icmp6.c user/ed/utmpx/sys/netinet6/ip6_input.c user/ed/utmpx/sys/netinet6/nd6_rtr.c user/ed/utmpx/sys/nfsclient/bootp_subr.c user/ed/utmpx/sys/nfsclient/nfs_vfsops.c user/ed/utmpx/sys/nfsclient/nfs_vnops.c user/ed/utmpx/sys/nfsserver/nfs.h user/ed/utmpx/sys/nfsserver/nfs_fha.c user/ed/utmpx/sys/nfsserver/nfs_srvkrpc.c user/ed/utmpx/sys/opencrypto/cryptosoft.c user/ed/utmpx/sys/pc98/conf/DEFAULTS user/ed/utmpx/sys/pc98/conf/Makefile user/ed/utmpx/sys/pci/ncr.c user/ed/utmpx/sys/powerpc/aim/mmu_oea.c user/ed/utmpx/sys/powerpc/aim/mmu_oea64.c user/ed/utmpx/sys/powerpc/booke/pmap.c user/ed/utmpx/sys/powerpc/conf/DEFAULTS user/ed/utmpx/sys/powerpc/conf/Makefile user/ed/utmpx/sys/rpc/clnt_dg.c user/ed/utmpx/sys/rpc/rpcsec_gss/rpcsec_gss_prot.c user/ed/utmpx/sys/rpc/rpcsec_gss/svc_rpcsec_gss.c user/ed/utmpx/sys/sparc64/conf/DEFAULTS user/ed/utmpx/sys/sparc64/conf/GENERIC user/ed/utmpx/sys/sparc64/conf/Makefile user/ed/utmpx/sys/sun4v/conf/DEFAULTS user/ed/utmpx/sys/sun4v/conf/Makefile user/ed/utmpx/sys/sys/_semaphore.h user/ed/utmpx/sys/sys/proc.h user/ed/utmpx/sys/sys/sleepqueue.h user/ed/utmpx/sys/sys/socket.h user/ed/utmpx/sys/sys/tty.h user/ed/utmpx/sys/ufs/ffs/ffs_snapshot.c user/ed/utmpx/sys/ufs/ufs/ufs_dirhash.c user/ed/utmpx/sys/xen/xenbus/xenbus_probe.c user/ed/utmpx/tools/build/mk/OptionalObsoleteFiles.inc user/ed/utmpx/tools/regression/usr.bin/make/common.sh user/ed/utmpx/usr.bin/awk/Makefile user/ed/utmpx/usr.bin/ctags/Makefile user/ed/utmpx/usr.bin/ctags/ctags.c user/ed/utmpx/usr.bin/ctags/fortran.c user/ed/utmpx/usr.bin/last/last.c user/ed/utmpx/usr.bin/make/dir.c user/ed/utmpx/usr.bin/make/dir.h user/ed/utmpx/usr.bin/make/main.c user/ed/utmpx/usr.bin/make/make.1 user/ed/utmpx/usr.bin/tcopy/tcopy.c user/ed/utmpx/usr.bin/unzip/unzip.c user/ed/utmpx/usr.bin/w/Makefile user/ed/utmpx/usr.bin/w/w.c user/ed/utmpx/usr.bin/xlint/xlint/Makefile user/ed/utmpx/usr.bin/xlint/xlint/xlint.c user/ed/utmpx/usr.sbin/cdcontrol/Makefile user/ed/utmpx/usr.sbin/cdcontrol/cdcontrol.c user/ed/utmpx/usr.sbin/faithd/faithd.8 user/ed/utmpx/usr.sbin/mergemaster/mergemaster.8 user/ed/utmpx/usr.sbin/mergemaster/mergemaster.sh user/ed/utmpx/usr.sbin/traceroute/Makefile user/ed/utmpx/usr.sbin/usbconfig/Makefile user/ed/utmpx/usr.sbin/usbconfig/dump.c user/ed/utmpx/usr.sbin/usbconfig/dump.h user/ed/utmpx/usr.sbin/usbconfig/usbconfig.8 user/ed/utmpx/usr.sbin/usbconfig/usbconfig.c Directory Properties: user/ed/utmpx/ (props changed) user/ed/utmpx/contrib/one-true-awk/ (props changed) user/ed/utmpx/sys/mips/rmi/dev/ (props changed) Modified: user/ed/utmpx/Makefile ============================================================================== --- user/ed/utmpx/Makefile Sun Jan 10 13:15:58 2010 (r201997) +++ user/ed/utmpx/Makefile Sun Jan 10 13:30:45 2010 (r201998) @@ -278,7 +278,7 @@ tinderbox: # with a reasonable chance of success, regardless of how old your # existing system is. # -.if make(universe) || make(tinderbox) +.if make(universe) || make(universe_kernels) || make(tinderbox) TARGETS?=amd64 arm i386 ia64 mips pc98 powerpc sparc64 sun4v .if defined(DOING_TINDERBOX) @@ -297,10 +297,6 @@ universe_prologue: rm -f ${FAILFILE} .endif .for target in ${TARGETS} -KERNCONFS!= cd ${.CURDIR}/sys/${target}/conf && \ - find [A-Z0-9]*[A-Z0-9] -type f -maxdepth 0 \ - ! -name DEFAULTS ! -name LINT -KERNCONFS:= ${KERNCONFS:S/^NOTES$/LINT/} universe: universe_${target} .ORDER: universe_prologue universe_${target} universe_epilogue universe_${target}: @@ -320,16 +316,25 @@ universe_${target}: (echo "${target} 'make LINT' failed," \ "check _.${target}.makeLINT for details"| ${MAKEFAIL})) .endif + @cd ${.CURDIR} && ${MAKE} ${.MAKEFLAGS} TARGET=${target} \ + universe_kernels + @echo ">> ${target} completed on `LC_ALL=C date`" +.endfor +universe_kernels: universe_kernconfs +XMACHINE!= uname -m +TARGET?= ${XMACHINE} +KERNCONFS!= cd ${.CURDIR}/sys/${TARGET}/conf && \ + find [A-Z0-9]*[A-Z0-9] -type f -maxdepth 0 \ + ! -name DEFAULTS ! -name NOTES +universe_kernconfs: .for kernel in ${KERNCONFS} @(cd ${.CURDIR} && env __MAKE_CONF=/dev/null \ ${MAKE} ${JFLAG} buildkernel \ - TARGET=${target} \ + TARGET=${TARGET} \ KERNCONF=${kernel} \ - > _.${target}.${kernel} 2>&1 || \ - (echo "${target} ${kernel} kernel failed," \ - "check _.${target}.${kernel} for details"| ${MAKEFAIL})) -.endfor - @echo ">> ${target} completed on `LC_ALL=C date`" + > _.${TARGET}.${kernel} 2>&1 || \ + (echo "${TARGET} ${kernel} kernel failed," \ + "check _.${TARGET}.${kernel} for details"| ${MAKEFAIL})) .endfor universe: universe_epilogue universe_epilogue: Modified: user/ed/utmpx/ObsoleteFiles.inc ============================================================================== --- user/ed/utmpx/ObsoleteFiles.inc Sun Jan 10 13:15:58 2010 (r201997) +++ user/ed/utmpx/ObsoleteFiles.inc Sun Jan 10 13:30:45 2010 (r201998) @@ -14,7 +14,7 @@ # The file is partitioned: OLD_FILES first, then OLD_LIBS and OLD_DIRS last. # -# 20100104: utmp and utility functions replaced by utmpx +# 20100110: utmp and utility functions replaced by utmpx OLD_FILES+=usr/share/man/man3/login.3.gz OLD_FILES+=usr/share/man/man3/logout.3.gz OLD_FILES+=usr/share/man/man3/logwtmp.3.gz @@ -29,6 +29,8 @@ OLD_FILES+=usr/share/man/man5/lastlog.5. OLD_FILES+=usr/share/man/man5/utmp.5.gz OLD_FILES+=usr/share/man/man5/wtmp.5.gz OLD_LIBS+=lib/libutil.so.8 +# 20100105: new userland semaphore implementation +OLD_FILES+=usr/include/sys/semaphore.h # 20100103: ntptrace(8) removed OLD_FILES+=usr/sbin/ntptrace OLD_FILES+=usr/share/man/man8/ntptrace.8.gz Modified: user/ed/utmpx/UPDATING ============================================================================== --- user/ed/utmpx/UPDATING Sun Jan 10 13:15:58 2010 (r201997) +++ user/ed/utmpx/UPDATING Sun Jan 10 13:30:45 2010 (r201998) @@ -22,6 +22,11 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 9. machines to maximize performance. (To disable malloc debugging, run ln -s aj /etc/malloc.conf.) +20100108: + Introduce the kernel thread "deadlock resolver" (which can be enabled + via the DEADLKRES option, see NOTES for more details) and the + sleepq_type() function for sleepqueues. + 20091202: The rc.firewall and rc.firewall6 were unified, and rc.firewall6 and rc.d/ip6fw were removed. Modified: user/ed/utmpx/contrib/gcc/config/mips/freebsd.h ============================================================================== --- user/ed/utmpx/contrib/gcc/config/mips/freebsd.h Sun Jan 10 13:15:58 2010 (r201997) +++ user/ed/utmpx/contrib/gcc/config/mips/freebsd.h Sun Jan 10 13:30:45 2010 (r201998) @@ -97,6 +97,9 @@ Boston, MA 02110-1301, USA. */ Needs to agree with . GCC defaults come from c-decl.c, c-common.c, and config//.h. */ +#undef TARGET_DEFAULT +#define TARGET_DEFAULT (MASK_ABICALLS | MASK_SOFT_FLOAT) + #if TARGET_ENDIAN_DEFAULT != 0 #define TARGET_VERSION fprintf (stderr, " (FreeBSD/mips)"); #else Modified: user/ed/utmpx/contrib/one-true-awk/FIXES ============================================================================== --- user/ed/utmpx/contrib/one-true-awk/FIXES Sun Jan 10 13:15:58 2010 (r201997) +++ user/ed/utmpx/contrib/one-true-awk/FIXES Sun Jan 10 13:30:45 2010 (r201998) @@ -25,6 +25,23 @@ THIS SOFTWARE. This file lists all bug fixes, changes, etc., made since the AWK book was sent to the printers in August, 1987. +Nov 26, 2009: + fixed a long-standing issue with when FS takes effect. a + change to FS is now noticed immediately for subsequent splits. + + changed the name getline() to awkgetline() to avoid yet another + name conflict somewhere. + +Feb 11, 2009: + temporarily for now defined HAS_ISBLANK, since that seems to + be the best way through the thicket. isblank arrived in C99, + but seems to be arriving at different systems at different + times. + +Oct 8, 2008: + fixed typo in b.c that set tmpvec wrongly. no one had ever + run into the problem, apparently. thanks to alistair crooks. + Oct 23, 2007: minor fix in lib.c: increase inputFS to 100, change malloc for fields to n+1. Modified: user/ed/utmpx/contrib/one-true-awk/b.c ============================================================================== --- user/ed/utmpx/contrib/one-true-awk/b.c Sun Jan 10 13:15:58 2010 (r201997) +++ user/ed/utmpx/contrib/one-true-awk/b.c Sun Jan 10 13:30:45 2010 (r201998) @@ -24,6 +24,9 @@ THIS SOFTWARE. /* lasciate ogne speranza, voi ch'intrate. */ +#include +__FBSDID("$FreeBSD$"); + #define DEBUG #include @@ -285,9 +288,21 @@ int quoted(char **pp) /* pick up next th return c; } +static int collate_range_cmp(int a, int b) +{ + static char s[2][2]; + + if ((uschar)a == (uschar)b) + return 0; + s[0][0] = a; + s[1][0] = b; + return (strcoll(s[0], s[1])); +} + char *cclenter(const char *argp) /* add a character class */ { int i, c, c2; + int j; uschar *p = (uschar *) argp; uschar *op, *bp; static uschar *buf = 0; @@ -306,15 +321,18 @@ char *cclenter(const char *argp) /* add c2 = *p++; if (c2 == '\\') c2 = quoted((char **) &p); - if (c > c2) { /* empty; ignore */ + if (collate_range_cmp(c, c2) > 0) { bp--; i--; continue; } - while (c < c2) { + for (j = 0; j < NCHARS; j++) { + if ((collate_range_cmp(c, j) > 0) || + collate_range_cmp(j, c2) > 0) + continue; if (!adjbuf((char **) &buf, &bufsz, bp-buf+2, 100, (char **) &bp, "cclenter1")) FATAL("out of space for character class [%.10s...] 2", p); - *bp++ = ++c; + *bp++ = j; i++; } continue; @@ -731,6 +749,7 @@ Node *unary(Node *np) * to nelson beebe for the suggestion; let's see if it works everywhere. */ +/* #define HAS_ISBLANK */ #ifndef HAS_ISBLANK int (isblank)(int c) @@ -876,7 +895,7 @@ int cgoto(fa *f, int s, int c) if (q[j] >= maxsetvec) { maxsetvec *= 4; setvec = (int *) realloc(setvec, maxsetvec * sizeof(int)); - tmpset = (int *) realloc(setvec, maxsetvec * sizeof(int)); + tmpset = (int *) realloc(tmpset, maxsetvec * sizeof(int)); if (setvec == 0 || tmpset == 0) overflo("cgoto overflow"); } Modified: user/ed/utmpx/contrib/one-true-awk/lib.c ============================================================================== --- user/ed/utmpx/contrib/one-true-awk/lib.c Sun Jan 10 13:15:58 2010 (r201997) +++ user/ed/utmpx/contrib/one-true-awk/lib.c Sun Jan 10 13:30:45 2010 (r201998) @@ -274,6 +274,7 @@ void fldbld(void) /* create fields from } fr = fields; i = 0; /* number of fields accumulated here */ + strcpy(inputFS, *FS); if (strlen(inputFS) > 1) { /* it's a regular expression */ i = refldbld(r, inputFS); } else if ((sep = *inputFS) == ' ') { /* default whitespace */ Modified: user/ed/utmpx/contrib/one-true-awk/main.c ============================================================================== --- user/ed/utmpx/contrib/one-true-awk/main.c Sun Jan 10 13:15:58 2010 (r201997) +++ user/ed/utmpx/contrib/one-true-awk/main.c Sun Jan 10 13:30:45 2010 (r201998) @@ -22,7 +22,10 @@ ARISING OUT OF OR IN CONNECTION WITH THE THIS SOFTWARE. ****************************************************************/ -const char *version = "version 20070501"; +#include +__FBSDID("$FreeBSD$"); + +const char *version = "version 20091126 (FreeBSD)"; #define DEBUG #include @@ -58,6 +61,7 @@ int main(int argc, char *argv[]) const char *fs = NULL; setlocale(LC_CTYPE, ""); + setlocale(LC_COLLATE, ""); setlocale(LC_NUMERIC, "C"); /* for parsing cmdline & prog */ cmdname = argv[0]; if (argc == 1) { @@ -86,13 +90,18 @@ int main(int argc, char *argv[]) safe = 1; break; case 'f': /* next argument is program filename */ - argc--; - argv++; - if (argc <= 1) - FATAL("no program filename"); - if (npfile >= MAX_PFILE - 1) - FATAL("too many -f options"); - pfile[npfile++] = argv[1]; + if (argv[1][2] != 0) { /* arg is -fsomething */ + if (npfile >= MAX_PFILE - 1) + FATAL("too many -f options"); + pfile[npfile++] = &argv[1][2]; + } else { /* arg is -f something */ + argc--; argv++; + if (argc <= 1) + FATAL("no program filename"); + if (npfile >= MAX_PFILE - 1) + FATAL("too many -f options"); + pfile[npfile++] = argv[1]; + } break; case 'F': /* set field separator */ if (argv[1][2] != 0) { /* arg is -Fsomething */ @@ -111,8 +120,14 @@ int main(int argc, char *argv[]) WARNING("field separator FS is empty"); break; case 'v': /* -v a=1 to be done NOW. one -v for each */ - if (argv[1][2] == '\0' && --argc > 1 && isclvar((++argv)[1])) - setclvar(argv[1]); + if (argv[1][2] != 0) { /* arg is -vsomething */ + if (argv[1][2] != 0) + setclvar(&argv[1][2]); + } else { /* arg is -v something */ + argc--; argv++; + if (argc > 1 && isclvar(argv[1])) + setclvar(argv[1]); + } break; case 'd': dbg = atoi(&argv[1][2]); Modified: user/ed/utmpx/contrib/one-true-awk/makefile ============================================================================== --- user/ed/utmpx/contrib/one-true-awk/makefile Sun Jan 10 13:15:58 2010 (r201997) +++ user/ed/utmpx/contrib/one-true-awk/makefile Sun Jan 10 13:30:45 2010 (r201998) @@ -31,7 +31,6 @@ CC = gcc -fprofile-arcs -ftest-coverage CC = gcc -Wall -g CC = cc CC = gcc -O4 -CC = gcc -Wall -g YACC = bison -y Modified: user/ed/utmpx/contrib/one-true-awk/maketab.c ============================================================================== --- user/ed/utmpx/contrib/one-true-awk/maketab.c Sun Jan 10 13:15:58 2010 (r201997) +++ user/ed/utmpx/contrib/one-true-awk/maketab.c Sun Jan 10 13:30:45 2010 (r201998) @@ -102,7 +102,7 @@ struct xx { CALL, "call", "call" }, { ARG, "arg", "arg" }, { VARNF, "getnf", "NF" }, - { GETLINE, "getline", "getline" }, + { GETLINE, "awkgetline", "getline" }, { 0, "", "" }, }; Modified: user/ed/utmpx/contrib/one-true-awk/proctab.c ============================================================================== --- user/ed/utmpx/contrib/one-true-awk/proctab.c Sun Jan 10 13:15:58 2010 (r201997) +++ user/ed/utmpx/contrib/one-true-awk/proctab.c Sun Jan 10 13:30:45 2010 (r201998) @@ -180,7 +180,7 @@ Cell *(*proctab[93])(Node **, int) = { nullproc, /* NUMBER */ nullproc, /* STRING */ nullproc, /* REGEXPR */ - getline, /* GETLINE */ + awkgetline, /* GETLINE */ substr, /* SUBSTR */ split, /* SPLIT */ jump, /* RETURN */ Modified: user/ed/utmpx/contrib/one-true-awk/proto.h ============================================================================== --- user/ed/utmpx/contrib/one-true-awk/proto.h Sun Jan 10 13:15:58 2010 (r201997) +++ user/ed/utmpx/contrib/one-true-awk/proto.h Sun Jan 10 13:30:45 2010 (r201998) @@ -149,7 +149,7 @@ extern Cell *call(Node **, int); extern Cell *copycell(Cell *); extern Cell *arg(Node **, int); extern Cell *jump(Node **, int); -extern Cell *getline(Node **, int); +extern Cell *awkgetline(Node **, int); extern Cell *getnf(Node **, int); extern Cell *array(Node **, int); extern Cell *awkdelete(Node **, int); Modified: user/ed/utmpx/contrib/one-true-awk/run.c ============================================================================== --- user/ed/utmpx/contrib/one-true-awk/run.c Sun Jan 10 13:15:58 2010 (r201997) +++ user/ed/utmpx/contrib/one-true-awk/run.c Sun Jan 10 13:30:45 2010 (r201998) @@ -22,6 +22,9 @@ ARISING OUT OF OR IN CONNECTION WITH THE THIS SOFTWARE. ****************************************************************/ +#include +__FBSDID("$FreeBSD$"); + #define DEBUG #include #include @@ -388,7 +391,7 @@ Cell *jump(Node **a, int n) /* break, co return 0; /* not reached */ } -Cell *getline(Node **a, int n) /* get next line from specific input */ +Cell *awkgetline(Node **a, int n) /* get next line from specific input */ { /* a[0] is variable, a[1] is operator, a[2] is filename */ Cell *r, *x; extern Cell **fldtab; @@ -653,7 +656,7 @@ Cell *relop(Node **a, int n) /* a[0 < a[ j = x->fval - y->fval; i = j<0? -1: (j>0? 1: 0); } else { - i = strcmp(getsval(x), getsval(y)); + i = strcoll(getsval(x), getsval(y)); } tempfree(x); tempfree(y); @@ -1159,11 +1162,11 @@ Cell *cat(Node **a, int q) /* a[0] cat a x->sval, y->sval); strcpy(s, x->sval); strcpy(s+n1, y->sval); + tempfree(x); tempfree(y); z = gettemp(); z->sval = s; z->tval = STR; - tempfree(x); return(z); } Modified: user/ed/utmpx/contrib/tcp_wrappers/hosts_access.c ============================================================================== --- user/ed/utmpx/contrib/tcp_wrappers/hosts_access.c Sun Jan 10 13:15:58 2010 (r201997) +++ user/ed/utmpx/contrib/tcp_wrappers/hosts_access.c Sun Jan 10 13:30:45 2010 (r201998) @@ -148,6 +148,7 @@ struct request_info *request; char *sh_cmd; /* becomes optional shell command */ int match = NO; struct tcpd_context saved_context; + char *cp; saved_context = tcpd_context; /* stupid compilers */ @@ -164,7 +165,16 @@ struct request_info *request; tcpd_warn("missing newline or line too long"); continue; } - if (sv_list[0] == '#' || sv_list[strspn(sv_list, " \t\r\n")] == 0) + /* Ignore anything after unescaped # character */ + for (cp = strchr(sv_list, '#'); cp != NULL;) { + if (cp > sv_list && cp[-1] == '\\') { + cp = strchr(cp + 1, '#'); + continue; + } + *cp = '\0'; + break; + } + if (sv_list[strspn(sv_list, " \t\r\n")] == 0) continue; if ((cl_list = split_at(sv_list, ':')) == 0) { tcpd_warn("missing \":\" separator"); Modified: user/ed/utmpx/etc/rc.firewall ============================================================================== --- user/ed/utmpx/etc/rc.firewall Sun Jan 10 13:15:58 2010 (r201997) +++ user/ed/utmpx/etc/rc.firewall Sun Jan 10 13:30:45 2010 (r201998) @@ -220,6 +220,8 @@ case ${firewall_type} in # Allow any link-local multicast traffic ${fwcmd} add pass all from fe80::/10 to ff02::/16 ${fwcmd} add pass all from ${net6} to ff02::/16 + # Allow DHCPv6 + ${fwcmd} add pass udp from fe80::/10 to me6 546 fi # Allow TCP through if setup succeeded @@ -505,7 +507,10 @@ case ${firewall_type} in # Allow "mandatory" ICMP in. ${fwcmd} add pass icmp from any to any icmptype 3,4,11 - + if [ $ipv6_available -eq 0 ]; then + ${fwcmd} add pass ipv6-icmp from any to any icmp6type 3 + fi + # Add permits for this workstations published services below # Only IPs and nets in firewall_allowservices is allowed in. # If you really wish to let anyone use services on your Modified: user/ed/utmpx/games/fortune/datfiles/fortunes ============================================================================== --- user/ed/utmpx/games/fortune/datfiles/fortunes Sun Jan 10 13:15:58 2010 (r201997) +++ user/ed/utmpx/games/fortune/datfiles/fortunes Sun Jan 10 13:30:45 2010 (r201998) @@ -1604,13 +1604,6 @@ friends and family, and then justify thi for doing it." -- Bruce Feirstein, "Nice Guys Sleep Alone" % - As we know, there are known knowns. There are things we know we -know. We also know there are known unknowns. That is to say, we know -there're some things we do not know. But there're also unknown unknowns; -the ones we don't know we don't know." - -- Defense Secretary Donald Rumsfeld, - about the invasion to Iraq. -% At a recent meeting in Snowmass, Colorado, a participant from Los Angeles fainted from hyperoxygenation, and we had to hold his head under the exhaust of a bus until he revived. @@ -1703,14 +1696,6 @@ the Cat. "Then it doesn't matter which way you go," said the Cat. -- Lewis Carroll % - COMMENT - -Oh, life is a glorious cycle of song, -A medley of extemporanea; -And love is thing that can never go wrong; -And I am Marie of Roumania. - -- Dorothy Parker -% Concerning the war in Vietnam, Senator George Aiken of Vermont noted in January, 1966, "I'm not very keen for doves or hawks. I think we need more owls." @@ -1930,22 +1915,6 @@ Christmas tree. The piano is missing. you rent your home and own Firearms, in which case you can go to level 4. The best way to get to level 3 is egg-nog. % - FIGHTING WORDS - -Say my love is easy had, - Say I'm bitten raw with pride, -Say I am too often sad -- - Still behold me at your side. - -Say I'm neither brave nor young, - Say I woo and coddle care, -Say the devil touched my tongue -- - Still you have my heart to wear. - -But say my verses do not scan, - And I get me another man! - -- Dorothy Parker -% "For I perceive that behind this seemingly unrelated sequence of events, there lurks a singular, sinister attitude of mind." @@ -2217,20 +2186,6 @@ full of money before." "Didn't you see it?" "Damn kid had it under his coat." % - Hug O' War - -I will not play at tug o' war. -I'd rather play at hug o' war, -Where everyone hugs -Instead of tugs, -Where everyone giggles -And rolls on the rug, -Where everyone kisses, -And everyone grins, -And everyone cuddles, -And everyone wins. - -- Shel Silverstein -% Human thinking can skip over a great deal, leap over small misunderstandings, can contain ifs and buts in untroubled corners of the mind. But the machine has no corners. Despite all the attempts to @@ -2684,33 +2639,6 @@ right any day." life-style otherwise." -- Douglas Adams, "The Hitchhiker's Guide to the Galaxy" % - Insofar as I may be heard by anything, which may or may not care -what I say, I ask, if it matters, that you be forgiven for anything you -may have done or failed to do which requires forgiveness. Conversely, if -not forgiveness but something else may be required to insure any possible -benefit for which you may be eligible after the destruction of your body, -I ask this, whatever it may be, be granted or withheld, as the case may be, -in such a manner as to insure your receiving said benefit. I ask this in my -capacity as your elected intermediary between yourself and that which may -not be yourself, but which may have an interest in the matter of your -receiving as much as it is possible for you to receive of this thing, and -which may in some way be influenced by this ceremony. - Amen. - -- Roger Zelazny, "Creatures of Light and Darkness", 1969 -% - INVENTORY -Four be the things I am wiser to know: -Idleness, sorrow, a friend, and a foe. - -Four be the things I'd been better without: -Love, curiosity, freckles, and doubt. - -Three be the things I shall never attain: -Envy, content, and sufficient champagne. - -Three be the things I shall have till I die: -Laughter and hope and a sock in the eye. -% "Is there any point to which you would wish to draw my attention?" "To the curious incident of the dog in the night-time." "The dog did nothing in the night-time." @@ -3990,28 +3918,6 @@ almost succeeded in getting a VAX to thi organization say that each time the machine fails to think it ceases to exist. % - THE LESSER-KNOWN PROGRAMMING LANGUAGES #5: VALGOL -From its modest beginnings in Southern California's San Fernando Valley, -VALGOL is enjoying a dramatic surge of popularity across the industry. - -Here is a sample program: - LIKE, Y*KNOW(I MEAN)START - IF PIZZA = LIKE BITCHEN AND GUY = LIKE TUBULAR AND - VALLEY GIRL = LIKE GRODY**MAX(FERSURE)**2 THEN - FOR I = LIKE 1 TO OH*MAYBE 100 - DO*WAH - (DITTY**2) - BARF(I)=TOTALLY GROSS(OUT) - SURE - LIKE BAG THIS PROGRAM - REALLY - LIKE TOTALLY (Y*KNOW) - IM*SURE - GOTO THE MALL - -When the user makes a syntax error, the interpreter displays the message: - - GAG ME WITH A SPOON!! -% THE LESSER-KNOWN PROGRAMMING LANGUAGES #8: LAIDBACK This language was developed at the Marin County Center for T'ai Chi, @@ -5342,9 +5248,6 @@ that he didn't force you down on the ask -- A plethora of individuals wither expertise in culinary techniques vitiated the potable concoction produced by steeping certain coupestibles. -- Eleemosynary deeds have their initial incidence intramurally. --- Male cadavers are incapable of yielding testimony. --- Individuals who make their abode in vitreous edifices would be well - advised to refrain from catapulting projectiles. % =============== ALL FRESHMEN PLEASE NOTE =============== @@ -11083,9 +10986,6 @@ Armstrong's Collection Law: If the check is truly in the mail, it is surely made out to someone else. % -Arnold's Addendum: - Anything not fitting into these categories causes cancer in rats. -% Arnold's Laws of Documentation: 1.) If it should exist, it doesn't. 2.) If it does exist, it's out of date. @@ -12661,7 +12561,7 @@ Boren's Laws: (2) When in trouble, delegate. (3) When in doubt, mumble. % -boss, n: +Boss, n: According to the Oxford English Dictionary, in the Middle Ages the words "boss" and "botch" were largely synonymous, except that boss, in addition to meaning "a supervisor of workers" also meant "an @@ -12942,7 +12842,7 @@ wrote the program. Fortunately, the second-to-last bug has just been fixed. -- Ray Simard % -bug, n: +Bug, n: An elusive creature living in a program that makes it incorrect. The activity of "debugging", or removing bugs from a program, ends when people get tired of doing it, not when the bugs are removed. @@ -13531,14 +13431,14 @@ only robust persons doing this thing is others who have tried it. -- Ambrose Bierce, "The Devil's Dictionary" % - -Certain passages in several laws have always defied interpretation and the -most inexplicable must be a matter of opinion. A judge of the Court of -Session of Scotland has sent the editors of this book his candidate which -reads, "In the Nuts (unground), (other than ground nuts) Order, the expression -nuts shall have reference to such nuts, other than ground nuts, as would -but for this amending Order not qualify as nuts (unground) (other than ground -nuts) by reason of their being nuts (unground)." +Certain passages in several laws have always defied interpretation and +the most inexplicable must be a matter of opinion. A judge of the Court +of Session of Scotland has sent the editors of this book his candidate +which reads, "In the Nuts (unground), (other than ground nuts) Order, +the expression nuts shall have reference to such nuts, other than ground +nuts, as would but for this amending Order not qualify as nuts +(unground) (other than ground nuts) by reason of their being nuts +(unground)." -- Guinness Book of World Records, 1973 % Certainly the game is rigged. @@ -15064,17 +14964,6 @@ letter, or even 25 cents on a stamp! so post it as many places as you can. -- Emily Postnews Answers Your Questions on Netiquette % -Dear Sir, - I am firmly opposed to the spread of microchips either to the home or -to the office. We have more than enough of them foisted upon us in public -places. They are a disgusting Americanism, and can only result in the farmers -being forced to grow smaller potatoes, which in turn will cause massive un- -employment in the already severely depressed agricultural industry. - Yours faithfully, - Capt. Quinton D'Arcy, J.P. - Sevenoaks - -- Letters To The Editor, The Times of London -% Death before dishonor. But neither before breakfast. % @@ -17845,9 +17734,6 @@ Finagle's Eleventh Law: it happened according to his pet theory. % Finagle's First Law: - If an experiment works, something has gone wrong. -% -Finagle's First Law: To study a subject best, understand it thoroughly before you start. Finagle's Second Law: @@ -18180,9 +18066,6 @@ For children with short attention spans: For courage mounteth with occasion. -- William Shakespeare, "King John" % -For every action, there is an equal and opposite criticism. - -- Harrison -% For every bloke who makes his mark, there's half a dozen waiting to rub it out. -- Andy Capp @@ -19527,17 +19410,6 @@ Your butt is on the menu And the check is in the mail. -- The Piranha Club Anthem, to the tune of "De Camptown Races" % -From the "Guinness Book of World Records", 1973: - -Certain passages in several laws have always defied interpretation and -the most inexplicable must be a matter of opinion. A judge of the -Court of Session of Scotland has sent the editors of this book his -candidate which reads, "In the Nuts (unground), (other than ground -nuts) Order, the expression nuts shall have reference to such nuts, -other than ground nuts, as would but for this amending Order not -qualify as nuts (unground)(other than ground nuts) by reason of their -being nuts (unground)." -% From the moment I picked your book up until I put it down I was convulsed with laughter. Some day I intend reading it. -- Groucho Marx, from "The Book of Insults" @@ -24042,21 +23914,6 @@ I may not be totally perfect, but parts I met a wonderful new man. He's fictional, but you can't have everything. -- Cecelia, "The Purple Rose of Cairo" % -I met him in a swamp down in Dagobah -Where it bubbles all the time like a giant cabinet soda - S-O-D-A soda -I saw the little runt sitting there on a log -I asked him his name and in a raspy voice he said Yoda - Y-O-D-A Yoda, Yo-Yo-Yo-Yo Yoda - -Well I've been around but I ain't never seen -A guy who looks like a Muppet but he's wrinkled and green - Oh my Yoda, Yo-Yo-Yo-Yo Yoda -Well I'm not dumb but I can't understand -How he can raise me in the air just by raising his hand - Oh my Yoda, Yo-Yo-Yo-Yo Yoda, Yo-Yo-Yo-Yo Yoda - -- The STAR WARS Song, to "Lola", by the Kinks -% I met my latest girl friend in a department store. She was looking at clothes, and I was putting Slinkys on the escalators. -- Steven Wright @@ -24531,10 +24388,6 @@ are worth considering, to wit: "When paying tolls, remember that it is necessary to release the quarter a full 3 seconds before passing the basket if you are traveling more than 60 MPH." - -[110.13]: - "When traveling on a one-way street, stay to the right, so as not - to interfere with oncoming traffic." % I suppose some of the variation between Boston drivers and the rest of the country is due to the progressive Massachusetts Driver Education Manual which @@ -24628,12 +24481,6 @@ I think that I shall never see A billboard lovely as a tree. Indeed, unless the billboards fall I'll never see a tree at all. - -- Nash -% -I think that I shall never see -A billboard lovely as a tree. -Perhaps, unless the billboards fall -I'll never see a tree at all. -- Ogden Nash % I think that I shall never see @@ -25899,21 +25746,6 @@ this is the case, then programmers stand software engineers dig each other's graves. -- Unknown % -If I have seen farther than others, it is because I was standing on the -shoulders of giants. - -- Isaac Newton - -In the sciences, we are now uniquely privileged to sit side by side -with the giants on whose shoulders we stand. - -- Gerald Holton - -If I have not seen as far as others, it is because giants were standing -on my shoulders. - -- Hal Abelson - -In computer science, we stand on each other's feet. - -- Brian K. Reid -% If I have to lay an egg for my country, I'll do it. -- Bob Hope % @@ -37641,7 +37473,7 @@ Pardo's First Postulate: fattening. Arnold's Addendum: - Everything else causes cancer in rats. + Anything not fitting into these categories causes cancer in rats. % Parents often talk about the younger generation as if they didn't have much of anything to do with it. @@ -39438,10 +39270,6 @@ A: A dope ring. Q: Why do blondes put their hair in ponytails? A: To cover up the valve stem. - -Q: Why did the blonde get so excited after she finished her jigsaw - puzzle in only 6 months? -A: Because on the box it said "From 2-4 years". % Q: What do you call a blind pre-historic animal? A: Diyathinkhesaurus. @@ -41474,25 +41302,6 @@ Spock: Affirmative. Kirk: Mr. Sulu, go to pass two. Sulu: Aye aye, sir, going to pass two. % -Scratch the disks, dump the core, Shut it down, pull the plug -Roll the tapes across the floor, Give the core an extra tug -And the system is going to crash. And the system is going to crash. -Teletypes smashed to bits. Mem'ry cards, one and all, -Give the scopes some nasty hits Toss out halfway down the hall -And the system is going to crash. And the system is going to crash. -And we've also found Just flip one switch -When you turn the power down, And the lights will cease to twitch -You turn the disk readers into trash. And the tape drives will crumble -Oh, it's so much fun, in a flash. -Now the CPU won't run When the CPU -And the system is going to crash. Can print nothing out but "foo," - The system is going to crash. - -- To The Caissons Go Rolling Along -% -Scratch the disks! -Drop the core! -Roll the tapes across the floor! -% Screw up your courage! You've screwed up everything else. % Scribline, n.: @@ -46379,13 +46188,6 @@ constitutions, displaying the utmost imp overturning everything. -- Plato, "Republic", 370 B.C. % -The investment community feels very putupon. They feel there is no -reason why they shouldn't earn $1 million to $200 million a year, -and they don't want to be held responsible for the global financial -meltdown. - -- Daniel Fass, chairman of Obama's - financial-industry fundraising party -% The IQ of the group is the lowest IQ of a member of the group divided by the number of people in the group. % @@ -46676,7 +46478,8 @@ often turn to a related (but infinitely % THE LESSER-KNOWN PROGRAMMING LANGUAGES #14 -- VALGOL - VALGOL is enjoying a dramatic surge of popularity across the + From its modest beginnings in Southern California's San Fernando +Valley VALGOL is enjoying a dramatic surge of popularity across the industry. VALGOL commands include REALLY, LIKE, WELL, and Y*KNOW. Variables are assigned with the =LIKE and =TOTALLY operators. Other operators include the "California booleans", AX and NOWAY. Loops are @@ -48383,9 +48186,6 @@ and peculiar sort of voluntary thinking. The solution of this problem is trivial and is left as an exercise for the reader. % -The solution to a problem changes the nature of the problem. - -- Peer -% The somewhat old and crusty vicar was taking a well-earned retirement from his rather old and crusty parish. As is usual in these cases, a locum was sent to cover the transition period. This particular man was young and @@ -52054,7 +51854,7 @@ yourself and that which may have an inte as much as it is possible for you to receive of this thing, and which may in some way be influenced by this ceremony. Amen. - -- Roger Zelazny, "Creatures of Light and Darkness" + -- Roger Zelazny, "Creatures of Light and Darkness", 1969 % To understand a program you must become both the machine and the program. % @@ -56803,22 +56603,6 @@ I'd LOVE to, but... -- I'm teaching my ferret to yodel. -- My crayons all melted together. % -Why I Can't Go Out With You: - -I'd LOVE to, but ... - -- I have to floss my cat. - -- I've dedicated my life to linguini. - -- I need to spend more time with my blender. - -- it wouldn't be fair to the other Beautiful People. - -- it's my night to pet the dog/ferret/goldfish. - -- I'm going downtown to try on some gloves. - -- I have to check the freshness dates on my dairy products. - -- I'm going down to the bakery to watch the buns rise. - -- I have an appointment with a cuticle specialist. - -- I have some really hard words to look up. - -- I've got a Friends of the Lowly Rutabaga meeting. - -- I promised to help a friend fold road maps. -% Why is it called a funny bone when it hurts so much? % Why is it taking so long for her to bring out all the good in you? @@ -57873,9 +57657,6 @@ a private eye. Yeah, there are more important things in life than money, but they won't go out with you if you don't have any. % -YEAR: - A period of three hundred and sixty-five disappointments. -% Year Name James Bond Book ---- -------------------------------- -------------- ---- 50's James Bond TV Series Barry Nelson Modified: user/ed/utmpx/games/fortune/datfiles/fortunes-o.real ============================================================================== --- user/ed/utmpx/games/fortune/datfiles/fortunes-o.real Sun Jan 10 13:15:58 2010 (r201997) +++ user/ed/utmpx/games/fortune/datfiles/fortunes-o.real Sun Jan 10 13:30:45 2010 (r201998) @@ -663,6 +663,13 @@ posh hotel. "Why, yes, young man," said the gentleman. "Would you bring me a postcard?" % + As we know, there are known knowns. There are things we know we +know. We also know there are known unknowns. That is to say, we know +there are some things we do not know. But there are also unknown +unknowns; the ones we don't know we don't know. + -- United States Secretary of Defense Donald Rumsfeld + 12 February 2002, Regarding the US invasion of Iraq +% "Are pirates an ethnic group? Or are they just people who burn illegal cds?" "Arrrr! We prefer to be called Buccaneer-Americans." @@ -12873,6 +12880,14 @@ Contraception", has been withdrawn after pull it out at the last minute. -- Not the Nine O'Clock News % +The investment community feels very putupon. They feel there is no +reason why they shouldn't earn $1 million to $200 million a year, +and they don't want to be held responsible for the global financial +meltdown. + -- Daniel Fass, Chairman of United States President + Barack Obama's financial-industry fundraising party + 20 October 2009 +% The king arranged a regal marriage for his daughter -- a bond that would unite two great kingdoms. Yet, because the young couple seemed so formal to each other, he posted a spy outside the royal wedding chamber and demanded a full Modified: user/ed/utmpx/games/pom/pom.6 ============================================================================== --- user/ed/utmpx/games/pom/pom.6 Sun Jan 10 13:15:58 2010 (r201997) +++ user/ed/utmpx/games/pom/pom.6 Sun Jan 10 13:30:45 2010 (r201998) @@ -32,15 +32,34 @@ .\" @(#)pom.6 8.1 (Berkeley) 5/31/93 .\" $FreeBSD$ .\" -.TH POM 6 "May 31, 1993" +.Dd May 31, 1993 +.Dt POM 6 .UC 7 -.SH NAME -pom \- display the phase of the moon -.SH SYNOPSIS -.B pom -.SH DESCRIPTION +.Sh NAME +.Nm pom +.Nd display the phase of the moon +.Sh SYNOPSIS +.Nm +.Op Fl d Ar yyyy.mm.dd +.Op Fl t Ar hh:mm:ss +.Sh DESCRIPTION The -.I pom +.Nm utility displays the current phase of the moon. Useful for selecting software completion target dates and predicting managerial behavior. +.Pp +Use the arguments +.Fl d +and +.Fl o +to specify a specific date and time for which the phase of the moon +has to be calculated. +If +.Fl d +but not +.Fl t +has been specified, it will calculate the phase of the moon on that +day at midnight. +.Sh SEE ALSO +`Practical Astronomy with Your Calculator' by Duffett-Smith. Modified: user/ed/utmpx/games/pom/pom.c ============================================================================== --- user/ed/utmpx/games/pom/pom.c Sun Jan 10 13:15:58 2010 (r201997) +++ user/ed/utmpx/games/pom/pom.c Sun Jan 10 13:30:45 2010 (r201998) @@ -57,9 +57,13 @@ __FBSDID("$FreeBSD$"); * */ -#include #include +#include #include +#include +#include +#include +#include #ifndef PI #define PI 3.14159265358979323846 @@ -76,20 +80,62 @@ __FBSDID("$FreeBSD$"); static void adj360(double *); static double dtor(double); static double potm(double); +static void usage(char *progname); int -main(void) +main(int argc, char **argv) { time_t tt; - struct tm *GMT; + struct tm GMT, tmd; double days, today, tomorrow; - int cnt; + int ch, cnt; + char *odate = NULL, *otime = NULL; + + while ((ch = getopt(argc, argv, "d:t:")) != -1) + switch (ch) { + case 'd': + odate = optarg; + break; + case 't': + otime = optarg; + break; + default: + usage(argv[0]); + } + + argc -= optind; + argv += optind; + + if (argc) + usage(argv[0]); - (void) time(&tt); - GMT = gmtime(&tt); - days = (GMT->tm_yday + 1) + ((GMT->tm_hour + - (GMT->tm_min / 60.0) + (GMT->tm_sec / 3600.0)) / 24.0); - for (cnt = EPOCH; cnt < GMT->tm_year; ++cnt) + /* Adjust based on users preferences */ + time(&tt); + if (otime != NULL || odate != NULL) { + /* Save today in case -d isn't specified */ + localtime_r(&tt, &tmd); + + if (odate != NULL) { + tmd.tm_year = strtol(odate, NULL, 10) - 1900; + tmd.tm_mon = strtol(odate + 5, NULL, 10) - 1; + tmd.tm_mday = strtol(odate + 8, NULL, 10); + /* Use midnight as the middle of the night */ *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-src-user@FreeBSD.ORG Sun Jan 10 14:55:21 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id E816A1065676; Sun, 10 Jan 2010 14:55:21 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id BE8ED8FC20; Sun, 10 Jan 2010 14:55:21 +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 o0AEtLdd057464; Sun, 10 Jan 2010 14:55:21 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0AEtLSo057462; Sun, 10 Jan 2010 14:55:21 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201001101455.o0AEtLSo057462@svn.freebsd.org> From: Ed Schouten Date: Sun, 10 Jan 2010 14:55:21 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202001 - user/ed/utmpx/include X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 10 Jan 2010 14:55:22 -0000 Author: ed Date: Sun Jan 10 14:55:21 2010 New Revision: 202001 URL: http://svn.freebsd.org/changeset/base/202001 Log: Reserve some spare space, which we can use in the future. Modified: user/ed/utmpx/include/utmpx.h Modified: user/ed/utmpx/include/utmpx.h ============================================================================== --- user/ed/utmpx/include/utmpx.h Sun Jan 10 14:48:42 2010 (r202000) +++ user/ed/utmpx/include/utmpx.h Sun Jan 10 14:55:21 2010 (r202001) @@ -50,6 +50,7 @@ struct utmpx { #else char __ut_host[128]; #endif + char __ut_spare[64]; }; #define EMPTY 0 /* No valid user accounting information. */ From owner-svn-src-user@FreeBSD.ORG Sun Jan 10 14:55:39 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 16320106568B; Sun, 10 Jan 2010 14:55:39 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 05B838FC14; Sun, 10 Jan 2010 14:55:39 +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 o0AEtcbO057567; Sun, 10 Jan 2010 14:55:38 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0AEtc9B057565; Sun, 10 Jan 2010 14:55:38 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201001101455.o0AEtc9B057565@svn.freebsd.org> From: Ed Schouten Date: Sun, 10 Jan 2010 14:55:38 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202002 - user/ed/utmpx/lib/libc/gen X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 10 Jan 2010 14:55:39 -0000 Author: ed Date: Sun Jan 10 14:55:38 2010 New Revision: 202002 URL: http://svn.freebsd.org/changeset/base/202002 Log: SHUTDOWN_TIME is also an extension. Modified: user/ed/utmpx/lib/libc/gen/getutxent.3 Modified: user/ed/utmpx/lib/libc/gen/getutxent.3 ============================================================================== --- user/ed/utmpx/lib/libc/gen/getutxent.3 Sun Jan 10 14:55:21 2010 (r202001) +++ user/ed/utmpx/lib/libc/gen/getutxent.3 Sun Jan 10 14:55:38 2010 (r202002) @@ -422,11 +422,14 @@ The .Fn getutxuser and .Fn setutxdb -functions and the +functions, +the .Fa ut_host field of the .Vt utmpx -structure are extensions. +structure and +.Dv SHUTDOWN_TIME +are extensions. .Sh HISTORY These functions appeared in .Fx 9.0 . From owner-svn-src-user@FreeBSD.ORG Sun Jan 10 15:18:17 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 32A041065676; Sun, 10 Jan 2010 15:18:17 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 212508FC17; Sun, 10 Jan 2010 15:18:17 +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 o0AFIHE4062642; Sun, 10 Jan 2010 15:18:17 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0AFIGYb062637; Sun, 10 Jan 2010 15:18:16 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201001101518.o0AFIGYb062637@svn.freebsd.org> From: Ed Schouten Date: Sun, 10 Jan 2010 15:18:16 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202004 - in user/ed/utmpx: contrib/telnet/telnetd libexec/rlogind libexec/telnetd X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 10 Jan 2010 15:18:17 -0000 Author: ed Date: Sun Jan 10 15:18:16 2010 New Revision: 202004 URL: http://svn.freebsd.org/changeset/base/202004 Log: Massively simplify the shutdown code of telnetd/rlogind. ulog_logout() has no effect here, since we now use ut_id as identifiers instead of ut_lines. If phantom records really turn out to be a problem, we should just use getutxline() and call pututxline() for each entry returned. There is also no need to chown/chmod the pseudo-terminal devices, because they are garbage-collected automatically. Modified: user/ed/utmpx/contrib/telnet/telnetd/sys_term.c user/ed/utmpx/libexec/rlogind/Makefile user/ed/utmpx/libexec/rlogind/rlogind.c user/ed/utmpx/libexec/telnetd/Makefile Modified: user/ed/utmpx/contrib/telnet/telnetd/sys_term.c ============================================================================== --- user/ed/utmpx/contrib/telnet/telnetd/sys_term.c Sun Jan 10 15:12:15 2010 (r202003) +++ user/ed/utmpx/contrib/telnet/telnetd/sys_term.c Sun Jan 10 15:18:16 2010 (r202004) @@ -43,7 +43,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include "telnetd.h" #include "pathnames.h" @@ -1304,23 +1303,7 @@ scrub_env(void) void cleanup(int sig __unused) { - char *p; - sigset_t mask; - p = line + sizeof(_PATH_DEV) - 1; - /* - * Block all signals before clearing the utmp entry. We don't want to - * be called again after calling logout() and then not add the wtmp - * entry because of not finding the corresponding entry in utmp. - */ - sigfillset(&mask); - sigprocmask(SIG_SETMASK, &mask, NULL); - ulog_logout(p); - (void)chmod(line, 0666); - (void)chown(line, 0, 0); - *p = 'p'; - (void)chmod(line, 0666); - (void)chown(line, 0, 0); - (void) shutdown(net, 2); + (void) shutdown(net, SHUT_RDWR); _exit(1); } Modified: user/ed/utmpx/libexec/rlogind/Makefile ============================================================================== --- user/ed/utmpx/libexec/rlogind/Makefile Sun Jan 10 15:12:15 2010 (r202003) +++ user/ed/utmpx/libexec/rlogind/Makefile Sun Jan 10 15:18:16 2010 (r202004) @@ -5,8 +5,8 @@ PROG= rlogind MAN= rlogind.8 -DPADD= ${LIBULOG} ${LIBUTIL} -LDADD= -lulog -lutil +DPADD= ${LIBUTIL} +LDADD= -lutil WARNS?= 2 .if ${MK_INET6_SUPPORT} != "no" Modified: user/ed/utmpx/libexec/rlogind/rlogind.c ============================================================================== --- user/ed/utmpx/libexec/rlogind/rlogind.c Sun Jan 10 15:12:15 2010 (r202003) +++ user/ed/utmpx/libexec/rlogind/rlogind.c Sun Jan 10 15:18:16 2010 (r202004) @@ -85,7 +85,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include @@ -480,17 +479,7 @@ protocol(int f, int p) void cleanup(int signo) { - char *p; - p = line + sizeof(_PATH_DEV) - 1; - ulog_logout(p); - (void)chflags(line, 0); - (void)chmod(line, 0666); - (void)chown(line, 0, 0); - *p = 'p'; - (void)chflags(line, 0); - (void)chmod(line, 0666); - (void)chown(line, 0, 0); shutdown(netf, SHUT_RDWR); exit(1); } Modified: user/ed/utmpx/libexec/telnetd/Makefile ============================================================================== --- user/ed/utmpx/libexec/telnetd/Makefile Sun Jan 10 15:12:15 2010 (r202003) +++ user/ed/utmpx/libexec/telnetd/Makefile Sun Jan 10 15:18:16 2010 (r202004) @@ -28,8 +28,8 @@ CFLAGS+= -I${TELNETDIR} LIBTELNET= ${.OBJDIR}/../../lib/libtelnet/libtelnet.a -DPADD= ${LIBULOG} ${LIBUTIL} ${LIBTERMCAP} ${LIBTELNET} -LDADD= -lulog -lutil -ltermcap ${LIBTELNET} +DPADD= ${LIBUTIL} ${LIBTERMCAP} ${LIBTELNET} +LDADD= -lutil -ltermcap ${LIBTELNET} # XXX for src/release/picobsd .if !defined(RELEASE_CRUNCH) From owner-svn-src-user@FreeBSD.ORG Sun Jan 10 15:25:46 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 3CC701065670; Sun, 10 Jan 2010 15:25:46 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 2C6B88FC16; Sun, 10 Jan 2010 15:25:46 +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 o0AFPkxr064330; Sun, 10 Jan 2010 15:25:46 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0AFPkGg064328; Sun, 10 Jan 2010 15:25:46 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201001101525.o0AFPkGg064328@svn.freebsd.org> From: Ed Schouten Date: Sun, 10 Jan 2010 15:25:46 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202005 - user/ed/utmpx/lib/libulog X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 10 Jan 2010 15:25:46 -0000 Author: ed Date: Sun Jan 10 15:25:45 2010 New Revision: 202005 URL: http://svn.freebsd.org/changeset/base/202005 Log: Fix off-by-one. Modified: user/ed/utmpx/lib/libulog/ulog_login.c Modified: user/ed/utmpx/lib/libulog/ulog_login.c ============================================================================== --- user/ed/utmpx/lib/libulog/ulog_login.c Sun Jan 10 15:18:16 2010 (r202004) +++ user/ed/utmpx/lib/libulog/ulog_login.c Sun Jan 10 15:25:45 2010 (r202005) @@ -47,7 +47,7 @@ ulog_genid(struct utmpx *utx, const char * Prepend an 'u' to indicate it was done by libulog. */ utx->ut_id[0] = 'u'; - for (s = strlen(line), d = 1; s > 0 && d <= sizeof utx->ut_id; s--, d++) + for (s = strlen(line), d = 1; s > 0 && d < sizeof utx->ut_id; s--, d++) utx->ut_id[d] = line[s - 1]; } From owner-svn-src-user@FreeBSD.ORG Sun Jan 10 15:59:59 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 8B647106566B; Sun, 10 Jan 2010 15:59:59 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 7AA788FC1C; Sun, 10 Jan 2010 15:59:59 +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 o0AFxxic071845; Sun, 10 Jan 2010 15:59:59 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0AFxxw0071842; Sun, 10 Jan 2010 15:59:59 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201001101559.o0AFxxw0071842@svn.freebsd.org> From: Ed Schouten Date: Sun, 10 Jan 2010 15:59:59 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202007 - in user/ed/utmpx/usr.bin: . last X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 10 Jan 2010 15:59:59 -0000 Author: ed Date: Sun Jan 10 15:59:59 2010 New Revision: 202007 URL: http://svn.freebsd.org/changeset/base/202007 Log: Make last(1) build. It's still broken. Modified: user/ed/utmpx/usr.bin/Makefile user/ed/utmpx/usr.bin/last/last.c Modified: user/ed/utmpx/usr.bin/Makefile ============================================================================== --- user/ed/utmpx/usr.bin/Makefile Sun Jan 10 15:44:48 2010 (r202006) +++ user/ed/utmpx/usr.bin/Makefile Sun Jan 10 15:59:59 2010 (r202007) @@ -94,6 +94,7 @@ SUBDIR= alias \ ktrace \ ktrdump \ lam \ + last \ lastcomm \ ldd \ leave \ Modified: user/ed/utmpx/usr.bin/last/last.c ============================================================================== --- user/ed/utmpx/usr.bin/last/last.c Sun Jan 10 15:44:48 2010 (r202006) +++ user/ed/utmpx/usr.bin/last/last.c Sun Jan 10 15:59:59 2010 (r202007) @@ -82,13 +82,13 @@ LIST_HEAD(ttylisthead, ttytab) ttylist; struct ttytab { time_t logout; /* log out time */ - char tty[UT_LINESIZE + 1]; /* terminal name */ + char tty[sizeof ((struct utmpx *)0)->ut_line]; /* terminal name */ LIST_ENTRY(ttytab) list; }; static const char *crmsg; /* cause of last reboot */ -static long currentout, /* current logout value */ - maxrec; /* records to display */ +static time_t currentout; /* current logout value */ +static long maxrec; /* records to display */ static const char *file = NULL; /* wtmp file */ static int sflag = 0; /* show delta in seconds */ static int width = 5; /* show seconds in delta */ @@ -206,7 +206,8 @@ main(int argc, char *argv[]) void wtmp(void) { - struct utmp *bp; /* current structure */ +#if 0 + struct utmpx *bp; /* current structure */ int bytes, wfd; char ct[80]; struct tm *tm; @@ -219,7 +220,7 @@ wtmp(void) bl = (stb.st_size + sizeof(buf) - 1) / sizeof(buf); (void)time(&t); - buf[0].ut_time = _time_to_int(t); + buf[0].ut_tv.tv_sec = t; (void)signal(SIGINT, onintr); (void)signal(SIGQUIT, onintr); @@ -230,10 +231,11 @@ wtmp(void) for (bp = &buf[bytes / sizeof(buf[0]) - 1]; bp >= buf; --bp) doentry(bp); } - t = _int_to_time(buf[0].ut_time); + t = buf[0].ut_tv.tv_sec; tm = localtime(&t); (void) strftime(ct, sizeof(ct), "\nwtmp begins %+\n", tm); printf("%s", ct); +#endif } /* @@ -257,8 +259,8 @@ doentry(struct utmpx *bp) tt = LIST_NEXT(tt, list); free(ttx); } - currentout = -bp->ut_time; - crmsg = strncmp(bp->ut_name, "shutdown", UT_NAMESIZE) ? + currentout = -bp->ut_tv.tv_sec; + crmsg = strcmp(bp->ut_user, "shutdown") ? "crash" : "shutdown"; /* * if we're in snapshot mode, we want to exit if this @@ -286,7 +288,7 @@ doentry(struct utmpx *bp) } /* find associated tty */ LIST_FOREACH(tt, &ttylist, list) - if (!strncmp(tt->tty, bp->ut_line, UT_LINESIZE)) + if (!strcmp(tt->tty, bp->ut_line)) break; if (tt == NULL) { @@ -295,7 +297,7 @@ doentry(struct utmpx *bp) if (tt == NULL) errx(1, "malloc failure"); tt->logout = currentout; - strncpy(tt->tty, bp->ut_line, UT_LINESIZE); + strcpy(tt->tty, bp->ut_line); LIST_INSERT_HEAD(&ttylist, tt, list); } @@ -303,7 +305,7 @@ doentry(struct utmpx *bp) * print record if not in snapshot mode and wanted * or in snapshot mode and in snapshot range */ - if (bp->ut_name[0] && (want(bp) || (bp->ut_time < snaptime && + if (bp->ut_user[0] && (want(bp) || (bp->ut_tv.tv_sec < snaptime && (tt->logout > snaptime || tt->logout < 1)))) { snapfound = 1; /* @@ -317,7 +319,7 @@ doentry(struct utmpx *bp) bp->ut_line[4] = '\0'; printentry(bp, tt); } - tt->logout = bp->ut_time; + tt->logout = bp->ut_tv.tv_sec; } /* @@ -337,15 +339,13 @@ printentry(struct utmpx *bp, struct ttyt if (maxrec != -1 && !maxrec--) exit(0); - t = _int_to_time(bp->ut_time); + t = bp->ut_tv.tv_sec; tm = localtime(&t); (void) strftime(ct, sizeof(ct), d_first ? (yflag ? "%a %e %b %Y %R" : "%a %e %b %R") : (yflag ? "%a %b %e %Y %R" : "%a %b %e %R"), tm); - printf("%-*.*s %-*.*s %-*.*s %s%c", - UT_NAMESIZE, UT_NAMESIZE, bp->ut_name, - UT_LINESIZE, UT_LINESIZE, bp->ut_line, - UT_HOSTSIZE, UT_HOSTSIZE, bp->ut_host, + printf("%-10s %-8s %-24.24s %s%c", + bp->ut_user, bp->ut_line, bp->ut_host, ct, tt == NULL ? '\n' : ' '); if (tt == NULL) return; @@ -361,7 +361,7 @@ printentry(struct utmpx *bp, struct ttyt (void) strftime(ct, sizeof(ct), "%R", tm); printf("- %s", ct); } - delta = tt->logout - bp->ut_time; + delta = tt->logout - bp->ut_tv.tv_sec; if (sflag) { printf(" (%8ld)\n", (long)delta); } else { @@ -392,15 +392,15 @@ want(struct utmpx *bp) for (step = arglist; step; step = step->next) switch(step->type) { case HOST_TYPE: - if (!strncasecmp(step->name, bp->ut_host, UT_HOSTSIZE)) + if (!strcasecmp(step->name, bp->ut_host)) return (YES); break; case TTY_TYPE: - if (!strncmp(step->name, bp->ut_line, UT_LINESIZE)) + if (!strcmp(step->name, bp->ut_line)) return (YES); break; case USER_TYPE: - if (!strncmp(step->name, bp->ut_name, UT_NAMESIZE)) + if (!strcmp(step->name, bp->ut_user)) return (YES); break; } @@ -561,7 +561,7 @@ onintr(int signo) { char ct[80]; struct tm *tm; - time_t t = _int_to_time(buf[0].ut_time); + time_t t = buf[0].ut_tv.tv_sec; tm = localtime(&t); (void) strftime(ct, sizeof(ct), From owner-svn-src-user@FreeBSD.ORG Sun Jan 10 16:30:54 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id DADB4106566B; Sun, 10 Jan 2010 16:30:54 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id CB8318FC12; Sun, 10 Jan 2010 16:30:54 +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 o0AGUsMk078981; Sun, 10 Jan 2010 16:30:54 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0AGUs1R078979; Sun, 10 Jan 2010 16:30:54 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201001101630.o0AGUs1R078979@svn.freebsd.org> From: Ed Schouten Date: Sun, 10 Jan 2010 16:30:54 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202013 - user/ed/utmpx/usr.bin/w X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 10 Jan 2010 16:30:54 -0000 Author: ed Date: Sun Jan 10 16:30:54 2010 New Revision: 202013 URL: http://svn.freebsd.org/changeset/base/202013 Log: Make w(1) behave a little bit better when no TTY is associated. This allows it to more properly display entries generated by ftpd. Modified: user/ed/utmpx/usr.bin/w/w.c Modified: user/ed/utmpx/usr.bin/w/w.c ============================================================================== --- user/ed/utmpx/usr.bin/w/w.c Sun Jan 10 16:08:14 2010 (r202012) +++ user/ed/utmpx/usr.bin/w/w.c Sun Jan 10 16:30:54 2010 (r202013) @@ -282,7 +282,8 @@ main(int argc, char *argv[]) if ((kp = kvm_getprocs(kd, KERN_PROC_ALL, 0, &nentries)) == NULL) err(1, "%s", kvm_geterr(kd)); for (i = 0; i < nentries; i++, kp++) { - if (kp->ki_stat == SIDL || kp->ki_stat == SZOMB) + if (kp->ki_stat == SIDL || kp->ki_stat == SZOMB || + kp->ki_tdev == NODEV) continue; for (ep = ehead; ep != NULL; ep = ep->next) { if (ep->tdev == kp->ki_tdev) { @@ -417,9 +418,10 @@ main(int argc, char *argv[]) (void)printf("%-*.*s %-*.*s %-*.*s ", W_DISPUSERSIZE, W_DISPUSERSIZE, ep->utmp.ut_user, W_DISPLINESIZE, W_DISPLINESIZE, - strncmp(ep->utmp.ut_line, "tty", 3) && + *ep->utmp.ut_line ? + (strncmp(ep->utmp.ut_line, "tty", 3) && strncmp(ep->utmp.ut_line, "cua", 3) ? - ep->utmp.ut_line : ep->utmp.ut_line + 3, + ep->utmp.ut_line : ep->utmp.ut_line + 3) : "-", W_DISPHOSTSIZE, W_DISPHOSTSIZE, *p ? p : "-"); t = ep->utmp.ut_tv.tv_sec; longattime = pr_attime(&t, &now); From owner-svn-src-user@FreeBSD.ORG Sun Jan 10 17:15:37 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 2C4C0106566C; Sun, 10 Jan 2010 17:15:37 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 1D0598FC12; Sun, 10 Jan 2010 17:15:37 +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 o0AHFb6Z088993; Sun, 10 Jan 2010 17:15:37 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0AHFanH088990; Sun, 10 Jan 2010 17:15:36 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201001101715.o0AHFanH088990@svn.freebsd.org> From: Ed Schouten Date: Sun, 10 Jan 2010 17:15:36 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202018 - user/ed/utmpx/libexec/ftpd X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 10 Jan 2010 17:15:37 -0000 Author: ed Date: Sun Jan 10 17:15:36 2010 New Revision: 202018 URL: http://svn.freebsd.org/changeset/base/202018 Log: Make ftpd work with utmpx. Unfortunately we can't allow utmpx to be used with chroot as well. The interface doesn't allow us to keep file descriptors to the database files alive. Modified: user/ed/utmpx/libexec/ftpd/ftpd.c user/ed/utmpx/libexec/ftpd/logwtmp.c Modified: user/ed/utmpx/libexec/ftpd/ftpd.c ============================================================================== --- user/ed/utmpx/libexec/ftpd/ftpd.c Sun Jan 10 16:58:12 2010 (r202017) +++ user/ed/utmpx/libexec/ftpd/ftpd.c Sun Jan 10 17:15:36 2010 (r202018) @@ -173,8 +173,7 @@ static struct ftphost { char remotehost[NI_MAXHOST]; char *ident = NULL; -static char ttyline[20]; -char *tty = ttyline; /* for klogin */ +static char wtmpid[20]; #ifdef USE_PAM static int auth_pam(struct passwd**, const char*); @@ -584,8 +583,7 @@ gotchild: data_source.su_port = htons(ntohs(ctrl_addr.su_port) - 1); - /* set this here so klogin can use it... */ - (void)snprintf(ttyline, sizeof(ttyline), "ftp%d", getpid()); + (void)snprintf(wtmpid, sizeof(wtmpid), "%xftpd", getpid()); /* Try to handle urgent data inline */ #ifdef SO_OOBINLINE @@ -1180,8 +1178,8 @@ end_login(void) #endif (void) seteuid(0); - if (logged_in && dowtmp) - ftpd_logwtmp(ttyline, "", NULL); + if (logged_in && dowtmp && !dochroot) + ftpd_logwtmp(wtmpid, "", NULL); pw = NULL; #ifdef LOGIN_CAP setusercontext(NULL, getpwuid(0), 0, @@ -1476,9 +1474,17 @@ skip: } #endif + dochroot = + checkuser(_PATH_FTPCHROOT, pw->pw_name, 1, &residue) +#ifdef LOGIN_CAP /* Allow login.conf configuration as well */ + || login_getcapbool(lc, "ftp-chroot", 0) +#endif + ; + chrootdir = NULL; + /* open wtmp before chroot */ - if (dowtmp) - ftpd_logwtmp(ttyline, pw->pw_name, + if (dowtmp && !dochroot) + ftpd_logwtmp(wtmpid, pw->pw_name, (struct sockaddr *)&his_addr); logged_in = 1; @@ -1491,13 +1497,6 @@ skip: if (statfd < 0) stats = 0; - dochroot = - checkuser(_PATH_FTPCHROOT, pw->pw_name, 1, &residue) -#ifdef LOGIN_CAP /* Allow login.conf configuration as well */ - || login_getcapbool(lc, "ftp-chroot", 0) -#endif - ; - chrootdir = NULL; /* * For a chrooted local user, * a) see whether ftpchroot(5) specifies a chroot directory, @@ -2732,9 +2731,9 @@ void dologout(int status) { - if (logged_in && dowtmp) { + if (logged_in && dowtmp && !dochroot) { (void) seteuid(0); - ftpd_logwtmp(ttyline, "", NULL); + ftpd_logwtmp(wtmpid, "", NULL); } /* beware of flushing buffers after a SIGPIPE */ _exit(status); Modified: user/ed/utmpx/libexec/ftpd/logwtmp.c ============================================================================== --- user/ed/utmpx/libexec/ftpd/logwtmp.c Sun Jan 10 16:58:12 2010 (r202017) +++ user/ed/utmpx/libexec/ftpd/logwtmp.c Sun Jan 10 17:15:36 2010 (r202018) @@ -46,53 +46,35 @@ __FBSDID("$FreeBSD$"); #include #include -#include -#include -#include -#include -#if 0 -#include -#endif -#include +#include #include #include -#include +#include +#include #include "extern.h" -#if 0 -static int fd = -1; -#endif - -/* - * Modified version of logwtmp that holds wtmp file open - * after first call, for use with ftp (which may chroot - * after login, but before logout). - */ void -ftpd_logwtmp(line, name, addr) - char *line, *name; - struct sockaddr *addr; +ftpd_logwtmp(char *id, char *user, struct sockaddr *addr) { -#if 0 - struct utmp ut; - struct stat buf; - char host[UT_HOSTSIZE]; - - if (addr == NULL) - host[0] = '\0'; - else - realhostname_sa(host, sizeof(host), addr, addr->sa_len); - - if (fd < 0 && (fd = open(_PATH_WTMP, O_WRONLY|O_APPEND, 0)) < 0) - return; - if (fstat(fd, &buf) == 0) { - (void)strncpy(ut.ut_line, line, sizeof(ut.ut_line)); - (void)strncpy(ut.ut_name, name, sizeof(ut.ut_name)); - (void)strncpy(ut.ut_host, host, sizeof(ut.ut_host)); - ut.ut_time = _time_to_time32(time(NULL)); - if (write(fd, &ut, sizeof(struct utmp)) != - sizeof(struct utmp)) - (void)ftruncate(fd, buf.st_size); + struct utmpx ut; + + memset(&ut, 0, sizeof(ut)); + + if (*user != '\0') { + /* Log in. */ + ut.ut_type = USER_PROCESS; + (void)strncpy(ut.ut_user, user, sizeof(ut.ut_user)); + if (addr != NULL) + realhostname_sa(ut.ut_host, sizeof(ut.ut_host), + addr, addr->sa_len); + } else { + /* Log out. */ + ut.ut_type = DEAD_PROCESS; } -#endif + + ut.ut_pid = getpid(); + gettimeofday(&ut.ut_tv, NULL); + (void)strncpy(ut.ut_id, id, sizeof(ut.ut_id)); + + pututxline(&ut); } From owner-svn-src-user@FreeBSD.ORG Sun Jan 10 17:45:47 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 793AD106568D; Sun, 10 Jan 2010 17:45:47 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 6A7EB8FC24; Sun, 10 Jan 2010 17:45:47 +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 o0AHjlD8095651; Sun, 10 Jan 2010 17:45:47 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0AHjlqC095649; Sun, 10 Jan 2010 17:45:47 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201001101745.o0AHjlqC095649@svn.freebsd.org> From: Ed Schouten Date: Sun, 10 Jan 2010 17:45:47 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202020 - user/ed/utmpx/usr.bin/last X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 10 Jan 2010 17:45:47 -0000 Author: ed Date: Sun Jan 10 17:45:47 2010 New Revision: 202020 URL: http://svn.freebsd.org/changeset/base/202020 Log: Somewhat make last(1) work. Right now it's still quite broken. It doesn't properly detect logouts, because it doesn't honour ut_id and ut_type yet. Modified: user/ed/utmpx/usr.bin/last/last.c Modified: user/ed/utmpx/usr.bin/last/last.c ============================================================================== --- user/ed/utmpx/usr.bin/last/last.c Sun Jan 10 17:44:22 2010 (r202019) +++ user/ed/utmpx/usr.bin/last/last.c Sun Jan 10 17:45:47 2010 (r202020) @@ -66,8 +66,6 @@ __FBSDID("$FreeBSD$"); #define YES 1 /* true/yes */ #define ATOI2(ar) ((ar)[0] - '0') * 10 + ((ar)[1] - '0'); (ar) += 2; -static struct utmpx buf[1024]; /* utmp read buffer */ - typedef struct arg { char *name; /* argument */ #define HOST_TYPE -2 @@ -104,7 +102,6 @@ void addarg(int, char *); time_t dateconv(char *); void doentry(struct utmpx *); void hostconv(char *); -void onintr(int); void printentry(struct utmpx *, struct ttytab *); char *ttyconv(char *); int want(struct utmpx *); @@ -199,6 +196,8 @@ main(int argc, char *argv[]) exit(0); } +#define MAXUTXENTRIES 1024 + /* * wtmp -- * read through the wtmp file @@ -206,36 +205,37 @@ main(int argc, char *argv[]) void wtmp(void) { -#if 0 - struct utmpx *bp; /* current structure */ - int bytes, wfd; + struct utmpx buf[MAXUTXENTRIES]; + struct utmpx *ut; + static unsigned int first = 0, amount = 0; + time_t t; char ct[80]; struct tm *tm; - time_t t; LIST_INIT(&ttylist); + (void)time(&t); + /* Load the last entries from the file. */ if (setutxdb(UTXDB_LOG, file) != 0) err(1, "%s", file); - bl = (stb.st_size + sizeof(buf) - 1) / sizeof(buf); + while ((ut = getutxent()) != NULL) { + memcpy(&buf[(first + amount) % MAXUTXENTRIES], ut, sizeof *ut); + if (amount == MAXUTXENTRIES) + first++; + else + amount++; + if (t > ut->ut_tv.tv_sec) + t = ut->ut_tv.tv_sec; + } + endutxent(); + + /* Display them in reverse order. */ + while (amount > 0) + doentry(&buf[(first + amount--) % MAXUTXENTRIES]); - (void)time(&t); - buf[0].ut_tv.tv_sec = t; - (void)signal(SIGINT, onintr); - (void)signal(SIGQUIT, onintr); - - while (--bl >= 0) { - if (lseek(wfd, (off_t)(bl * sizeof(buf)), L_SET) == -1 || - (bytes = read(wfd, buf, sizeof(buf))) == -1) - err(1, "%s", file); - for (bp = &buf[bytes / sizeof(buf[0]) - 1]; bp >= buf; --bp) - doentry(bp); - } - t = buf[0].ut_tv.tv_sec; tm = localtime(&t); (void) strftime(ct, sizeof(ct), "\nwtmp begins %+\n", tm); printf("%s", ct); -#endif } /* @@ -550,25 +550,3 @@ terr: errx(1, "out of range or illegal time specification: [[CC]YY]MMDDhhmm[.SS]"); return timet; } - - -/* - * onintr -- - * on interrupt, we inform the user how far we've gotten - */ -void -onintr(int signo) -{ - char ct[80]; - struct tm *tm; - time_t t = buf[0].ut_tv.tv_sec; - - tm = localtime(&t); - (void) strftime(ct, sizeof(ct), - d_first ? "%a %e %b %R" : "%a %b %e %R", - tm); - printf("\ninterrupted %s\n", ct); - if (signo == SIGINT) - exit(1); - (void)fflush(stdout); /* fix required for rsh */ -} From owner-svn-src-user@FreeBSD.ORG Sun Jan 10 18:00:45 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 74A3E1065670; Sun, 10 Jan 2010 18:00:45 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 659D98FC14; Sun, 10 Jan 2010 18:00:45 +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 o0AI0j6N098991; Sun, 10 Jan 2010 18:00:45 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0AI0jcp098989; Sun, 10 Jan 2010 18:00:45 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201001101800.o0AI0jcp098989@svn.freebsd.org> From: Ed Schouten Date: Sun, 10 Jan 2010 18:00:45 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202021 - user/ed/utmpx/usr.bin/last X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 10 Jan 2010 18:00:45 -0000 Author: ed Date: Sun Jan 10 18:00:45 2010 New Revision: 202021 URL: http://svn.freebsd.org/changeset/base/202021 Log: Make last(1) work a lot better. I think it should work properly now. Modified: user/ed/utmpx/usr.bin/last/last.c Modified: user/ed/utmpx/usr.bin/last/last.c ============================================================================== --- user/ed/utmpx/usr.bin/last/last.c Sun Jan 10 17:45:47 2010 (r202020) +++ user/ed/utmpx/usr.bin/last/last.c Sun Jan 10 18:00:45 2010 (r202021) @@ -76,12 +76,12 @@ typedef struct arg { } ARG; ARG *arglist; /* head of linked list */ -LIST_HEAD(ttylisthead, ttytab) ttylist; +LIST_HEAD(idlisthead, idtab) idlist; -struct ttytab { +struct idtab { time_t logout; /* log out time */ - char tty[sizeof ((struct utmpx *)0)->ut_line]; /* terminal name */ - LIST_ENTRY(ttytab) list; + char id[sizeof ((struct utmpx *)0)->ut_id]; /* identifier */ + LIST_ENTRY(idtab) list; }; static const char *crmsg; /* cause of last reboot */ @@ -102,7 +102,7 @@ void addarg(int, char *); time_t dateconv(char *); void doentry(struct utmpx *); void hostconv(char *); -void printentry(struct utmpx *, struct ttytab *); +void printentry(struct utmpx *, struct idtab *); char *ttyconv(char *); int want(struct utmpx *); void usage(void); @@ -212,7 +212,7 @@ wtmp(void) char ct[80]; struct tm *tm; - LIST_INIT(&ttylist); + LIST_INIT(&idlist); (void)time(&t); /* Load the last entries from the file. */ @@ -245,22 +245,19 @@ wtmp(void) void doentry(struct utmpx *bp) { - struct ttytab *tt, *ttx; /* ttylist entry */ + struct idtab *tt, *ttx; /* idlist entry */ - /* - * if the terminal line is '~', the machine stopped. - * see utmp(5) for more info. - */ - if (bp->ut_line[0] == '~' && !bp->ut_line[1]) { + /* the machine stopped */ + if (bp->ut_type == BOOT_TIME || bp->ut_type == SHUTDOWN_TIME) { /* everybody just logged out */ - for (tt = LIST_FIRST(&ttylist); tt;) { + for (tt = LIST_FIRST(&idlist); tt;) { LIST_REMOVE(tt, list); ttx = tt; tt = LIST_NEXT(tt, list); free(ttx); } currentout = -bp->ut_tv.tv_sec; - crmsg = strcmp(bp->ut_user, "shutdown") ? + crmsg = bp->ut_type != SHUTDOWN_TIME ? "crash" : "shutdown"; /* * if we're in snapshot mode, we want to exit if this @@ -276,47 +273,39 @@ doentry(struct utmpx *bp) printentry(bp, NULL); return; } - /* - * if the line is '{' or '|', date got set; see - * utmp(5) for more info. - */ - if ((bp->ut_line[0] == '{' || bp->ut_line[0] == '|') && - !bp->ut_line[1]) { + /* date got set */ + if (bp->ut_type == OLD_TIME || bp->ut_type == NEW_TIME) { if (want(bp) && !snaptime) printentry(bp, NULL); return; } - /* find associated tty */ - LIST_FOREACH(tt, &ttylist, list) - if (!strcmp(tt->tty, bp->ut_line)) + + if (bp->ut_type != USER_PROCESS && bp->ut_type != DEAD_PROCESS) + return; + + /* find associated identifier */ + LIST_FOREACH(tt, &idlist, list) + if (!memcmp(tt->id, bp->ut_id, sizeof bp->ut_id)) break; if (tt == NULL) { /* add new one */ - tt = malloc(sizeof(struct ttytab)); + tt = malloc(sizeof(struct idtab)); if (tt == NULL) errx(1, "malloc failure"); tt->logout = currentout; - strcpy(tt->tty, bp->ut_line); - LIST_INSERT_HEAD(&ttylist, tt, list); + memcpy(tt->id, bp->ut_id, sizeof bp->ut_id); + LIST_INSERT_HEAD(&idlist, tt, list); } /* * print record if not in snapshot mode and wanted * or in snapshot mode and in snapshot range */ - if (bp->ut_user[0] && (want(bp) || (bp->ut_tv.tv_sec < snaptime && + if (bp->ut_type == USER_PROCESS && (want(bp) || + (bp->ut_tv.tv_sec < snaptime && (tt->logout > snaptime || tt->logout < 1)))) { snapfound = 1; - /* - * when uucp and ftp log in over a network, the entry in - * the utmp file is the name plus their process id. See - * etc/ftpd.c and usr.bin/uucp/uucpd.c for more information. - */ - if (!strncmp(bp->ut_line, "ftp", sizeof("ftp") - 1)) - bp->ut_line[3] = '\0'; - else if (!strncmp(bp->ut_line, "uucp", sizeof("uucp") - 1)) - bp->ut_line[4] = '\0'; printentry(bp, tt); } tt->logout = bp->ut_tv.tv_sec; @@ -330,7 +319,7 @@ doentry(struct utmpx *bp) * logout type (crash/shutdown) as appropriate. */ void -printentry(struct utmpx *bp, struct ttytab *tt) +printentry(struct utmpx *bp, struct idtab *tt) { char ct[80]; struct tm *tm; From owner-svn-src-user@FreeBSD.ORG Sun Jan 10 18:09:33 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id DEFD8106566C; Sun, 10 Jan 2010 18:09:33 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id D072D8FC15; Sun, 10 Jan 2010 18:09:33 +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 o0AI9X8e001093; Sun, 10 Jan 2010 18:09:33 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0AI9Xjt001091; Sun, 10 Jan 2010 18:09:33 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201001101809.o0AI9Xjt001091@svn.freebsd.org> From: Ed Schouten Date: Sun, 10 Jan 2010 18:09:33 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202022 - user/ed/utmpx/usr.bin/last X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 10 Jan 2010 18:09:34 -0000 Author: ed Date: Sun Jan 10 18:09:33 2010 New Revision: 202022 URL: http://svn.freebsd.org/changeset/base/202022 Log: Seems there was still something missing. We now need to print custom strings for entries that have nothing to do with logins/logouts. Modified: user/ed/utmpx/usr.bin/last/last.c Modified: user/ed/utmpx/usr.bin/last/last.c ============================================================================== --- user/ed/utmpx/usr.bin/last/last.c Sun Jan 10 18:00:45 2010 (r202021) +++ user/ed/utmpx/usr.bin/last/last.c Sun Jan 10 18:09:33 2010 (r202022) @@ -333,9 +333,25 @@ printentry(struct utmpx *bp, struct idta (void) strftime(ct, sizeof(ct), d_first ? (yflag ? "%a %e %b %Y %R" : "%a %e %b %R") : (yflag ? "%a %b %e %Y %R" : "%a %b %e %R"), tm); - printf("%-10s %-8s %-24.24s %s%c", - bp->ut_user, bp->ut_line, bp->ut_host, - ct, tt == NULL ? '\n' : ' '); + switch (bp->ut_type) { + case BOOT_TIME: + printf("%-44s", "boot time"); + break; + case SHUTDOWN_TIME: + printf("%-44s", "shutdown time"); + break; + case OLD_TIME: + printf("%-44s", "old time"); + break; + case NEW_TIME: + printf("%-44s", "new time"); + break; + case USER_PROCESS: + printf("%-10s %-8s %-24.24s", + bp->ut_user, bp->ut_line, bp->ut_host); + break; + } + printf(" %s%c", ct, tt == NULL ? '\n' : ' '); if (tt == NULL) return; if (!tt->logout) { From owner-svn-src-user@FreeBSD.ORG Sun Jan 10 20:19:30 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 7F82A1065676; Sun, 10 Jan 2010 20:19:30 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 716608FC0A; Sun, 10 Jan 2010 20:19:30 +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 o0AKJUZo030389; Sun, 10 Jan 2010 20:19:30 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0AKJUTP030387; Sun, 10 Jan 2010 20:19:30 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201001102019.o0AKJUTP030387@svn.freebsd.org> From: Ed Schouten Date: Sun, 10 Jan 2010 20:19:30 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202042 - user/ed/utmpx/share/termcap X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 10 Jan 2010 20:19:30 -0000 Author: ed Date: Sun Jan 10 20:19:30 2010 New Revision: 202042 URL: http://svn.freebsd.org/changeset/base/202042 Log: Make the End key work again. I changed the termcap entry for xterm some time ago, but it seems this broke the End key. Re-apply our local patch. I'm not going to MFC the entries after all. They've caused enough trouble. PR: conf/142578 Submitted by: Yuri Pankov Modified: user/ed/utmpx/share/termcap/termcap.src Modified: user/ed/utmpx/share/termcap/termcap.src ============================================================================== --- user/ed/utmpx/share/termcap/termcap.src Sun Jan 10 20:14:38 2010 (r202041) +++ user/ed/utmpx/share/termcap/termcap.src Sun Jan 10 20:19:30 2010 (r202042) @@ -2807,9 +2807,9 @@ xterm-clear:\ :te=\E[?1049l:ti=\E[?1049h:\ :tc=xterm-new: xterm-new|modern xterm:\ - :*6=\EOF:@7=\EOF:F1=\E[23~:F2=\E[24~:K2=\EOE:Km=\E[M:\ + :@7=\EOF:@8=\EOM:F1=\E[23~:F2=\E[24~:K2=\EOE:Km=\E[M:\ :k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:k5=\E[15~:k6=\E[17~:\ - :k7=\E[18~:k8=\E[19~:k9=\E[20~:k;=\E[21~:kH=\EOF:kI=\E[2~:\ + :k7=\E[18~:k8=\E[19~:k9=\E[20~:k;=\E[21~:kI=\E[2~:\ :kN=\E[6~:kP=\E[5~:kd=\EOB:kh=\EOH:kl=\EOD:kr=\EOC:ku=\EOA:\ :tc=xterm-basic: # From owner-svn-src-user@FreeBSD.ORG Sun Jan 10 20:21:42 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D53721065670; Sun, 10 Jan 2010 20:21:42 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id C76EA8FC0C; Sun, 10 Jan 2010 20:21:42 +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 o0AKLgpo030922; Sun, 10 Jan 2010 20:21:42 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0AKLgVr030920; Sun, 10 Jan 2010 20:21:42 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201001102021.o0AKLgVr030920@svn.freebsd.org> From: Ed Schouten Date: Sun, 10 Jan 2010 20:21:42 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202043 - user/ed/utmpx/etc X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 10 Jan 2010 20:21:42 -0000 Author: ed Date: Sun Jan 10 20:21:42 2010 New Revision: 202043 URL: http://svn.freebsd.org/changeset/base/202043 Log: Don't forget to fix termcap.small as well. Make the End key work again. PR: conf/142578 Submitted by: Yuri Pankov Modified: user/ed/utmpx/etc/termcap.small Modified: user/ed/utmpx/etc/termcap.small ============================================================================== --- user/ed/utmpx/etc/termcap.small Sun Jan 10 20:19:30 2010 (r202042) +++ user/ed/utmpx/etc/termcap.small Sun Jan 10 20:21:42 2010 (r202043) @@ -294,9 +294,9 @@ pc3|ibmpc3|IBM PC 386BSD Console:\ # $XTermId: termcap,v 1.78 2009/11/09 00:24:26 tom Exp $ # xterm-new|modern xterm:\ - :*6=\EOF:@7=\EOF:F1=\E[23~:F2=\E[24~:K2=\EOE:Km=\E[M:\ + :@7=\EOF:@8=\EOM:F1=\E[23~:F2=\E[24~:K2=\EOE:Km=\E[M:\ :k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:k5=\E[15~:k6=\E[17~:\ - :k7=\E[18~:k8=\E[19~:k9=\E[20~:k;=\E[21~:kH=\EOF:kI=\E[2~:\ + :k7=\E[18~:k8=\E[19~:k9=\E[20~:k;=\E[21~:kI=\E[2~:\ :kN=\E[6~:kP=\E[5~:kd=\EOB:kh=\EOH:kl=\EOD:kr=\EOC:ku=\EOA:\ :tc=xterm-basic: # From owner-svn-src-user@FreeBSD.ORG Sun Jan 10 23:37:04 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B76B21065670; Sun, 10 Jan 2010 23:37:04 +0000 (UTC) (envelope-from kmacy@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 8DCDA8FC14; Sun, 10 Jan 2010 23:37:04 +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 o0ANb4qW075906; Sun, 10 Jan 2010 23:37:04 GMT (envelope-from kmacy@svn.freebsd.org) Received: (from kmacy@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0ANb493075904; Sun, 10 Jan 2010 23:37:04 GMT (envelope-from kmacy@svn.freebsd.org) Message-Id: <201001102337.o0ANb493075904@svn.freebsd.org> From: Kip Macy Date: Sun, 10 Jan 2010 23:37:04 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202051 - user/kmacy/releng_8_rump/lib/libunet X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 10 Jan 2010 23:37:04 -0000 Author: kmacy Date: Sun Jan 10 23:37:04 2010 New Revision: 202051 URL: http://svn.freebsd.org/changeset/base/202051 Log: implement hash table for wakeup channel lookups Modified: user/kmacy/releng_8_rump/lib/libunet/unet_kern_synch.c Modified: user/kmacy/releng_8_rump/lib/libunet/unet_kern_synch.c ============================================================================== --- user/kmacy/releng_8_rump/lib/libunet/unet_kern_synch.c Sun Jan 10 22:34:18 2010 (r202050) +++ user/kmacy/releng_8_rump/lib/libunet/unet_kern_synch.c Sun Jan 10 23:37:04 2010 (r202051) @@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$"); int hogticks; typedef struct sleep_entry { + LIST_ENTRY(sleep_entry) list_entry; void *chan; const char *wmesg; pthread_cond_t cond; @@ -45,6 +46,8 @@ SYSINIT(synch_setup, SI_SUB_KICK_SCHEDUL static struct se_head *se_active; static u_long se_hashmask; static pthread_mutex_t synch_lock; +#define SE_HASH(chan) (((uintptr_t)chan) & se_hashmask) +LIST_HEAD(se_head, sleep_entry); static void synch_setup(void *arg) @@ -61,21 +64,33 @@ se_alloc(void *chan, const char *wmesg) { sleep_entry_t se; pthread_condattr_t attr; + struct se_head *hash_list; se = malloc(sizeof(*se), M_DEVBUF, 0); se->chan = chan; se->wmesg = wmesg; + se->waiters = 1; pthread_condattr_init(&attr); pthread_cond_init(&se->cond, &attr); /* insert in hash table */ + hash_list = &se_active[SE_HASH(chan)]; + LIST_INSERT_HEAD(hash_list, se, list_entry); + return (se); } sleep_entry_t se_lookup(void *chan) { - /* lookup in hashtable */ + struct se_head *hash_list; + sleep_entry_t se; + + hash_list = &se_active[SE_HASH(chan)]; + LIST_FOREACH(se, hash_list, list_entry) + if (se->chan == chan) + return (se); + return (NULL); } @@ -84,7 +99,7 @@ se_free(sleep_entry_t se) { if (--se->waiters == 0) { - /* unlink se */ + LIST_REMOVE(se, list_entry); pthread_cond_destroy(&se->cond); free(se, M_DEVBUF); } @@ -120,7 +135,7 @@ _sleep(void *ident, struct lock_object * else se = se_alloc(ident, wmesg); pthread_mutex_unlock(&synch_lock); - + if (timo) rv = pthread_cond_timedwait(&se->cond, &lock->lo_mutex, &ts); else From owner-svn-src-user@FreeBSD.ORG Mon Jan 11 00:11:17 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 43FA61065672; Mon, 11 Jan 2010 00:11:17 +0000 (UTC) (envelope-from kmacy@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 333378FC08; Mon, 11 Jan 2010 00:11:17 +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 o0B0BHwY084399; Mon, 11 Jan 2010 00:11:17 GMT (envelope-from kmacy@svn.freebsd.org) Received: (from kmacy@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0B0BH7U084397; Mon, 11 Jan 2010 00:11:17 GMT (envelope-from kmacy@svn.freebsd.org) Message-Id: <201001110011.o0B0BH7U084397@svn.freebsd.org> From: Kip Macy Date: Mon, 11 Jan 2010 00:11:17 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202053 - user/kmacy/releng_8_rump/lib/libunet X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Jan 2010 00:11:17 -0000 Author: kmacy Date: Mon Jan 11 00:11:16 2010 New Revision: 202053 URL: http://svn.freebsd.org/changeset/base/202053 Log: add basic descriptor management Modified: user/kmacy/releng_8_rump/lib/libunet/unet_kern_descrip.c Modified: user/kmacy/releng_8_rump/lib/libunet/unet_kern_descrip.c ============================================================================== --- user/kmacy/releng_8_rump/lib/libunet/unet_kern_descrip.c Sun Jan 10 23:51:02 2010 (r202052) +++ user/kmacy/releng_8_rump/lib/libunet/unet_kern_descrip.c Mon Jan 11 00:11:16 2010 (r202053) @@ -76,6 +76,15 @@ __FBSDID("$FreeBSD$"); #include #include +static MALLOC_DEFINE(M_FILEDESC, "filedesc", "Open file descriptor table"); + +static uma_zone_t file_zone; + +volatile int openfiles; /* actual number of open files */ + +/* A mutex to protect the association between a proc and filedesc. */ +static struct mtx fdesc_mtx; + /* * This is common code for FIOSETOWN ioctl called by fcntl(fd, F_SETOWN, arg). @@ -87,16 +96,13 @@ int fsetown(pid_t pgid, struct sigio **sigiop) { - panic(""); - return (0); } pid_t fgetown(struct sigio **sigiop) { - - panic(""); + return (0); } @@ -104,8 +110,7 @@ fgetown(struct sigio **sigiop) void funsetown(struct sigio **sigiop) { - - panic(""); + /* nothing to do here */ } @@ -119,8 +124,52 @@ funsetown(struct sigio **sigiop) int falloc(struct thread *td, struct file **resultfp, int *resultfd) { - panic(""); + struct proc *p = td->td_proc; + struct file *fp; + int error, i; + int maxuserfiles = maxfiles - (maxfiles / 20); + static struct timeval lastfail; + static int curfail; + + fp = uma_zalloc(file_zone, M_WAITOK | M_ZERO); + if ((openfiles >= maxuserfiles && + priv_check(td, PRIV_MAXFILES) != 0) || + openfiles >= maxfiles) { + if (ppsratecheck(&lastfail, &curfail, 1)) { + printf("kern.maxfiles limit exceeded by uid %i, please see tuning(7).\n", + td->td_ucred->cr_ruid); + } + uma_zfree(file_zone, fp); + return (ENFILE); + } + atomic_add_int(&openfiles, 1); + /* + * If the process has file descriptor zero open, add the new file + * descriptor to the list of open files at that point, otherwise + * put it at the front of the list of open files. + */ + refcount_init(&fp->f_count, 1); + if (resultfp) + fhold(fp); + fp->f_cred = crhold(td->td_ucred); + fp->f_ops = &badfileops; + fp->f_data = NULL; + fp->f_vnode = NULL; + FILEDESC_XLOCK(p->p_fd); + if ((error = fdalloc(td, 0, &i))) { + FILEDESC_XUNLOCK(p->p_fd); + fdrop(fp, td); + if (resultfp) + fdrop(fp, td); + return (error); + } + p->p_fd->fd_ofiles[i] = fp; + FILEDESC_XUNLOCK(p->p_fd); + if (resultfp) + *resultfp = fp; + if (resultfd) + *resultfd = i; return (0); } @@ -131,9 +180,24 @@ falloc(struct thread *td, struct file ** int _fdrop(struct file *fp, struct thread *td) { + int error; - panic(""); - return (0); + error = 0; + if (fp->f_count != 0) + panic("fdrop: count %d", fp->f_count); + if (fp->f_ops != &badfileops) + error = fo_close(fp, td); + /* + * The f_cdevpriv cannot be assigned non-NULL value while we + * are destroying the file. + */ + if (fp->f_cdevpriv != NULL) + devfs_fpdrop(fp); + atomic_subtract_int(&openfiles, 1); + crfree(fp->f_cred); + uma_zfree(file_zone, fp); + + return (error); } void @@ -245,6 +309,18 @@ fget_write(struct thread *td, int fd, st } +/* ARGSUSED*/ +static void +filelistinit(void *dummy) +{ + + file_zone = uma_zcreate("Files", sizeof(struct file), NULL, NULL, + NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); + mtx_init(&sigio_lock, "sigio lock", NULL, MTX_DEF); + mtx_init(&fdesc_mtx, "fdesc", NULL, MTX_DEF); +} +SYSINIT(select, SI_SUB_LOCK, SI_ORDER_FIRST, filelistinit, NULL); + /*-------------------------------------------------------------------*/ static int From owner-svn-src-user@FreeBSD.ORG Mon Jan 11 00:22:47 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 93D511065679; Mon, 11 Jan 2010 00:22:47 +0000 (UTC) (envelope-from kmacy@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 835D38FC1A; Mon, 11 Jan 2010 00:22:47 +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 o0B0Mltn087342; Mon, 11 Jan 2010 00:22:47 GMT (envelope-from kmacy@svn.freebsd.org) Received: (from kmacy@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0B0Mlts087339; Mon, 11 Jan 2010 00:22:47 GMT (envelope-from kmacy@svn.freebsd.org) Message-Id: <201001110022.o0B0Mlts087339@svn.freebsd.org> From: Kip Macy Date: Mon, 11 Jan 2010 00:22:47 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202055 - user/kmacy/releng_8_rump/lib/libunet X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Jan 2010 00:22:47 -0000 Author: kmacy Date: Mon Jan 11 00:22:47 2010 New Revision: 202055 URL: http://svn.freebsd.org/changeset/base/202055 Log: - opt out of supporting SIGIO for now - white space cleanup Modified: user/kmacy/releng_8_rump/lib/libunet/unet_glue.c user/kmacy/releng_8_rump/lib/libunet/unet_kern_synch.c Modified: user/kmacy/releng_8_rump/lib/libunet/unet_glue.c ============================================================================== --- user/kmacy/releng_8_rump/lib/libunet/unet_glue.c Mon Jan 11 00:18:40 2010 (r202054) +++ user/kmacy/releng_8_rump/lib/libunet/unet_glue.c Mon Jan 11 00:22:47 2010 (r202055) @@ -39,6 +39,8 @@ MALLOC_DEFINE(M_DEVBUF, "devbuf", "devic MALLOC_DEFINE(M_TEMP, "temp", "misc temporary data buffers"); +extern void abort(void); + int ticks; time_t time_second = 1; @@ -601,7 +603,8 @@ pgsigio(sigiop, sig, checkctty) struct sigio **sigiop; int sig, checkctty; { - panic(""); + printf("SIGIO not supported yet\n"); + abort(); #ifdef notyet ksiginfo_t ksi; struct sigio *sigio; Modified: user/kmacy/releng_8_rump/lib/libunet/unet_kern_synch.c ============================================================================== --- user/kmacy/releng_8_rump/lib/libunet/unet_kern_synch.c Mon Jan 11 00:18:40 2010 (r202054) +++ user/kmacy/releng_8_rump/lib/libunet/unet_kern_synch.c Mon Jan 11 00:22:47 2010 (r202055) @@ -143,7 +143,7 @@ _sleep(void *ident, struct lock_object * pthread_mutex_lock(&synch_lock); se_free(se); - pthread_mutex_unlock(&synch_lock); + pthread_mutex_unlock(&synch_lock); return (rv); } From owner-svn-src-user@FreeBSD.ORG Mon Jan 11 00:51:25 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 7702D106566B; Mon, 11 Jan 2010 00:51:25 +0000 (UTC) (envelope-from kmacy@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 653F08FC08; Mon, 11 Jan 2010 00:51:25 +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 o0B0pPoQ094397; Mon, 11 Jan 2010 00:51:25 GMT (envelope-from kmacy@svn.freebsd.org) Received: (from kmacy@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0B0pPs8094395; Mon, 11 Jan 2010 00:51:25 GMT (envelope-from kmacy@svn.freebsd.org) Message-Id: <201001110051.o0B0pPs8094395@svn.freebsd.org> From: Kip Macy Date: Mon, 11 Jan 2010 00:51:25 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202058 - user/kmacy/releng_8_rump/lib/libunet X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Jan 2010 00:51:25 -0000 Author: kmacy Date: Mon Jan 11 00:51:25 2010 New Revision: 202058 URL: http://svn.freebsd.org/changeset/base/202058 Log: integrate bulk of kern_descrip.c - excluding procstat and vnode bits Modified: user/kmacy/releng_8_rump/lib/libunet/unet_kern_descrip.c Modified: user/kmacy/releng_8_rump/lib/libunet/unet_kern_descrip.c ============================================================================== --- user/kmacy/releng_8_rump/lib/libunet/unet_kern_descrip.c Mon Jan 11 00:41:14 2010 (r202057) +++ user/kmacy/releng_8_rump/lib/libunet/unet_kern_descrip.c Mon Jan 11 00:51:25 2010 (r202058) @@ -1,5 +1,3 @@ - - /*- * Copyright (c) 1982, 1986, 1989, 1991, 1993 * The Regents of the University of California. All rights reserved. @@ -75,16 +73,751 @@ __FBSDID("$FreeBSD$"); #include #include #include +#ifdef KTRACE +#include +#endif + +#include + +#include + +#include static MALLOC_DEFINE(M_FILEDESC, "filedesc", "Open file descriptor table"); +static MALLOC_DEFINE(M_FILEDESC_TO_LEADER, "filedesc_to_leader", + "file desc to leader structures"); +static MALLOC_DEFINE(M_SIGIO, "sigio", "sigio structures"); static uma_zone_t file_zone; +#define vref(v) +#define VREF(x) vref((x)) +#define knote_fdclose(x, y) + + +/* Flags for do_dup() */ +#define DUP_FIXED 0x1 /* Force fixed allocation */ +#define DUP_FCNTL 0x2 /* fcntl()-style errors */ + +static int do_dup(struct thread *td, int flags, int old, int new, + register_t *retval); +static int fd_first_free(struct filedesc *, int, int); +static int fd_last_used(struct filedesc *, int, int); +static void fdgrowtable(struct filedesc *, int); +static void fdunused(struct filedesc *fdp, int fd); +static void fdused(struct filedesc *fdp, int fd); + +/* + * A process is initially started out with NDFILE descriptors stored within + * this structure, selected to be enough for typical applications based on + * the historical limit of 20 open files (and the usage of descriptors by + * shells). If these descriptors are exhausted, a larger descriptor table + * may be allocated, up to a process' resource limit; the internal arrays + * are then unused. + */ +#define NDFILE 20 +#define NDSLOTSIZE sizeof(NDSLOTTYPE) +#define NDENTRIES (NDSLOTSIZE * __CHAR_BIT) +#define NDSLOT(x) ((x) / NDENTRIES) +#define NDBIT(x) ((NDSLOTTYPE)1 << ((x) % NDENTRIES)) +#define NDSLOTS(x) (((x) + NDENTRIES - 1) / NDENTRIES) + +/* + * Storage required per open file descriptor. + */ +#define OFILESIZE (sizeof(struct file *) + sizeof(char)) + +/* + * Storage to hold unused ofiles that need to be reclaimed. + */ +struct freetable { + struct file **ft_table; + SLIST_ENTRY(freetable) ft_next; +}; + +/* + * Basic allocation of descriptors: + * one of the above, plus arrays for NDFILE descriptors. + */ +struct filedesc0 { + struct filedesc fd_fd; + /* + * ofiles which need to be reclaimed on free. + */ + SLIST_HEAD(,freetable) fd_free; + /* + * These arrays are used when the number of open files is + * <= NDFILE, and are then pointed to by the pointers above. + */ + struct file *fd_dfiles[NDFILE]; + char fd_dfileflags[NDFILE]; + NDSLOTTYPE fd_dmap[NDSLOTS(NDFILE)]; +}; + +/* + * Descriptor management. + */ volatile int openfiles; /* actual number of open files */ +struct mtx sigio_lock; /* mtx to protect pointers to sigio */ +void (*mq_fdclose)(struct thread *td, int fd, struct file *fp); /* A mutex to protect the association between a proc and filedesc. */ static struct mtx fdesc_mtx; +/* + * Find the first zero bit in the given bitmap, starting at low and not + * exceeding size - 1. + */ +static int +fd_first_free(struct filedesc *fdp, int low, int size) +{ + NDSLOTTYPE *map = fdp->fd_map; + NDSLOTTYPE mask; + int off, maxoff; + + if (low >= size) + return (low); + + off = NDSLOT(low); + if (low % NDENTRIES) { + mask = ~(~(NDSLOTTYPE)0 >> (NDENTRIES - (low % NDENTRIES))); + if ((mask &= ~map[off]) != 0UL) + return (off * NDENTRIES + ffsl(mask) - 1); + ++off; + } + for (maxoff = NDSLOTS(size); off < maxoff; ++off) + if (map[off] != ~0UL) + return (off * NDENTRIES + ffsl(~map[off]) - 1); + return (size); +} + +/* + * Find the highest non-zero bit in the given bitmap, starting at low and + * not exceeding size - 1. + */ +static int +fd_last_used(struct filedesc *fdp, int low, int size) +{ + NDSLOTTYPE *map = fdp->fd_map; + NDSLOTTYPE mask; + int off, minoff; + + if (low >= size) + return (-1); + + off = NDSLOT(size); + if (size % NDENTRIES) { + mask = ~(~(NDSLOTTYPE)0 << (size % NDENTRIES)); + if ((mask &= map[off]) != 0) + return (off * NDENTRIES + flsl(mask) - 1); + --off; + } + for (minoff = NDSLOT(low); off >= minoff; --off) + if (map[off] != 0) + return (off * NDENTRIES + flsl(map[off]) - 1); + return (low - 1); +} + +static int +fdisused(struct filedesc *fdp, int fd) +{ + KASSERT(fd >= 0 && fd < fdp->fd_nfiles, + ("file descriptor %d out of range (0, %d)", fd, fdp->fd_nfiles)); + return ((fdp->fd_map[NDSLOT(fd)] & NDBIT(fd)) != 0); +} + +/* + * Mark a file descriptor as used. + */ +static void +fdused(struct filedesc *fdp, int fd) +{ + + FILEDESC_XLOCK_ASSERT(fdp); + KASSERT(!fdisused(fdp, fd), + ("fd already used")); + + fdp->fd_map[NDSLOT(fd)] |= NDBIT(fd); + if (fd > fdp->fd_lastfile) + fdp->fd_lastfile = fd; + if (fd == fdp->fd_freefile) + fdp->fd_freefile = fd_first_free(fdp, fd, fdp->fd_nfiles); +} + +/* + * Mark a file descriptor as unused. + */ +static void +fdunused(struct filedesc *fdp, int fd) +{ + + FILEDESC_XLOCK_ASSERT(fdp); + KASSERT(fdisused(fdp, fd), + ("fd is already unused")); + KASSERT(fdp->fd_ofiles[fd] == NULL, + ("fd is still in use")); + + fdp->fd_map[NDSLOT(fd)] &= ~NDBIT(fd); + if (fd < fdp->fd_freefile) + fdp->fd_freefile = fd; + if (fd == fdp->fd_lastfile) + fdp->fd_lastfile = fd_last_used(fdp, 0, fd); +} + +/* + * System calls on descriptors. + */ +#ifndef _SYS_SYSPROTO_H_ +struct getdtablesize_args { + int dummy; +}; +#endif +/* ARGSUSED */ +int +getdtablesize(struct thread *td, struct getdtablesize_args *uap) +{ + struct proc *p = td->td_proc; + + PROC_LOCK(p); + td->td_retval[0] = + min((int)lim_cur(p, RLIMIT_NOFILE), maxfilesperproc); + PROC_UNLOCK(p); + return (0); +} + +/* + * Duplicate a file descriptor to a particular value. + * + * Note: keep in mind that a potential race condition exists when closing + * descriptors from a shared descriptor table (via rfork). + */ +#ifndef _SYS_SYSPROTO_H_ +struct dup2_args { + u_int from; + u_int to; +}; +#endif +/* ARGSUSED */ +int +dup2(struct thread *td, struct dup2_args *uap) +{ + + return (do_dup(td, DUP_FIXED, (int)uap->from, (int)uap->to, + td->td_retval)); +} + +/* + * Duplicate a file descriptor. + */ +#ifndef _SYS_SYSPROTO_H_ +struct dup_args { + u_int fd; +}; +#endif +/* ARGSUSED */ +int +dup(struct thread *td, struct dup_args *uap) +{ + + return (do_dup(td, 0, (int)uap->fd, 0, td->td_retval)); +} + +/* + * The file control system call. + */ +#ifndef _SYS_SYSPROTO_H_ +struct fcntl_args { + int fd; + int cmd; + long arg; +}; +#endif +/* ARGSUSED */ +int +fcntl(struct thread *td, struct fcntl_args *uap) +{ + struct flock fl; + struct oflock ofl; + intptr_t arg; + int error; + int cmd; + + error = 0; + cmd = uap->cmd; + switch (uap->cmd) { + case F_OGETLK: + case F_OSETLK: + case F_OSETLKW: + /* + * Convert old flock structure to new. + */ + error = copyin((void *)(intptr_t)uap->arg, &ofl, sizeof(ofl)); + fl.l_start = ofl.l_start; + fl.l_len = ofl.l_len; + fl.l_pid = ofl.l_pid; + fl.l_type = ofl.l_type; + fl.l_whence = ofl.l_whence; + fl.l_sysid = 0; + + switch (uap->cmd) { + case F_OGETLK: + cmd = F_GETLK; + break; + case F_OSETLK: + cmd = F_SETLK; + break; + case F_OSETLKW: + cmd = F_SETLKW; + break; + } + arg = (intptr_t)&fl; + break; + case F_GETLK: + case F_SETLK: + case F_SETLKW: + case F_SETLK_REMOTE: + error = copyin((void *)(intptr_t)uap->arg, &fl, sizeof(fl)); + arg = (intptr_t)&fl; + break; + default: + arg = uap->arg; + break; + } + if (error) + return (error); + error = kern_fcntl(td, uap->fd, cmd, arg); + if (error) + return (error); + if (uap->cmd == F_OGETLK) { + ofl.l_start = fl.l_start; + ofl.l_len = fl.l_len; + ofl.l_pid = fl.l_pid; + ofl.l_type = fl.l_type; + ofl.l_whence = fl.l_whence; + error = copyout(&ofl, (void *)(intptr_t)uap->arg, sizeof(ofl)); + } else if (uap->cmd == F_GETLK) { + error = copyout(&fl, (void *)(intptr_t)uap->arg, sizeof(fl)); + } + return (error); +} + +static inline struct file * +fdtofp(int fd, struct filedesc *fdp) +{ + struct file *fp; + + FILEDESC_LOCK_ASSERT(fdp); + if ((unsigned)fd >= fdp->fd_nfiles || + (fp = fdp->fd_ofiles[fd]) == NULL) + return (NULL); + return (fp); +} + +int +kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg) +{ + struct filedesc *fdp; + struct flock *flp; + struct file *fp; + struct proc *p; + char *pop; + struct vnode *vp; + int error, flg, tmp; + int vfslocked; + u_int old, new; + uint64_t bsize; + + vfslocked = 0; + error = 0; + flg = F_POSIX; + p = td->td_proc; + fdp = p->p_fd; + + switch (cmd) { + case F_DUPFD: + tmp = arg; + error = do_dup(td, DUP_FCNTL, fd, tmp, td->td_retval); + break; + + case F_DUP2FD: + tmp = arg; + error = do_dup(td, DUP_FIXED, fd, tmp, td->td_retval); + break; + + case F_GETFD: + FILEDESC_SLOCK(fdp); + if ((fp = fdtofp(fd, fdp)) == NULL) { + FILEDESC_SUNLOCK(fdp); + error = EBADF; + break; + } + pop = &fdp->fd_ofileflags[fd]; + td->td_retval[0] = (*pop & UF_EXCLOSE) ? FD_CLOEXEC : 0; + FILEDESC_SUNLOCK(fdp); + break; + + case F_SETFD: + FILEDESC_XLOCK(fdp); + if ((fp = fdtofp(fd, fdp)) == NULL) { + FILEDESC_XUNLOCK(fdp); + error = EBADF; + break; + } + pop = &fdp->fd_ofileflags[fd]; + *pop = (*pop &~ UF_EXCLOSE) | + (arg & FD_CLOEXEC ? UF_EXCLOSE : 0); + FILEDESC_XUNLOCK(fdp); + break; + + case F_GETFL: + FILEDESC_SLOCK(fdp); + if ((fp = fdtofp(fd, fdp)) == NULL) { + FILEDESC_SUNLOCK(fdp); + error = EBADF; + break; + } + td->td_retval[0] = OFLAGS(fp->f_flag); + FILEDESC_SUNLOCK(fdp); + break; + + case F_SETFL: + FILEDESC_SLOCK(fdp); + if ((fp = fdtofp(fd, fdp)) == NULL) { + FILEDESC_SUNLOCK(fdp); + error = EBADF; + break; + } + fhold(fp); + FILEDESC_SUNLOCK(fdp); + do { + tmp = flg = fp->f_flag; + tmp &= ~FCNTLFLAGS; + tmp |= FFLAGS(arg & ~O_ACCMODE) & FCNTLFLAGS; + } while(atomic_cmpset_int(&fp->f_flag, flg, tmp) == 0); + tmp = fp->f_flag & FNONBLOCK; + error = fo_ioctl(fp, FIONBIO, &tmp, td->td_ucred, td); + if (error) { + fdrop(fp, td); + break; + } + tmp = fp->f_flag & FASYNC; + error = fo_ioctl(fp, FIOASYNC, &tmp, td->td_ucred, td); + if (error == 0) { + fdrop(fp, td); + break; + } + atomic_clear_int(&fp->f_flag, FNONBLOCK); + tmp = 0; + (void)fo_ioctl(fp, FIONBIO, &tmp, td->td_ucred, td); + fdrop(fp, td); + break; + + case F_GETOWN: + FILEDESC_SLOCK(fdp); + if ((fp = fdtofp(fd, fdp)) == NULL) { + FILEDESC_SUNLOCK(fdp); + error = EBADF; + break; + } + fhold(fp); + FILEDESC_SUNLOCK(fdp); + error = fo_ioctl(fp, FIOGETOWN, &tmp, td->td_ucred, td); + if (error == 0) + td->td_retval[0] = tmp; + fdrop(fp, td); + break; + + case F_SETOWN: + FILEDESC_SLOCK(fdp); + if ((fp = fdtofp(fd, fdp)) == NULL) { + FILEDESC_SUNLOCK(fdp); + error = EBADF; + break; + } + fhold(fp); + FILEDESC_SUNLOCK(fdp); + tmp = arg; + error = fo_ioctl(fp, FIOSETOWN, &tmp, td->td_ucred, td); + fdrop(fp, td); + break; + + case F_SETLK_REMOTE: + error = priv_check(td, PRIV_NFS_LOCKD); + if (error) + return (error); + flg = F_REMOTE; + goto do_setlk; + + case F_SETLKW: + flg |= F_WAIT; + /* FALLTHROUGH F_SETLK */ + + case F_SETLK: + do_setlk: + FILEDESC_SLOCK(fdp); + if ((fp = fdtofp(fd, fdp)) == NULL) { + FILEDESC_SUNLOCK(fdp); + error = EBADF; + break; + } + if (fp->f_type != DTYPE_VNODE) { + FILEDESC_SUNLOCK(fdp); + error = EBADF; + break; + } + flp = (struct flock *)arg; + if (flp->l_whence == SEEK_CUR) { + if (fp->f_offset < 0 || + (flp->l_start > 0 && + fp->f_offset > OFF_MAX - flp->l_start)) { + FILEDESC_SUNLOCK(fdp); + error = EOVERFLOW; + break; + } + flp->l_start += fp->f_offset; + } + + FILEDESC_SUNLOCK(fdp); + default: + error = EINVAL; + break; + } + return (error); +} + +/* + * Common code for dup, dup2, fcntl(F_DUPFD) and fcntl(F_DUP2FD). + */ +static int +do_dup(struct thread *td, int flags, int old, int new, + register_t *retval) +{ + struct filedesc *fdp; + struct proc *p; + struct file *fp; + struct file *delfp; + int error, holdleaders, maxfd; + + p = td->td_proc; + fdp = p->p_fd; + + /* + * Verify we have a valid descriptor to dup from and possibly to + * dup to. Unlike dup() and dup2(), fcntl()'s F_DUPFD should + * return EINVAL when the new descriptor is out of bounds. + */ + if (old < 0) + return (EBADF); + if (new < 0) + return (flags & DUP_FCNTL ? EINVAL : EBADF); + PROC_LOCK(p); + maxfd = min((int)lim_cur(p, RLIMIT_NOFILE), maxfilesperproc); + PROC_UNLOCK(p); + if (new >= maxfd) + return (flags & DUP_FCNTL ? EINVAL : EMFILE); + + FILEDESC_XLOCK(fdp); + if (old >= fdp->fd_nfiles || fdp->fd_ofiles[old] == NULL) { + FILEDESC_XUNLOCK(fdp); + return (EBADF); + } + if (flags & DUP_FIXED && old == new) { + *retval = new; + FILEDESC_XUNLOCK(fdp); + return (0); + } + fp = fdp->fd_ofiles[old]; + fhold(fp); + + /* + * If the caller specified a file descriptor, make sure the file + * table is large enough to hold it, and grab it. Otherwise, just + * allocate a new descriptor the usual way. Since the filedesc + * lock may be temporarily dropped in the process, we have to look + * out for a race. + */ + if (flags & DUP_FIXED) { + if (new >= fdp->fd_nfiles) + fdgrowtable(fdp, new + 1); + if (fdp->fd_ofiles[new] == NULL) + fdused(fdp, new); + } else { + if ((error = fdalloc(td, new, &new)) != 0) { + FILEDESC_XUNLOCK(fdp); + fdrop(fp, td); + return (error); + } + } + + /* + * If the old file changed out from under us then treat it as a + * bad file descriptor. Userland should do its own locking to + * avoid this case. + */ + if (fdp->fd_ofiles[old] != fp) { + /* we've allocated a descriptor which we won't use */ + if (fdp->fd_ofiles[new] == NULL) + fdunused(fdp, new); + FILEDESC_XUNLOCK(fdp); + fdrop(fp, td); + return (EBADF); + } + KASSERT(old != new, + ("new fd is same as old")); + + /* + * Save info on the descriptor being overwritten. We cannot close + * it without introducing an ownership race for the slot, since we + * need to drop the filedesc lock to call closef(). + * + * XXX this duplicates parts of close(). + */ + delfp = fdp->fd_ofiles[new]; + holdleaders = 0; + if (delfp != NULL) { + if (td->td_proc->p_fdtol != NULL) { + /* + * Ask fdfree() to sleep to ensure that all relevant + * process leaders can be traversed in closef(). + */ + fdp->fd_holdleaderscount++; + holdleaders = 1; + } + } + + /* + * Duplicate the source descriptor + */ + fdp->fd_ofiles[new] = fp; + fdp->fd_ofileflags[new] = fdp->fd_ofileflags[old] &~ UF_EXCLOSE; + if (new > fdp->fd_lastfile) + fdp->fd_lastfile = new; + *retval = new; + + /* + * If we dup'd over a valid file, we now own the reference to it + * and must dispose of it using closef() semantics (as if a + * close() were performed on it). + * + * XXX this duplicates parts of close(). + */ + if (delfp != NULL) { + knote_fdclose(td, new); + if (delfp->f_type == DTYPE_MQUEUE) + mq_fdclose(td, new, delfp); + FILEDESC_XUNLOCK(fdp); + (void) closef(delfp, td); + if (holdleaders) { + FILEDESC_XLOCK(fdp); + fdp->fd_holdleaderscount--; + if (fdp->fd_holdleaderscount == 0 && + fdp->fd_holdleaderswakeup != 0) { + fdp->fd_holdleaderswakeup = 0; + wakeup(&fdp->fd_holdleaderscount); + } + FILEDESC_XUNLOCK(fdp); + } + } else { + FILEDESC_XUNLOCK(fdp); + } + return (0); +} + +/* + * If sigio is on the list associated with a process or process group, + * disable signalling from the device, remove sigio from the list and + * free sigio. + */ +void +funsetown(struct sigio **sigiop) +{ + struct sigio *sigio; + + SIGIO_LOCK(); + sigio = *sigiop; + if (sigio == NULL) { + SIGIO_UNLOCK(); + return; + } + *(sigio->sio_myref) = NULL; + if ((sigio)->sio_pgid < 0) { + struct pgrp *pg = (sigio)->sio_pgrp; + PGRP_LOCK(pg); + SLIST_REMOVE(&sigio->sio_pgrp->pg_sigiolst, sigio, + sigio, sio_pgsigio); + PGRP_UNLOCK(pg); + } else { + struct proc *p = (sigio)->sio_proc; + PROC_LOCK(p); + SLIST_REMOVE(&sigio->sio_proc->p_sigiolst, sigio, + sigio, sio_pgsigio); + PROC_UNLOCK(p); + } + SIGIO_UNLOCK(); + crfree(sigio->sio_ucred); + free(sigio, M_SIGIO); +} + +/* + * Free a list of sigio structures. + * We only need to lock the SIGIO_LOCK because we have made ourselves + * inaccessible to callers of fsetown and therefore do not need to lock + * the proc or pgrp struct for the list manipulation. + */ +void +funsetownlst(struct sigiolst *sigiolst) +{ + struct proc *p; + struct pgrp *pg; + struct sigio *sigio; + + sigio = SLIST_FIRST(sigiolst); + if (sigio == NULL) + return; + p = NULL; + pg = NULL; + + /* + * Every entry of the list should belong + * to a single proc or pgrp. + */ + if (sigio->sio_pgid < 0) { + pg = sigio->sio_pgrp; + PGRP_LOCK_ASSERT(pg, MA_NOTOWNED); + } else /* if (sigio->sio_pgid > 0) */ { + p = sigio->sio_proc; + PROC_LOCK_ASSERT(p, MA_NOTOWNED); + } + + SIGIO_LOCK(); + while ((sigio = SLIST_FIRST(sigiolst)) != NULL) { + *(sigio->sio_myref) = NULL; + if (pg != NULL) { + KASSERT(sigio->sio_pgid < 0, + ("Proc sigio in pgrp sigio list")); + KASSERT(sigio->sio_pgrp == pg, + ("Bogus pgrp in sigio list")); + PGRP_LOCK(pg); + SLIST_REMOVE(&pg->pg_sigiolst, sigio, sigio, + sio_pgsigio); + PGRP_UNLOCK(pg); + } else /* if (p != NULL) */ { + KASSERT(sigio->sio_pgid > 0, + ("Pgrp sigio in proc sigio list")); + KASSERT(sigio->sio_proc == p, + ("Bogus proc in sigio list")); + PROC_LOCK(p); + SLIST_REMOVE(&p->p_sigiolst, sigio, sigio, + sio_pgsigio); + PROC_UNLOCK(p); + } + SIGIO_UNLOCK(); + crfree(sigio->sio_ucred); + free(sigio, M_SIGIO); + SIGIO_LOCK(); + } + SIGIO_UNLOCK(); +} /* * This is common code for FIOSETOWN ioctl called by fcntl(fd, F_SETOWN, arg). @@ -95,25 +828,388 @@ static struct mtx fdesc_mtx; int fsetown(pid_t pgid, struct sigio **sigiop) { + struct proc *proc; + struct pgrp *pgrp; + struct sigio *sigio; + int ret; + + if (pgid == 0) { + funsetown(sigiop); + return (0); + } + ret = 0; + + /* Allocate and fill in the new sigio out of locks. */ + sigio = malloc(sizeof(struct sigio), M_SIGIO, M_WAITOK); + sigio->sio_pgid = pgid; + sigio->sio_ucred = crhold(curthread->td_ucred); + sigio->sio_myref = sigiop; + + SIGIO_LOCK(); + *sigiop = sigio; + SIGIO_UNLOCK(); return (0); + +fail: + sx_sunlock(&proctree_lock); + crfree(sigio->sio_ucred); + free(sigio, M_SIGIO); + return (ret); } - + +/* + * This is common code for FIOGETOWN ioctl called by fcntl(fd, F_GETOWN, arg). + */ pid_t -fgetown(struct sigio **sigiop) +fgetown(sigiop) + struct sigio **sigiop; +{ + pid_t pgid; + + SIGIO_LOCK(); + pgid = (*sigiop != NULL) ? (*sigiop)->sio_pgid : 0; + SIGIO_UNLOCK(); + return (pgid); +} + +/* + * Close a file descriptor. + */ +#ifndef _SYS_SYSPROTO_H_ +struct close_args { + int fd; +}; +#endif +/* ARGSUSED */ +int +close(td, uap) + struct thread *td; + struct close_args *uap; +{ + + return (kern_close(td, uap->fd)); +} + +int +kern_close(td, fd) + struct thread *td; + int fd; +{ + struct filedesc *fdp; + struct file *fp; + int error; + int holdleaders; + + error = 0; + holdleaders = 0; + fdp = td->td_proc->p_fd; + + AUDIT_SYSCLOSE(td, fd); + + FILEDESC_XLOCK(fdp); + if ((unsigned)fd >= fdp->fd_nfiles || + (fp = fdp->fd_ofiles[fd]) == NULL) { + FILEDESC_XUNLOCK(fdp); + return (EBADF); + } + fdp->fd_ofiles[fd] = NULL; + fdp->fd_ofileflags[fd] = 0; + fdunused(fdp, fd); + if (td->td_proc->p_fdtol != NULL) { + /* + * Ask fdfree() to sleep to ensure that all relevant + * process leaders can be traversed in closef(). + */ + fdp->fd_holdleaderscount++; + holdleaders = 1; + } + + /* + * We now hold the fp reference that used to be owned by the + * descriptor array. We have to unlock the FILEDESC *AFTER* + * knote_fdclose to prevent a race of the fd getting opened, a knote + * added, and deleteing a knote for the new fd. + */ + knote_fdclose(td, fd); + if (fp->f_type == DTYPE_MQUEUE) + mq_fdclose(td, fd, fp); + FILEDESC_XUNLOCK(fdp); + + error = closef(fp, td); + if (holdleaders) { + FILEDESC_XLOCK(fdp); + fdp->fd_holdleaderscount--; + if (fdp->fd_holdleaderscount == 0 && + fdp->fd_holdleaderswakeup != 0) { + fdp->fd_holdleaderswakeup = 0; + wakeup(&fdp->fd_holdleaderscount); + } + FILEDESC_XUNLOCK(fdp); + } + return (error); +} + +/* + * Close open file descriptors. + */ +#ifndef _SYS_SYSPROTO_H_ +struct closefrom_args { + int lowfd; +}; +#endif +/* ARGSUSED */ +int +closefrom(struct thread *td, struct closefrom_args *uap) +{ + struct filedesc *fdp; + int fd; + + fdp = td->td_proc->p_fd; + AUDIT_ARG_FD(uap->lowfd); + + /* + * Treat negative starting file descriptor values identical to + * closefrom(0) which closes all files. + */ + if (uap->lowfd < 0) + uap->lowfd = 0; + FILEDESC_SLOCK(fdp); + for (fd = uap->lowfd; fd < fdp->fd_nfiles; fd++) { + if (fdp->fd_ofiles[fd] != NULL) { + FILEDESC_SUNLOCK(fdp); + (void)kern_close(td, fd); + FILEDESC_SLOCK(fdp); + } + } + FILEDESC_SUNLOCK(fdp); + return (0); +} + +#if defined(COMPAT_43) +/* + * Return status information about a file descriptor. + */ +#ifndef _SYS_SYSPROTO_H_ +struct ofstat_args { + int fd; + struct ostat *sb; +}; +#endif +/* ARGSUSED */ +int +ofstat(struct thread *td, struct ofstat_args *uap) { + struct ostat oub; + struct stat ub; + int error; + + error = kern_fstat(td, uap->fd, &ub); + if (error == 0) { + cvtstat(&ub, &oub); + error = copyout(&oub, uap->sb, sizeof(oub)); + } + return (error); +} +#endif /* COMPAT_43 */ + +/* + * Return status information about a file descriptor. + */ +#ifndef _SYS_SYSPROTO_H_ +struct fstat_args { + int fd; + struct stat *sb; +}; +#endif +/* ARGSUSED */ +int +fstat(struct thread *td, struct fstat_args *uap) +{ + struct stat ub; + int error; + + error = kern_fstat(td, uap->fd, &ub); + if (error == 0) + error = copyout(&ub, uap->sb, sizeof(ub)); + return (error); +} + +int +kern_fstat(struct thread *td, int fd, struct stat *sbp) +{ + struct file *fp; + int error; + + AUDIT_ARG_FD(fd); + + if ((error = fget(td, fd, &fp)) != 0) + return (error); + + AUDIT_ARG_FILE(td->td_proc, fp); + + error = fo_stat(fp, sbp, td->td_ucred, td); + fdrop(fp, td); +#ifdef KTRACE + if (error == 0 && KTRPOINT(td, KTR_STRUCT)) + ktrstat(sbp); +#endif + return (error); +} + +/* + * Grow the file table to accomodate (at least) nfd descriptors. This may + * block and drop the filedesc lock, but it will reacquire it before + * returning. + */ *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-src-user@FreeBSD.ORG Mon Jan 11 05:05:29 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 340321065679; Mon, 11 Jan 2010 05:05:29 +0000 (UTC) (envelope-from kmacy@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 223118FC18; Mon, 11 Jan 2010 05:05:29 +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 o0B55TlT057587; Mon, 11 Jan 2010 05:05:29 GMT (envelope-from kmacy@svn.freebsd.org) Received: (from kmacy@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0B55TYM057584; Mon, 11 Jan 2010 05:05:29 GMT (envelope-from kmacy@svn.freebsd.org) Message-Id: <201001110505.o0B55TYM057584@svn.freebsd.org> From: Kip Macy Date: Mon, 11 Jan 2010 05:05:29 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202067 - in user/kmacy/releng_8_rump/lib/libunet: . include/vm X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Jan 2010 05:05:29 -0000 Author: kmacy Date: Mon Jan 11 05:05:28 2010 New Revision: 202067 URL: http://svn.freebsd.org/changeset/base/202067 Log: - fix v*slab functions - use pthread cond functions instead of sleep wakeup - move uma_zone and uma_keg into unet_uma_core.c - don't use kernel struct mtx wrappers for locking - don't use kernel malloc - in theory uma now only needs some additional initializers Modified: user/kmacy/releng_8_rump/lib/libunet/include/vm/uma_int.h user/kmacy/releng_8_rump/lib/libunet/unet_uma_core.c Modified: user/kmacy/releng_8_rump/lib/libunet/include/vm/uma_int.h ============================================================================== --- user/kmacy/releng_8_rump/lib/libunet/include/vm/uma_int.h Mon Jan 11 04:49:44 2010 (r202066) +++ user/kmacy/releng_8_rump/lib/libunet/include/vm/uma_int.h Mon Jan 11 05:05:28 2010 (r202067) @@ -180,47 +180,6 @@ struct uma_cache { }; typedef struct uma_cache * uma_cache_t; - -/* - * Keg management structure - * - * TODO: Optimize for cache line size - * - */ -struct uma_keg { - LIST_ENTRY(uma_keg) uk_link; /* List of all kegs */ - - struct mtx uk_lock; /* Lock for the keg */ - struct uma_hash uk_hash; - - char *uk_name; /* Name of creating zone. */ - LIST_HEAD(,uma_zone) uk_zones; /* Keg's zones */ - LIST_HEAD(,uma_slab) uk_part_slab; /* partially allocated slabs */ - LIST_HEAD(,uma_slab) uk_free_slab; /* empty slab list */ - LIST_HEAD(,uma_slab) uk_full_slab; /* full slabs */ - - u_int32_t uk_recurse; /* Allocation recursion count */ - u_int32_t uk_align; /* Alignment mask */ - u_int32_t uk_pages; /* Total page count */ - u_int32_t uk_free; /* Count of items free in slabs */ - u_int32_t uk_size; /* Requested size of each item */ - u_int32_t uk_rsize; /* Real size of each item */ - u_int32_t uk_maxpages; /* Maximum number of pages to alloc */ - - uma_init uk_init; /* Keg's init routine */ - uma_fini uk_fini; /* Keg's fini routine */ - uma_alloc uk_allocf; /* Allocation function */ - uma_free uk_freef; /* Free routine */ - - struct vm_object *uk_obj; /* Zone specific object */ - vm_offset_t uk_kva; /* Base kva for zones with objs */ - uma_zone_t uk_slabzone; /* Slab zone backing us, if OFFPAGE */ - - u_int16_t uk_pgoff; /* Offset to uma_slab struct */ - u_int16_t uk_ppera; /* pages per allocation from backend */ - u_int16_t uk_ipers; /* Items per slab */ - u_int32_t uk_flags; /* Internal flags */ -}; typedef struct uma_keg * uma_keg_t; /* Page management structure */ @@ -290,44 +249,6 @@ struct uma_klink { typedef struct uma_klink *uma_klink_t; /* - * Zone management structure - * - * TODO: Optimize for cache line size - * - */ -struct uma_zone { - char *uz_name; /* Text name of the zone */ - struct mtx *uz_lock; /* Lock for the zone (keg's lock) */ - - LIST_ENTRY(uma_zone) uz_link; /* List of all zones in keg */ - LIST_HEAD(,uma_bucket) uz_full_bucket; /* full buckets */ - LIST_HEAD(,uma_bucket) uz_free_bucket; /* Buckets for frees */ - - LIST_HEAD(,uma_klink) uz_kegs; /* List of kegs. */ - struct uma_klink uz_klink; /* klink for first keg. */ - - uma_slaballoc uz_slab; /* Allocate a slab from the backend. */ - uma_ctor uz_ctor; /* Constructor for each allocation */ - uma_dtor uz_dtor; /* Destructor */ - uma_init uz_init; /* Initializer for each item */ - uma_fini uz_fini; /* Discards memory */ - - u_int64_t uz_allocs; /* Total number of allocations */ - u_int64_t uz_frees; /* Total number of frees */ - u_int64_t uz_fails; /* Total number of alloc failures */ - u_int32_t uz_flags; /* Flags inherited from kegs */ - u_int32_t uz_size; /* Size inherited from kegs */ - uint16_t uz_fills; /* Outstanding bucket fills */ - uint16_t uz_count; /* Highest value ub_ptr can have */ - - /* - * This HAS to be the last item because we adjust the zone size - * based on NCPU and then allocate the space for the zones. - */ - struct uma_cache uz_cpu[1]; /* Per cpu caches */ -}; - -/* * These flags must not overlap with the UMA_ZONE flags specified in uma.h. */ #define UMA_ZFLAG_BUCKET 0x02000000 /* Bucket zone. */ @@ -349,6 +270,7 @@ void uma_large_free(uma_slab_t slab); /* Lock Macros */ +#if 0 #define KEG_LOCK_INIT(k, lc) \ do { \ if ((lc)) \ @@ -358,7 +280,12 @@ void uma_large_free(uma_slab_t slab); mtx_init(&(k)->uk_lock, (k)->uk_name, \ "UMA zone", MTX_DEF | MTX_DUPOK); \ } while (0) - +#else +#define KEG_LOCK_INIT(k, lc) \ + do { \ + pthread_mutex_init(&(k)->uk_lock, NULL); \ + } while (0) +#endif #define KEG_LOCK_FINI(k) mtx_destroy(&(k)->uk_lock) #define KEG_LOCK(k) mtx_lock(&(k)->uk_lock) #define KEG_UNLOCK(k) mtx_unlock(&(k)->uk_lock) @@ -391,28 +318,6 @@ hash_sfind(struct uma_hash *hash, u_int8 return (NULL); } -static __inline uma_slab_t -vtoslab(vm_offset_t va) -{ - panic(""); - - return (NULL); -} - -static __inline void -vsetslab(vm_offset_t va, uma_slab_t slab) -{ - - panic(""); -} - -static __inline void -vsetobj(vm_offset_t va, vm_object_t obj) -{ - - panic(""); -} - /* * The following two functions may be defined by architecture specific code * if they can provide more effecient allocation functions. This is useful Modified: user/kmacy/releng_8_rump/lib/libunet/unet_uma_core.c ============================================================================== --- user/kmacy/releng_8_rump/lib/libunet/unet_uma_core.c Mon Jan 11 04:49:44 2010 (r202066) +++ user/kmacy/releng_8_rump/lib/libunet/unet_uma_core.c Mon Jan 11 05:05:28 2010 (r202067) @@ -2,6 +2,7 @@ * Copyright (c) 2002-2005, 2009 Jeffrey Roberson * Copyright (c) 2004, 2005 Bosko Milekic * Copyright (c) 2004-2006 Robert N. M. Watson + * Copyright (c) 2010 Kip M. Macy * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -61,11 +62,9 @@ __FBSDID("$FreeBSD$"); #include "opt_param.h" #include -#include #include #include #include -#include #include #include #include @@ -75,13 +74,7 @@ __FBSDID("$FreeBSD$"); #include #include -#include -#include -#include -#include -#include -#include -#include + #include #include #include @@ -90,6 +83,27 @@ __FBSDID("$FreeBSD$"); #include + +#include +#include +#include +#define __BSD_VISIBLE 1 +#undef _KERNEL +#include +#include +#include + +#define M_NOWAIT 0x0001 /* do not block */ +#define M_WAITOK 0x0002 /* ok to block */ +#define M_ZERO 0x0100 /* bzero the allocation */ +#define M_NOVM 0x0200 /* don't ask VM for pages */ +#define M_USE_RESERVE 0x0400 /* can alloc out of reserve memory */ + +#define M_MAGIC 877983977 /* time when first defined :-) */ + +#define M_TEMP NULL +#define M_UMAHASH NULL + #undef UMA_MD_SMALL_ALLOC /* @@ -116,7 +130,7 @@ static uma_zone_t hashzone; /* The boot-time adjusted value for cache line alignment. */ static int uma_align_cache = 64 - 1; -static MALLOC_DEFINE(M_UMAHASH, "UMAHash", "UMA Hash Buckets"); + /* * Are we allowed to allocate buckets? @@ -127,14 +141,14 @@ static int bucketdisable = 1; static LIST_HEAD(,uma_keg) uma_kegs = LIST_HEAD_INITIALIZER(&uma_kegs); /* This mutex protects the keg list */ -static struct mtx uma_mtx; +static pthread_mutex_t uma_mtx; /* Linked list of boot time pages */ static LIST_HEAD(,uma_slab) uma_boot_pages = LIST_HEAD_INITIALIZER(&uma_boot_pages); /* This mutex protects the boot time pages list */ -static struct mtx uma_boot_pages_mtx; +static pthread_mutex_t uma_boot_pages_mtx; /* Is the VM done starting up? */ static int booted = 0; @@ -150,6 +164,90 @@ static u_int uma_max_ipers_ref; static struct callout uma_callout; #define UMA_TIMEOUT 20 /* Seconds for callout interval. */ + +/* + * Keg management structure + * + * TODO: Optimize for cache line size + * + */ +struct uma_keg { + LIST_ENTRY(uma_keg) uk_link; /* List of all kegs */ + + pthread_mutex_t uk_lock; /* Lock for the keg */ + pthread_cond_t uk_cv; + + struct uma_hash uk_hash; + + char *uk_name; /* Name of creating zone. */ + LIST_HEAD(,uma_zone) uk_zones; /* Keg's zones */ + LIST_HEAD(,uma_slab) uk_part_slab; /* partially allocated slabs */ + LIST_HEAD(,uma_slab) uk_free_slab; /* empty slab list */ + LIST_HEAD(,uma_slab) uk_full_slab; /* full slabs */ + + u_int32_t uk_recurse; /* Allocation recursion count */ + u_int32_t uk_align; /* Alignment mask */ + u_int32_t uk_pages; /* Total page count */ + u_int32_t uk_free; /* Count of items free in slabs */ + u_int32_t uk_size; /* Requested size of each item */ + u_int32_t uk_rsize; /* Real size of each item */ + u_int32_t uk_maxpages; /* Maximum number of pages to alloc */ + + uma_init uk_init; /* Keg's init routine */ + uma_fini uk_fini; /* Keg's fini routine */ + uma_alloc uk_allocf; /* Allocation function */ + uma_free uk_freef; /* Free routine */ + + struct vm_object *uk_obj; /* Zone specific object */ + vm_offset_t uk_kva; /* Base kva for zones with objs */ + uma_zone_t uk_slabzone; /* Slab zone backing us, if OFFPAGE */ + + u_int16_t uk_pgoff; /* Offset to uma_slab struct */ + u_int16_t uk_ppera; /* pages per allocation from backend */ + u_int16_t uk_ipers; /* Items per slab */ + u_int32_t uk_flags; /* Internal flags */ +}; + +/* + * Zone management structure + * + * TODO: Optimize for cache line size + * + */ +struct uma_zone { + char *uz_name; /* Text name of the zone */ + pthread_mutex_t *uz_lock; /* Lock for the zone (keg's lock) */ + pthread_cond_t uz_cv; + + LIST_ENTRY(uma_zone) uz_link; /* List of all zones in keg */ + LIST_HEAD(,uma_bucket) uz_full_bucket; /* full buckets */ + LIST_HEAD(,uma_bucket) uz_free_bucket; /* Buckets for frees */ + + LIST_HEAD(,uma_klink) uz_kegs; /* List of kegs. */ + struct uma_klink uz_klink; /* klink for first keg. */ + + uma_slaballoc uz_slab; /* Allocate a slab from the backend. */ + uma_ctor uz_ctor; /* Constructor for each allocation */ + uma_dtor uz_dtor; /* Destructor */ + uma_init uz_init; /* Initializer for each item */ + uma_fini uz_fini; /* Discards memory */ + + u_int64_t uz_allocs; /* Total number of allocations */ + u_int64_t uz_frees; /* Total number of frees */ + u_int64_t uz_fails; /* Total number of alloc failures */ + u_int32_t uz_flags; /* Flags inherited from kegs */ + u_int32_t uz_size; /* Size inherited from kegs */ + uint16_t uz_fills; /* Outstanding bucket fills */ + uint16_t uz_count; /* Highest value ub_ptr can have */ + + /* + * This HAS to be the last item because we adjust the zone size + * based on NCPU and then allocate the space for the zones. + */ + struct uma_cache uz_cpu[1]; /* Per cpu caches */ +}; + + /* * This structure is passed as the zone ctor arg so that I don't have to create * a special allocation function just for zones. @@ -262,23 +360,85 @@ SYSCTL_PROC(_vm, OID_AUTO, zone_count, C SYSCTL_PROC(_vm, OID_AUTO, zone_stats, CTLFLAG_RD|CTLTYPE_STRUCT, 0, 0, sysctl_vm_zone_stats, "s,struct uma_type_header", "Zone Stats"); -void -lock_thread_bucket(void) + +#define KASSERT(a, b) +#define panic(x, ...) + + +pthread_mutex_t bucket_lock; + +static __inline void +thread_bucket_lock(void) { - panic(""); + pthread_mutex_lock(&bucket_lock); } -void -unlock_thread_bucket(void) +static __inline void +thread_bucket_unlock(void) { - panic(""); + pthread_mutex_unlock(&bucket_lock); } - -#define critical_enter() lock_thread_bucket() -#define critical_exit() unlock_thread_bucket() +#define critical_enter() thread_bucket_lock() +#define critical_exit() thread_bucket_unlock() + +#undef mtx_lock +#undef mtx_unlock +#undef mtx_destroy +#define mtx_lock pthread_mutex_lock +#define mtx_unlock pthread_mutex_unlock +#define mtx_destroy pthread_mutex_destroy + +static int uma_page_mask; + + +#define UMA_PAGE_HASH(va) (((va) >> PAGE_SHIFT) & uma_page_mask) + +typedef struct uma_page { + LIST_ENTRY(uma_page) list_entry; + vm_offset_t up_va; + uma_slab_t up_slab; +} *uma_page_t; + +LIST_HEAD(uma_page_head, uma_page); +struct uma_page_head *uma_page_slab_hash; + +static __inline uma_slab_t +vtoslab(vm_offset_t va) +{ + struct uma_page_head *hash_list; + uma_page_t up; + + hash_list = &uma_page_slab_hash[UMA_PAGE_HASH(va)]; + LIST_FOREACH(up, hash_list, list_entry) + if (up->up_va == va) + return (up->up_slab); + return (NULL); +} + +static __inline void +vsetslab(vm_offset_t va, uma_slab_t slab) +{ + struct uma_page_head *hash_list; + uma_page_t up; + + hash_list = &uma_page_slab_hash[UMA_PAGE_HASH(va)]; + LIST_FOREACH(up, hash_list, list_entry) + if (up->up_va == va) + break; + + if (up != NULL) { + up->up_slab = slab; + return; + } + + up = malloc(sizeof(*up)); + up->up_va = va; + up->up_slab = slab; + LIST_INSERT_HEAD(hash_list, up, list_entry); +} /* @@ -496,8 +656,7 @@ hash_alloc(struct uma_hash *hash) if (oldsize) { hash->uh_hashsize = oldsize * 2; alloc = sizeof(hash->uh_slab_hash[0]) * hash->uh_hashsize; - hash->uh_slab_hash = (struct slabhead *)malloc(alloc, - M_UMAHASH, M_NOWAIT); + hash->uh_slab_hash = (struct slabhead *)malloc(alloc); } else { alloc = sizeof(hash->uh_slab_hash[0]) * UMA_HASH_SIZE_INIT; hash->uh_slab_hash = zone_alloc_item(hashzone, NULL, @@ -576,7 +735,7 @@ hash_free(struct uma_hash *hash) zone_free_item(hashzone, hash->uh_slab_hash, NULL, SKIP_NONE, ZFREE_STATFREE); else - free(hash->uh_slab_hash, M_UMAHASH); + free(hash->uh_slab_hash); } /* @@ -749,19 +908,6 @@ finished: flags = slab->us_flags; mem = slab->us_data; - if (keg->uk_flags & UMA_ZONE_VTOSLAB) { - vm_object_t obj; - - if (flags & UMA_SLAB_KMEM) - obj = kmem_object; - else if (flags & UMA_SLAB_KERNEL) - obj = kernel_object; - else - obj = NULL; - for (i = 0; i < keg->uk_ppera; i++) - vsetobj((vm_offset_t)mem + (i * PAGE_SIZE), - obj); - } if (keg->uk_flags & UMA_ZONE_OFFPAGE) zone_free_item(keg->uk_slabzone, slab, NULL, SKIP_NONE, ZFREE_STATFREE); @@ -776,6 +922,7 @@ finished: static void zone_drain_wait(uma_zone_t zone, int waitok) { + struct timespec abstime; /* * Set draining to interlock with zone_dtor() so we can release our @@ -788,7 +935,9 @@ zone_drain_wait(uma_zone_t zone, int wai if (waitok == M_NOWAIT) goto out; mtx_unlock(&uma_mtx); - msleep(zone, zone->uz_lock, PVM, "zonedrain", 1); + abstime.tv_sec = 0; + abstime.tv_nsec = 1000000; /* 1ms */ + pthread_cond_timedwait(&zone->uz_cv, zone->uz_lock, &abstime); mtx_lock(&uma_mtx); } zone->uz_flags |= UMA_ZFLAG_DRAINING; @@ -802,7 +951,7 @@ zone_drain_wait(uma_zone_t zone, int wai zone_foreach_keg(zone, &keg_drain); ZONE_LOCK(zone); zone->uz_flags &= ~UMA_ZFLAG_DRAINING; - wakeup(zone); + pthread_cond_broadcast(&zone->uz_cv); out: ZONE_UNLOCK(zone); } @@ -910,19 +1059,7 @@ keg_alloc_slab(uma_keg_t keg, uma_zone_t (keg->uk_rsize * i), keg->uk_size); } - if (keg->uk_flags & UMA_ZONE_VTOSLAB) { - vm_object_t obj; - if (flags & UMA_SLAB_KMEM) - obj = kmem_object; - else if (flags & UMA_SLAB_KERNEL) - obj = kernel_object; - else - obj = NULL; - for (i = 0; i < keg->uk_ppera; i++) - vsetobj((vm_offset_t)mem + - (i * PAGE_SIZE), obj); - } if (keg->uk_flags & UMA_ZONE_OFFPAGE) zone_free_item(keg->uk_slabzone, slab, NULL, SKIP_NONE, ZFREE_STATFREE); @@ -997,7 +1134,7 @@ page_alloc(uma_zone_t zone, int bytes, u void *p; /* Returned page */ *pflag = UMA_SLAB_KMEM; - p = (void *) kmem_malloc(kmem_map, bytes, wait); + p = mmap(NULL, bytes, PROT_READ|PROT_WRITE, MAP_ANON, -1, 0); return (p); } @@ -1016,16 +1153,12 @@ page_alloc(uma_zone_t zone, int bytes, u static void page_free(void *mem, int size, u_int8_t flags) { - vm_map_t map; - - if (flags & UMA_SLAB_KMEM) - map = kmem_map; - else if (flags & UMA_SLAB_KERNEL) - map = kernel_map; - else - panic("UMA: page_free used with invalid flags %d", flags); - - kmem_free(map, (vm_offset_t)mem, size); + /* + * XXX need to free mem's uma_page va -> slab mappings + * + */ + + munmap(mem, size); } /* @@ -1491,7 +1624,7 @@ zone_dtor(void *arg, int size, void *uda LIST_REMOVE(klink, kl_link); if (klink == &zone->uz_klink) continue; - free(klink, M_TEMP); + free(klink); } /* * We only destroy kegs from non secondary zones. @@ -1543,8 +1676,8 @@ uma_startup(void *bootmem, int boot_page #ifdef UMA_DEBUG printf("Creating uma keg headers zone and keg.\n"); #endif - mtx_init(&uma_mtx, "UMA lock", NULL, MTX_DEF); - + pthread_mutex_init(&uma_mtx, NULL); + /* * Figure out the maximum number of items-per-slab we'll have if * we're using the OFFPAGE slab header to track free items, given @@ -1638,7 +1771,7 @@ uma_startup(void *bootmem, int boot_page slab->us_flags = UMA_SLAB_BOOT; LIST_INSERT_HEAD(&uma_boot_pages, slab, us_link); } - mtx_init(&uma_boot_pages_mtx, "UMA boot pages", NULL, MTX_DEF); + pthread_mutex_init(&uma_boot_pages_mtx, NULL); #ifdef UMA_DEBUG printf("Creating uma zone headers zone and keg.\n"); @@ -1881,7 +2014,10 @@ uma_large_malloc(int size, int wait) void uma_large_free(uma_slab_t slab) { - vsetobj((vm_offset_t)slab->us_data, kmem_object); + /* + * free uma_page entries? + * + */ page_free(slab->us_data, slab->us_size, slab->us_flags); zone_free_item(slabzone, slab, NULL, SKIP_NONE, ZFREE_STATFREE); } @@ -2095,7 +2231,7 @@ keg_fetch_slab(uma_keg_t keg, uma_zone_t zone->uz_flags |= UMA_ZFLAG_FULL; if (flags & M_NOWAIT) break; - msleep(keg, &keg->uk_lock, PVM, "keglimit", 0); + pthread_cond_wait(&keg->uk_cv, &keg->uk_lock); continue; } keg->uk_recurse++; @@ -2649,12 +2785,12 @@ zone_free_item(uma_zone_t zone, void *it * keeping this simple for now (rather than adding count of blocked * threads etc). */ - wakeup(keg); + pthread_cond_broadcast(&keg->uk_cv); } if (clearfull) { zone_relock(zone, keg); zone->uz_flags &= ~UMA_ZFLAG_FULL; - wakeup(zone); + pthread_cond_broadcast(&zone->uz_cv); ZONE_UNLOCK(zone); } else KEG_UNLOCK(keg); @@ -2720,7 +2856,7 @@ restart: buflen = sizeof(ush) + count * (sizeof(uth) + sizeof(ups) * (mp_maxid + 1)) + 1; - buffer = malloc(buflen, M_TEMP, M_WAITOK | M_ZERO); + buffer = malloc(buflen); mtx_lock(&uma_mtx); i = 0; @@ -2729,7 +2865,7 @@ restart: i++; } if (i > count) { - free(buffer, M_TEMP); + free(buffer); goto restart; } count = i; @@ -2823,6 +2959,6 @@ skip: sbuf_finish(&sbuf); error = SYSCTL_OUT(req, sbuf_data(&sbuf), sbuf_len(&sbuf)); out: - free(buffer, M_TEMP); + free(buffer); return (error); } From owner-svn-src-user@FreeBSD.ORG Mon Jan 11 09:57:29 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 656AD106566C; Mon, 11 Jan 2010 09:57:29 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 55A158FC08; Mon, 11 Jan 2010 09:57:29 +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 o0B9vTRk021746; Mon, 11 Jan 2010 09:57:29 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0B9vTF2021743; Mon, 11 Jan 2010 09:57:29 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201001110957.o0B9vTF2021743@svn.freebsd.org> From: Ed Schouten Date: Mon, 11 Jan 2010 09:57:29 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202071 - user/ed/utmpx/usr.bin/getent X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Jan 2010 09:57:29 -0000 Author: ed Date: Mon Jan 11 09:57:29 2010 New Revision: 202071 URL: http://svn.freebsd.org/changeset/base/202071 Log: Allow utmpx to be displayed using getent(1). Modified: user/ed/utmpx/usr.bin/getent/getent.1 user/ed/utmpx/usr.bin/getent/getent.c Modified: user/ed/utmpx/usr.bin/getent/getent.1 ============================================================================== --- user/ed/utmpx/usr.bin/getent/getent.1 Mon Jan 11 09:16:42 2010 (r202070) +++ user/ed/utmpx/usr.bin/getent/getent.1 Mon Jan 11 09:57:29 2010 (r202071) @@ -75,6 +75,7 @@ argument may be one of: .It Li rpc Ta name number [alias ...] .It Li services Ta name port/protocol [alias ...] .It Li shells Ta /path/to/shell +.It Li utmpx Ta [time] type: properties .El .Pp If one or more @@ -109,6 +110,7 @@ utility exits 0 on success, or 3 if there is no support for enumeration on .Ar database . .Sh SEE ALSO +.Xr getutxent 3 , .Xr ethers 5 , .Xr group 5 , .Xr hosts 5 , Modified: user/ed/utmpx/usr.bin/getent/getent.c ============================================================================== --- user/ed/utmpx/usr.bin/getent/getent.c Mon Jan 11 09:16:42 2010 (r202070) +++ user/ed/utmpx/usr.bin/getent/getent.c Mon Jan 11 09:57:29 2010 (r202071) @@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include static int usage(void); static int parsenum(const char *, unsigned long *); @@ -72,6 +73,7 @@ static int protocols(int, char *[]); static int rpc(int, char *[]); static int services(int, char *[]); static int shells(int, char *[]); +static int utmpx(int, char *[]); enum { RV_OK = 0, @@ -93,6 +95,7 @@ static struct getentdb { { "rpc", rpc, }, { "services", services, }, { "shells", shells, }, + { "utmpx", utmpx, }, { NULL, NULL, }, }; @@ -562,3 +565,89 @@ shells(int argc, char *argv[]) endusershell(); return rv; } + +/* + * utmpx + */ + +#define UTMPXPRINTID do { \ + size_t i; \ + for (i = 0; i < sizeof ut->ut_id; i++) \ + printf("%02hhx", ut->ut_id[i]); \ +} while (0) + +static void +utmpxprint(const struct utmpx *ut) +{ + + if (ut->ut_type == EMPTY) + return; + + printf("[%.24s] ", ctime(&ut->ut_tv.tv_sec)); + + switch (ut->ut_type) { + case BOOT_TIME: + printf("system boot\n"); + return; + case SHUTDOWN_TIME: + printf("system shutdown\n"); + return; + case OLD_TIME: + printf("old system time\n"); + return; + case NEW_TIME: + printf("new system time\n"); + return; + case USER_PROCESS: + printf("user process: id=\""); + UTMPXPRINTID; + printf("\" user=\"%s\" line=\"%s\" host=\"%s\"\n", + ut->ut_user, ut->ut_line, ut->ut_host); + break; + case DEAD_PROCESS: + printf("dead process: id=\""); + UTMPXPRINTID; + printf("\"\n"); + break; + default: + printf("unknown record type\n"); + break; + } +} + +static int +utmpx(int argc, char *argv[]) +{ + const struct utmpx *ut; + int rv = RV_OK, db; + + assert(argc > 1); + assert(argv != NULL); + + if (argc == 2) { + db = UTXDB_ACTIVE; + } else if (argc == 3) { + if (strcmp(argv[2], "active") == 0) + db = UTXDB_ACTIVE; + else if (strcmp(argv[2], "lastlogin") == 0) + db = UTXDB_LASTLOGIN; + else if (strcmp(argv[2], "log") == 0) + db = UTXDB_LOG; + else + rv = RV_USAGE; + } else { + rv = RV_USAGE; + } + + if (rv == RV_USAGE) { + fprintf(stderr, "Usage: %s utmpx [active | lastlogin | log]\n", + getprogname()); + } else if (rv == RV_OK) { + if (setutxdb(db, NULL) != 0) + return (RV_NOTFOUND); + while ((ut = getutxent()) != NULL) + utmpxprint(ut); + endutxent(); + } + return (rv); +} From owner-svn-src-user@FreeBSD.ORG Mon Jan 11 10:12:35 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 5FD69106566B; Mon, 11 Jan 2010 10:12:35 +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 4E1EE8FC0A; Mon, 11 Jan 2010 10:12:35 +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 o0BACZ9M025253; Mon, 11 Jan 2010 10:12:35 GMT (envelope-from luigi@svn.freebsd.org) Received: (from luigi@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0BACZOr025242; Mon, 11 Jan 2010 10:12:35 GMT (envelope-from luigi@svn.freebsd.org) Message-Id: <201001111012.o0BACZOr025242@svn.freebsd.org> From: Luigi Rizzo Date: Mon, 11 Jan 2010 10:12:35 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202072 - in user/luigi/ipfw3-head: sbin/ipfw sys/netinet sys/netinet/ipfw X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Jan 2010 10:12:35 -0000 Author: luigi Date: Mon Jan 11 10:12:35 2010 New Revision: 202072 URL: http://svn.freebsd.org/changeset/base/202072 Log: snapshot Added: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c (contents, props changed) Modified: user/luigi/ipfw3-head/sbin/ipfw/dummynet.c user/luigi/ipfw3-head/sbin/ipfw/ipfw2.h user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h user/luigi/ipfw3-head/sys/netinet/ip_fw.h user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw2.c user/luigi/ipfw3-head/sys/netinet/ipfw/ip_fw_private.h Modified: user/luigi/ipfw3-head/sbin/ipfw/dummynet.c ============================================================================== --- user/luigi/ipfw3-head/sbin/ipfw/dummynet.c Mon Jan 11 09:57:29 2010 (r202071) +++ user/luigi/ipfw3-head/sbin/ipfw/dummynet.c Mon Jan 11 10:12:35 2010 (r202072) @@ -71,6 +71,8 @@ static struct _s_x dummynet_params[] = { { "queue", TOK_FLOWSET }, { "flowset", TOK_FLOWSET }, { "sched", TOK_SCHED }, + { "pri", TOK_PRI }, + { "type", TOK_TYPE }, { "flow-id", TOK_FLOWID}, { "dst-ipv6", TOK_DSTIP6}, { "dst-ip6", TOK_DSTIP6}, @@ -97,6 +99,7 @@ o_next(struct dn_id **o, int len, int ty return ret; } +#if 0 static int sort_q(void *arg, const void *pa, const void *pb) { @@ -284,10 +287,11 @@ print_extra_delay_parms(struct dn_pipe * printf("\t profile: name \"%s\" loss %f samples %d\n", p->name, loss, p->samples_no); } - +#endif void ipfw_list_pipes(void *data, uint nbytes, int ac, char *av[]) { +#if 0 int rulenum; void *next = data; struct dn_pipe *p = (struct dn_pipe *) data; @@ -321,11 +325,6 @@ ipfw_list_pipes(void *data, uint nbytes, /* * Print rate (or clocking interface) */ -#if 0 - if (p->if_name[0] != '\0') - sprintf(buf, "%s", p->if_name); - else -#endif if (b == 0) sprintf(buf, "unlimited"); else if (b >= 1000000) @@ -371,6 +370,7 @@ ipfw_list_pipes(void *data, uint nbytes, print_flowset_parms(fs, prefix); list_queues(fs, q); } +#endif } /* @@ -379,6 +379,7 @@ ipfw_list_pipes(void *data, uint nbytes, int ipfw_delete_pipe(int pipe_or_queue, int i) { +#if 0 struct dn_pipe p; memset(&p, 0, sizeof p); @@ -391,6 +392,7 @@ ipfw_delete_pipe(int pipe_or_queue, int i = 1; warn("rule %u: setsockopt(IP_DUMMYNET_DEL)", i); } +#endif return i; } @@ -778,6 +780,7 @@ ipfw_config_pipe(int ac, char **av) case 1: sch = o_next(&buf, sizeof(*sch), DN_SCH); sch->sched_nr = i + DN_PIPEOFFSET; + sch->oid.subtype = DN_SCHED_FIFO; p = o_next(&buf, sizeof(*p), DN_PIPE); p->pipe_nr = i + DN_PIPEOFFSET; mask = &sch->sched_mask; @@ -787,6 +790,7 @@ ipfw_config_pipe(int ac, char **av) /* sch2 and p2 will be set later */ sch2 = o_next(&buf, sizeof(*sch2), DN_SCH); + sch2->oid.subtype = DN_SCHED_WF2QP; p2 = o_next(&buf, sizeof(*p2), DN_PIPE); break; @@ -1015,14 +1019,25 @@ end_mask: ac--; av++; break; -#if 0 + case TOK_TYPE: { + int l; + NEED(sch, "type is only for schedulers"); + NEED1("type needs a string"); + l = strlen(av[0]); + if (l == 0 || l > 15) + errx(1, "type %s too long\n", av[0]); + strcpy(sch->type, av[0]); + sch->oid.subtype = 0; /* use string */ + ac--; av++; + break; + } + case TOK_WEIGHT: NEED(fs, "weight is only for flowsets"); NEED1("weight needs argument 0..100\n"); fs->weight = strtoul(av[0], &end, 0); ac--; av++; break; -#endif case TOK_SCHED: case TOK_PIPE: @@ -1171,6 +1186,7 @@ end_mask: if (sch2) { *sch2 = *sch; sch2->sched_nr = i; + sch2->oid.subtype = DN_SCHED_WF2QP; } if (p2) { *p2 = *p; Modified: user/luigi/ipfw3-head/sbin/ipfw/ipfw2.h ============================================================================== --- user/luigi/ipfw3-head/sbin/ipfw/ipfw2.h Mon Jan 11 09:57:29 2010 (r202071) +++ user/luigi/ipfw3-head/sbin/ipfw/ipfw2.h Mon Jan 11 10:12:35 2010 (r202072) @@ -163,7 +163,12 @@ enum tokens { TOK_GRED, TOK_DROPTAIL, TOK_PROTO, + /* dummynet tokens */ TOK_WEIGHT, + TOK_PRI, + TOK_TYPE, + TOK_SLOTSIZE, + TOK_IP, TOK_IF, TOK_ALOG, Modified: user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h Mon Jan 11 09:57:29 2010 (r202071) +++ user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h Mon Jan 11 10:12:35 2010 (r202072) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 1998-2002 Luigi Rizzo, Universita` di Pisa + * Copyright (c) 1998-2010 Luigi Rizzo, Universita` di Pisa * Portions Copyright (c) 2000 Akamba Corp. * All rights reserved * @@ -56,6 +56,7 @@ struct dn_id { * entries with the exception of DN_LAST */ enum { + DN_NONE = 0, DN_PIPE = 1, DN_FS, DN_SCH, @@ -74,7 +75,9 @@ enum { }; enum { /* subtype for schedulers, flowset and the like */ - DN_UNKNOWN = 0, + DN_SCHED_UNKNOWN = 0, + DN_SCHED_FIFO = 1, + DN_SCHED_WF2QP = 2, /* others are in individual modules */ }; @@ -107,19 +110,15 @@ struct new_profile { }; /* - * pipe template. In the kernel it is right after a scheduler. + * pipe template. */ struct new_pipe { struct dn_id oid; - /* these initial fields are set from the command line - * pipe N config bw B delay D profile PRF (mask M1 plr P queue Q - * buckets BB ) ... - * The second set of parameters (M1, ...) belong to the - * scheduler or the flowset. They can be specified in 'pipe config' - * only for backward compatibility. + /* * Userland sets bw and delay in bits/s and milliseconds. * The kernel converts this back and forth to bits/tick and ticks. + * XXX what about burst ? */ int32_t pipe_nr ; /* N, number */ int bandwidth; /* B, really, bits/tick. */ @@ -160,6 +159,9 @@ struct new_fs { /* mask to select the appropriate queue */ struct ipfw_flow_id flow_mask; /* M */ int sched_nr; /* the scheduler we attach to */ + /* generic scheduler parameters */ + int weight; + int slot_size; }; /* @@ -188,6 +190,7 @@ struct new_sch { int bucket; /* number of buckets for the instances */ int flags; /* have_mask, ... */ + char type[16]; /* null terminated */ /* mask to select the appropriate scheduler instance */ struct ipfw_flow_id sched_mask; /* M */ }; @@ -270,75 +273,6 @@ flow using a number of heaps defined int * */ -/* - * per flow queue. This contains the flow identifier, the queue - * of packets, counters, and parameters used to support both RED and - * WF2Q+. - * - * A dn_flow_queue is created and initialized whenever a packet for - * a new flow arrives. - */ -struct dn_flow_queue { - struct dn_flow_queue *next ; - struct ipfw_flow_id id ; - - struct mbuf *head, *tail ; /* queue of packets */ - u_int len ; - u_int len_bytes ; - - /* - * When we emulate MAC overheads, or channel unavailability due - * to other traffic on a shared medium, we augment the packet at - * the head of the queue with an 'extra_bits' field representsing - * the additional delay the packet will be subject to: - * extra_bits = bw*unavailable_time. - * With large bandwidth and large delays, extra_bits (and also numbytes) - * can become very large, so better play safe and use 64 bit - */ - uint64_t numbytes ; /* credit for transmission (dynamic queues) */ - int64_t extra_bits; /* extra bits simulating unavailable channel */ - - u_int64_t tot_pkts ; /* statistics counters */ - u_int64_t tot_bytes ; - u_int32_t drops ; - - int hash_slot ; /* debugging/diagnostic */ - - /* RED parameters */ - int avg ; /* average queue length est. (scaled) */ - int count ; /* arrivals since last RED drop */ - int random ; /* random value (scaled) */ - dn_key idle_time; /* start of queue idle time */ - - /* WF2Q+ support */ - struct dn_flow_set *fs ; /* parent flow set */ - int heap_pos ; /* position (index) of struct in heap */ - dn_key sched_time ; /* current time when queue enters ready_heap */ - - dn_key S,F ; /* start time, finish time */ - /* - * Setting F < S means the timestamp is invalid. We only need - * to test this when the queue is empty. - */ -} ; - -/* - * flow_set descriptor. Contains the "template" parameters for the - * queue configuration, and pointers to the hash table of dn_flow_queue's. - * - * The hash table is an array of lists -- we identify the slot by - * hashing the flow-id, then scan the list looking for a match. - * The size of the hash table (buckets) is configurable on a per-queue - * basis. - * - * A dn_flow_set is created whenever a new queue or pipe is created (in the - * latter case, the structure is located inside the struct dn_pipe). - */ -struct dn_flow_set { - SLIST_ENTRY(dn_flow_set) next; /* linked list in a hash slot */ - - u_short fs_nr ; /* flow_set number */ - u_short flags_fs; #define DN_HAVE_FLOW_MASK 0x0001 #define DN_IS_RED 0x0002 #define DN_IS_GENTLE_RED 0x0004 @@ -348,100 +282,4 @@ struct dn_flow_set { #define DN_IS_PIPE 0x4000 #define DN_IS_QUEUE 0x8000 - struct dn_pipe *pipe ; /* pointer to parent pipe */ - u_short parent_nr ; /* parent pipe#, 0 if local to a pipe */ - - int weight ; /* WFQ queue weight */ - int qsize ; /* queue size in slots or bytes */ - int plr ; /* pkt loss rate (2^31-1 means 100%) */ - - struct ipfw_flow_id flow_mask ; - - /* hash table of queues onto this flow_set */ - int rq_size ; /* number of slots */ - int rq_elements ; /* active elements */ - struct dn_flow_queue **rq; /* array of rq_size entries */ - - u_int32_t last_expired ; /* do not expire too frequently */ - int backlogged ; /* #active queues for this flowset */ - - /* RED parameters */ -#define SCALE_RED 16 -#define SCALE(x) ( (x) << SCALE_RED ) -#define SCALE_VAL(x) ( (x) >> SCALE_RED ) -#define SCALE_MUL(x,y) ( ( (x) * (y) ) >> SCALE_RED ) - int w_q ; /* queue weight (scaled) */ - int max_th ; /* maximum threshold for queue (scaled) */ - int min_th ; /* minimum threshold for queue (scaled) */ - int max_p ; /* maximum value for p_b (scaled) */ - u_int c_1 ; /* max_p/(max_th-min_th) (scaled) */ - u_int c_2 ; /* max_p*min_th/(max_th-min_th) (scaled) */ - u_int c_3 ; /* for GRED, (1-max_p)/max_th (scaled) */ - u_int c_4 ; /* for GRED, 1 - 2*max_p (scaled) */ - u_int * w_q_lookup ; /* lookup table for computing (1-w_q)^t */ - u_int lookup_depth ; /* depth of lookup table */ - int lookup_step ; /* granularity inside the lookup table */ - int lookup_weight ; /* equal to (1-w_q)^t / (1-w_q)^(t+1) */ - int avg_pkt_size ; /* medium packet size */ - int max_pkt_size ; /* max packet size */ -}; - -struct dn_heap; -/* - * Pipe descriptor. Contains global parameters, delay-line queue, - * and the flow_set used for fixed-rate queues. - * - * For WF2Q+ support it also has 3 heaps holding dn_flow_queue: - * not_eligible_heap, for queues whose start time is higher - * than the virtual time. Sorted by start time. - * scheduler_heap, for queues eligible for scheduling. Sorted by - * finish time. - * idle_heap, all flows that are idle and can be removed. We - * do that on each tick so we do not slow down too much - * operations during forwarding. - * - */ -struct dn_pipe { /* a pipe */ - SLIST_ENTRY(dn_pipe) next; /* linked list in a hash slot */ - - int pipe_nr ; /* number */ - int bandwidth; /* really, bytes/tick. */ - int delay ; /* really, ticks */ - - struct mbuf *head, *tail ; /* packets in delay line */ - - /* WF2Q+ */ - struct dn_heap *scheduler_heap ; /* top extract - key Finish time*/ - struct dn_heap *not_eligible_heap; /* top extract- key Start time */ - struct dn_heap *idle_heap ; /* random extract - key Start=Finish time */ - - dn_key V ; /* virtual time */ - int sum; /* sum of weights of all active sessions */ - - /* Same as in dn_flow_queue, numbytes can become large */ - int64_t numbytes; /* bits I can transmit (more or less). */ - uint64_t burst; /* burst size, scaled: bits * hz */ - - dn_key sched_time ; /* time pipe was scheduled in ready_heap */ - dn_key idle_time; /* start of pipe idle time */ - - /* - * When the tx clock come from an interface (if_name[0] != '\0'), its name - * is stored below, whereas the ifp is filled when the rule is configured. - */ - char if_name[IFNAMSIZ]; - struct ifnet *ifp ; - int ready ; /* set if ifp != NULL and we got a signal from it */ - - struct dn_flow_set fs ; /* used with fixed-rate flows */ - - /* fields to simulate a delay profile */ - -#define ED_MAX_NAME_LEN 32 - char name[ED_MAX_NAME_LEN]; - int loss_level; - int samples_no; - int *samples; -}; - #endif /* _IP_DUMMYNET_H */ Modified: user/luigi/ipfw3-head/sys/netinet/ip_fw.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ip_fw.h Mon Jan 11 09:57:29 2010 (r202071) +++ user/luigi/ipfw3-head/sys/netinet/ip_fw.h Mon Jan 11 10:12:35 2010 (r202072) @@ -487,24 +487,26 @@ struct ip_fw { #define RULESIZE(rule) (sizeof(struct ip_fw) + \ ((struct ip_fw *)(rule))->cmd_len * 4 - 4) +#if 1 // moved to in.h /* * This structure is used as a flow mask and a flow id for various * parts of the code. */ struct ipfw_flow_id { - u_int32_t dst_ip; - u_int32_t src_ip; - u_int16_t dst_port; - u_int16_t src_port; - u_int8_t fib; - u_int8_t proto; - u_int8_t flags; /* protocol-specific flags */ + uint32_t dst_ip; + uint32_t src_ip; + uint16_t dst_port; + uint16_t src_port; + uint8_t fib; + uint8_t proto; + uint8_t flags; /* protocol-specific flags */ uint8_t addr_type; /* 4 = ipv4, 6 = ipv6, 1=ether ? */ - struct in6_addr dst_ip6; /* could also store MAC addr! */ + struct in6_addr dst_ip6; struct in6_addr src_ip6; - u_int32_t flow_id6; - u_int32_t frag_id6; + uint32_t flow_id6; + uint32_t frag_id6; }; +#endif #define IS_IP6_FLOW_ID(id) ((id)->addr_type == 6) Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h Mon Jan 11 09:57:29 2010 (r202071) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h Mon Jan 11 10:12:35 2010 (r202072) @@ -63,6 +63,7 @@ struct dn_heap { /* HEAP_TOP returns the pointer to the top element of the heap */ #define HEAP_TOP(h) ((h)->p) +#define SET_HEAP_OFS(h, n) do { (h)->ofs = n; } while (0) int heap_init(struct dn_heap *h, int size); int heap_insert (struct dn_heap *h, uint64_t key1, void *p); void heap_extract(struct dn_heap *h, void *obj); Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h Mon Jan 11 09:57:29 2010 (r202071) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h Mon Jan 11 10:12:35 2010 (r202072) @@ -121,19 +121,18 @@ struct dn_sched { /* config or destroy the scheduler template */ int (*config)(struct new_schk *, int reconfigure); - int (*destroy)(struct new_schk*); + int (*destroy)(struct new_schk*, int delete); /* create, drain or destroy a new scheduler instance */ int (*new_sched)(struct new_schk *, struct new_sch_inst *); - int (*drain_sched)(struct new_sch_inst *, int flag); int (*free_sched)(struct new_sch_inst *); - /* create or destroy a flowset attached to this scheduler */ + /* init or deinit a flowset attached to this scheduler */ int (*new_fs)(void *command, struct dn_id *g, int reconfigure); int (*free_fs)(struct new_fsk *); - /* create or destroy a queue attached to this scheduler */ - int (*new_queue)(struct new_queue *q, struct dn_id *f); + /* init or destroy a queue attached to this scheduler */ + int (*new_queue)(struct new_queue *q); int (*free_queue)(struct new_queue *q); }; @@ -152,20 +151,10 @@ SLIST_HEAD(dn_sched_head, dn_sched); */ struct mbuf* dn_pkt_done(struct mbuf *pkt, struct new_queue *q); -/* Called to delete a queue 'q'. If packet belong to this queue should be - * reenqueued, the 'reenqueue' should be set to 1 - */ -int dn_delete_queue (struct new_queue *q, int reenqueue); - -/* Called by enqueue() when it needs to create a new queue. - * - f: extension of the flowset. - * - s: scheduler specific scheduler instance data - * - i: index of the hash table, or 0 if no hash table is used - * - id: flow id for this queue - * - size: size of the queue, including the private data +/* + * delete a queue, which we assume nobody references */ -struct new_queue * dn_create_queue(struct dn_id *f, void *s, int i, - struct ipfw_flow_id *id); +int dn_delete_queue(struct new_queue *q); /* Allocate an hash table. * Returns the pointer to the table @@ -209,18 +198,20 @@ struct new_queue * dn_q_hash_id(struct i struct new_queue **rq, struct dn_id *f); /* - * Function that need to be called before returning a packet from dequeue. - * Update queue statistic + * Extract the head of a queue, update stats. Must be the very last + * thing done on a queue as it may go away. */ static __inline struct mbuf* -dn_return_packet(struct mbuf *pkt, struct new_queue *q) +dn_return_packet(struct new_queue *q) { - - q->head = pkt->m_nextpkt; + struct mbuf *m = q->mq.head; + q->mq.head = m->m_nextpkt; q->lenght--; - q->len_bytes -= pkt->m_pkthdr.len; + q->len_bytes -= m->m_pkthdr.len; + if (q->mq.head == NULL && q->fs->kflags & DN_DELETE) + dn_delete_queue(q); - return pkt; + return m; } int dn_sched_modevent(module_t mod, int cmd, void *arg); Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c Mon Jan 11 09:57:29 2010 (r202071) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c Mon Jan 11 10:12:35 2010 (r202072) @@ -1,6 +1,5 @@ /* * Copyright (c) 2010 Riccardo Panicucci, Universita` di Pisa - * Copyright (c) 1998-2002 Luigi Rizzo, Universita` di Pisa * All rights reserved * * Redistribution and use in source and binary forms, with or without @@ -28,20 +27,19 @@ #include #include #include -#include /* IFNAMSIZ, struct ifaddr, ifq head, lock.h mutex.h */ +#include +#include +#include +#include /* IFNAMSIZ */ #include -#include /* ip_len, ip_off */ -#include /* ip_len, ip_off */ -#include +#include /* ipfw_rule_ref */ +#include /* flow_id */ #include #include -#include +//#include #include -#include -#include #include -#define DN_FIFO 1 /* * This file implements a FIFO scheduler. * A FIFO scheduler is a simple scheduler algorithm that can be use to @@ -59,11 +57,11 @@ /* A scheduler instance of a FIFO scheduler requires only a queue. */ struct fifo_si { - struct new_queue *q; + struct new_queue *q; }; static int -fifo_enqueue(struct new_sch_inst *_si, struct new_fs *f, +fifo_enqueue(struct new_sch_inst *_si, struct new_fsk *f, struct mbuf *m, struct ipfw_flow_id *id) { /* @@ -89,14 +87,13 @@ fifo_enqueue(struct new_sch_inst *_si, s /* Access to specific scheduler instance data */ struct fifo_si *si = (struct fifo_si *)(_si+1); - struct new_queue *q = (struct new_queue *)f; if (si->q == NULL) { - si->q = q; - } else if (si->q != q) { - printf("%s queue changed from %p to %p?\n", - __FUNCTION__, si->q, q); - return 1; + si->q = dn_create_queue(_si, f, id); + if (si->q == NULL) { + FREE_PKT(m); + return 1; + } } /* Now the si->q is valid, so insert the packet in this queue */ if (dn_queue_packet(si->q, m)) { @@ -125,41 +122,24 @@ fifo_dequeue(struct new_sch_inst *_si) * return NULL. */ - /* Pointer to the packet to return , if exists*/ - struct mbuf *pkt; - - /* Accessing to scheduler instance private data */ + /* Access scheduler instance private data */ struct fifo_si *si = (struct fifo_si *)(_si + 1); - struct new_queue *q = si->q; - if (q == NULL) { - /* Queue is not valid, no packet to dequeue */ + if (q == NULL || q->mq.head == NULL) return NULL; - } - /* Take the first packet from the queue, if exists */ - pkt = q->head; - - if (pkt != NULL) { - /* Packet exists, return it */ - return dn_return_packet(pkt, q); - } - - /* No packets in queue, return NULL */ - return NULL; + return dn_return_packet(q); } static int fifo_new_sched(struct new_schk *s, struct new_sch_inst *_si) { - /* This scheduler instance only has a queue pointer. */ - struct fifo_si *si = (struct fifo_si *)(_si + 1); + /* This scheduler instance only has a queue pointer. */ + struct fifo_si *si = (struct fifo_si *)(_si + 1); - /* Initialize scheduler instance private data */ - si->q = NULL; - - return 0; + si->q = NULL; + return 0; } static int @@ -171,30 +151,12 @@ fifo_free_sched(struct new_sch_inst *_si * allocate memory * - Delete the queue if exists */ - struct fifo_si *si = (struct fifo_si *)(_si + 1); - - if (si->q) - dn_delete_queue(si->q, 0); + struct fifo_si *si = (struct fifo_si *)(_si + 1); - return 0; -} + if (si->q) + dn_delete_queue(si->q); -static int -fifo_drain(struct new_sch_inst *_si, int flag) -{ - /* - * Called by the system to free memory. - * Remove the queue if it is empty or if the DN_FORCE flag is set - */ - - struct fifo_si *si = (struct fifo_si *)(_si + 1); - - if (si->q && (si->q->head == NULL || flag & DN_FORCE)) { - dn_delete_queue(si->q, 0); - si->q = NULL; - } - - return 0; + return 0; } /* @@ -204,8 +166,8 @@ fifo_drain(struct new_sch_inst *_si, int * the pointer is initialized to NULL */ static struct dn_sched fifo_desc = { - .type = DN_FIFO, - .name = "FIFO scheduler algorithm descriptor", + .type = DN_SCHED_FIFO, + .name = "FIFO", .sch_inst_len = sizeof(struct fifo_si), .queue_len = sizeof(struct new_queue), @@ -215,7 +177,6 @@ static struct dn_sched fifo_desc = { .new_sched = fifo_new_sched, .free_sched = fifo_free_sched, - .drain_sched = fifo_drain, }; DECLARE_DNSCHED_MODULE(dn_fifo, &fifo_desc); Added: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c Mon Jan 11 10:12:35 2010 (r202072) @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2010 Riccardo Panicucci, Universita` di Pisa + * All rights reserved + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* XXX this is only a stub for wf2q+ */ +#include +#include +#include +#include +#include +#include +#include /* IFNAMSIZ */ +#include +#include /* ipfw_rule_ref */ +#include /* flow_id */ +#include +#include +//#include +#include +#include + +/* + * This file implements a FIFO scheduler. + * A FIFO scheduler is a simple scheduler algorithm that can be use to + * scheduling internet packets. + * The scheduler receive a packet (by enqueue() function) and put in in the + * unique queue that manages. + * When the scheduler can transmit, the first packet in the queue is sent + * out (First In First Out) + * The complexity of this algorithm is O(1), all flows use the same queue. + * + * No parameters are required to configure a FIFO scheduler or a + * FIFO flowset. + * + */ + +/* A scheduler instance of a FIFO scheduler requires only a queue. */ +struct fifo_si { + struct new_queue *q; +}; + +static int +fifo_enqueue(struct new_sch_inst *_si, struct new_fsk *f, + struct mbuf *m, struct ipfw_flow_id *id) +{ + /* + * The system pass to the enqueue() function 4 parameters: + * - s: scheduler instance which the packet belongs + * - f: flowset scheduler private data + * - m: the packet + * - id: flow id of the packet, the mask is applyed by system + * + * The scheduler should save all data needs into variables in the + * scheduler instance. In the FIFO scheduling algorithm there is only + * one queue, so a queue should be saved in the scheduler instance. + * When the first packet arrives, the queue doesn't exist and the + * scheduler must create it calling the dn_create_queue() function. + * To really enqueue the packet, the scheduler must call the + * dn_queue_packet() function that insert the packet in the queue passes. + * If for some reason (for example the queue is full) the packet can't + * be enqueued, dn_queue_packet() returns 1. + * + * See the enqueue() function for wf2q+ scheduler algorithm for + * another examples of enqueue() + */ + + /* Access to specific scheduler instance data */ + struct fifo_si *si = (struct fifo_si *)(_si+1); + + if (si->q == NULL) { + si->q = dn_create_queue(_si, f, id); + if (si->q == NULL) { + FREE_PKT(m); + return 1; + } + } + /* Now the si->q is valid, so insert the packet in this queue */ + if (dn_queue_packet(si->q, m)) { + /* packet was dropped */ + return 1; + } + + /* Ok, the packet is now in the queue. + * The dequeue() function will be called when the scheduler + * instance has credit to transmit packets + */ + return 0; +} + +static struct mbuf * +fifo_dequeue(struct new_sch_inst *_si) +{ + /* + * The dequeue() function is called by the system when the scheduler + * instance can transmit packets. The dequeue() is called until the + * instance has credit and packet to send. + * If the scheduler wants to dequeue a packet, it should call the + * dn_return_packet() function, that take a packet pkt and the relative + * queue and update. + * If the queue is empty, no packet can be send and the dequeue() must + * return NULL. + */ + + /* Access scheduler instance private data */ + struct fifo_si *si = (struct fifo_si *)(_si + 1); + struct new_queue *q = si->q; + + if (q == NULL || q->mq.head == NULL) + return NULL; + + return dn_return_packet(q); +} + +static int +fifo_new_sched(struct new_schk *s, struct new_sch_inst *_si) +{ + /* This scheduler instance only has a queue pointer. */ + struct fifo_si *si = (struct fifo_si *)(_si + 1); + + si->q = NULL; + return 0; +} + +static int +fifo_free_sched(struct new_sch_inst *_si) +{ + /* + * Delete a FIFO scheduler instance + * - Deallocate memory if the create_scheduler_instance() function + * allocate memory + * - Delete the queue if exists + */ + struct fifo_si *si = (struct fifo_si *)(_si + 1); + + if (si->q) + dn_delete_queue(si->q); + + return 0; +} + +/* + * FIFO scheduler descriptor + * contains the type of the scheduler, the name, the size of the various + * structures and function pointers. If a function is not implemented, + * the pointer is initialized to NULL + */ +static struct dn_sched fifo_desc = { + .type = DN_SCHED_WF2QP, + .name = "WF2Q+", + + .sch_inst_len = sizeof(struct fifo_si), + .queue_len = sizeof(struct new_queue), + + .enqueue = fifo_enqueue, + .dequeue = fifo_dequeue, + + .new_sched = fifo_new_sched, + .free_sched = fifo_free_sched, +}; + +DECLARE_DNSCHED_MODULE(dn_wf2qp, &fifo_desc); Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Mon Jan 11 09:57:29 2010 (r202071) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Mon Jan 11 10:12:35 2010 (r202072) @@ -49,7 +49,6 @@ __FBSDID("$FreeBSD$"); //#include #include #include -//#include #include /* IFNAMSIZ, struct ifaddr, ifq head, lock.h mutex.h */ #include #include @@ -140,10 +139,6 @@ SYSCTL_DECL(_net_inet_ip); SYSCTL_NODE(_net_inet_ip, OID_AUTO, dummynet, CTLFLAG_RW, 0, "Dummynet"); SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, hash_size, CTLFLAG_RW, &dn_cfg.hash_size, 0, "Default hash table size"); -#if 0 /* curr_time is 64 bit */ -SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, curr_time, - CTLFLAG_RD, &curr_time, 0, "Current tick"); -#endif SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, searches, CTLFLAG_RD, &searches, 0, "Number of queue searches"); SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, search_steps, @@ -188,33 +183,11 @@ SYSCTL_LONG(_net_inet_ip_dummynet, OID_A CTLFLAG_RW, &dn_cfg.pipe_byte_limit, 0, "Upper limit in bytes for pipe queue."); #endif -#ifdef DUMMYNET_DEBUG -int dummynet_debug = 0; -#ifdef SYSCTL_NODE -SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, debug, CTLFLAG_RW, &dummynet_debug, - 0, "control debugging printfs"); -#endif -#define DPRINTF(X) if (dummynet_debug) printf X -#else -#define DPRINTF(X) -#endif - struct mtx dummynet_mtx; static void dummynet_send(struct mbuf *); /* - * Flow queue is idle if: - * 1) it's empty for at least 1 tick - * 2) it has invalid timestamp (WF2Q case) - * 3) parent pipe has no 'exhausted' burst. - */ -#define QUEUE_IS_IDLE(q) ((q)->head == NULL && (q)->S == (q)->F + 1 && \ - curr_time > (q)->idle_time + 1 && \ - ((q)->numbytes + (curr_time - (q)->idle_time - 1) * \ - (q)->fs->pipe->bandwidth >= (q)->fs->pipe->burst)) - -/* * Packets processed by dummynet have an mbuf tag associated with * them that carries their dummynet state. * Outside dummynet, only the 'rule' field is relevant, and it must @@ -248,104 +221,112 @@ dn_tag_get(struct mbuf *m) return (struct dn_pkt_tag *)(mtag+1); } +static inline void +mq_append(struct mq *q, struct mbuf *m) +{ + if (q->head == NULL) + q->head = m; + else + q->tail->m_nextpkt = m; + q->tail = m; + m->m_nextpkt = NULL; +} + +/* + * Check if the packet should be drop depending on the queue management + * or queue size overflow. + * Put the packet m into the queue q. + * Update statistics for the queue. + * + * The function returns 1 if the packet is dropped. + */ +int +dn_queue_packet(struct new_queue *q, struct mbuf* m) +{ + struct new_fs *f = &(q->fs->fs); + uint64_t len = m->m_pkthdr.len; + + /* Update statistics, then check reasons to drop pkt. */ + q->tot_bytes += m->m_pkthdr.len; + q->tot_pkts++; + + if (f->plr && random() < f->plr) + goto drop; + if (f->flags & DN_QSIZE_BYTES) { + if (q->len_bytes > f->qsize) + goto drop; + } else if (q->lenght >= f->qsize) { + goto drop; + } + mq_append(&q->mq, m); + q->lenght++; + q->len_bytes += len; + return 0; + +drop: + io_pkt_drop++; + q->drops++; + FREE_PKT(m); + return 1; +} + /* * Fetch packets from the delay line which are due now. If there are * leftover packets, reinsert the delay line in the heap. */ -static struct mbuf * -transmit_event(struct delay_line *dline, dn_key now) +static void +transmit_event(struct mq *q, struct delay_line *dline, dn_key now) { - struct mbuf *m; - struct mbuf *head = NULL, *tail = NULL; + struct mbuf *m = NULL; struct dn_pkt_tag *pkt = NULL; /* XXX we are under scheduler lock */ - while ((m = dline->head) != NULL) { + while ((m = dline->mq.head) != NULL) { pkt = dn_tag_get(m); if (!DN_KEY_LEQ(pkt->output_time, now)) break; - dline->head = m->m_nextpkt; - if (tail != NULL) - tail->m_nextpkt = m; - else *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-src-user@FreeBSD.ORG Mon Jan 11 11:09:04 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 53EC61065692; Mon, 11 Jan 2010 11:09:04 +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 441028FC17; Mon, 11 Jan 2010 11:09:04 +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 o0BB9441042413; Mon, 11 Jan 2010 11:09:04 GMT (envelope-from luigi@svn.freebsd.org) Received: (from luigi@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0BB94lW042411; Mon, 11 Jan 2010 11:09:04 GMT (envelope-from luigi@svn.freebsd.org) Message-Id: <201001111109.o0BB94lW042411@svn.freebsd.org> From: Luigi Rizzo Date: Mon, 11 Jan 2010 11:09:04 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202079 - user/luigi/ipfw3-head/sys/netinet/ipfw X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Jan 2010 11:09:04 -0000 Author: luigi Date: Mon Jan 11 11:09:03 2010 New Revision: 202079 URL: http://svn.freebsd.org/changeset/base/202079 Log: documentation update Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dummynet.txt Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dummynet.txt ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dummynet.txt Mon Jan 11 10:49:34 2010 (r202078) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dummynet.txt Mon Jan 11 11:09:03 2010 (r202079) @@ -47,7 +47,7 @@ association of flowsets and schedulers i "sched 10" represents one or more scheduler instances, selected through a mask on the 5-tuple itself. - ipfw sched 20 config sched_mask yyy ... + ipfw sched 20 config type FIFO sched_mask yyy ... There are in fact two masks applied to each packet: + the "sched_mask" sends packets arriving to a scheduler_id to @@ -57,69 +57,102 @@ There are in fact two masks applied to e As an example, we can have ipfw queue 5 config sched 10 flow_mask src-ip 0x000000ff - ipfw sched 10 config sched_mask src-ip 0xffffff00 + ipfw sched 10 config type WF2Q+ sched_mask src-ip 0xffffff00 means that sched 10 will have one instance per /24 source subnet, and within that, each individual source will be a flow. Internal structure ----------------- -Dummynet-related data is split into five main strucs: - -- struct new_pipe: contains data about the physical link such - as bandwith, delay, fields to simulate a delay profile and so on. - -- struct new_fs: describes a flowset. It contains template values for the - specified flowset, and a pointer (alg_fs) to an opaque struct that - can contain per-flowset scheduler-specific parameters, such as - weight, priorities, slot sizes and the like. - It also contains a flow_mask to allow to create more queues - depending of the flow id of the packet. All queues are stored into the - scheduler instance. - -- struct new_sch: it acts as a template for the scheduler used. It contains - enqueue and dequeue packet functions, a configure function for - possible global parameters, and two functions to create and destroy - the scheduler instance. - A scheduler can have more scheduler instance: a field sched_mask is - used to know how many instance could exist for this scheduler. - This struct also contains an hash table of queues pointers - -- struct new_sch_inst: it is the struct that represents the instance of the - scheduler. It has a pointer to the template, and some general parameter - and status variable relative to the single instance. - It also contains all queues associated with this instance and the delay line, - which is a list of packets that will be sent after a certain amount of time. - -- struct new_queue: it contains all data belonging to a single queue, as - total bytes, number of packets dropped, list of packet... - It can have some extra data about the scheduling algorithm. - XXX this is one instance of a flowset ? - - - +----------------+ - +--------+ ptr_sched | | +----------+ - | new_fs |--------------->| new_sch |-------->| new_pipe | - `--------' | | +----------+ - | +----------------+ - | | ^ - | V \___ - | +------------+ | - | | hash table | | - | | (m1) | | - | +------------+ | - | | ..... \_ | - -----------+ ... v \ | - | new_queue |<-----| -------------- | | +Dummynet-related data is split into several data structures, +part of them constituting the userland-kernel API, and others +specific to the kernel. + +USERLAND-KERNEL API + + struct new_pipe: + contains data about the physical link such as + bandwith, delay, burst size; + + struct new_profile: + fields to simulate a delay profile + + struct new_sch: + defines a scheduler (and a link attached to it). + Parameters include scheduler type, sched_mask, number of + buckets, and possibly other scheduler-specific parameters, + + struct new_fs: + describes a flowset, i.e. a template for queues. + Main parameters are the scheduler we attach to, a flow_mask, + buckets, queue size, plr, weight, and other scheduler-specific + parameters. + +KERNEL REPRESENTATION + + struct new_queue + individual queue of packets, which are created by a + flowset and attached to a scheduler instance. + A new_queue has a pointer to the new_fsk (which in turn counts + how many queues point to it), a pointer to the + new_sch_inst it attaches to, and is linked in a list + of queues attached to the new_sch_inst + CREATE: done on packet arrivals when a flow matches a flowset. + DELETE: done only when deleting the parent new_sch_inst + + struct new_fsk + includes a new_fs; a pointer to the new_schk; a link field + for the list of new_fsk attached to the same scheduler; + a refcount for the number of queues pointing to it; + The new_fsk is in a hash table when it is attached to a + scheduler, or in the fsunlinked list when shutting down + or no scheduler is active. + CREATE: done on configuration commands. + DELETE: configuration commands mark the flowset as DN_DELETE, + and move it to fsunlinked. Then as queue are drained, + they are deleted and when the last one goes away, + also the flowset goes away. + + struct new_sch_inst + a scheduler instance, created from a new_schk applying sched_mask. + Contains a delay line, a list of queues, and a reference to the + parent. Both new_sch_inst and its delay line can be in the + system_heap if they have events to be processed. + CREATE: created from a new_schk applying sched_mask + DELETE: configuration command delete a scheduler which in turn + sweeps the hash table of instances, deletes all queues + and then the instance. + + struct new_schk + includes new_sch, new_pipe, a pointer to new_profile, + a hash table of new_sch_inst, a list of new_fsk + attached to it. + CREATE: configuration command. If there are flowsets that + refer to this number, they are attached and moved + to the hash table + DELETE: manual, see new_sch_inst + + + +--------------+ + +------------+ ptr_sched | fsk_list | + | NEW_FSK |--------------->| NEW_SCHK |<----. + | refcnt | | new_pipe | | + | sch_chain | +--------------+ | + +------------+ | hash table | | + ^ | (m1) | | + | +--------------+ | + | | ..... \ | + -----------+ ... v \ | + | NEW_QUEUE |<-----| -------------- ` | +-----------+ | | | | | .... | | new_sch_inst | | | -----------+ | | | | | - | new_queue |<-----| -------------- | | + | NEW_QUEUE |<-----| -------------- | | +-----------+ | v | | .--------------. -------------- | | | hash table | | | | - | | (m2) + |<-----| new_sch_inst |_/ - | | new_sch_inst | | | + | | (m2) + |<-----| NEW_SCH_INST |_| + | | new_sch_inst | | ql_head | | `--------------' -------------- | ^ | | @@ -128,11 +161,8 @@ Dummynet-related data is split into five Note that the hash table m2 is not mandatory, a scheduler instance can use its own struct to store its queues -Three global data structures (hash tables) contain all -pipes, schedulers and flowsets. -- pipehash[x]: contains all pipes in the system - not needed to be efficient - we never do a lookup - in a critical section +The following global data structures contain all +schedulers and flowsets. - schedulerhash[x]: contains all scheduler templates in the system this needs to be a hash table because we may have to do From owner-svn-src-user@FreeBSD.ORG Mon Jan 11 12:31:36 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 96C2E1065676; Mon, 11 Jan 2010 12:31:36 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 880E78FC19; Mon, 11 Jan 2010 12:31:36 +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 o0BCVaPk060640; Mon, 11 Jan 2010 12:31:36 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0BCVaLg060638; Mon, 11 Jan 2010 12:31:36 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201001111231.o0BCVaLg060638@svn.freebsd.org> From: Ed Schouten Date: Mon, 11 Jan 2010 12:31:36 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202080 - user/ed/utmpx/usr.bin/last X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Jan 2010 12:31:36 -0000 Author: ed Date: Mon Jan 11 12:31:36 2010 New Revision: 202080 URL: http://svn.freebsd.org/changeset/base/202080 Log: Make "shutdown" lines fit properly when using 80 columns. Modified: user/ed/utmpx/usr.bin/last/last.c Modified: user/ed/utmpx/usr.bin/last/last.c ============================================================================== --- user/ed/utmpx/usr.bin/last/last.c Mon Jan 11 11:09:03 2010 (r202079) +++ user/ed/utmpx/usr.bin/last/last.c Mon Jan 11 12:31:36 2010 (r202080) @@ -335,19 +335,19 @@ printentry(struct utmpx *bp, struct idta (yflag ? "%a %b %e %Y %R" : "%a %b %e %R"), tm); switch (bp->ut_type) { case BOOT_TIME: - printf("%-44s", "boot time"); + printf("%-42s", "boot time"); break; case SHUTDOWN_TIME: - printf("%-44s", "shutdown time"); + printf("%-42s", "shutdown time"); break; case OLD_TIME: - printf("%-44s", "old time"); + printf("%-42s", "old time"); break; case NEW_TIME: - printf("%-44s", "new time"); + printf("%-42s", "new time"); break; case USER_PROCESS: - printf("%-10s %-8s %-24.24s", + printf("%-10s %-8s %-22.22s", bp->ut_user, bp->ut_line, bp->ut_host); break; } From owner-svn-src-user@FreeBSD.ORG Mon Jan 11 15:12:13 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id F27B41065695; Mon, 11 Jan 2010 15:12:13 +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 E00158FC20; Mon, 11 Jan 2010 15:12:13 +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 o0BFCD7R096293; Mon, 11 Jan 2010 15:12:13 GMT (envelope-from luigi@svn.freebsd.org) Received: (from luigi@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0BFCDrV096285; Mon, 11 Jan 2010 15:12:13 GMT (envelope-from luigi@svn.freebsd.org) Message-Id: <201001111512.o0BFCDrV096285@svn.freebsd.org> From: Luigi Rizzo Date: Mon, 11 Jan 2010 15:12:13 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202083 - in user/luigi/ipfw3-head: sbin/ipfw sys/netinet/ipfw X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Jan 2010 15:12:14 -0000 Author: luigi Date: Mon Jan 11 15:12:13 2010 New Revision: 202083 URL: http://svn.freebsd.org/changeset/base/202083 Log: data start flowing... Modified: user/luigi/ipfw3-head/sbin/ipfw/dummynet.c user/luigi/ipfw3-head/sbin/ipfw/ipfw2.c user/luigi/ipfw3-head/sbin/ipfw/ipfw2.h user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Modified: user/luigi/ipfw3-head/sbin/ipfw/dummynet.c ============================================================================== --- user/luigi/ipfw3-head/sbin/ipfw/dummynet.c Mon Jan 11 12:35:16 2010 (r202082) +++ user/luigi/ipfw3-head/sbin/ipfw/dummynet.c Mon Jan 11 15:12:13 2010 (r202083) @@ -288,65 +288,51 @@ print_extra_delay_parms(struct dn_pipe * p->name, loss, p->samples_no); } #endif -void -ipfw_list_pipes(void *data, uint nbytes, int ac, char *av[]) -{ -#if 0 - int rulenum; - void *next = data; - struct dn_pipe *p = (struct dn_pipe *) data; - struct dn_flow_set *fs; - struct dn_flow_queue *q; - int l; - if (ac > 0) - rulenum = strtoul(*av++, NULL, 10); +/* + * filt is an array of sorted ranges whithin where we list + */ +static void +list_pipes(struct dn_id *oid, struct dn_id *end, int *filt) +{ + for (; oid != end; oid = O_NEXT(oid, oid->len)) { + struct new_pipe *p = (struct new_pipe *)oid; + //struct dn_flow_set *fs; + //struct dn_flow_queue *q; + + double b = p->bandwidth; + char buf[30]; + char prefix[80]; + char burst[5 + 7]; + + if (oid->type != DN_PIPE) + continue; + /* + * Print rate (or clocking interface) + */ + if (b == 0) + sprintf(buf, "unlimited"); + else if (b >= 1000000) + sprintf(buf, "%7.3f Mbit/s", b/1000000); + else if (b >= 1000) + sprintf(buf, "%7.3f Kbit/s", b/1000); else - rulenum = 0; - for (; nbytes >= sizeof *p; p = (struct dn_pipe *)next) { - double b = p->bandwidth; - char buf[30]; - char prefix[80]; - char burst[5 + 7]; - - if (SLIST_NEXT(p, next) != (struct dn_pipe *)DN_IS_PIPE) - break; /* done with pipes, now queues */ + sprintf(buf, "%7.3f bit/s ", b); - /* - * compute length, as pipe have variable size - */ - l = sizeof(*p) + p->fs.rq_elements * sizeof(*q); - next = (char *)p + l; - nbytes -= l; - - if ((rulenum != 0 && rulenum != p->pipe_nr) || co.do_pipe == 2) - continue; - - /* - * Print rate (or clocking interface) - */ - if (b == 0) - sprintf(buf, "unlimited"); - else if (b >= 1000000) - sprintf(buf, "%7.3f Mbit/s", b/1000000); - else if (b >= 1000) - sprintf(buf, "%7.3f Kbit/s", b/1000); - else - sprintf(buf, "%7.3f bit/s ", b); - - sprintf(prefix, "%05d: %s %4d ms ", + sprintf(prefix, "%05d: %s %4d ms ", p->pipe_nr, buf, p->delay); - print_flowset_parms(&(p->fs), prefix); + // print_flowset_parms(&(p->fs), prefix); + printf("%s", prefix); - if (humanize_number(burst, sizeof(burst), p->burst, + if (humanize_number(burst, sizeof(burst), p->burst, "Byte", HN_AUTOSCALE, 0) < 0 || co.verbose) - printf("\t burst: %ju Byte\n", p->burst); - else - printf("\t burst: %s\n", burst); - - print_extra_delay_parms(p); + printf("\t burst: %ju Byte\n", p->burst); + else + printf("\t burst: %s\n", burst); + // print_extra_delay_parms(p); +#if 0 q = (struct dn_flow_queue *)(p+1); list_queues(&(p->fs), q); } @@ -371,6 +357,7 @@ ipfw_list_pipes(void *data, uint nbytes, list_queues(fs, q); } #endif + } } /* @@ -549,7 +536,8 @@ read_bandwidth(char *arg, int *bandwidth errx(EX_DATAERR, "bandwidth too large"); *bandwidth = bw; - if_name[0] = '\0'; + if (if_name) + if_name[0] = '\0'; } } @@ -807,6 +795,10 @@ ipfw_config_pipe(int ac, char **av) mask = &sch->sched_mask; break; } + if (p) + p->bandwidth = -1; + if (p2) + p2->bandwidth = -1; while (ac > 0) { double d; @@ -1198,3 +1190,36 @@ end_mask: if (i) err(1, "setsockopt(%s)", "IP_DUMMYNET_CONFIGURE"); } + +void +dummynet_list(int ac, char *av[], int show_counters) +{ + struct dn_id oid , *x; + int ret, l = sizeof(oid); + + oid.type = DN_CMD_GET; + oid.len = l; + oid.id = 0; + switch (co.do_pipe) { + case 1: + oid.subtype = DN_SCH; /* list pipe */ + break; + case 2: + oid.subtype = DN_FS; /* list queue */ + break; + } + ret = do_cmd(IP_DUMMYNET_GET, &oid, (uintptr_t)&l); + printf("%s returns %d need %d\n", __FUNCTION__, ret, oid.id); + if (ret != 0 || oid.id <= sizeof(oid)) + return; + l = oid.id; + x = malloc(l); + if (x == NULL) { + err(1, "no memory in %s", __FUNCTION__); + } + *x = oid; + ret = do_cmd(IP_DUMMYNET_GET, x, (uintptr_t)&l); + printf("%s returns %d need %d\n", __FUNCTION__, ret, oid.id); + list_pipes(x, O_NEXT(x, l), NULL); + free(x); +} Modified: user/luigi/ipfw3-head/sbin/ipfw/ipfw2.c ============================================================================== --- user/luigi/ipfw3-head/sbin/ipfw/ipfw2.c Mon Jan 11 12:35:16 2010 (r202082) +++ user/luigi/ipfw3-head/sbin/ipfw/ipfw2.c Mon Jan 11 15:12:13 2010 (r202083) @@ -1762,6 +1762,10 @@ ipfw_list(int ac, char *av[], int show_c fprintf(stderr, "Testing only, list disabled\n"); return; } + if (co.do_pipe) { + dummynet_list(ac, av, show_counters); + return; + } ac--; av++; @@ -1778,11 +1782,6 @@ ipfw_list(int ac, char *av[], int show_c co.do_pipe ? "DUMMYNET" : "FW"); } - if (co.do_pipe) { - ipfw_list_pipes(data, nbytes, ac, av); - goto done; - } - /* * Count static rules. They have variable size so we * need to scan the list to count them. Modified: user/luigi/ipfw3-head/sbin/ipfw/ipfw2.h ============================================================================== --- user/luigi/ipfw3-head/sbin/ipfw/ipfw2.h Mon Jan 11 12:35:16 2010 (r202082) +++ user/luigi/ipfw3-head/sbin/ipfw/ipfw2.h Mon Jan 11 15:12:13 2010 (r202083) @@ -265,7 +265,7 @@ u_int32_t altq_name_to_qid(const char *n void print_altq_cmd(struct _ipfw_insn_altq *altqptr); /* dummynet.c */ -void ipfw_list_pipes(void *data, uint nbytes, int ac, char *av[]); +void dummynet_list(int ac, char *av[], int show_counters); int ipfw_delete_pipe(int pipe_or_queue, int n); /* ipv6.c */ Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c Mon Jan 11 12:35:16 2010 (r202082) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c Mon Jan 11 15:12:13 2010 (r202083) @@ -91,12 +91,14 @@ fifo_enqueue(struct new_sch_inst *_si, s if (si->q == NULL) { si->q = dn_create_queue(_si, f, id); if (si->q == NULL) { + printf("%s dn_create_queue failed\n", __FUNCTION__); FREE_PKT(m); return 1; } } /* Now the si->q is valid, so insert the packet in this queue */ if (dn_queue_packet(si->q, m)) { + printf("%s dn_queue_packet failed\n", __FUNCTION__); /* packet was dropped */ return 1; } Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Mon Jan 11 12:35:16 2010 (r202082) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Mon Jan 11 15:12:13 2010 (r202083) @@ -249,7 +249,6 @@ dn_queue_packet(struct new_queue *q, str /* Update statistics, then check reasons to drop pkt. */ q->tot_bytes += m->m_pkthdr.len; q->tot_pkts++; - if (f->plr && random() < f->plr) goto drop; if (f->flags & DN_QSIZE_BYTES) { @@ -442,6 +441,7 @@ create_si(struct new_schk *s, int slot) int ret; int l = sizeof(*si) + s->fp->sch_inst_len; +printf("%s start slot %d\n", __FUNCTION__, slot); si = malloc(l, M_DUMMYNET, M_NOWAIT | M_ZERO); if (si == NULL) @@ -467,6 +467,7 @@ create_si(struct new_schk *s, int slot) /* Put entry in front of the hash list of the parent. */ SLIST_INSERT_HEAD(&s->ht[slot], si, next); si->hash_slot = slot; + dn_cfg.si_count++; return si; error: @@ -483,6 +484,7 @@ find_sch_inst(struct new_schk *s, struct int i; struct ipfw_flow_id id_t; +printf("%s start id %p\n", __FUNCTION__, id); if ( 0 == (s->sch.flags & DN_HAVE_MASK) ) { i = 0; si = SLIST_FIRST(&s->ht[0]); @@ -760,8 +762,7 @@ dummynet_io(struct mbuf **m0, int dir, s dn_key now; /* save a copy of curr_time */ int fs_id = (fwa->rule.info & IPFW_INFO_MASK) + - (fwa->rule.info & IPFW_IS_PIPE) ? DN_PIPEOFFSET : 0; - + ((fwa->rule.info & IPFW_IS_PIPE) ? DN_PIPEOFFSET : 0); DUMMYNET_LOCK(); io_pkt++; /* XXX locate_flowset could be optimised with a direct ref. */ @@ -793,6 +794,7 @@ dummynet_io(struct mbuf **m0, int dir, s if (fs->kflags & DN_HAVE_MASK) do_mask(&fs->fs.flow_mask, &(fwa->f_id)); if (sch->fp->enqueue(sch_inst, fs, m, &(fwa->f_id))) { + printf("%s dropped by enqueue\n", __FUNCTION__); /* packet was dropped by enqueue() */ *m0 = NULL; goto dropit; Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h Mon Jan 11 12:35:16 2010 (r202082) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h Mon Jan 11 15:12:13 2010 (r202083) @@ -71,6 +71,12 @@ struct dn_parms { struct timeval prev_t; struct dn_heap system_heap; + /* how many objects we have -- useful for reporting space */ + int schk_count; + int si_count; + int fsk_count; + int queue_count; + int hmask; /* mask for hashsize, must be 2^n-1 */ /* fhash and schedhash are hmask+1 entries */ struct new_fsk_head fsunlinked; @@ -156,6 +162,7 @@ struct new_schk { */ int ht_slots; /* number of slots */ struct new_sch_inst_head *ht; + struct new_sch_inst_head h0; /* used if malloc fails */ int kflags; Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Mon Jan 11 12:35:16 2010 (r202082) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Mon Jan 11 15:12:13 2010 (r202083) @@ -61,6 +61,13 @@ __FBSDID("$FreeBSD$"); static int ip_dn_ctl(struct sockopt *sopt); + /* which objects to copy */ +#define DN_C_PIPE 0x01 +#define DN_C_SCH 0x02 +#define DN_C_SCH_INST 0x04 +#define DN_C_FS 0x08 +#define DN_C_QUEUE 0x10 + static int config_pipe(struct new_pipe *p, struct dn_id *arg); static int config_profile(struct new_profile *p, struct dn_id *arg); @@ -139,6 +146,7 @@ destroy_si(struct new_sch_inst *si) dn_delete_queue(q); } free(si, M_DUMMYNET); + dn_cfg.si_count--; return 0; } @@ -161,9 +169,23 @@ destroy_fs(struct new_fsk *fs) fs->kflags |= DN_DELETE; if (fs->refcnt != 0) return; + dn_cfg.fsk_count--; SLIST_REMOVE(&s->fsk_list, fs, new_fsk, sch_chain); } +static struct new_fsk * +create_fs(void) +{ + struct new_fsk *fs; + + fs = malloc(sizeof(*fs), M_DUMMYNET, M_NOWAIT | M_ZERO); + if (fs) { + SLIST_INSERT_HEAD(&dn_cfg.fsunlinked, fs, next); + dn_cfg.fsk_count++; + } + return fs; +} + /* * helper for schedulers. Creates a queue */ @@ -180,7 +202,7 @@ dn_create_queue(struct new_sch_inst *si, return NULL; } - set_oid(&q->oid, DN_QUEUE, size, 0); + set_oid(&q->oid, DN_QUEUE, 0, size); q->fs = fs; q->si = si; fs->refcnt++; @@ -188,6 +210,7 @@ dn_create_queue(struct new_sch_inst *si, if (si->sched->fp->new_queue) si->sched->fp->new_queue(q); SLIST_INSERT_HEAD(&si->ql_list, q, ql_next); + dn_cfg.queue_count++; return q; } @@ -206,13 +229,14 @@ dn_delete_queue(struct new_queue *q) fs->sched->fp->free_queue(q); free(q, M_DUMMYNET); fs->refcnt--; + dn_cfg.queue_count--; if (fs->refcnt == 0 && fs->kflags & DN_DELETE) destroy_fs(fs); return 0; } static struct new_schk * -destroy_sched(struct new_schk *s, int del) +destroy_schk(struct new_schk *s, int del) { int i; struct new_sch_inst *si; @@ -228,9 +252,87 @@ destroy_sched(struct new_schk *s, int de if (fp->destroy) fp->destroy(s, 1); free(s, M_DUMMYNET); + dn_cfg.schk_count--; return NULL; } +static struct new_schk * +create_schk(struct dn_sched *fp) +{ + struct new_schk *s; + int l = sizeof(*s) + fp->schk_len; + + s = malloc(l, M_DUMMYNET, M_NOWAIT | M_ZERO); + if (s) { + set_oid(&s->pipe.oid, DN_PIPE, 0, sizeof(s->pipe)); + s->fp = fp; + SLIST_INIT(&s->fsk_list); + /* use a default hash */ + s->ht_slots = 1; + s->ht = &s->h0; + dn_cfg.schk_count++; + } + return s; +} + +static int +copy_obj(char **start, char *end, void *_o) +{ + struct dn_id *o = _o; + + if (end - *start < o->len) + return 1; + bcopy(_o, *start, o->len); + *start += o->len; + return 0; +} + +/* copy data, return 1 when full */ +static int +copy_data(char **start, char *end, int flags) +{ + int i; + + if (flags & (DN_C_PIPE | DN_C_SCH | DN_C_SCH_INST)) { + for (i = 0; i < dn_cfg.hmask+1; i++) { + struct new_schk *s; + SLIST_FOREACH(s, &dn_cfg.schedhash[i], next) { + if (flags & DN_C_PIPE) { + printf("copy pipe %d len %d\n", + s->pipe.pipe_nr, s->pipe.oid.len); + if (copy_obj(start, end, &s->pipe)) + return 1; + } + if (flags & DN_C_SCH) { + printf("copy sched %d\n", s->sch.sched_nr); + if (copy_obj(start, end, &s->sch)) + return 1; + } + if (flags & DN_C_SCH_INST) { + printf("copy shc_inst %d\n", s->sch.sched_nr); + /* scan the hashtable */ + } + } + } + } + if (flags & (DN_C_FS)) { + struct new_fsk *fs; + for (i = 0; i < dn_cfg.hmask+1; i++) { + SLIST_FOREACH(fs, &dn_cfg.fshash[i], next) { + printf("copy flowset %d\n", fs->fs.fs_nr); + if (copy_obj(start, end, &fs->fs)) + return 1; + } + } + SLIST_FOREACH(fs, &dn_cfg.fsunlinked, next) { + printf("copy flowset %d\n", fs->fs.fs_nr); + if (copy_obj(start, end, &fs->fs)) + return 1; + } + } + return 0; +} + /* * Delete all objects: * - mark as shutting down; @@ -256,7 +358,7 @@ dummynet_flush(void) while ( (s = SLIST_FIRST(sh)) != NULL) { SLIST_REMOVE_HEAD(sh, next); - destroy_sched(s, 1 /* delete */); + destroy_schk(s, 1 /* delete */); } } @@ -444,7 +546,7 @@ config_sched(struct new_sch *nsch, struc { struct new_schk *s; struct dn_sched *fp; - int i, l, is_new; + int i, is_new; struct new_fsk_head fsk_list; SLIST_INIT(&fsk_list); @@ -466,23 +568,25 @@ config_sched(struct new_sch *nsch, struc DUMMYNET_LOCK(); s = locate_scheduler(i); printf("%s type %s old %p\n", __FUNCTION__, fp->name, s); - if (s && s->fp != fp) /* type changed, hard delete */ - s = destroy_sched(s, 1); + if (s && s->fp != fp) { /* type changed, hard delete */ + /* preserve old pipe ? */ + s = destroy_schk(s, 1); + } if (s) { is_new = 0; } else { - l = sizeof(*s) + fp->schk_len; - s = malloc(l, M_DUMMYNET, M_NOWAIT | M_ZERO); + s = create_schk(fp); if (s == NULL) return ENOMEM; - s->fp = fp; - SLIST_INIT(&s->fsk_list); + s->pipe.pipe_nr = i; + SLIST_INSERT_HEAD(&dn_cfg.schedhash[HASH(i)], s, next); is_new = 1; } s->sch = *nsch; s->cfg = arg; - if (is_new) { - SLIST_INSERT_HEAD(&dn_cfg.schedhash[HASH(i)], s, next); + /* initialize the hash table */ + if (s->sch.flags & DN_HAVE_MASK) { + } else { } /* call init function */ if (s->fp->config) @@ -514,18 +618,26 @@ config_fs(struct new_fs *nfs, struct dn_ if (i <= 0 || i > DN_MAXID) return EINVAL; /* XXX other sanity checks */ + if (nfs->flags & DN_QSIZE_IS_BYTES) { + if (nfs->qsize > dn_cfg.pipe_byte_limit) + nfs->qsize = dn_cfg.pipe_byte_limit; + } else { + if (nfs->qsize == 0) + nfs->qsize = 50; + if (nfs->qsize > dn_cfg.pipe_slot_limit) + nfs->qsize = dn_cfg.pipe_slot_limit; + } + DUMMYNET_LOCK(); fs = ipdn_locate_flowset(i); printf("%s %d old %p\n", __FUNCTION__, i, fs); if (fs == NULL) { - fs = malloc(sizeof(*fs), - M_DUMMYNET, M_NOWAIT | M_ZERO); + fs = create_fs(); if (fs == NULL) { DUMMYNET_UNLOCK(); return ENOMEM; } - SLIST_INSERT_HEAD(&dn_cfg.fsunlinked, fs, next); } fs->fs = *nfs; /* update config */ /* copy values, check if scheduler exists and mark active */ @@ -621,46 +733,69 @@ config_profile(struct new_profile *pf, s return 0; } -static size_t -dn_calc_size(void) -{ - return 100; -} - static int dummynet_get(struct sockopt *sopt) { - int error=0; - char *buf, *bp ; /* bp is the "copy-pointer" */ - size_t size ; - int i; - - /* XXX lock held too long */ - DUMMYNET_LOCK(); - /* - * XXX: Ugly, but we need to allocate memory with M_WAITOK flag and we - * cannot use this flag while holding a mutex. - */ - for (i = 0; i < 10; i++) { - size = dn_calc_size(); - DUMMYNET_UNLOCK(); - buf = malloc(size, M_TEMP, M_WAITOK); + int have = 0, i, need, error; + char *start = NULL, *buf, *end; + size_t sopt_valsize; + struct dn_id cmd; + int to_copy = 0; + + /* save original values */ + sopt_valsize = sopt->sopt_valsize; + printf("%s have %d bytes\n", __FUNCTION__, sopt_valsize); + + error = sooptcopyin(sopt, &cmd, sizeof(cmd), sizeof(cmd)); + sopt->sopt_valsize = sopt_valsize; + if (error) + return error; + printf("%s cmd %d len %d\n", __FUNCTION__, cmd.type, cmd.len); + for (have = 0, i = 0; i < 10; i++) { DUMMYNET_LOCK(); - if (size >= dn_calc_size()) - break; - free(buf, M_TEMP); - buf = NULL; - } - if (buf == NULL) { + switch (cmd.subtype) { + default: + return EINVAL; + case DN_SCH: /* pipe show */ + to_copy = DN_C_SCH | DN_C_PIPE; + need = dn_cfg.schk_count * + (sizeof(struct new_sch) + sizeof(struct new_pipe)); + break; + case DN_FS: /* queue show */ + to_copy = DN_C_FS; + need = dn_cfg.fsk_count * + (sizeof(struct new_fs)); + break; + } + need += sizeof(cmd); + cmd.id = need; + printf("pass %d have %d need %d len %d\n", + i, have, need, sopt_valsize); + if (have >= need) + break; DUMMYNET_UNLOCK(); - return ENOBUFS ; + if (start) + free(start, M_DUMMYNET); + buf = NULL; + if (need > sopt_valsize) + break; + have = need; + start = malloc(have, M_DUMMYNET, M_WAITOK | M_ZERO); + if (start == NULL) + return ENOMEM; } - bp = buf; + if (start == NULL) + return sooptcopyout(sopt, &cmd, sizeof(cmd)); + end = start + have; + sopt->sopt_valsize = sopt_valsize; + bcopy(&cmd, start, sizeof(cmd)); + buf = start + sizeof(cmd); + /* start copying other objects */ + copy_data(&buf, end, to_copy); DUMMYNET_UNLOCK(); - - error = sooptcopyout(sopt, buf, size); - free(buf, M_TEMP); - return error ; + error = sooptcopyout(sopt, start, buf - start); + free(start, M_DUMMYNET); + return error; } /* @@ -699,8 +834,7 @@ ip_dn_ctl(struct sockopt *sopt) case IP_DUMMYNET_CONFIGURE : case IP_DUMMYNET_DEL : /* remove a pipe or queue */ - l = (sopt->sopt_dir == SOPT_SET) ? sopt->sopt_valsize : - *(int *)(sopt->sopt_valsize); + l = sopt->sopt_valsize; if (l < 0 || l > 12000) { printf("argument too large, %d\n", l); break; From owner-svn-src-user@FreeBSD.ORG Mon Jan 11 16:30:09 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id EE3B9106568B; Mon, 11 Jan 2010 16:30:09 +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 DD49B8FC18; Mon, 11 Jan 2010 16:30:09 +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 o0BGU9PX013711; Mon, 11 Jan 2010 16:30:09 GMT (envelope-from luigi@svn.freebsd.org) Received: (from luigi@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0BGU9n2013709; Mon, 11 Jan 2010 16:30:09 GMT (envelope-from luigi@svn.freebsd.org) Message-Id: <201001111630.o0BGU9n2013709@svn.freebsd.org> From: Luigi Rizzo Date: Mon, 11 Jan 2010 16:30:09 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202087 - user/luigi/ipfw3-head/sys/netinet/ipfw X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Jan 2010 16:30:10 -0000 Author: luigi Date: Mon Jan 11 16:30:09 2010 New Revision: 202087 URL: http://svn.freebsd.org/changeset/base/202087 Log: missing argument for free() Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Mon Jan 11 16:27:56 2010 (r202086) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Mon Jan 11 16:30:09 2010 (r202087) @@ -919,8 +919,8 @@ ip_dn_destroy(void) taskqueue_free(dn_tq); dummynet_flush(); - free(dn_cfg.schedhash); - heap_free(&dn_cfg.sysem_heap); + free(dn_cfg.schedhash, M_DUMMYNET); + heap_free(&dn_cfg.system_heap); DUMMYNET_LOCK_DESTROY(); } From owner-svn-src-user@FreeBSD.ORG Mon Jan 11 16:31:30 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 55D2E10656C1; Mon, 11 Jan 2010 16:31:30 +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 441168FC1E; Mon, 11 Jan 2010 16:31:30 +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 o0BGVUYj014055; Mon, 11 Jan 2010 16:31:30 GMT (envelope-from luigi@svn.freebsd.org) Received: (from luigi@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0BGVUvv014050; Mon, 11 Jan 2010 16:31:30 GMT (envelope-from luigi@svn.freebsd.org) Message-Id: <201001111631.o0BGVUvv014050@svn.freebsd.org> From: Luigi Rizzo Date: Mon, 11 Jan 2010 16:31:30 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202088 - in user/luigi/ipfw3-head/sys: conf modules/dummynet netinet/ipfw X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Jan 2010 16:31:30 -0000 Author: luigi Date: Mon Jan 11 16:31:29 2010 New Revision: 202088 URL: http://svn.freebsd.org/changeset/base/202088 Log: add dn_sched_wf2q.c and glue for modules Modified: user/luigi/ipfw3-head/sys/conf/files user/luigi/ipfw3-head/sys/modules/dummynet/Makefile user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Modified: user/luigi/ipfw3-head/sys/conf/files ============================================================================== --- user/luigi/ipfw3-head/sys/conf/files Mon Jan 11 16:30:09 2010 (r202087) +++ user/luigi/ipfw3-head/sys/conf/files Mon Jan 11 16:31:29 2010 (r202088) @@ -2451,6 +2451,7 @@ netinet/in_rmx.c optional inet netinet/ip_divert.c optional inet ipdivert ipfirewall netinet/ipfw/dn_heap.c optional inet dummynet netinet/ipfw/dn_sched_fifo.c optional inet dummynet +netinet/ipfw/dn_sched_wf2q.c optional inet dummynet netinet/ipfw/ip_dummynet.c optional inet dummynet netinet/ipfw/ip_dn_io.c optional inet dummynet netinet/ip_ecn.c optional inet | inet6 Modified: user/luigi/ipfw3-head/sys/modules/dummynet/Makefile ============================================================================== --- user/luigi/ipfw3-head/sys/modules/dummynet/Makefile Mon Jan 11 16:30:09 2010 (r202087) +++ user/luigi/ipfw3-head/sys/modules/dummynet/Makefile Mon Jan 11 16:31:29 2010 (r202088) @@ -4,7 +4,7 @@ .PATH: ${.CURDIR}/../../netinet/ipfw KMOD= dummynet -SRCS= ip_dummynet.c +SRCS= ip_dummynet.c ip_dn_io.c dn_sched_fifo.c dn_sched_wf2q.c SRCS+= opt_inet6.h .if !defined(KERNBUILDDIR) Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h Mon Jan 11 16:30:09 2010 (r202087) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h Mon Jan 11 16:31:29 2010 (r202088) @@ -43,7 +43,7 @@ struct dn_sched { int type; /* the scheduler type */ const char *name; /* scheduler name */ - int ref_count; /* number of instances in the system */ + int ref_count; /* XXX number of instances in the system */ /* * The following define the size of 4 optional data structures @@ -205,10 +205,11 @@ static __inline struct mbuf* dn_return_packet(struct new_queue *q) { struct mbuf *m = q->mq.head; + KASSERT(m != NULL, ("empty queue to dn_return_packet")); q->mq.head = m->m_nextpkt; q->lenght--; q->len_bytes -= m->m_pkthdr.len; - if (q->mq.head == NULL && q->fs->kflags & DN_DELETE) + if (q->mq.head == NULL && q->fs && q->fs->kflags & DN_DELETE) dn_delete_queue(q); return m; Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Mon Jan 11 16:30:09 2010 (r202087) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Mon Jan 11 16:31:29 2010 (r202088) @@ -85,7 +85,7 @@ struct dn_parms dn_cfg = { .red_lookup_depth = 256, /* RED - default lookup table depth */ .red_avg_pkt_size = 512, /* RED - default medium packet size */ .red_max_pkt_size = 1500, /* RED - default max packet size */ - .hmask = (1<<4) - 1. + .hmask = (1<<4) - 1, }; static long tick_last; /* Last tick duration (usec). */ @@ -317,6 +317,7 @@ extra_bits(struct mbuf *m, struct new_pi return bits; } +#if 0 /* Insert packet pkt into delay line, adding the delay. * dt->output_time was already set */ static void @@ -327,6 +328,7 @@ move_pkt(struct mbuf *m, struct new_pipe dt->output_time += p->delay ; mq_append(&d->mq, m); } +#endif /* Do masking depending of flow id */ static struct ipfw_flow_id * @@ -441,7 +443,6 @@ create_si(struct new_schk *s, int slot) int ret; int l = sizeof(*si) + s->fp->sch_inst_len; -printf("%s start slot %d\n", __FUNCTION__, slot); si = malloc(l, M_DUMMYNET, M_NOWAIT | M_ZERO); if (si == NULL) @@ -484,7 +485,6 @@ find_sch_inst(struct new_schk *s, struct int i; struct ipfw_flow_id id_t; -printf("%s start id %p\n", __FUNCTION__, id); if ( 0 == (s->sch.flags & DN_HAVE_MASK) ) { i = 0; si = SLIST_FIRST(&s->ht[0]); @@ -537,7 +537,8 @@ serve_sched(struct mq *q, struct new_sch (m->m_pkthdr.len * 8 + extra_bits(m, &s->pipe)); si->credit -= len_scaled; /* Move packet in the delay line */ - move_pkt(m, &s->pipe, &si->dline); + dn_tag_get(m)->output_time += s->pipe.delay ; + mq_append(&si->dline.mq, m); } if (si->credit >= 0) { /* Instance is idle, because it did not return @@ -551,7 +552,7 @@ serve_sched(struct mq *q, struct new_sch * of the last packet, which is 'tosend' */ dn_key t; - KASSERT (bw > 0, "bw=0 and credit<0 ?"); + KASSERT (bw > 0, ("bw=0 and credit<0 ?")); t = (bw - 1 - si->credit) / bw; /* Delay output time because under credit */ if (m) @@ -622,10 +623,8 @@ dummynet_task(void *context, int pending p = HEAP_TOP(&dn_cfg.system_heap)->object; heap_extract(&dn_cfg.system_heap, NULL); } else { - p = NULL; - } - if (p == NULL) break; + } if (p->type == DN_SCH_I) { serve_sched(&q, (struct new_sch_inst *)p, curr_time); @@ -823,7 +822,6 @@ dummynet_io(struct mbuf **m0, int dir, s if (dn_cfg.io_fast && m == *m0 && (dir & PROTO_LAYER2) == 0 ) { /* fast io */ io_pkt_fast++; - printf("dummynet TEST: ** IOFAST **\n"); if (m->m_nextpkt != NULL) { printf("dummynet: fast io: pkt chain detected!\n"); m->m_nextpkt = NULL; From owner-svn-src-user@FreeBSD.ORG Mon Jan 11 17:34:32 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 5F3A21065679; Mon, 11 Jan 2010 17:34:32 +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 4E4AB8FC15; Mon, 11 Jan 2010 17:34:32 +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 o0BHYWFm028105; Mon, 11 Jan 2010 17:34:32 GMT (envelope-from luigi@svn.freebsd.org) Received: (from luigi@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0BHYW7u028103; Mon, 11 Jan 2010 17:34:32 GMT (envelope-from luigi@svn.freebsd.org) Message-Id: <201001111734.o0BHYW7u028103@svn.freebsd.org> From: Luigi Rizzo Date: Mon, 11 Jan 2010 17:34:32 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202093 - user/luigi/ipfw3-head/sys/netinet/ipfw X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Jan 2010 17:34:32 -0000 Author: luigi Date: Mon Jan 11 17:34:32 2010 New Revision: 202093 URL: http://svn.freebsd.org/changeset/base/202093 Log: whitespace fix Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Mon Jan 11 17:29:20 2010 (r202092) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Mon Jan 11 17:34:32 2010 (r202093) @@ -351,7 +351,6 @@ dummynet_flush(void) DUMMYNET_LOCK(); - /* Free all schedulers. Instances only go away this way. */ for (i = 0; i < dn_cfg.hmask+1; i++) { struct new_schk_head *sh = &dn_cfg.schedhash[i]; From owner-svn-src-user@FreeBSD.ORG Mon Jan 11 17:35:34 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id EF2DA106568D; Mon, 11 Jan 2010 17:35:34 +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 DE5FB8FC17; Mon, 11 Jan 2010 17:35:34 +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 o0BHZYLV028375; Mon, 11 Jan 2010 17:35:34 GMT (envelope-from luigi@svn.freebsd.org) Received: (from luigi@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0BHZY7k028373; Mon, 11 Jan 2010 17:35:34 GMT (envelope-from luigi@svn.freebsd.org) Message-Id: <201001111735.o0BHZY7k028373@svn.freebsd.org> From: Luigi Rizzo Date: Mon, 11 Jan 2010 17:35:34 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202094 - user/luigi/ipfw3-head/sys/netinet/ipfw X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Jan 2010 17:35:35 -0000 Author: luigi Date: Mon Jan 11 17:35:34 2010 New Revision: 202094 URL: http://svn.freebsd.org/changeset/base/202094 Log: make dummynet consume packets correctly Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Mon Jan 11 17:34:32 2010 (r202093) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Mon Jan 11 17:35:34 2010 (r202094) @@ -799,8 +799,10 @@ dummynet_io(struct mbuf **m0, int dir, s goto dropit; } - if (sch_inst->kflags & DN_ACTIVE) + if (sch_inst->kflags & DN_ACTIVE) { + m = *m0 = NULL; /* consumed */ goto done; /* already active, nothing to do */ + } /* compute the initial allowance */ pipe = &sch->pipe; @@ -826,14 +828,14 @@ dummynet_io(struct mbuf **m0, int dir, s printf("dummynet: fast io: pkt chain detected!\n"); m->m_nextpkt = NULL; } + m = NULL; } else { *m0 = NULL; - /* XXX outside lock ? */ - if (m) - dummynet_send(m); } done: DUMMYNET_UNLOCK(); + if (m) + dummynet_send(m); return 0; dropit: From owner-svn-src-user@FreeBSD.ORG Mon Jan 11 18:08:39 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 983CD1065672; Mon, 11 Jan 2010 18:08:39 +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 866728FC15; Mon, 11 Jan 2010 18:08:39 +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 o0BI8dQO035742; Mon, 11 Jan 2010 18:08:39 GMT (envelope-from luigi@svn.freebsd.org) Received: (from luigi@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0BI8dBK035737; Mon, 11 Jan 2010 18:08:39 GMT (envelope-from luigi@svn.freebsd.org) Message-Id: <201001111808.o0BI8dBK035737@svn.freebsd.org> From: Luigi Rizzo Date: Mon, 11 Jan 2010 18:08:39 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202096 - in user/luigi/ipfw3-head/sys/netinet: . ipfw X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Jan 2010 18:08:39 -0000 Author: luigi Date: Mon Jan 11 18:08:39 2010 New Revision: 202096 URL: http://svn.freebsd.org/changeset/base/202096 Log: pass more stats upstream Modified: user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Modified: user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h Mon Jan 11 17:58:15 2010 (r202095) +++ user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h Mon Jan 11 18:08:39 2010 (r202096) @@ -170,10 +170,12 @@ struct new_fs { */ struct new_inst { struct dn_id oid; + struct ipfw_flow_id id; uint32_t parent_nr; /* sched or flowset nr */ - uint32_t lenght; /* Queue lenght, in packets */ + uint32_t length; /* Queue lenght, in packets */ uint32_t len_bytes; /* Queue lenght, in bytes */ uint32_t drops; + int hash_slot; uint64_t tot_pkts; /* statistics counters */ uint64_t tot_bytes; }; Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Mon Jan 11 17:58:15 2010 (r202095) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Mon Jan 11 18:08:39 2010 (r202096) @@ -244,11 +244,14 @@ int dn_queue_packet(struct new_queue *q, struct mbuf* m) { struct new_fs *f = &(q->fs->fs); + struct new_inst *ni = &q->si->ni; uint64_t len = m->m_pkthdr.len; /* Update statistics, then check reasons to drop pkt. */ - q->tot_bytes += m->m_pkthdr.len; + q->tot_bytes += len; q->tot_pkts++; + ni->tot_bytes += len; + ni->tot_pkts++; if (f->plr && random() < f->plr) goto drop; if (f->flags & DN_QSIZE_BYTES) { @@ -260,11 +263,14 @@ dn_queue_packet(struct new_queue *q, str mq_append(&q->mq, m); q->lenght++; q->len_bytes += len; + ni->length++; + ni->len_bytes += len; return 0; drop: io_pkt_drop++; q->drops++; + ni->drops++; FREE_PKT(m); return 1; } @@ -447,7 +453,10 @@ create_si(struct new_schk *s, int slot) if (si == NULL) goto error; - set_oid(&si->oid, DN_SCH_I, 0, l); + /* XXX note we set the length only for the initial part which + * is passed up to userland. + */ + set_oid(&si->ni.oid, DN_SCH_I, 0, sizeof(struct new_inst)); set_oid(&(si->dline.oid), DN_DELAY_LINE, 0, sizeof(struct delay_line)); si->sched = s; @@ -467,7 +476,7 @@ create_si(struct new_schk *s, int slot) si->idle_time = 0; /* Put entry in front of the hash list of the parent. */ SLIST_INSERT_HEAD(&s->ht[slot], si, next); - si->hash_slot = slot; + si->ni.hash_slot = slot; dn_cfg.si_count++; return si; @@ -497,7 +506,7 @@ find_sch_inst(struct new_schk *s, struct searches++; SLIST_FOREACH(si, &s->ht[i], next) { search_steps++; - if (!mask_are_equals(&id_t, &si->id)) + if (!mask_are_equals(&id_t, &si->ni.id)) break; /* found */ } } @@ -505,7 +514,7 @@ find_sch_inst(struct new_schk *s, struct if (si == NULL) { /* no match, need to allocate a new entry */ si = create_si(s, i); if (si && s->sch.flags & DN_HAVE_MASK) - si->id = id_t; + si->ni.id = id_t; } return si; } Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h Mon Jan 11 17:58:15 2010 (r202095) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h Mon Jan 11 18:08:39 2010 (r202096) @@ -196,12 +196,10 @@ SLIST_HEAD(new_queue_head, new_queue); * This struct is created a runtime. */ struct new_sch_inst { - struct dn_id oid; + struct new_inst ni; /* oid, id and stats */ SLIST_ENTRY(new_sch_inst) next; /* next item in the bucket */ struct delay_line dline; struct new_schk *sched; /* the template */ - int hash_slot; /* used to print the id of the scheduler instance */ - struct ipfw_flow_id id; /* flow-id for this instance */ int kflags; /* DN_SCHED_ACTIVE */ /* queues attached to this scheduler instance */ Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Mon Jan 11 17:58:15 2010 (r202095) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Mon Jan 11 18:08:39 2010 (r202096) @@ -134,7 +134,8 @@ destroy_si(struct new_sch_inst *si) struct delay_line *dl = &si->dline; struct new_queue *q; - if (si->oid.id >= 0) /* is in the heap */ + /* XXX below we use oid.id as a marker of presence in the sysheap */ + if (si->ni.oid.id >= 0) /* is in the heap */ heap_extract(&dn_cfg.system_heap, si); if (s->fp->free_sched) s->fp->free_sched(si); @@ -298,19 +299,22 @@ copy_data(char **start, char *end, int f struct new_schk *s; SLIST_FOREACH(s, &dn_cfg.schedhash[i], next) { if (flags & DN_C_PIPE) { - printf("copy pipe %d len %d\n", - s->pipe.pipe_nr, s->pipe.oid.len); if (copy_obj(start, end, &s->pipe)) return 1; } if (flags & DN_C_SCH) { - printf("copy sched %d\n", s->sch.sched_nr); if (copy_obj(start, end, &s->sch)) return 1; } if (flags & DN_C_SCH_INST) { - printf("copy shc_inst %d\n", s->sch.sched_nr); - /* scan the hashtable */ + int j; + struct new_sch_inst *si; + for (j = 0; j < s->ht_slots; j++) { + SLIST_FOREACH(si, &s->ht[j], next) { + if (copy_obj(start, end, &si->ni)) + return 1; + } + } } } } @@ -756,9 +760,10 @@ dummynet_get(struct sockopt *sopt) default: return EINVAL; case DN_SCH: /* pipe show */ - to_copy = DN_C_SCH | DN_C_PIPE; + to_copy = DN_C_SCH | DN_C_PIPE | DN_C_SCH_INST; need = dn_cfg.schk_count * (sizeof(struct new_sch) + sizeof(struct new_pipe)); + need += dn_cfg.si_count * sizeof(struct new_inst); break; case DN_FS: /* queue show */ to_copy = DN_C_FS; From owner-svn-src-user@FreeBSD.ORG Mon Jan 11 18:35:59 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 2EC07106568D; Mon, 11 Jan 2010 18:35:59 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 1DFA48FC16; Mon, 11 Jan 2010 18:35:59 +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 o0BIZxYF042014; Mon, 11 Jan 2010 18:35:59 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0BIZw2n042010; Mon, 11 Jan 2010 18:35:58 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201001111835.o0BIZw2n042010@svn.freebsd.org> From: Ed Schouten Date: Mon, 11 Jan 2010 18:35:58 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202098 - in user/ed/utmpx: bin/csh contrib/tcsh X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Jan 2010 18:35:59 -0000 Author: ed Date: Mon Jan 11 18:35:58 2010 New Revision: 202098 URL: http://svn.freebsd.org/changeset/base/202098 Log: Make utmpx work with csh without modifying anything in contrib/tcsh. Eventually we should get rid of UTMPX_FILE, because maybe in the very far future we have some kind of high-tech logging daemon -- who knows. For now, just set UTMPX_FILE to the file our implementation uses. Discussed with: mp Modified: user/ed/utmpx/bin/csh/config.h user/ed/utmpx/bin/csh/config_p.h user/ed/utmpx/contrib/tcsh/tc.who.c Modified: user/ed/utmpx/bin/csh/config.h ============================================================================== --- user/ed/utmpx/bin/csh/config.h Mon Jan 11 18:10:13 2010 (r202097) +++ user/ed/utmpx/bin/csh/config.h Mon Jan 11 18:35:58 2010 (r202098) @@ -54,7 +54,7 @@ #define HAVE_GETPWENT 1 /* Define to 1 if you have the `getutent' function. */ -/* #undef HAVE_GETUTENT */ +#define HAVE_GETUTENT 1 /* Define if you have the iconv() function. */ /* #undef HAVE_ICONV */ Modified: user/ed/utmpx/bin/csh/config_p.h ============================================================================== --- user/ed/utmpx/bin/csh/config_p.h Mon Jan 11 18:10:13 2010 (r202097) +++ user/ed/utmpx/bin/csh/config_p.h Mon Jan 11 18:35:58 2010 (r202098) @@ -110,4 +110,6 @@ # define NLS_CATALOGS #endif +#define UTMPX_FILE "/var/run/utx.active" + #endif /* _h_config */ Modified: user/ed/utmpx/contrib/tcsh/tc.who.c ============================================================================== --- user/ed/utmpx/contrib/tcsh/tc.who.c Mon Jan 11 18:10:13 2010 (r202097) +++ user/ed/utmpx/contrib/tcsh/tc.who.c Mon Jan 11 18:35:58 2010 (r202098) @@ -55,8 +55,6 @@ RCSID("$tcsh: tc.who.c,v 3.51 2006/03/03 # define TCSH_PATH_UTMP _PATH_UTMPX # elif defined(UTMPX_FILE) # define TCSH_PATH_UTMP UTMPX_FILE -# else -# define TCSH_PATH_UTMP "/nonexistent" # endif /* __UTMPX_FILE && !UTMPX_FILE */ # ifdef TCSH_PATH_UTMP # define utmp utmpx From owner-svn-src-user@FreeBSD.ORG Mon Jan 11 18:39:11 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 819E7106566C; Mon, 11 Jan 2010 18:39:11 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 70C698FC15; Mon, 11 Jan 2010 18:39:11 +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 o0BIdBTm042775; Mon, 11 Jan 2010 18:39:11 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0BIdBLD042772; Mon, 11 Jan 2010 18:39:11 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201001111839.o0BIdBLD042772@svn.freebsd.org> From: Ed Schouten Date: Mon, 11 Jan 2010 18:39:11 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202099 - in user/ed/utmpx: include lib/libc/gen X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Jan 2010 18:39:11 -0000 Author: ed Date: Mon Jan 11 18:39:11 2010 New Revision: 202099 URL: http://svn.freebsd.org/changeset/base/202099 Log: Reduce ut_line to 16. After some thinking I realized 32 bytes here is just a waste of space. Modified: user/ed/utmpx/include/utmpx.h user/ed/utmpx/lib/libc/gen/utxdb.h Modified: user/ed/utmpx/include/utmpx.h ============================================================================== --- user/ed/utmpx/include/utmpx.h Mon Jan 11 18:35:58 2010 (r202098) +++ user/ed/utmpx/include/utmpx.h Mon Jan 11 18:39:11 2010 (r202099) @@ -44,7 +44,7 @@ struct utmpx { char ut_id[8]; /* Record identifier. */ pid_t ut_pid; /* Process ID. */ char ut_user[32]; /* User login name. */ - char ut_line[32]; /* Device name. */ + char ut_line[16]; /* Device name. */ #if __BSD_VISIBLE char ut_host[128]; /* Remote hostname. */ #else Modified: user/ed/utmpx/lib/libc/gen/utxdb.h ============================================================================== --- user/ed/utmpx/lib/libc/gen/utxdb.h Mon Jan 11 18:35:58 2010 (r202098) +++ user/ed/utmpx/lib/libc/gen/utxdb.h Mon Jan 11 18:39:11 2010 (r202099) @@ -51,7 +51,7 @@ struct futx { char fu_id[8]; uint32_t fu_pid; char fu_user[32]; - char fu_line[32]; + char fu_line[16]; char fu_host[128]; } __packed; From owner-svn-src-user@FreeBSD.ORG Mon Jan 11 18:48:46 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 71F66106568F; Mon, 11 Jan 2010 18:48:46 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 5C9D88FC26; Mon, 11 Jan 2010 18:48:46 +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 o0BImkdA045034; Mon, 11 Jan 2010 18:48:46 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0BImjbE044998; Mon, 11 Jan 2010 18:48:45 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201001111848.o0BImjbE044998@svn.freebsd.org> From: Ed Schouten Date: Mon, 11 Jan 2010 18:48:45 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202102 - in user/ed/utmpx: . contrib/opie/libopie lib/libc/stdio lib/libusb share/man/man5 sys/amd64/amd64 sys/amd64/conf sys/amd64/include sys/conf sys/dev/ae sys/dev/ahci sys/dev/cfe... X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Jan 2010 18:48:46 -0000 Author: ed Date: Mon Jan 11 18:48:45 2010 New Revision: 202102 URL: http://svn.freebsd.org/changeset/base/202102 Log: Merge HEAD to remove conflicts. This should be the final merge before importing it into HEAD. Added: user/ed/utmpx/sys/dev/cfe/cfe_env.c - copied unchanged from r202100, head/sys/dev/cfe/cfe_env.c user/ed/utmpx/sys/dev/siba/siba_cc.c - copied unchanged from r202100, head/sys/dev/siba/siba_cc.c user/ed/utmpx/sys/ia64/ia64/iodev_machdep.c - copied unchanged from r202100, head/sys/ia64/ia64/iodev_machdep.c user/ed/utmpx/sys/ia64/include/iodev.h - copied unchanged from r202100, head/sys/ia64/include/iodev.h - copied from r202100, head/sys/mips/alchemy/ user/ed/utmpx/sys/mips/conf/ALCHEMY - copied unchanged from r202100, head/sys/mips/conf/ALCHEMY user/ed/utmpx/sys/mips/include/cdefs.h - copied unchanged from r202100, head/sys/mips/include/cdefs.h user/ed/utmpx/sys/mips/include/fls64.h - copied unchanged from r202100, head/sys/mips/include/fls64.h user/ed/utmpx/sys/mips/mips/bus_space_generic.c - copied unchanged from r202100, head/sys/mips/mips/bus_space_generic.c user/ed/utmpx/sys/mips/mips/elf_trampoline.c - copied unchanged from r202100, head/sys/mips/mips/elf_trampoline.c user/ed/utmpx/sys/mips/mips/inckern.S - copied unchanged from r202100, head/sys/mips/mips/inckern.S user/ed/utmpx/sys/mips/mips/sys_machdep.c - copied unchanged from r202100, head/sys/mips/mips/sys_machdep.c user/ed/utmpx/sys/modules/epic/ - copied from r202100, head/sys/modules/epic/ user/ed/utmpx/sys/sparc64/ebus/epic.c - copied unchanged from r202100, head/sys/sparc64/ebus/epic.c Directory Properties: user/ed/utmpx/sys/mips/alchemy/ (props changed) Deleted: user/ed/utmpx/sys/mips/include/bus_octeon.h user/ed/utmpx/sys/mips/include/intr.h user/ed/utmpx/sys/mips/include/pltfm.h Modified: user/ed/utmpx/Makefile user/ed/utmpx/contrib/opie/libopie/login.c user/ed/utmpx/lib/libc/stdio/fread.c user/ed/utmpx/lib/libc/stdio/fwrite.c user/ed/utmpx/lib/libusb/libusb20.c user/ed/utmpx/share/man/man5/devfs.rules.5 user/ed/utmpx/sys/amd64/amd64/io.c user/ed/utmpx/sys/amd64/amd64/mp_machdep.c user/ed/utmpx/sys/amd64/amd64/pmap.c user/ed/utmpx/sys/amd64/conf/GENERIC user/ed/utmpx/sys/amd64/include/iodev.h user/ed/utmpx/sys/conf/files.ia64 user/ed/utmpx/sys/conf/files.sparc64 user/ed/utmpx/sys/dev/ae/if_ae.c user/ed/utmpx/sys/dev/ahci/ahci.c user/ed/utmpx/sys/dev/cfe/cfe_api.c user/ed/utmpx/sys/dev/ic/ns16550.h user/ed/utmpx/sys/dev/io/iodev.c user/ed/utmpx/sys/dev/usb/serial/u3g.c user/ed/utmpx/sys/dev/usb/usbdevs user/ed/utmpx/sys/i386/conf/GENERIC user/ed/utmpx/sys/i386/i386/io.c user/ed/utmpx/sys/i386/i386/locore.s user/ed/utmpx/sys/i386/i386/pmap.c user/ed/utmpx/sys/i386/include/iodev.h user/ed/utmpx/sys/i386/xen/mp_machdep.c user/ed/utmpx/sys/i386/xen/xen_machdep.c user/ed/utmpx/sys/ia64/conf/DEFAULTS user/ed/utmpx/sys/ia64/conf/GENERIC user/ed/utmpx/sys/ia64/ia64/sys_machdep.c user/ed/utmpx/sys/ia64/include/sysarch.h user/ed/utmpx/sys/kern/kern_environment.c user/ed/utmpx/sys/mips/adm5120/adm5120_machdep.c user/ed/utmpx/sys/mips/adm5120/files.adm5120 user/ed/utmpx/sys/mips/adm5120/if_admsw.c user/ed/utmpx/sys/mips/adm5120/obio.c user/ed/utmpx/sys/mips/adm5120/uart_cpu_adm5120.c user/ed/utmpx/sys/mips/cavium/dev/rgmii/octeon_fau.c user/ed/utmpx/sys/mips/cavium/dev/rgmii/octeon_fpa.c user/ed/utmpx/sys/mips/cavium/dev/rgmii/octeon_ipd.c user/ed/utmpx/sys/mips/cavium/dev/rgmii/octeon_pko.c user/ed/utmpx/sys/mips/cavium/dev/rgmii/octeon_rgmx.c user/ed/utmpx/sys/mips/cavium/files.octeon1 (contents, props changed) user/ed/utmpx/sys/mips/cavium/obio.c user/ed/utmpx/sys/mips/cavium/octeon_ebt3000_cf.c user/ed/utmpx/sys/mips/cavium/octeon_machdep.c user/ed/utmpx/sys/mips/cavium/std.octeon1 (contents, props changed) user/ed/utmpx/sys/mips/cavium/uart_bus_octeonusart.c user/ed/utmpx/sys/mips/cavium/uart_cpu_octeonusart.c user/ed/utmpx/sys/mips/cavium/uart_dev_oct16550.c user/ed/utmpx/sys/mips/conf/MALTA user/ed/utmpx/sys/mips/conf/OCTEON1 (contents, props changed) user/ed/utmpx/sys/mips/conf/OCTEON1-32 (contents, props changed) user/ed/utmpx/sys/mips/conf/SENTRY5 user/ed/utmpx/sys/mips/idt/files.idt user/ed/utmpx/sys/mips/idt/idt_machdep.c user/ed/utmpx/sys/mips/idt/obio.c user/ed/utmpx/sys/mips/idt/uart_bus_rc32434.c user/ed/utmpx/sys/mips/idt/uart_cpu_rc32434.c user/ed/utmpx/sys/mips/include/_align.h user/ed/utmpx/sys/mips/include/_bus.h user/ed/utmpx/sys/mips/include/_types.h user/ed/utmpx/sys/mips/include/asm.h user/ed/utmpx/sys/mips/include/atomic.h user/ed/utmpx/sys/mips/include/bus.h user/ed/utmpx/sys/mips/include/cache.h user/ed/utmpx/sys/mips/include/cache_mipsNN.h user/ed/utmpx/sys/mips/include/cpu.h user/ed/utmpx/sys/mips/include/cpufunc.h user/ed/utmpx/sys/mips/include/cpuinfo.h user/ed/utmpx/sys/mips/include/cpuregs.h user/ed/utmpx/sys/mips/include/db_machdep.h user/ed/utmpx/sys/mips/include/elf.h user/ed/utmpx/sys/mips/include/endian.h user/ed/utmpx/sys/mips/include/float.h user/ed/utmpx/sys/mips/include/hwfunc.h user/ed/utmpx/sys/mips/include/intr_machdep.h user/ed/utmpx/sys/mips/include/kdb.h user/ed/utmpx/sys/mips/include/locore.h user/ed/utmpx/sys/mips/include/md_var.h user/ed/utmpx/sys/mips/include/param.h user/ed/utmpx/sys/mips/include/pcb.h user/ed/utmpx/sys/mips/include/pmap.h user/ed/utmpx/sys/mips/include/proc.h user/ed/utmpx/sys/mips/include/profile.h user/ed/utmpx/sys/mips/include/psl.h user/ed/utmpx/sys/mips/include/pte.h user/ed/utmpx/sys/mips/include/regdef.h user/ed/utmpx/sys/mips/include/regnum.h user/ed/utmpx/sys/mips/include/trap.h user/ed/utmpx/sys/mips/include/ucontext.h user/ed/utmpx/sys/mips/malta/files.malta user/ed/utmpx/sys/mips/malta/gt_pci.c user/ed/utmpx/sys/mips/malta/malta_machdep.c user/ed/utmpx/sys/mips/malta/maltareg.h user/ed/utmpx/sys/mips/malta/obio.c user/ed/utmpx/sys/mips/malta/std.malta user/ed/utmpx/sys/mips/malta/uart_bus_maltausart.c user/ed/utmpx/sys/mips/malta/uart_cpu_maltausart.c user/ed/utmpx/sys/mips/malta/yamon.h user/ed/utmpx/sys/mips/mips/busdma_machdep.c user/ed/utmpx/sys/mips/mips/cache.c user/ed/utmpx/sys/mips/mips/cache_mipsNN.c user/ed/utmpx/sys/mips/mips/copystr.S user/ed/utmpx/sys/mips/mips/cpu.c user/ed/utmpx/sys/mips/mips/db_trace.c user/ed/utmpx/sys/mips/mips/elf_machdep.c user/ed/utmpx/sys/mips/mips/exception.S user/ed/utmpx/sys/mips/mips/fp.S user/ed/utmpx/sys/mips/mips/gdb_machdep.c user/ed/utmpx/sys/mips/mips/genassym.c user/ed/utmpx/sys/mips/mips/in_cksum.c user/ed/utmpx/sys/mips/mips/intr_machdep.c user/ed/utmpx/sys/mips/mips/locore.S user/ed/utmpx/sys/mips/mips/machdep.c user/ed/utmpx/sys/mips/mips/mainbus.c user/ed/utmpx/sys/mips/mips/mem.c user/ed/utmpx/sys/mips/mips/nexus.c user/ed/utmpx/sys/mips/mips/pm_machdep.c user/ed/utmpx/sys/mips/mips/pmap.c user/ed/utmpx/sys/mips/mips/psraccess.S user/ed/utmpx/sys/mips/mips/support.S user/ed/utmpx/sys/mips/mips/swtch.S user/ed/utmpx/sys/mips/mips/tick.c user/ed/utmpx/sys/mips/mips/tlb.S user/ed/utmpx/sys/mips/mips/trap.c user/ed/utmpx/sys/mips/mips/vm_machdep.c user/ed/utmpx/sys/mips/rmi/dev/sec/rmilib.c (contents, props changed) user/ed/utmpx/sys/mips/rmi/dev/sec/rmilib.h (contents, props changed) user/ed/utmpx/sys/mips/rmi/dev/sec/rmisec.c (contents, props changed) user/ed/utmpx/sys/mips/rmi/dev/xlr/rge.c (contents, props changed) user/ed/utmpx/sys/mips/rmi/files.xlr (contents, props changed) user/ed/utmpx/sys/mips/rmi/iodi.c (contents, props changed) user/ed/utmpx/sys/mips/sentry5/files.sentry5 user/ed/utmpx/sys/mips/sentry5/obio.c user/ed/utmpx/sys/mips/sentry5/s5_machdep.c user/ed/utmpx/sys/mips/sentry5/uart_bus_sbusart.c user/ed/utmpx/sys/mips/sentry5/uart_cpu_sbusart.c user/ed/utmpx/sys/mips/sibyte/sb_zbbus.c user/ed/utmpx/sys/mips/sibyte/sb_zbpci.c user/ed/utmpx/sys/modules/Makefile user/ed/utmpx/sys/pc98/conf/GENERIC user/ed/utmpx/sys/powerpc/conf/GENERIC user/ed/utmpx/sys/sparc64/conf/GENERIC user/ed/utmpx/sys/sparc64/pci/fire.c user/ed/utmpx/sys/sun4v/conf/GENERIC user/ed/utmpx/sys/sys/systm.h user/ed/utmpx/usr.bin/lastcomm/lastcomm.c user/ed/utmpx/usr.bin/make/job.c user/ed/utmpx/usr.bin/netstat/if.c user/ed/utmpx/usr.bin/netstat/main.c user/ed/utmpx/usr.bin/netstat/netstat.1 user/ed/utmpx/usr.bin/netstat/netstat.h user/ed/utmpx/usr.sbin/usbconfig/usbconfig.c Directory Properties: user/ed/utmpx/ (props changed) user/ed/utmpx/contrib/one-true-awk/ (props changed) user/ed/utmpx/sys/conf/ldscript.mips.mips64 (props changed) user/ed/utmpx/sys/conf/ldscript.mips.octeon1.32 (props changed) user/ed/utmpx/sys/conf/ldscript.mips.octeon1.64 (props changed) user/ed/utmpx/sys/conf/ldscript.mips.octeon1.n32 (props changed) user/ed/utmpx/sys/dev/flash/mx25l.c (props changed) user/ed/utmpx/sys/dev/flash/mx25lreg.h (props changed) user/ed/utmpx/sys/dev/siba/siba/ (props changed) user/ed/utmpx/sys/mips/atheros/ (props changed) user/ed/utmpx/sys/mips/cavium/ (props changed) user/ed/utmpx/sys/mips/conf/AR71XX (props changed) user/ed/utmpx/sys/mips/conf/AR71XX.hints (props changed) user/ed/utmpx/sys/mips/conf/MALTA64 (props changed) user/ed/utmpx/sys/mips/conf/OCTEON1.hints (props changed) user/ed/utmpx/sys/mips/conf/SWARM (props changed) user/ed/utmpx/sys/mips/conf/SWARM.hints (props changed) user/ed/utmpx/sys/mips/conf/XLR (props changed) user/ed/utmpx/sys/mips/mips/ptrace_machdep.c (props changed) user/ed/utmpx/sys/mips/rmi/ (props changed) user/ed/utmpx/sys/mips/rmi/Makefile.msgring (props changed) user/ed/utmpx/sys/mips/rmi/board.c (props changed) user/ed/utmpx/sys/mips/rmi/board.h (props changed) user/ed/utmpx/sys/mips/rmi/bus_space_rmi.c (props changed) user/ed/utmpx/sys/mips/rmi/clock.c (props changed) user/ed/utmpx/sys/mips/rmi/clock.h (props changed) user/ed/utmpx/sys/mips/rmi/debug.h (props changed) user/ed/utmpx/sys/mips/rmi/dev/ (props changed) user/ed/utmpx/sys/mips/rmi/dev/sec/desc.h (props changed) user/ed/utmpx/sys/mips/rmi/dev/sec/stats.h (props changed) user/ed/utmpx/sys/mips/rmi/dev/xlr/atx_cpld.h (props changed) user/ed/utmpx/sys/mips/rmi/dev/xlr/rge.h (props changed) user/ed/utmpx/sys/mips/rmi/dev/xlr/xgmac_mdio.h (props changed) user/ed/utmpx/sys/mips/sibyte/ (props changed) Modified: user/ed/utmpx/Makefile ============================================================================== --- user/ed/utmpx/Makefile Mon Jan 11 18:44:41 2010 (r202101) +++ user/ed/utmpx/Makefile Mon Jan 11 18:48:45 2010 (r202102) @@ -321,8 +321,9 @@ universe_${target}: @echo ">> ${target} completed on `LC_ALL=C date`" .endfor universe_kernels: universe_kernconfs -XMACHINE!= uname -m -TARGET?= ${XMACHINE} +.if !defined(TARGET) +TARGET!= uname -m +.endif KERNCONFS!= cd ${.CURDIR}/sys/${TARGET}/conf && \ find [A-Z0-9]*[A-Z0-9] -type f -maxdepth 0 \ ! -name DEFAULTS ! -name NOTES Modified: user/ed/utmpx/contrib/opie/libopie/login.c ============================================================================== --- user/ed/utmpx/contrib/opie/libopie/login.c Mon Jan 11 18:44:41 2010 (r202101) +++ user/ed/utmpx/contrib/opie/libopie/login.c Mon Jan 11 18:48:45 2010 (r202102) @@ -21,13 +21,14 @@ you didn't get a copy, you may request o #include "opie_cfg.h" #include #include -#include #if DOUTMPX #include #define pututline(x) pututxline(x) #define endutent endutxent #define utmp utmpx +#else +#include #endif /* DOUTMPX */ #if HAVE_STRING_H Modified: user/ed/utmpx/lib/libc/stdio/fread.c ============================================================================== --- user/ed/utmpx/lib/libc/stdio/fread.c Mon Jan 11 18:44:41 2010 (r202101) +++ user/ed/utmpx/lib/libc/stdio/fread.c Mon Jan 11 18:48:45 2010 (r202102) @@ -37,6 +37,8 @@ static char sccsid[] = "@(#)fread.c 8.2 __FBSDID("$FreeBSD$"); #include "namespace.h" +#include +#include #include #include #include "un-namespace.h" @@ -69,8 +71,27 @@ __fread(void * __restrict buf, size_t si /* * ANSI and SUSv2 require a return value of 0 if size or count are 0. */ - if ((resid = count * size) == 0) + if ((count == 0) || (size == 0)) return (0); + + /* + * Check for integer overflow. As an optimization, first check that + * at least one of {count, size} is at least 2^16, since if both + * values are less than that, their product can't possible overflow + * (size_t is always at least 32 bits on FreeBSD). + */ + if (((count | size) > 0xFFFF) && + (count > SIZE_MAX / size)) { + errno = EINVAL; + fp->_flags |= __SERR; + return (0); + } + + /* + * Compute the (now required to not overflow) number of bytes to + * read and actually do the work. + */ + resid = count * size; ORIENT(fp, -1); if (fp->_r < 0) fp->_r = 0; Modified: user/ed/utmpx/lib/libc/stdio/fwrite.c ============================================================================== --- user/ed/utmpx/lib/libc/stdio/fwrite.c Mon Jan 11 18:44:41 2010 (r202101) +++ user/ed/utmpx/lib/libc/stdio/fwrite.c Mon Jan 11 18:48:45 2010 (r202102) @@ -37,6 +37,8 @@ static char sccsid[] = "@(#)fwrite.c 8.1 __FBSDID("$FreeBSD$"); #include "namespace.h" +#include +#include #include #include "un-namespace.h" #include "local.h" @@ -60,10 +62,24 @@ fwrite(buf, size, count, fp) /* * ANSI and SUSv2 require a return value of 0 if size or count are 0. */ - n = count * size; - if (n == 0) + if ((count == 0) || (size == 0)) return (0); + /* + * Check for integer overflow. As an optimization, first check that + * at least one of {count, size} is at least 2^16, since if both + * values are less than that, their product can't possible overflow + * (size_t is always at least 32 bits on FreeBSD). + */ + if (((count | size) > 0xFFFF) && + (count > SIZE_MAX / size)) { + errno = EINVAL; + fp->_flags |= __SERR; + return (0); + } + + n = count * size; + iov.iov_base = (void *)buf; uio.uio_resid = iov.iov_len = n; uio.uio_iov = &iov; Modified: user/ed/utmpx/lib/libusb/libusb20.c ============================================================================== --- user/ed/utmpx/lib/libusb/libusb20.c Mon Jan 11 18:44:41 2010 (r202101) +++ user/ed/utmpx/lib/libusb/libusb20.c Mon Jan 11 18:48:45 2010 (r202102) @@ -130,8 +130,19 @@ libusb20_tr_close(struct libusb20_transf if (xfer->ppBuffer) { free(xfer->ppBuffer); } - /* clear some fields */ + /* reset variable fields in case the transfer is opened again */ + xfer->priv_sc0 = 0; + xfer->priv_sc1 = 0; xfer->is_opened = 0; + xfer->is_pending = 0; + xfer->is_cancel = 0; + xfer->is_draining = 0; + xfer->is_restart = 0; + xfer->status = 0; + xfer->flags = 0; + xfer->nFrames = 0; + xfer->aFrames = 0; + xfer->timeout = 0; xfer->maxFrames = 0; xfer->maxTotalLength = 0; xfer->maxPacketLen = 0; Modified: user/ed/utmpx/share/man/man5/devfs.rules.5 ============================================================================== --- user/ed/utmpx/share/man/man5/devfs.rules.5 Mon Jan 11 18:44:41 2010 (r202101) +++ user/ed/utmpx/share/man/man5/devfs.rules.5 Mon Jan 11 18:48:45 2010 (r202102) @@ -100,13 +100,15 @@ The first line declares and starts a new .Va localrules and the number 10. .Pp -To make all the -.Xr ulpt 4 -devices accessible to their owner and the +To give +.Xr usbconfig 8 +and +.Xr libusb 3 +enabled applications permission to all usb devices for their owner and the .Dq Li usb group, a similar rule may be used: .Pp -.Dl "add path 'ulpt*' mode 0660 group usb" +.Dl "add path 'usb/*' mode 0660 group usb" .Sh SEE ALSO .Xr glob 3 , .Xr devfs 5 , Modified: user/ed/utmpx/sys/amd64/amd64/io.c ============================================================================== --- user/ed/utmpx/sys/amd64/amd64/io.c Mon Jan 11 18:44:41 2010 (r202101) +++ user/ed/utmpx/sys/amd64/amd64/io.c Mon Jan 11 18:48:45 2010 (r202102) @@ -76,3 +76,12 @@ ioclose(struct cdev *dev __unused, int f return (0); } + +/* ARGSUSED */ +int +ioioctl(struct cdev *dev __unused, u_long cmd __unused, caddr_t data __unused, + int fflag __unused, struct thread *td __unused) +{ + + return (ENXIO); +} Modified: user/ed/utmpx/sys/amd64/amd64/mp_machdep.c ============================================================================== --- user/ed/utmpx/sys/amd64/amd64/mp_machdep.c Mon Jan 11 18:44:41 2010 (r202101) +++ user/ed/utmpx/sys/amd64/amd64/mp_machdep.c Mon Jan 11 18:48:45 2010 (r202102) @@ -98,12 +98,6 @@ char *doublefault_stack; char *nmi_stack; void *dpcpu; -/* Hotwire a 0->4MB V==P mapping */ -extern pt_entry_t *KPTphys; - -/* SMP page table page */ -extern pt_entry_t *SMPpt; - struct pcb stoppcbs[MAXCPU]; struct xpcb **stopxpcbs = NULL; Modified: user/ed/utmpx/sys/amd64/amd64/pmap.c ============================================================================== --- user/ed/utmpx/sys/amd64/amd64/pmap.c Mon Jan 11 18:44:41 2010 (r202101) +++ user/ed/utmpx/sys/amd64/amd64/pmap.c Mon Jan 11 18:48:45 2010 (r202102) @@ -664,7 +664,6 @@ pmap_page_init(vm_page_t m) void pmap_init(void) { - pd_entry_t *pd; vm_page_t mpte; vm_size_t s; int i, pv_npg; @@ -673,18 +672,13 @@ pmap_init(void) * Initialize the vm page array entries for the kernel pmap's * page table pages. */ - pd = pmap_pde(kernel_pmap, KERNBASE); for (i = 0; i < NKPT; i++) { - if ((pd[i] & (PG_PS | PG_V)) == (PG_PS | PG_V)) - continue; - KASSERT((pd[i] & PG_V) != 0, - ("pmap_init: page table page is missing")); - mpte = PHYS_TO_VM_PAGE(pd[i] & PG_FRAME); + mpte = PHYS_TO_VM_PAGE(KPTphys + (i << PAGE_SHIFT)); KASSERT(mpte >= vm_page_array && mpte < &vm_page_array[vm_page_array_size], ("pmap_init: page table page is out of range")); mpte->pindex = pmap_pde_pindex(KERNBASE) + i; - mpte->phys_addr = pd[i] & PG_FRAME; + mpte->phys_addr = KPTphys + (i << PAGE_SHIFT); } /* Modified: user/ed/utmpx/sys/amd64/conf/GENERIC ============================================================================== --- user/ed/utmpx/sys/amd64/conf/GENERIC Mon Jan 11 18:44:41 2010 (r202101) +++ user/ed/utmpx/sys/amd64/conf/GENERIC Mon Jan 11 18:48:45 2010 (r202102) @@ -75,6 +75,7 @@ options MAC # TrustedBSD MAC Framewor options FLOWTABLE # per-cpu routing cache #options KDTRACE_FRAME # Ensure frames are compiled in #options KDTRACE_HOOKS # Kernel DTrace hooks +options INCLUDE_CONFIG_FILE # Include this file in kernel # Debugging for use in -current options KDB # Enable kernel debugger support. Modified: user/ed/utmpx/sys/amd64/include/iodev.h ============================================================================== --- user/ed/utmpx/sys/amd64/include/iodev.h Mon Jan 11 18:44:41 2010 (r202101) +++ user/ed/utmpx/sys/amd64/include/iodev.h Mon Jan 11 18:48:45 2010 (r202102) @@ -28,3 +28,4 @@ d_open_t ioopen; d_close_t ioclose; +d_ioctl_t ioioctl; Modified: user/ed/utmpx/sys/conf/files.ia64 ============================================================================== --- user/ed/utmpx/sys/conf/files.ia64 Mon Jan 11 18:44:41 2010 (r202101) +++ user/ed/utmpx/sys/conf/files.ia64 Mon Jan 11 18:48:45 2010 (r202102) @@ -54,6 +54,7 @@ dev/atkbdc/psm.c optional psm atkbdc dev/fb/fb.c optional fb | vga dev/fb/vga.c optional vga dev/hwpmc/hwpmc_ia64.c optional hwpmc +dev/io/iodev.c optional io dev/kbd/kbd.c optional atkbd | sc | ukbd | usb2_input_kbd dev/syscons/scterm-teken.c optional sc dev/syscons/scvgarndr.c optional sc vga @@ -86,6 +87,7 @@ ia64/ia64/gdb_machdep.c optional gdb ia64/ia64/highfp.c standard ia64/ia64/in_cksum.c optional inet ia64/ia64/interrupt.c standard +ia64/ia64/iodev_machdep.c optional io ia64/ia64/locore.S standard no-obj ia64/ia64/machdep.c standard ia64/ia64/mca.c standard Modified: user/ed/utmpx/sys/conf/files.sparc64 ============================================================================== --- user/ed/utmpx/sys/conf/files.sparc64 Mon Jan 11 18:44:41 2010 (r202101) +++ user/ed/utmpx/sys/conf/files.sparc64 Mon Jan 11 18:48:45 2010 (r202102) @@ -67,12 +67,14 @@ libkern/flsl.c standard libkern/memmove.c standard sparc64/central/central.c optional central sparc64/ebus/ebus.c optional ebus +sparc64/ebus/epic.c optional epic ebus sparc64/fhc/clkbrd.c optional fhc sparc64/fhc/fhc.c optional fhc sparc64/isa/isa.c optional isa sparc64/isa/isa_dma.c optional isa sparc64/isa/ofw_isa.c optional ebus | isa sparc64/pci/apb.c optional pci +sparc64/pci/fire.c optional pci sparc64/pci/ofw_pcib.c optional pci sparc64/pci/ofw_pcib_subr.c optional pci sparc64/pci/ofw_pcibus.c optional pci Modified: user/ed/utmpx/sys/dev/ae/if_ae.c ============================================================================== --- user/ed/utmpx/sys/dev/ae/if_ae.c Mon Jan 11 18:44:41 2010 (r202101) +++ user/ed/utmpx/sys/dev/ae/if_ae.c Mon Jan 11 18:48:45 2010 (r202102) @@ -367,6 +367,7 @@ ae_attach(device_t dev) if (ifp == NULL) { device_printf(dev, "could not allocate ifnet structure.\n"); error = ENXIO; + goto fail; } ifp->if_softc = sc; Modified: user/ed/utmpx/sys/dev/ahci/ahci.c ============================================================================== --- user/ed/utmpx/sys/dev/ahci/ahci.c Mon Jan 11 18:44:41 2010 (r202101) +++ user/ed/utmpx/sys/dev/ahci/ahci.c Mon Jan 11 18:48:45 2010 (r202102) @@ -570,6 +570,12 @@ ahci_setup_interrupt(device_t dev) device_printf(dev, "unable to setup interrupt\n"); return ENXIO; } + if (ctlr->numirqs > 1) { + bus_describe_intr(dev, ctlr->irqs[i].r_irq, + ctlr->irqs[i].handle, + ctlr->irqs[i].mode == AHCI_IRQ_MODE_ONE ? + "ch%d" : "%d", i); + } } return (0); } @@ -622,8 +628,14 @@ ahci_intr_one(void *data) int unit; unit = irq->r_irq_rid - 1; + /* Some controllers have edge triggered IS. */ + if (ctlr->quirks & AHCI_Q_EDGEIS) + ATA_OUTL(ctlr->r_mem, AHCI_IS, 1 << unit); if ((arg = ctlr->interrupt[unit].argument)) ctlr->interrupt[unit].function(arg); + /* AHCI declares level triggered IS. */ + if (!(ctlr->quirks & AHCI_Q_EDGEIS)) + ATA_OUTL(ctlr->r_mem, AHCI_IS, 1 << unit); } static struct resource * Modified: user/ed/utmpx/sys/dev/cfe/cfe_api.c ============================================================================== --- user/ed/utmpx/sys/dev/cfe/cfe_api.c Mon Jan 11 18:44:41 2010 (r202101) +++ user/ed/utmpx/sys/dev/cfe/cfe_api.c Mon Jan 11 18:48:45 2010 (r202102) @@ -160,7 +160,7 @@ cfe_enumenv(int idx, char *name, int nam { cfe_xiocb_t xiocb; - xiocb.xiocb_fcode = CFE_CMD_ENV_SET; + xiocb.xiocb_fcode = CFE_CMD_ENV_ENUM; xiocb.xiocb_status = 0; xiocb.xiocb_handle = 0; xiocb.xiocb_flags = 0; Copied: user/ed/utmpx/sys/dev/cfe/cfe_env.c (from r202100, head/sys/dev/cfe/cfe_env.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ user/ed/utmpx/sys/dev/cfe/cfe_env.c Mon Jan 11 18:48:45 2010 (r202102, copy of r202100, head/sys/dev/cfe/cfe_env.c) @@ -0,0 +1,74 @@ +/*- + * Copyright (c) 2009 Neelkanth Natu + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include + +#include + +__FBSDID("$FreeBSD$"); + +#ifndef CFE_ENV_SIZE +#define CFE_ENV_SIZE PAGE_SIZE /* default is one page */ +#endif + +extern void cfe_env_init(void); + +static char cfe_env_buf[CFE_ENV_SIZE]; + +void +cfe_env_init(void) +{ + int idx, len; + char name[64], val[128], *cp, *cplim; + + cp = cfe_env_buf; + cplim = cp + CFE_ENV_SIZE; + + idx = 0; + while (1) { + if (cfe_enumenv(idx, name, sizeof(name), val, sizeof(val)) != 0) + break; + + if (bootverbose) + printf("Importing CFE env: \"%s=%s\"\n", name, val); + + /* + * name=val\0\0 + */ + len = strlen(name) + 1 + strlen(val) + 1 + 1; + if (cplim - cp < len) + printf("No space to store CFE env: \"%s=%s\"\n", + name, val); + else + cp += sprintf(cp, "%s=%s", name, val) + 1; + ++idx; + } + *cp++ = '\0'; + + kern_envp = cfe_env_buf; +} Modified: user/ed/utmpx/sys/dev/ic/ns16550.h ============================================================================== --- user/ed/utmpx/sys/dev/ic/ns16550.h Mon Jan 11 18:44:41 2010 (r202101) +++ user/ed/utmpx/sys/dev/ic/ns16550.h Mon Jan 11 18:48:45 2010 (r202102) @@ -52,6 +52,7 @@ #define REG_IIR com_iir #define IIR_IMASK 0xf #define IIR_RXTOUT 0xc +#define IIR_BUSY 0x7 #define IIR_RLS 0x6 #define IIR_RXRDY 0x4 #define IIR_TXRDY 0x2 @@ -181,6 +182,10 @@ #define com_xoff1 6 /* XOFF 1 character (R/W) */ #define com_xoff2 7 /* XOFF 2 character (R/W) */ +#define com_usr 39 /* Octeon 16750/16550 Uart Status Reg */ +#define REG_USR com_usr +#define USR_TXFIFO_NOTFULL 2 /* Uart TX FIFO Not full */ + /* 16950 register #1. Access enabled by ACR[7]. Also requires !LCR[7]. */ #define com_asr 1 /* additional status register (R[0-7]/W[0-1]) */ Modified: user/ed/utmpx/sys/dev/io/iodev.c ============================================================================== --- user/ed/utmpx/sys/dev/io/iodev.c Mon Jan 11 18:44:41 2010 (r202101) +++ user/ed/utmpx/sys/dev/io/iodev.c Mon Jan 11 18:48:45 2010 (r202102) @@ -41,8 +41,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include - #include #include @@ -54,6 +52,7 @@ static struct cdevsw io_cdevsw = { .d_version = D_VERSION, .d_open = ioopen, .d_close = ioclose, + .d_ioctl = ioioctl, .d_name = "io", }; Copied: user/ed/utmpx/sys/dev/siba/siba_cc.c (from r202100, head/sys/dev/siba/siba_cc.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ user/ed/utmpx/sys/dev/siba/siba_cc.c Mon Jan 11 18:48:45 2010 (r202102, copy of r202100, head/sys/dev/siba/siba_cc.c) @@ -0,0 +1,154 @@ +/*- + * Copyright (c) 2007 Bruce M. Simpson. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Child driver for ChipCommon core. + * This is not MI code at the moment. + * Two 16C550 compatible UARTs live here. On the WGT634U, uart1 is the + * system console, and uart0 is not pinned out. + * Because their presence is conditional, they should probably + * be attached from here. + * GPIO lives here. + * The hardware watchdog lives here. + * Clock control registers live here. + * You don't need to read them to determine the clock speed on the 5365, + * which is always 200MHz and thus may be hardcoded (for now). + * Flash config registers live here. There may or may not be system flash. + * The external interface bus lives here (conditionally). + * There is a JTAG interface here which may be used to attach probes to + * the SoC for debugging. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +static int siba_cc_attach(device_t); +static int siba_cc_probe(device_t); +static void siba_cc_intr(void *v); + +static int +siba_cc_probe(device_t dev) +{ + + if (siba_get_vendor(dev) == SIBA_VID_BROADCOM && + siba_get_device(dev) == SIBA_DEVID_CHIPCOMMON) { + device_set_desc(dev, "ChipCommon core"); + return (BUS_PROBE_DEFAULT); + } + + return (ENXIO); +} + +struct siba_cc_softc { + void *notused; +}; + +static int +siba_cc_attach(device_t dev) +{ + //struct siba_cc_softc *sc = device_get_softc(dev); + struct resource *mem; + struct resource *irq; + int rid; + + /* + * Allocate the resources which the parent bus has already + * determined for us. + * TODO: interrupt routing + */ +#define MIPS_MEM_RID 0x20 + rid = MIPS_MEM_RID; + mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); + if (mem == NULL) { + device_printf(dev, "unable to allocate memory\n"); + return (ENXIO); + } + + rid = 0; + irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 0); + if (irq == NULL) { + device_printf(dev, "unable to allocate irq\n"); + return (ENXIO); + } + + /* now setup the interrupt */ + /* may be fast, exclusive or mpsafe at a later date */ + + /* + * XXX is this interrupt line in ChipCommon used for anything + * other than the uart? in that case we shouldn't hog it ourselves + * and let uart claim it to avoid polled mode. + */ + int err; + void *cookie; + err = bus_setup_intr(dev, irq, INTR_TYPE_TTY, NULL, siba_cc_intr, NULL, + &cookie); + if (err != 0) { + device_printf(dev, "unable to setup intr\n"); + return (ENXIO); + } + + /* TODO: attach uart child */ + + return (0); +} + +static void +siba_cc_intr(void *v) +{ + +} + +static device_method_t siba_cc_methods[] = { + /* Device interface */ + DEVMETHOD(device_attach, siba_cc_attach), + DEVMETHOD(device_probe, siba_cc_probe), + + {0, 0}, +}; + +static driver_t siba_cc_driver = { + "siba_cc", + siba_cc_methods, + sizeof(struct siba_softc), +}; +static devclass_t siba_cc_devclass; + +DRIVER_MODULE(siba_cc, siba, siba_cc_driver, siba_cc_devclass, 0, 0); Modified: user/ed/utmpx/sys/dev/usb/serial/u3g.c ============================================================================== --- user/ed/utmpx/sys/dev/usb/serial/u3g.c Mon Jan 11 18:44:41 2010 (r202101) +++ user/ed/utmpx/sys/dev/usb/serial/u3g.c Mon Jan 11 18:48:45 2010 (r202102) @@ -316,6 +316,7 @@ static const struct usb_device_id u3g_de U3G_DEV(OPTION, E7041, 0), U3G_DEV(OPTION, E7061, 0), U3G_DEV(OPTION, E7100, 0), + U3G_DEV(OPTION, GE40X, 0), U3G_DEV(OPTION, GT3G, 0), U3G_DEV(OPTION, GT3GPLUS, 0), U3G_DEV(OPTION, GT3GQUAD, 0), Modified: user/ed/utmpx/sys/dev/usb/usbdevs ============================================================================== --- user/ed/utmpx/sys/dev/usb/usbdevs Mon Jan 11 18:44:41 2010 (r202101) +++ user/ed/utmpx/sys/dev/usb/usbdevs Mon Jan 11 18:48:45 2010 (r202102) @@ -2099,6 +2099,7 @@ product OPTION E7041 0x7041 3G modem product OPTION E7061 0x7061 3G modem product OPTION E7100 0x7100 3G modem product OPTION GTM380 0x7201 3G modem +product OPTION GE40X 0x7601 Globetrotter HSUPA /* OQO */ product OQO WIFI01 0x0002 model 01 WiFi interface Modified: user/ed/utmpx/sys/i386/conf/GENERIC ============================================================================== --- user/ed/utmpx/sys/i386/conf/GENERIC Mon Jan 11 18:44:41 2010 (r202101) +++ user/ed/utmpx/sys/i386/conf/GENERIC Mon Jan 11 18:48:45 2010 (r202102) @@ -75,6 +75,7 @@ options AUDIT # Security event auditi options MAC # TrustedBSD MAC Framework options FLOWTABLE # per-cpu routing cache #options KDTRACE_HOOKS # Kernel DTrace hooks +options INCLUDE_CONFIG_FILE # Include this file in kernel # Debugging for use in -current options KDB # Enable kernel debugger support. Modified: user/ed/utmpx/sys/i386/i386/io.c ============================================================================== --- user/ed/utmpx/sys/i386/i386/io.c Mon Jan 11 18:44:41 2010 (r202101) +++ user/ed/utmpx/sys/i386/i386/io.c Mon Jan 11 18:48:45 2010 (r202102) @@ -76,3 +76,12 @@ ioclose(struct cdev *dev __unused, int f return (0); } + +/* ARGSUSED */ +int +ioioctl(struct cdev *dev __unused, u_long cmd __unused, caddr_t data __unused, + int fflag __unused, struct thread *td __unused) +{ + + return (ENXIO); +} Modified: user/ed/utmpx/sys/i386/i386/locore.s ============================================================================== --- user/ed/utmpx/sys/i386/i386/locore.s Mon Jan 11 18:44:41 2010 (r202101) +++ user/ed/utmpx/sys/i386/i386/locore.s Mon Jan 11 18:48:45 2010 (r202102) @@ -104,9 +104,7 @@ IdlePTD: .long 0 /* phys addr of kernel IdlePDPT: .long 0 /* phys addr of kernel PDPT */ #endif -#ifdef SMP .globl KPTphys -#endif KPTphys: .long 0 /* phys addr of kernel page tables */ .globl proc0kstack Modified: user/ed/utmpx/sys/i386/i386/pmap.c ============================================================================== --- user/ed/utmpx/sys/i386/i386/pmap.c Mon Jan 11 18:44:41 2010 (r202101) +++ user/ed/utmpx/sys/i386/i386/pmap.c Mon Jan 11 18:48:45 2010 (r202102) @@ -206,6 +206,7 @@ int pseflag = 0; /* PG_PS or-in */ static int nkpt; vm_offset_t kernel_vm_end; extern u_int32_t KERNend; +extern u_int32_t KPTphys; #ifdef PAE pt_entry_t pg_nx; @@ -659,13 +660,13 @@ pmap_init(void) * Initialize the vm page array entries for the kernel pmap's * page table pages. */ - for (i = 0; i < nkpt; i++) { - mpte = PHYS_TO_VM_PAGE(PTD[i + KPTDI] & PG_FRAME); + for (i = 0; i < NKPT; i++) { + mpte = PHYS_TO_VM_PAGE(KPTphys + (i << PAGE_SHIFT)); KASSERT(mpte >= vm_page_array && mpte < &vm_page_array[vm_page_array_size], ("pmap_init: page table page is out of range")); mpte->pindex = i + KPTDI; - mpte->phys_addr = PTD[i + KPTDI] & PG_FRAME; + mpte->phys_addr = KPTphys + (i << PAGE_SHIFT); } /* Modified: user/ed/utmpx/sys/i386/include/iodev.h ============================================================================== --- user/ed/utmpx/sys/i386/include/iodev.h Mon Jan 11 18:44:41 2010 (r202101) +++ user/ed/utmpx/sys/i386/include/iodev.h Mon Jan 11 18:48:45 2010 (r202102) @@ -28,3 +28,4 @@ d_open_t ioopen; d_close_t ioclose; +d_ioctl_t ioioctl; Modified: user/ed/utmpx/sys/i386/xen/mp_machdep.c ============================================================================== --- user/ed/utmpx/sys/i386/xen/mp_machdep.c Mon Jan 11 18:44:41 2010 (r202101) +++ user/ed/utmpx/sys/i386/xen/mp_machdep.c Mon Jan 11 18:48:45 2010 (r202102) @@ -105,9 +105,6 @@ static char callfunc_name[NR_CPUS][15]; /* Free these after use */ void *bootstacks[MAXCPU]; -/* Hotwire a 0->4MB V==P mapping */ -extern pt_entry_t *KPTphys; - struct pcb stoppcbs[MAXCPU]; /* Variables needed for SMP tlb shootdown. */ Modified: user/ed/utmpx/sys/i386/xen/xen_machdep.c ============================================================================== --- user/ed/utmpx/sys/i386/xen/xen_machdep.c Mon Jan 11 18:44:41 2010 (r202101) +++ user/ed/utmpx/sys/i386/xen/xen_machdep.c Mon Jan 11 18:48:45 2010 (r202102) @@ -715,9 +715,6 @@ xen_destroy_contiguous_region(void *addr balloon_unlock(flags); } -extern unsigned long cpu0prvpage; -extern unsigned long *SMPpt; -extern struct user *proc0uarea; extern vm_offset_t proc0kstack; extern int vm86paddr, vm86phystk; char *bootmem_start, *bootmem_current, *bootmem_end; Modified: user/ed/utmpx/sys/ia64/conf/DEFAULTS ============================================================================== --- user/ed/utmpx/sys/ia64/conf/DEFAULTS Mon Jan 11 18:44:41 2010 (r202101) +++ user/ed/utmpx/sys/ia64/conf/DEFAULTS Mon Jan 11 18:48:45 2010 (r202102) @@ -9,6 +9,7 @@ machine ia64 device acpi # ACPI support # Pseudo devices. +device io # I/O & EFI runtime device device mem # Memory and kernel memory devices # UART chips on this platform Modified: user/ed/utmpx/sys/ia64/conf/GENERIC ============================================================================== --- user/ed/utmpx/sys/ia64/conf/GENERIC Mon Jan 11 18:44:41 2010 (r202101) +++ user/ed/utmpx/sys/ia64/conf/GENERIC Mon Jan 11 18:48:45 2010 (r202102) @@ -67,6 +67,7 @@ options WITNESS # Enable checks to det options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed options _KPOSIX_PRIORITY_SCHEDULING # Posix P1003_1B RT extensions options HWPMC_HOOKS # Necessary kernel hooks for hwpmc(4) +options INCLUDE_CONFIG_FILE # Include this file in kernel # Various "busses" device firewire # FireWire bus code Copied: user/ed/utmpx/sys/ia64/ia64/iodev_machdep.c (from r202100, head/sys/ia64/ia64/iodev_machdep.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ user/ed/utmpx/sys/ia64/ia64/iodev_machdep.c Mon Jan 11 18:48:45 2010 (r202102, copy of r202100, head/sys/ia64/ia64/iodev_machdep.c) @@ -0,0 +1,160 @@ +/*- + * Copyright (c) 2010 Marcel Moolenaar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static int iodev_pio_read(struct iodev_pio_req *req); +static int iodev_pio_write(struct iodev_pio_req *req); + +/* ARGSUSED */ +int +ioopen(struct cdev *dev __unused, int flags __unused, int fmt __unused, + struct thread *td) +{ + int error; + + error = priv_check(td, PRIV_IO); + if (error == 0) + error = securelevel_gt(td->td_ucred, 0); + + return (error); +} + +/* ARGSUSED */ +int +ioclose(struct cdev *dev __unused, int flags __unused, int fmt __unused, + struct thread *td __unused) +{ + + return (0); +} + +/* ARGSUSED */ +int +ioioctl(struct cdev *dev __unused, u_long cmd, caddr_t data, + int fflag __unused, struct thread *td __unused) +{ + struct iodev_pio_req *pio_req; + int error; + + error = ENOIOCTL; + switch (cmd) { + case IODEV_PIO: + pio_req = (struct iodev_pio_req *)data; + switch (pio_req->access) { + case IODEV_PIO_READ: + error = iodev_pio_read(pio_req); + break; + case IODEV_PIO_WRITE: + error = iodev_pio_write(pio_req); + break; + default: + error = EINVAL; + break; + } + break; + } + + return (error); +} + +static int +iodev_pio_read(struct iodev_pio_req *req) +{ + + switch (req->width) { + case 1: + req->val = bus_space_read_io_1(req->port); + break; + case 2: + if (req->port & 1) { + req->val = bus_space_read_io_1(req->port); + req->val |= bus_space_read_io_1(req->port + 1) << 8; + } else + req->val = bus_space_read_io_2(req->port); + break; + case 4: + if (req->port & 1) { + req->val = bus_space_read_io_1(req->port); + req->val |= bus_space_read_io_2(req->port + 1) << 8; + req->val |= bus_space_read_io_1(req->port + 3) << 24; + } else if (req->port & 2) { + req->val = bus_space_read_io_2(req->port); + req->val |= bus_space_read_io_2(req->port + 2) << 16; + } else + req->val = bus_space_read_io_4(req->port); + break; + default: + return (EINVAL); + } + + return (0); +} + +static int +iodev_pio_write(struct iodev_pio_req *req) +{ + + switch (req->width) { + case 1: + bus_space_write_io_1(req->port, req->val); + break; + case 2: + if (req->port & 1) { + bus_space_write_io_1(req->port, req->val); + bus_space_write_io_1(req->port + 1, req->val >> 8); + } else + bus_space_write_io_2(req->port, req->val); + break; + case 4: + if (req->port & 1) { + bus_space_write_io_1(req->port, req->val); + bus_space_write_io_2(req->port + 1, req->val >> 8); + bus_space_write_io_1(req->port + 3, req->val >> 24); + } else if (req->port & 2) { + bus_space_write_io_2(req->port, req->val); + bus_space_write_io_2(req->port + 2, req->val >> 16); + } else + bus_space_write_io_4(req->port, req->val); + break; + default: + return (EINVAL); + } + + return (0); +} Modified: user/ed/utmpx/sys/ia64/ia64/sys_machdep.c ============================================================================== --- user/ed/utmpx/sys/ia64/ia64/sys_machdep.c Mon Jan 11 18:44:41 2010 (r202101) +++ user/ed/utmpx/sys/ia64/ia64/sys_machdep.c Mon Jan 11 18:48:45 2010 (r202102) @@ -49,72 +49,9 @@ struct sysarch_args { int sysarch(struct thread *td, struct sysarch_args *uap) { - struct ia64_iodesc iod; int error; - error = 0; switch(uap->op) { - case IA64_IORD: - copyin(uap->parms, &iod, sizeof(iod)); - switch (iod.width) { - case 1: - iod.val = inb(iod.port); - break; - case 2: - if (iod.port & 1) { - iod.val = inb(iod.port); - iod.val |= inb(iod.port + 1) << 8; - } else - iod.val = inw(iod.port); - break; - case 4: - if (iod.port & 3) { - if (iod.port & 1) { - iod.val = inb(iod.port); - iod.val |= inw(iod.port + 1) << 8; - iod.val |= inb(iod.port + 3) << 24; - } else { - iod.val = inw(iod.port); - iod.val |= inw(iod.port + 2) << 16; - } - } else - iod.val = inl(iod.port); - break; - default: - error = EINVAL; - } - copyout(&iod, uap->parms, sizeof(iod)); - break; - case IA64_IOWR: - copyin(uap->parms, &iod, sizeof(iod)); - switch (iod.width) { - case 1: - outb(iod.port, iod.val); - break; - case 2: - if (iod.port & 1) { - outb(iod.port, iod.val); - outb(iod.port + 1, iod.val >> 8); - } else - outw(iod.port, iod.val); - break; - case 4: - if (iod.port & 3) { - if (iod.port & 1) { - outb(iod.port, iod.val); - outw(iod.port + 1, iod.val >> 8); - outb(iod.port + 3, iod.val >> 24); - } else { - outw(iod.port, iod.val); - outw(iod.port + 2, iod.val >> 16); - } - } else - outl(iod.port, iod.val); - break; - default: - error = EINVAL; - } - break; default: error = EINVAL; break; Copied: user/ed/utmpx/sys/ia64/include/iodev.h (from r202100, head/sys/ia64/include/iodev.h) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ user/ed/utmpx/sys/ia64/include/iodev.h Mon Jan 11 18:48:45 2010 (r202102, copy of r202100, head/sys/ia64/include/iodev.h) @@ -0,0 +1,51 @@ +/*- + * Copyright (c) 2010 Marcel Moolenaar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _MACHINE_IODEV_H_ +#define _MACHINE_IODEV_H_ + *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-src-user@FreeBSD.ORG Mon Jan 11 19:10:30 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 49FC11065692; Mon, 11 Jan 2010 19:10:30 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 397B58FC37; Mon, 11 Jan 2010 19:10:30 +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 o0BJAUmE049955; Mon, 11 Jan 2010 19:10:30 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0BJAUtZ049953; Mon, 11 Jan 2010 19:10:30 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201001111910.o0BJAUtZ049953@svn.freebsd.org> From: Ed Schouten Date: Mon, 11 Jan 2010 19:10:30 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202104 - user/ed/utmpx/usr.sbin/ac X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Jan 2010 19:10:30 -0000 Author: ed Date: Mon Jan 11 19:10:29 2010 New Revision: 202104 URL: http://svn.freebsd.org/changeset/base/202104 Log: Enable the code to shut down sessions at the end properly. Modified: user/ed/utmpx/usr.sbin/ac/ac.c Modified: user/ed/utmpx/usr.sbin/ac/ac.c ============================================================================== --- user/ed/utmpx/usr.sbin/ac/ac.c Mon Jan 11 19:04:24 2010 (r202103) +++ user/ed/utmpx/usr.sbin/ac/ac.c Mon Jan 11 19:10:29 2010 (r202104) @@ -477,7 +477,7 @@ int ac(const char *file) { struct utmp_list *lp, *head = NULL; - struct utmpx *usr; + struct utmpx *usr, usht; struct tm *ltm; time_t prev_secs, secs, ut_timecopy; int day, rfound, tchanged, tskipped; @@ -581,32 +581,28 @@ ac(const char *file) } } endutxent(); -#if 0 - if (usr != NULL) { - if (!(Flags & AC_W)) - usr->ut_tv.tv_sec = time(NULL); - usr->ut_type = SHUTDOWN_TIME; - - if (Flags & AC_D) { - ut_timecopy = usr->ut_tv.tv_sec; - ltm = localtime(&ut_timecopy); - if (day >= 0 && day != ltm->tm_yday) { - /* - * print yesterday's total - */ - secs = ut_timecopy; - secs -= ltm->tm_sec; - secs -= 60 * ltm->tm_min; - secs -= 3600 * ltm->tm_hour; - show_today(Users, head, secs); - } + if (!(Flags & AC_W)) + usht.ut_tv.tv_sec = time(NULL); + usht.ut_type = SHUTDOWN_TIME; + + if (Flags & AC_D) { + ut_timecopy = usht.ut_tv.tv_sec; + ltm = localtime(&ut_timecopy); + if (day >= 0 && day != ltm->tm_yday) { + /* + * print yesterday's total + */ + secs = ut_timecopy; + secs -= ltm->tm_sec; + secs -= 60 * ltm->tm_min; + secs -= 3600 * ltm->tm_hour; + show_today(Users, head, secs); } - /* - * anyone still logged in gets time up to now - */ - head = log_out(head, usr); } -#endif + /* + * anyone still logged in gets time up to now + */ + head = log_out(head, &usht); if (Flags & AC_D) show_today(Users, head, time((time_t *)0)); From owner-svn-src-user@FreeBSD.ORG Mon Jan 11 19:59:12 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 7B1CF1065670; Mon, 11 Jan 2010 19:59:12 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 6B48A8FC2A; Mon, 11 Jan 2010 19:59:12 +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 o0BJxC1K060880; Mon, 11 Jan 2010 19:59:12 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0BJxCXh060878; Mon, 11 Jan 2010 19:59:12 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201001111959.o0BJxCXh060878@svn.freebsd.org> From: Ed Schouten Date: Mon, 11 Jan 2010 19:59:12 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202108 - user/ed/utmpx/bin/csh X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Jan 2010 19:59:12 -0000 Author: ed Date: Mon Jan 11 19:59:12 2010 New Revision: 202108 URL: http://svn.freebsd.org/changeset/base/202108 Log: Only define UTMPX_FILE on FreeBSD. Proposed by: mp Modified: user/ed/utmpx/bin/csh/config_p.h Modified: user/ed/utmpx/bin/csh/config_p.h ============================================================================== --- user/ed/utmpx/bin/csh/config_p.h Mon Jan 11 19:52:40 2010 (r202107) +++ user/ed/utmpx/bin/csh/config_p.h Mon Jan 11 19:59:12 2010 (r202108) @@ -85,6 +85,7 @@ /* Use LC_MESSAGES locale category to open the message catalog */ #define MCLoadBySet NL_CAT_LOCALE #define BUFSIZE 8192 +#define UTMPX_FILE "/var/run/utx.active" #endif #if defined(__bsdi__) @@ -110,6 +111,4 @@ # define NLS_CATALOGS #endif -#define UTMPX_FILE "/var/run/utx.active" - #endif /* _h_config */ From owner-svn-src-user@FreeBSD.ORG Mon Jan 11 20:07:24 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id BEA1F106566B; Mon, 11 Jan 2010 20:07:24 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id AEB688FC12; Mon, 11 Jan 2010 20:07:24 +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 o0BK7O3i062948; Mon, 11 Jan 2010 20:07:24 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0BK7ObI062946; Mon, 11 Jan 2010 20:07:24 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201001112007.o0BK7ObI062946@svn.freebsd.org> From: Ed Schouten Date: Mon, 11 Jan 2010 20:07:24 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202110 - user/ed/utmpx/crypto/openssh X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Jan 2010 20:07:24 -0000 Author: ed Date: Mon Jan 11 20:07:24 2010 New Revision: 202110 URL: http://svn.freebsd.org/changeset/base/202110 Log: Mute a compiler warning about a missing prototype. Modified: user/ed/utmpx/crypto/openssh/loginrec.c Modified: user/ed/utmpx/crypto/openssh/loginrec.c ============================================================================== --- user/ed/utmpx/crypto/openssh/loginrec.c Mon Jan 11 20:05:38 2010 (r202109) +++ user/ed/utmpx/crypto/openssh/loginrec.c Mon Jan 11 20:07:24 2010 (r202110) @@ -207,6 +207,7 @@ int syslogin_write_entry(struct logininf int getlast_entry(struct logininfo *li); int lastlog_get_entry(struct logininfo *li); +int utmpx_get_entry(struct logininfo *li); int wtmp_get_entry(struct logininfo *li); int wtmpx_get_entry(struct logininfo *li); From owner-svn-src-user@FreeBSD.ORG Mon Jan 11 20:23:17 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 98E1C106568F; Mon, 11 Jan 2010 20:23:17 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 493218FC1C; Mon, 11 Jan 2010 20:23:17 +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 o0BKNHCw066509; Mon, 11 Jan 2010 20:23:17 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0BKNH4u066507; Mon, 11 Jan 2010 20:23:17 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201001112023.o0BKNH4u066507@svn.freebsd.org> From: Ed Schouten Date: Mon, 11 Jan 2010 20:23:17 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202111 - user/ed/utmpx/crypto/openssh X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Jan 2010 20:23:17 -0000 Author: ed Date: Mon Jan 11 20:23:17 2010 New Revision: 202111 URL: http://svn.freebsd.org/changeset/base/202111 Log: Also use MIN_SIZEOF() for the line name inside the lastlog code. The use of MIN_SIZEOF() doesn't seem to be used consistenly throughout the code. Modified: user/ed/utmpx/crypto/openssh/loginrec.c Modified: user/ed/utmpx/crypto/openssh/loginrec.c ============================================================================== --- user/ed/utmpx/crypto/openssh/loginrec.c Mon Jan 11 20:07:24 2010 (r202110) +++ user/ed/utmpx/crypto/openssh/loginrec.c Mon Jan 11 20:23:17 2010 (r202111) @@ -1567,9 +1567,10 @@ lastlog_get_entry(struct logininfo *li) memset(&l, '\0', sizeof(l)); ll = &l; } - line_fullname(li->line, ll->ll_line, sizeof(li->line)); + line_fullname(li->line, ll->ll_line, + MIN_SIZEOF(li->line, ll->ll_line)); strlcpy(li->hostname, ll->ll_host, - MIN_SIZEOF(li->hostname, ll->ll_host)); + MIN_SIZEOF(li->hostname, ll->ll_host)); li->tv_sec = ll->ll_tv.tv_sec; li->tv_usec = ll->ll_tv.tv_usec; return (1); From owner-svn-src-user@FreeBSD.ORG Mon Jan 11 21:01:35 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 8A724106566C; Mon, 11 Jan 2010 21:01:35 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 7AA8D8FC14; Mon, 11 Jan 2010 21:01:35 +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 o0BL1ZKQ075249; Mon, 11 Jan 2010 21:01:35 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0BL1ZxG075247; Mon, 11 Jan 2010 21:01:35 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201001112101.o0BL1ZxG075247@svn.freebsd.org> From: Ed Schouten Date: Mon, 11 Jan 2010 21:01:35 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202114 - user/ed/utmpx/usr.sbin/lastlogin X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Jan 2010 21:01:35 -0000 Author: ed Date: Mon Jan 11 21:01:35 2010 New Revision: 202114 URL: http://svn.freebsd.org/changeset/base/202114 Log: Make lastlogin(1) more graphically consistent with last(1). Modified: user/ed/utmpx/usr.sbin/lastlogin/lastlogin.c Modified: user/ed/utmpx/usr.sbin/lastlogin/lastlogin.c ============================================================================== --- user/ed/utmpx/usr.sbin/lastlogin/lastlogin.c Mon Jan 11 20:44:05 2010 (r202113) +++ user/ed/utmpx/usr.sbin/lastlogin/lastlogin.c Mon Jan 11 21:01:35 2010 (r202114) @@ -95,7 +95,7 @@ output(struct utmpx *u) { time_t t = u->ut_tv.tv_sec; - printf("%-16s %-8s %-16s %s", + printf("%-10s %-8s %-22s %s", u->ut_user, u->ut_line, u->ut_host, ctime(&t)); } From owner-svn-src-user@FreeBSD.ORG Mon Jan 11 22:31:48 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 5C0C21065676; Mon, 11 Jan 2010 22:31:48 +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 4C5688FC1F; Mon, 11 Jan 2010 22:31:48 +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 o0BMVmgE095519; Mon, 11 Jan 2010 22:31:48 GMT (envelope-from luigi@svn.freebsd.org) Received: (from luigi@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0BMVm2o095515; Mon, 11 Jan 2010 22:31:48 GMT (envelope-from luigi@svn.freebsd.org) Message-Id: <201001112231.o0BMVm2o095515@svn.freebsd.org> From: Luigi Rizzo Date: Mon, 11 Jan 2010 22:31:48 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202122 - user/luigi/ipfw3-head/sbin/ipfw X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Jan 2010 22:31:48 -0000 Author: luigi Date: Mon Jan 11 22:31:47 2010 New Revision: 202122 URL: http://svn.freebsd.org/changeset/base/202122 Log: start implementing commands with the new IP_DUMMYNET3 sockopt Modified: user/luigi/ipfw3-head/sbin/ipfw/dummynet.c user/luigi/ipfw3-head/sbin/ipfw/ipfw2.c user/luigi/ipfw3-head/sbin/ipfw/ipfw2.h Modified: user/luigi/ipfw3-head/sbin/ipfw/dummynet.c ============================================================================== --- user/luigi/ipfw3-head/sbin/ipfw/dummynet.c Mon Jan 11 22:28:40 2010 (r202121) +++ user/luigi/ipfw3-head/sbin/ipfw/dummynet.c Mon Jan 11 22:31:47 2010 (r202122) @@ -1184,7 +1184,7 @@ end_mask: *p2 = *p; p2->pipe_nr = i; } - i = do_cmd(IP_DUMMYNET_CONFIGURE, base, + i = do_cmd(IP_DUMMYNET3, base, (char *)buf - (char *)base); if (i) @@ -1192,9 +1192,18 @@ end_mask: } void +dummynet_flush(void) +{ + struct dn_id oid; + oid.type = DN_CMD_FLUSH; + oid.len = sizeof(oid); + do_cmd(IP_DUMMYNET3, &oid, sizeof(oid)); +} + +void dummynet_list(int ac, char *av[], int show_counters) { - struct dn_id oid , *x; + struct dn_id oid, *x; int ret, l = sizeof(oid); oid.type = DN_CMD_GET; @@ -1208,7 +1217,7 @@ dummynet_list(int ac, char *av[], int sh oid.subtype = DN_FS; /* list queue */ break; } - ret = do_cmd(IP_DUMMYNET_GET, &oid, (uintptr_t)&l); + ret = do_cmd(-IP_DUMMYNET3, &oid, (uintptr_t)&l); printf("%s returns %d need %d\n", __FUNCTION__, ret, oid.id); if (ret != 0 || oid.id <= sizeof(oid)) return; @@ -1218,7 +1227,7 @@ dummynet_list(int ac, char *av[], int sh err(1, "no memory in %s", __FUNCTION__); } *x = oid; - ret = do_cmd(IP_DUMMYNET_GET, x, (uintptr_t)&l); + ret = do_cmd(-IP_DUMMYNET3, x, (uintptr_t)&l); printf("%s returns %d need %d\n", __FUNCTION__, ret, oid.id); list_pipes(x, O_NEXT(x, l), NULL); free(x); Modified: user/luigi/ipfw3-head/sbin/ipfw/ipfw2.c ============================================================================== --- user/luigi/ipfw3-head/sbin/ipfw/ipfw2.c Mon Jan 11 22:28:40 2010 (r202121) +++ user/luigi/ipfw3-head/sbin/ipfw/ipfw2.c Mon Jan 11 22:31:47 2010 (r202122) @@ -353,6 +353,7 @@ safe_realloc(void *ptr, size_t size) /* * conditionally runs the command. + * Selected options or negative -> getsockopt */ int do_cmd(int optname, void *optval, uintptr_t optlen) @@ -372,11 +373,15 @@ do_cmd(int optname, void *optval, uintpt optname == IP_FW_ADD || optname == IP_FW_TABLE_LIST || optname == IP_FW_TABLE_GETSIZE || optname == IP_FW_NAT_GET_CONFIG || - optname == IP_FW_NAT_GET_LOG) + optname < 0 || + optname == IP_FW_NAT_GET_LOG) { + if (optname < 0) + optname = -optname; i = getsockopt(s, IPPROTO_IP, optname, optval, (socklen_t *)optlen); - else + } else { i = setsockopt(s, IPPROTO_IP, optname, optval, optlen); + } return i; } @@ -3697,6 +3702,10 @@ ipfw_flush(int force) if (c == 'N') /* user said no */ return; } + if (co.do_pipe) { + dummynet_flush(); + return; + } /* `ipfw set N flush` - is the same that `ipfw delete set N` */ if (co.use_set) { uint32_t arg = ((co.use_set - 1) & 0xffff) | (1 << 24); Modified: user/luigi/ipfw3-head/sbin/ipfw/ipfw2.h ============================================================================== --- user/luigi/ipfw3-head/sbin/ipfw/ipfw2.h Mon Jan 11 22:28:40 2010 (r202121) +++ user/luigi/ipfw3-head/sbin/ipfw/ipfw2.h Mon Jan 11 22:31:47 2010 (r202122) @@ -266,6 +266,7 @@ void print_altq_cmd(struct _ipfw_insn_al /* dummynet.c */ void dummynet_list(int ac, char *av[], int show_counters); +void dummynet_flush(void); int ipfw_delete_pipe(int pipe_or_queue, int n); /* ipv6.c */ From owner-svn-src-user@FreeBSD.ORG Mon Jan 11 22:35:19 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id CC6AD1065672; Mon, 11 Jan 2010 22:35: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 BB2578FC14; Mon, 11 Jan 2010 22:35: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 o0BMZJ0k096407; Mon, 11 Jan 2010 22:35:19 GMT (envelope-from luigi@svn.freebsd.org) Received: (from luigi@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0BMZJU7096402; Mon, 11 Jan 2010 22:35:19 GMT (envelope-from luigi@svn.freebsd.org) Message-Id: <201001112235.o0BMZJU7096402@svn.freebsd.org> From: Luigi Rizzo Date: Mon, 11 Jan 2010 22:35:19 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202124 - user/luigi/ipfw3-head/sys/netinet/ipfw X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Jan 2010 22:35:19 -0000 Author: luigi Date: Mon Jan 11 22:35:19 2010 New Revision: 202124 URL: http://svn.freebsd.org/changeset/base/202124 Log: remove some debugging messages, start implementing the new sockopt Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h Mon Jan 11 22:34:25 2010 (r202123) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h Mon Jan 11 22:35:19 2010 (r202124) @@ -32,8 +32,6 @@ #ifndef _DN_SCHED_H #define _DN_SCHED_H -// MALLOC_DECLARE(M_DUMMYNET); - /* * Descriptor for the scheduler. * Contains all function pointers for a given scheduler @@ -144,14 +142,6 @@ SLIST_HEAD(dn_sched_head, dn_sched); */ /* - * You must call dn_pkt_done() when extracting packets from a queue. - * The function is used to update packet and queue statistics. - * - pkt: packet to return; - * - q: packet belongs to this queue - */ -struct mbuf* dn_pkt_done(struct mbuf *pkt, struct new_queue *q); - -/* * delete a queue, which we assume nobody references */ int dn_delete_queue(struct new_queue *q); @@ -199,7 +189,7 @@ struct new_queue * dn_q_hash_id(struct i /* * Extract the head of a queue, update stats. Must be the very last - * thing done on a queue as it may go away. + * thing done on a queue as the queue itself may go away. */ static __inline struct mbuf* dn_return_packet(struct new_queue *q) @@ -207,8 +197,9 @@ dn_return_packet(struct new_queue *q) struct mbuf *m = q->mq.head; KASSERT(m != NULL, ("empty queue to dn_return_packet")); q->mq.head = m->m_nextpkt; - q->lenght--; - q->len_bytes -= m->m_pkthdr.len; + q->ni.length--; + q->si->ni.len_bytes -= m->m_pkthdr.len; + q->si->ni.len_bytes -= m->m_pkthdr.len; if (q->mq.head == NULL && q->fs && q->fs->kflags & DN_DELETE) dn_delete_queue(q); Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Mon Jan 11 22:34:25 2010 (r202123) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Mon Jan 11 22:35:19 2010 (r202124) @@ -46,7 +46,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -//#include #include #include #include /* IFNAMSIZ, struct ifaddr, ifq head, lock.h mutex.h */ @@ -205,10 +204,8 @@ struct dn_pkt_tag { }; /* - * Return the mbuf tag holding the dummynet state. As an optimization - * this is assumed to be the first tag on the list. If this turns out - * wrong we'll need to search the list. - * XXX OK + * Return the mbuf tag holding the dummynet state (it should + * be the first one on the list). */ static struct dn_pkt_tag * dn_tag_get(struct mbuf *m) @@ -233,12 +230,9 @@ mq_append(struct mq *q, struct mbuf *m) } /* - * Check if the packet should be drop depending on the queue management - * or queue size overflow. - * Put the packet m into the queue q. - * Update statistics for the queue. - * - * The function returns 1 if the packet is dropped. + * Enqueue a packet in q, subject to space and queue management policy. + * Update stats for the queue and the scheduler. + * Return 0 on success, 1 on drop. The packet is consumed anyways. */ int dn_queue_packet(struct new_queue *q, struct mbuf* m) @@ -248,28 +242,28 @@ dn_queue_packet(struct new_queue *q, str uint64_t len = m->m_pkthdr.len; /* Update statistics, then check reasons to drop pkt. */ - q->tot_bytes += len; - q->tot_pkts++; + q->ni.tot_bytes += len; + q->ni.tot_pkts++; ni->tot_bytes += len; ni->tot_pkts++; if (f->plr && random() < f->plr) goto drop; if (f->flags & DN_QSIZE_BYTES) { - if (q->len_bytes > f->qsize) + if (q->ni.len_bytes > f->qsize) goto drop; - } else if (q->lenght >= f->qsize) { + } else if (q->ni.length >= f->qsize) { goto drop; } mq_append(&q->mq, m); - q->lenght++; - q->len_bytes += len; + q->ni.length++; + q->ni.len_bytes += len; ni->length++; ni->len_bytes += len; return 0; drop: io_pkt_drop++; - q->drops++; + q->ni.drops++; ni->drops++; FREE_PKT(m); return 1; @@ -278,14 +272,14 @@ drop: /* * Fetch packets from the delay line which are due now. If there are * leftover packets, reinsert the delay line in the heap. + * Runs under scheduler lock. */ static void transmit_event(struct mq *q, struct delay_line *dline, dn_key now) { - struct mbuf *m = NULL; + struct mbuf *m; struct dn_pkt_tag *pkt = NULL; - /* XXX we are under scheduler lock */ while ((m = dline->mq.head) != NULL) { pkt = dn_tag_get(m); if (!DN_KEY_LEQ(pkt->output_time, now)) @@ -301,8 +295,8 @@ transmit_event(struct mq *q, struct dela /* * Convert the additional MAC overheads/delays into an equivalent - * number of bits for the given data rate. The samples are in milliseconds - * so we need to divide by 1000. + * number of bits for the given data rate. The samples are + * in milliseconds so we need to divide by 1000. */ static uint64_t extra_bits(struct mbuf *m, struct new_pipe *p) @@ -323,19 +317,6 @@ extra_bits(struct mbuf *m, struct new_pi return bits; } -#if 0 -/* Insert packet pkt into delay line, adding the delay. - * dt->output_time was already set */ -static void -move_pkt(struct mbuf *m, struct new_pipe *p, struct delay_line *d) -{ - struct dn_pkt_tag *dt = dn_tag_get(m); - - dt->output_time += p->delay ; - mq_append(&d->mq, m); -} -#endif - /* Do masking depending of flow id */ static struct ipfw_flow_id * do_mask(struct ipfw_flow_id *mask, struct ipfw_flow_id *id) @@ -406,11 +387,10 @@ do_hash(struct ipfw_flow_id *id) } /* - * returns 0 masks match, - * returns 1 otherwise + * Like bcmp, returns 0 if ids match, 1 otherwise. */ static int -mask_are_equals (struct ipfw_flow_id *id1, struct ipfw_flow_id *id2) +flow_id_cmp(struct ipfw_flow_id *id1, struct ipfw_flow_id *id2) { int is_v6 = IS_IP6_FLOW_ID(id1); if (is_v6 != IS_IP6_FLOW_ID(id2)) @@ -450,7 +430,6 @@ create_si(struct new_schk *s, int slot) int l = sizeof(*si) + s->fp->sch_inst_len; si = malloc(l, M_DUMMYNET, M_NOWAIT | M_ZERO); - if (si == NULL) goto error; /* XXX note we set the length only for the initial part which @@ -473,7 +452,6 @@ create_si(struct new_schk *s, int slot) /* Initialize list of queues attached here */ SLIST_INIT(&si->ql_list); - si->idle_time = 0; /* Put entry in front of the hash list of the parent. */ SLIST_INSERT_HEAD(&s->ht[slot], si, next); si->ni.hash_slot = slot; @@ -486,50 +464,60 @@ error: return NULL; } -/* find the scheduler instance for this packet */ +/* + * Find the scheduler instance for this packet. If we need to apply + * a mask, do on a local copy of the flow_id to preserve the original. + */ static struct new_sch_inst * find_sch_inst(struct new_schk *s, struct ipfw_flow_id *id) { - struct new_sch_inst *si; - int i; - struct ipfw_flow_id id_t; - - if ( 0 == (s->sch.flags & DN_HAVE_MASK) ) { - i = 0; - si = SLIST_FIRST(&s->ht[0]); - } else { - id_t = *id; - do_mask(&s->sch.sched_mask, &id_t); - i = do_hash(&id_t); - i = i % s->ht_slots; - /* finally, scan the current hash bucket for a match */ - searches++; - SLIST_FOREACH(si, &s->ht[i], next) { - search_steps++; - if (!mask_are_equals(&id_t, &si->ni.id)) - break; /* found */ - } - } - - if (si == NULL) { /* no match, need to allocate a new entry */ - si = create_si(s, i); - if (si && s->sch.flags & DN_HAVE_MASK) - si->ni.id = id_t; - } - return si; + struct new_sch_inst *si; + struct ipfw_flow_id id_t; + int i; + + if ( 0 == (s->sch.flags & DN_HAVE_MASK) ) { + i = 0; + si = SLIST_FIRST(&s->ht[0]); + } else { + id_t = *id; + do_mask(&s->sch.sched_mask, &id_t); + i = do_hash(&id_t); + i = i % s->ht_slots; + /* finally, scan the current hash bucket for a match */ + searches++; + SLIST_FOREACH(si, &s->ht[i], next) { + search_steps++; + if (!flow_id_cmp(&id_t, &si->ni.id)) + break; /* found */ + } + } + + if (si == NULL) { /* no match, allocate a new entry */ + si = create_si(s, i); + if (si && s->sch.flags & DN_HAVE_MASK) + si->ni.id = id_t; + } + return si; } /* - * Send traffic from a scheduler instance due by 'now' + * Send traffic from a scheduler instance due by 'now'. + * Return a pointer to the head of the queue. */ -static void +static struct mbuf * serve_sched(struct mq *q, struct new_sch_inst *si, dn_key now) { + struct mq def_q; struct new_schk *s = si->sched; struct mbuf *m = NULL; int delay_line_idle = (si->dline.mq.head == NULL); int done, bw; + if (q == NULL) { + q = &def_q; + q->head = NULL; + } + bw = s->pipe.bandwidth; si->kflags &= ~DN_ACTIVE; @@ -543,35 +531,31 @@ serve_sched(struct mq *q, struct new_sch uint64_t len_scaled; done++; len_scaled = bw == 0 ? 0 : hz * - (m->m_pkthdr.len * 8 + extra_bits(m, &s->pipe)); + (m->m_pkthdr.len * 8 + extra_bits(m, &s->pipe)); si->credit -= len_scaled; /* Move packet in the delay line */ dn_tag_get(m)->output_time += s->pipe.delay ; mq_append(&si->dline.mq, m); } + /* + * If credit >= 0 the instance is idle, mark time. + * Otherwise put back in the heap, and adjust the output + * time of the last inserted packet, m, which was too early. + */ if (si->credit >= 0) { - /* Instance is idle, because it did not return - * packets while credit was available. - */ - si->idle_time = curr_time; + si->idle_time = now; } else { - /* Credit has become negative, so reinsert the - * instance in the heap for when credit will be - * positive again. Also update the output time - * of the last packet, which is 'tosend' - */ dn_key t; KASSERT (bw > 0, ("bw=0 and credit<0 ?")); t = (bw - 1 - si->credit) / bw; - /* Delay output time because under credit */ if (m) dn_tag_get(m)->output_time += t; si->kflags |= DN_ACTIVE; - heap_insert(&dn_cfg.system_heap, curr_time + t, si); + heap_insert(&dn_cfg.system_heap, now + t, si); } - if (delay_line_idle && done) transmit_event(q, &si->dline, now); + return q->head; } /* @@ -623,7 +607,7 @@ dummynet_task(void *context, int pending tick_adjustment++; } - /* serve all pending events */ + /* serve pending events, accumulate in q */ for (;;) { struct dn_id *p; /* generic parameter to handler */ @@ -658,20 +642,21 @@ dummynet_send(struct mbuf *m) for (; m != NULL; m = n) { struct ifnet *ifp; - int dst; struct m_tag *tag; + int dst; n = m->m_nextpkt; m->m_nextpkt = NULL; tag = m_tag_first(m); - if (tag == NULL) { + if (tag == NULL) { /* should not happen */ dst = DIR_DROP; } else { struct dn_pkt_tag *pkt = dn_tag_get(m); - /* extract the dummynet info, rename the tag */ + /* extract the dummynet info, rename the tag + * to carry reinject info. + */ dst = pkt->dn_dir; ifp = pkt->ifp; - /* rename the tag so it carries reinject info */ tag->m_tag_cookie = MTAG_IPFW_RULE; tag->m_tag_id = 0; } @@ -681,11 +666,13 @@ dummynet_send(struct mbuf *m) SET_HOST_IPLEN(mtod(m, struct ip *)); ip_output(m, NULL, NULL, IP_FORWARDING, NULL, NULL); break ; + case DIR_IN : /* put header in network format for ip_input() */ //SET_NET_IPLEN(mtod(m, struct ip *)); netisr_dispatch(NETISR_IP, m); break; + #ifdef INET6 case DIR_IN | PROTO_IPV6: netisr_dispatch(NETISR_IPV6, m); @@ -696,6 +683,7 @@ dummynet_send(struct mbuf *m) ip6_output(m, NULL, NULL, IPV6_FORWARDING, NULL, NULL, NULL); break; #endif + case DIR_FWD | PROTO_IFB: /* DN_TO_IFB_FWD: */ if (bridge_dn_p != NULL) ((*bridge_dn_p)(m, ifp)); @@ -703,6 +691,7 @@ dummynet_send(struct mbuf *m) printf("dummynet: if_bridge not loaded\n"); break; + case DIR_IN | PROTO_LAYER2: /* DN_TO_ETH_DEMUX: */ /* * The Ethernet code assumes the Ethernet header is @@ -717,6 +706,7 @@ dummynet_send(struct mbuf *m) } ether_demux(m->m_pkthdr.rcvif, m); break; + case DIR_OUT | PROTO_LAYER2: /* N_TO_ETH_OUT: */ ether_output_frame(ifp, m); break; @@ -760,13 +750,8 @@ int dummynet_io(struct mbuf **m0, int dir, struct ip_fw_args *fwa) { struct mbuf *m = *m0; - struct dn_pkt_tag *pkt; - struct m_tag *mtag; struct new_fsk *fs = NULL; - struct new_pipe *pipe = NULL; - struct new_queue *q = NULL; - struct new_schk *sch; - struct new_sch_inst *sch_inst; + struct new_sch_inst *si; dn_key now; /* save a copy of curr_time */ int fs_id = (fwa->rule.info & IPFW_INFO_MASK) + @@ -777,57 +762,58 @@ dummynet_io(struct mbuf **m0, int dir, s fs = ipdn_locate_flowset(fs_id); if (fs == NULL) goto dropit; /* This queue/pipe does not exist! */ - sch = fs->sched; - if (sch == NULL) /* should not happen */ + if (fs->sched == NULL) /* should not happen */ goto dropit; /* find_sch_inst can be fast */ - sch_inst = find_sch_inst(sch, &(fwa->f_id)); - if (sch_inst == NULL) + si = find_sch_inst(fs->sched, &(fwa->f_id)); + if (si == NULL) goto dropit; /* tag the mbuf */ + { + struct dn_pkt_tag *dt; + struct m_tag *mtag; mtag = m_tag_get(PACKET_TAG_DUMMYNET, - sizeof(struct dn_pkt_tag), M_NOWAIT | M_ZERO); + sizeof(*dt), M_NOWAIT | M_ZERO); if (mtag == NULL) goto dropit; /* Cannot allocate packet header. */ m_tag_prepend(m, mtag); /* Attach to mbuf chain. */ - pkt = (struct dn_pkt_tag *)(mtag + 1); - pkt->rule = fwa->rule; - pkt->rule.info &= IPFW_ONEPASS; /* only keep this info */ - pkt->dn_dir = dir; - pkt->ifp = fwa->oif; - now = curr_time; /* in case it changes, use the same value */ - pkt->output_time = now; /* XXX rewritten when reaches head */ - + dt = (struct dn_pkt_tag *)(mtag + 1); + dt->rule = fwa->rule; + dt->rule.info &= IPFW_ONEPASS; /* only keep this info */ + dt->dn_dir = dir; + dt->ifp = fwa->oif; + /* dt->output tame is updated as we move through */ + dt->output_time = now = curr_time; + } if (fs->kflags & DN_HAVE_MASK) do_mask(&fs->fs.flow_mask, &(fwa->f_id)); - if (sch->fp->enqueue(sch_inst, fs, m, &(fwa->f_id))) { + if (fs->sched->fp->enqueue(si, fs, m, &(fwa->f_id))) { printf("%s dropped by enqueue\n", __FUNCTION__); /* packet was dropped by enqueue() */ *m0 = NULL; goto dropit; } - if (sch_inst->kflags & DN_ACTIVE) { + if (si->kflags & DN_ACTIVE) { m = *m0 = NULL; /* consumed */ goto done; /* already active, nothing to do */ } /* compute the initial allowance */ - pipe = &sch->pipe; - sch_inst->credit = dn_cfg.io_fast ? pipe->bandwidth : 0; + { + struct new_pipe *pipe = &fs->sched->pipe; + si->credit = dn_cfg.io_fast ? pipe->bandwidth : 0; if (pipe->burst) { - uint64_t burst = (now - sch_inst->idle_time) * + uint64_t burst = (now - si->idle_time) * pipe->bandwidth; if (burst > pipe->burst) burst = pipe->burst; - sch_inst->credit += burst; + si->credit += burst; } - { /* pass through scheduler and delay line */ - struct mq q = { NULL, NULL }; - serve_sched(&q, sch_inst, now); - m = q.head; - } + } + /* pass through scheduler and delay line */ + m = serve_sched(NULL, si, now); /* optimization -- pass it back to ipfw for immediate send */ if (dn_cfg.io_fast && m == *m0 && (dir & PROTO_LAYER2) == 0 ) { @@ -849,10 +835,8 @@ done: dropit: io_pkt_drop++; - if (q) - q->drops++; DUMMYNET_UNLOCK(); FREE_PKT(m); *m0 = NULL; - return ((fs && (fs->fs.flags & DN_NOERROR)) ? 0 : ENOBUFS); + return (fs && (fs->fs.flags & DN_NOERROR)) ? 0 : ENOBUFS; } Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h Mon Jan 11 22:34:25 2010 (r202123) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h Mon Jan 11 22:35:19 2010 (r202124) @@ -169,10 +169,9 @@ struct new_schk { struct dn_sched *fp; /* Pointer to scheduler functions */ }; -/* Implementation of the packets queue associated with a scheduler instance */ +/* The packets queue associated with a scheduler instance */ struct new_queue { - struct dn_id oid; - struct ipfw_flow_id id; + struct new_inst ni; /* oid, flow_id, stats */ struct mq mq; /* packets queue */ SLIST_ENTRY(new_queue) ql_next; /* linked list to sch_inst */ @@ -180,13 +179,6 @@ struct new_queue { struct new_fsk *fs; /* parent flowset. */ /* If fs->kflags & DN_DELETE, remove the queue when empty. */ - - /* stats */ - u_int lenght; /* Queue lenght, in packets */ - u_int len_bytes; /* Queue lenght, in bytes */ - uint64_t tot_pkts; /* statistics counters */ - uint64_t tot_bytes; - uint32_t drops; }; SLIST_HEAD(new_queue_head, new_queue); Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Mon Jan 11 22:34:25 2010 (r202123) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Mon Jan 11 22:35:19 2010 (r202124) @@ -50,7 +50,6 @@ __FBSDID("$FreeBSD$"); #include #include /* IFNAMSIZ, struct ifaddr, ifq head, lock.h mutex.h */ #include -//#include /* ip_len, ip_off */ #include /* ip_output(), IP_FORWARDING */ #include #include @@ -61,7 +60,7 @@ __FBSDID("$FreeBSD$"); static int ip_dn_ctl(struct sockopt *sopt); - /* which objects to copy */ +/* which objects to copy */ #define DN_C_PIPE 0x01 #define DN_C_SCH 0x02 #define DN_C_SCH_INST 0x04 @@ -203,7 +202,7 @@ dn_create_queue(struct new_sch_inst *si, return NULL; } - set_oid(&q->oid, DN_QUEUE, 0, size); + set_oid(&q->ni.oid, DN_QUEUE, 0, size); q->fs = fs; q->si = si; fs->refcnt++; @@ -400,29 +399,33 @@ static int do_config(void *p, int l) { struct dn_id *next, *o; - int err = 0, cmd = 0; + int err = 0; struct dn_id *arg = NULL; for (o = p; l >= sizeof(*o); o = next) { struct dn_id *prev = arg; - err = EINVAL; if (o->len < sizeof(*o) || l < o->len) { printf("bad len o->len %d len %d\n", o->len, l); + err = EINVAL; break; } l -= o->len; printf("%s cmd %d len %d left %d\n", __FUNCTION__, o->type, o->len, l); next = (struct dn_id *)((char *)o + o->len); + err = 0; switch (o->type) { + default: + printf("cmd %d not implemented\n", o->type); + break; + case DN_CMD_CONFIGURE: - case DN_CMD_GET: - case DN_CMD_DELETE: + break; + case DN_CMD_FLUSH: - cmd = o->type; - err = 0; + dummynet_flush(); break; - case DN_TEXT: /* store for the next block */ + case DN_TEXT: /* store argument the next block */ prev = NULL; arg = o; break; @@ -450,13 +453,12 @@ do_config(void *p, int l) static struct new_schk * locate_scheduler(int sch_nr) { - struct new_schk *sch; - - SLIST_FOREACH(sch, &dn_cfg.schedhash[HASH(sch_nr)], next) - if (sch->sch.sched_nr == sch_nr) - return (sch); + struct new_schk *sch; - return (NULL); + SLIST_FOREACH(sch, &dn_cfg.schedhash[HASH(sch_nr)], next) + if (sch->sch.sched_nr == sch_nr) + return (sch); + return (NULL); } /* update all flowsets which may refer to this scheduler */ @@ -634,7 +636,6 @@ config_fs(struct new_fs *nfs, struct dn_ DUMMYNET_LOCK(); fs = ipdn_locate_flowset(i); - printf("%s %d old %p\n", __FUNCTION__, i, fs); if (fs == NULL) { fs = create_fs(); if (fs == NULL) { @@ -646,27 +647,21 @@ config_fs(struct new_fs *nfs, struct dn_ /* copy values, check if scheduler exists and mark active */ s = locate_scheduler(nfs->sched_nr); s_changed = s == NULL || fs->sched == NULL || fs->sched->fp != s->fp; - if (fs->sched) { - printf("%s remove from fsk_list\n", __FUNCTION__); + if (fs->sched) { // XXX and not DN_DELETE ? SLIST_REMOVE(&fs->sched->fsk_list, fs, new_fsk, sch_chain); - printf("%s remove from fshash\n", __FUNCTION__); SLIST_REMOVE(&dn_cfg.fshash[HASH(i)], fs, new_fsk, next); if (s_changed && fs->sched->fp->free_fs) fs->sched->fp->free_fs(fs); } else { - printf("%s remove from fsunlinked\n", __FUNCTION__); SLIST_REMOVE(&dn_cfg.fsunlinked, fs, new_fsk, next); } fs->sched = s; if (s) { - printf("%s insert in fsk_list\n", __FUNCTION__); SLIST_INSERT_HEAD(&s->fsk_list, fs, sch_chain); - printf("%s insert in fshash\n", __FUNCTION__); SLIST_INSERT_HEAD(&dn_cfg.fshash[HASH(i)], fs, next); if (s_changed && s->fp->new_fs) s->fp->new_fs(fs, arg, 1); } else { - printf("%s insert in fsunlinked\n", __FUNCTION__); SLIST_INSERT_HEAD(&dn_cfg.fsunlinked, fs, next); } dn_cfg.id++; @@ -737,69 +732,84 @@ config_profile(struct new_profile *pf, s } static int -dummynet_get(struct sockopt *sopt) +compute_space(struct dn_id *cmd, int *to_copy) { - int have = 0, i, need, error; - char *start = NULL, *buf, *end; - size_t sopt_valsize; - struct dn_id cmd; - int to_copy = 0; - - /* save original values */ - sopt_valsize = sopt->sopt_valsize; - printf("%s have %d bytes\n", __FUNCTION__, sopt_valsize); - - error = sooptcopyin(sopt, &cmd, sizeof(cmd), sizeof(cmd)); - sopt->sopt_valsize = sopt_valsize; - if (error) - return error; - printf("%s cmd %d len %d\n", __FUNCTION__, cmd.type, cmd.len); - for (have = 0, i = 0; i < 10; i++) { - DUMMYNET_LOCK(); - switch (cmd.subtype) { + int need; + + *to_copy = 0; + switch (cmd->subtype) { default: - return EINVAL; + return -1; case DN_SCH: /* pipe show */ - to_copy = DN_C_SCH | DN_C_PIPE | DN_C_SCH_INST; - need = dn_cfg.schk_count * - (sizeof(struct new_sch) + sizeof(struct new_pipe)); - need += dn_cfg.si_count * sizeof(struct new_inst); - break; + *to_copy = DN_C_SCH | DN_C_PIPE | DN_C_SCH_INST; + need = dn_cfg.schk_count * + (sizeof(struct new_sch) + sizeof(struct new_pipe)); + need += dn_cfg.si_count * sizeof(struct new_inst); + break; case DN_FS: /* queue show */ - to_copy = DN_C_FS; - need = dn_cfg.fsk_count * - (sizeof(struct new_fs)); - break; - } - need += sizeof(cmd); - cmd.id = need; - printf("pass %d have %d need %d len %d\n", - i, have, need, sopt_valsize); - if (have >= need) - break; - DUMMYNET_UNLOCK(); - if (start) - free(start, M_DUMMYNET); - buf = NULL; - if (need > sopt_valsize) - break; - have = need; - start = malloc(have, M_DUMMYNET, M_WAITOK | M_ZERO); + *to_copy = DN_C_FS; + need = dn_cfg.fsk_count * (sizeof(struct new_fs)); + break; + } + return need; +} + +static int +dummynet_get(struct sockopt *sopt) +{ + int have, i, need, error, to_copy = 0; + char *start = NULL, *buf, *end; + size_t sopt_valsize; + struct dn_id cmd; + + /* save and restore original sopt_valsize around copyin */ + sopt_valsize = sopt->sopt_valsize; + printf("%s have %d bytes\n", __FUNCTION__, sopt_valsize); + error = sooptcopyin(sopt, &cmd, sizeof(cmd), sizeof(cmd)); + sopt->sopt_valsize = sopt_valsize; + if (error) + return error; + printf("%s cmd %d len %d\n", __FUNCTION__, cmd.type, cmd.len); + /* Count space (under lock) and allocate (outside lock). + * Exit with lock held if we manage to get enough buffer. + * Try a few times then give up. + */ + for (have = 0, i = 0; i < 10; i++) { + DUMMYNET_LOCK(); + need = compute_space(&cmd, &to_copy); + if (need < 0) { + DUMMYNET_UNLOCK(); + return EINVAL; + } + need += sizeof(cmd); + cmd.id = need; + printf("pass %d have %d need %d len %d\n", + i, have, need, sopt_valsize); + if (have >= need) + break; + DUMMYNET_UNLOCK(); + if (start) + free(start, M_DUMMYNET); + buf = NULL; + if (need > sopt_valsize) + break; + have = need; + start = malloc(have, M_DUMMYNET, M_WAITOK | M_ZERO); + if (start == NULL) + return ENOMEM; + } if (start == NULL) - return ENOMEM; - } - if (start == NULL) - return sooptcopyout(sopt, &cmd, sizeof(cmd)); - end = start + have; - sopt->sopt_valsize = sopt_valsize; - bcopy(&cmd, start, sizeof(cmd)); - buf = start + sizeof(cmd); - /* start copying other objects */ - copy_data(&buf, end, to_copy); - DUMMYNET_UNLOCK(); - error = sooptcopyout(sopt, start, buf - start); - free(start, M_DUMMYNET); - return error; + return sooptcopyout(sopt, &cmd, sizeof(cmd)); + end = start + have; + sopt->sopt_valsize = sopt_valsize; + bcopy(&cmd, start, sizeof(cmd)); + buf = start + sizeof(cmd); + /* start copying other objects */ + copy_data(&buf, end, to_copy); + DUMMYNET_UNLOCK(); + error = sooptcopyout(sopt, start, buf - start); + free(start, M_DUMMYNET); + return error; } /* @@ -828,16 +838,19 @@ ip_dn_ctl(struct sockopt *sopt) error = EINVAL; break; - case IP_DUMMYNET_GET : - error = dummynet_get(sopt); - break; - case IP_DUMMYNET_FLUSH : - dummynet_flush(); - break; - case IP_DUMMYNET_CONFIGURE : case IP_DUMMYNET_DEL : /* remove a pipe or queue */ + case IP_DUMMYNET_GET : + printf("dummynet: -- compat option %d", sopt->sopt_name); + error = EINVAL; + break; + + case IP_DUMMYNET3 : /* remove a pipe or queue */ + if (sopt->sopt_dir == SOPT_GET) { + error = dummynet_get(sopt); + break; + } l = sopt->sopt_valsize; if (l < 0 || l > 12000) { printf("argument too large, %d\n", l); @@ -964,18 +977,9 @@ load_descriptor(struct dn_sched *d) { struct dn_sched *s; - ip_dn_init(); if (d == NULL) return 1; /* error */ - - printf("%s %s start\n", __FUNCTION__, d->name); - /* Search if scheduler already exists */ - SLIST_FOREACH(s, &list_of_scheduler, next) { - if (strcmp(s->name, d->name) == 0) { - printf("%s %s already there\n", __FUNCTION__, d->name); - return 1; /* scheduler already exists */ - } - } + ip_dn_init(); /* just in case */ /* Check that mandatory funcs exists */ if (d->enqueue == NULL || d->dequeue == NULL) { @@ -983,12 +987,20 @@ load_descriptor(struct dn_sched *d) return 1; } + /* Search if scheduler already exists */ DUMMYNET_LOCK(); - SLIST_INSERT_HEAD(&list_of_scheduler, d, next); - printf("%s %s loaded\n", __FUNCTION__, d->name); + SLIST_FOREACH(s, &list_of_scheduler, next) { + if (strcmp(s->name, d->name) == 0) { + printf("%s %s already loaded\n", __FUNCTION__, d->name); + break; /* scheduler already exists */ + } + } + if (s == NULL) + SLIST_INSERT_HEAD(&list_of_scheduler, d, next); DUMMYNET_UNLOCK(); + printf("dn_sched %s %sloaded\n", d->name, s ? "not ":""); - return 0; /* ok */ + return s ? 1 : 0; } static int @@ -1017,27 +1029,18 @@ unload_descriptor(struct dn_sched *s) int dn_sched_modevent(module_t mod, int cmd, void *arg) { - struct dn_sched *sch = arg; - int error = EOPNOTSUPP; - printf("%s called\n", __FUNCTION__); - - switch(cmd) { - case MOD_LOAD: - error = load_descriptor(sch); - break; - - case MOD_UNLOAD: - error = unload_descriptor(sch); - break; - } - - return error; + struct dn_sched *sch = arg; + + if (cmd == MOD_LOAD) + return load_descriptor(sch); + else if (cmd == MOD_UNLOAD) + return unload_descriptor(sch); + else + return EINVAL; } static moduledata_t dummynet_mod = { - "dummynet", - dummynet_modevent, - NULL + "dummynet", dummynet_modevent, NULL }; DECLARE_MODULE(dummynet, dummynet_mod, From owner-svn-src-user@FreeBSD.ORG Mon Jan 11 23:00:18 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 5457D1065697; Mon, 11 Jan 2010 23:00:18 +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 437048FC0C; Mon, 11 Jan 2010 23:00:18 +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 o0BN0Iwc002226; Mon, 11 Jan 2010 23:00:18 GMT (envelope-from luigi@svn.freebsd.org) Received: (from luigi@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0BN0IxS002220; Mon, 11 Jan 2010 23:00:18 GMT (envelope-from luigi@svn.freebsd.org) Message-Id: <201001112300.o0BN0IxS002220@svn.freebsd.org> From: Luigi Rizzo Date: Mon, 11 Jan 2010 23:00:18 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202128 - user/luigi/ipfw3-head/sys/netinet/ipfw X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Jan 2010 23:00:18 -0000 Author: luigi Date: Mon Jan 11 23:00:17 2010 New Revision: 202128 URL: http://svn.freebsd.org/changeset/base/202128 Log: clean up a bit the pipe flush code. Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h Mon Jan 11 22:57:52 2010 (r202127) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h Mon Jan 11 23:00:17 2010 (r202128) @@ -144,7 +144,7 @@ SLIST_HEAD(dn_sched_head, dn_sched); /* * delete a queue, which we assume nobody references */ -int dn_delete_queue(struct new_queue *q); +int dn_delete_queue(struct new_queue *q, int extract); /* Allocate an hash table. * Returns the pointer to the table @@ -200,9 +200,9 @@ dn_return_packet(struct new_queue *q) q->ni.length--; q->si->ni.len_bytes -= m->m_pkthdr.len; q->si->ni.len_bytes -= m->m_pkthdr.len; - if (q->mq.head == NULL && q->fs && q->fs->kflags & DN_DELETE) - dn_delete_queue(q); - + if (q->mq.head == NULL && q->fs && q->fs->kflags & DN_DELETE) { + dn_delete_queue(q, 1 /* remove from ql_list */); + } return m; } Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c Mon Jan 11 22:57:52 2010 (r202127) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c Mon Jan 11 23:00:17 2010 (r202128) @@ -144,23 +144,6 @@ fifo_new_sched(struct new_schk *s, struc return 0; } -static int -fifo_free_sched(struct new_sch_inst *_si) -{ - /* - * Delete a FIFO scheduler instance - * - Deallocate memory if the create_scheduler_instance() function - * allocate memory - * - Delete the queue if exists - */ - struct fifo_si *si = (struct fifo_si *)(_si + 1); - - if (si->q) - dn_delete_queue(si->q); - - return 0; -} - /* * FIFO scheduler descriptor * contains the type of the scheduler, the name, the size of the various @@ -178,7 +161,6 @@ static struct dn_sched fifo_desc = { .dequeue = fifo_dequeue, .new_sched = fifo_new_sched, - .free_sched = fifo_free_sched, }; DECLARE_DNSCHED_MODULE(dn_fifo, &fifo_desc); Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c Mon Jan 11 22:57:52 2010 (r202127) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c Mon Jan 11 23:00:17 2010 (r202128) @@ -143,25 +143,8 @@ fifo_new_sched(struct new_schk *s, struc return 0; } -static int -fifo_free_sched(struct new_sch_inst *_si) -{ - /* - * Delete a FIFO scheduler instance - * - Deallocate memory if the create_scheduler_instance() function - * allocate memory - * - Delete the queue if exists - */ - struct fifo_si *si = (struct fifo_si *)(_si + 1); - - if (si->q) - dn_delete_queue(si->q); - - return 0; -} - /* - * FIFO scheduler descriptor + * WF2Q(fake) scheduler descriptor * contains the type of the scheduler, the name, the size of the various * structures and function pointers. If a function is not implemented, * the pointer is initialized to NULL @@ -177,7 +160,6 @@ static struct dn_sched fifo_desc = { .dequeue = fifo_dequeue, .new_sched = fifo_new_sched, - .free_sched = fifo_free_sched, }; DECLARE_DNSCHED_MODULE(dn_wf2qp, &fifo_desc); Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Mon Jan 11 22:57:52 2010 (r202127) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Mon Jan 11 23:00:17 2010 (r202128) @@ -280,6 +280,7 @@ transmit_event(struct mq *q, struct dela struct mbuf *m; struct dn_pkt_tag *pkt = NULL; + dline->oid.subtype = 0; /* not in heap */ while ((m = dline->mq.head) != NULL) { pkt = dn_tag_get(m); if (!DN_KEY_LEQ(pkt->output_time, now)) @@ -287,8 +288,10 @@ transmit_event(struct mq *q, struct dela dline->mq.head = m->m_nextpkt; mq_append(q, m); } - if (m != NULL) + if (m != NULL) { + dline->oid.subtype = 1; /* in heap */ heap_insert(&dn_cfg.system_heap, pkt->output_time, dline); + } } #define div64(a, b) ((int64_t)(a) / (int64_t)(b)) @@ -437,6 +440,7 @@ create_si(struct new_schk *s, int slot) */ set_oid(&si->ni.oid, DN_SCH_I, 0, sizeof(struct new_inst)); set_oid(&(si->dline.oid), DN_DELAY_LINE, 0, sizeof(struct delay_line)); + si->ni.oid.id = si->dline.oid.id = -1; /* mark outside scheduler */ si->sched = s; si->dline.si = si; Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Mon Jan 11 22:57:52 2010 (r202127) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Mon Jan 11 23:00:17 2010 (r202128) @@ -133,17 +133,16 @@ destroy_si(struct new_sch_inst *si) struct delay_line *dl = &si->dline; struct new_queue *q; - /* XXX below we use oid.id as a marker of presence in the sysheap */ - if (si->ni.oid.id >= 0) /* is in the heap */ + if (si->kflags & DN_ACTIVE) /* is in the heap */ heap_extract(&dn_cfg.system_heap, si); if (s->fp->free_sched) s->fp->free_sched(si); - if (dl->oid.id >= 0) /* is in the heap */ + if (dl->oid.subtype) /* is in the heap */ heap_extract(&dn_cfg.system_heap, dl); dn_free_pkts(dl->mq.head); while ( (q = SLIST_FIRST(&si->ql_list)) ) { SLIST_REMOVE_HEAD(&si->ql_list, ql_next); - dn_delete_queue(q); + dn_delete_queue(q, 0); } free(si, M_DUMMYNET); dn_cfg.si_count--; @@ -218,11 +217,12 @@ dn_create_queue(struct new_sch_inst *si, * Delete a queue (helper for the schedulers) */ int -dn_delete_queue(struct new_queue *q) +dn_delete_queue(struct new_queue *q, int extract) { struct new_fsk *fs = q->fs; - SLIST_REMOVE(&q->si->ql_list, q, new_queue, ql_next); + if (extract) + SLIST_REMOVE(&q->si->ql_list, q, new_queue, ql_next); if (q->mq.head) dn_free_pkts(q->mq.head); if (fs->sched->fp->free_queue) @@ -236,12 +236,13 @@ dn_delete_queue(struct new_queue *q) } static struct new_schk * -destroy_schk(struct new_schk *s, int del) +destroy_schk(struct new_schk *s) { int i; struct new_sch_inst *si; struct dn_sched *fp = s->fp; +printf("%s slots %d\n", __FUNCTION__, s->ht_slots); for (i = 0; i < s->ht_slots; i++) { struct new_sch_inst_head *h = &s->ht[i]; while ((si = SLIST_FIRST(h)) != NULL) { @@ -360,7 +361,7 @@ dummynet_flush(void) while ( (s = SLIST_FIRST(sh)) != NULL) { SLIST_REMOVE_HEAD(sh, next); - destroy_schk(s, 1 /* delete */); + destroy_schk(s); } } @@ -575,7 +576,7 @@ config_sched(struct new_sch *nsch, struc printf("%s type %s old %p\n", __FUNCTION__, fp->name, s); if (s && s->fp != fp) { /* type changed, hard delete */ /* preserve old pipe ? */ - s = destroy_schk(s, 1); + s = destroy_schk(s); } if (s) { is_new = 0; From owner-svn-src-user@FreeBSD.ORG Tue Jan 12 07:02:55 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 4F9601065672; Tue, 12 Jan 2010 07:02:55 +0000 (UTC) (envelope-from kmacy@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 3D9B98FC20; Tue, 12 Jan 2010 07:02:55 +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 o0C72ttK009293; Tue, 12 Jan 2010 07:02:55 GMT (envelope-from kmacy@svn.freebsd.org) Received: (from kmacy@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0C72tc4009289; Tue, 12 Jan 2010 07:02:55 GMT (envelope-from kmacy@svn.freebsd.org) Message-Id: <201001120702.o0C72tc4009289@svn.freebsd.org> From: Kip Macy Date: Tue, 12 Jan 2010 07:02:55 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202139 - user/kmacy/releng_8_rump/lib/libunet X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 12 Jan 2010 07:02:55 -0000 Author: kmacy Date: Tue Jan 12 07:02:54 2010 New Revision: 202139 URL: http://svn.freebsd.org/changeset/base/202139 Log: implement callout support using pthread condvars Modified: user/kmacy/releng_8_rump/lib/libunet/unet_glue.c user/kmacy/releng_8_rump/lib/libunet/unet_kern_intr.c user/kmacy/releng_8_rump/lib/libunet/unet_kern_timeout.c Modified: user/kmacy/releng_8_rump/lib/libunet/unet_glue.c ============================================================================== --- user/kmacy/releng_8_rump/lib/libunet/unet_glue.c Tue Jan 12 06:14:24 2010 (r202138) +++ user/kmacy/releng_8_rump/lib/libunet/unet_glue.c Tue Jan 12 07:02:54 2010 (r202139) @@ -35,6 +35,9 @@ SYSCTL_NODE(, CTL_NET, net, CTLFLAG SYSCTL_NODE(, CTL_VM, vm, CTLFLAG_RW, 0, "Virtual memory"); +SYSCTL_NODE(, CTL_DEBUG, debug, CTLFLAG_RW, 0, + "Debugging"); + MALLOC_DEFINE(M_DEVBUF, "devbuf", "device driver memory"); MALLOC_DEFINE(M_TEMP, "temp", "misc temporary data buffers"); Modified: user/kmacy/releng_8_rump/lib/libunet/unet_kern_intr.c ============================================================================== --- user/kmacy/releng_8_rump/lib/libunet/unet_kern_intr.c Tue Jan 12 06:14:24 2010 (r202138) +++ user/kmacy/releng_8_rump/lib/libunet/unet_kern_intr.c Tue Jan 12 07:02:54 2010 (r202139) @@ -27,6 +27,10 @@ __FBSDID("$FreeBSD$"); #include #include + +struct intr_event *clk_intr_event; + + /* * Bind an interrupt event to the specified CPU. Note that not all * platforms support binding an interrupt to a CPU. For those Modified: user/kmacy/releng_8_rump/lib/libunet/unet_kern_timeout.c ============================================================================== --- user/kmacy/releng_8_rump/lib/libunet/unet_kern_timeout.c Tue Jan 12 06:14:24 2010 (r202138) +++ user/kmacy/releng_8_rump/lib/libunet/unet_kern_timeout.c Tue Jan 12 07:02:54 2010 (r202139) @@ -52,15 +52,42 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include +#include + +SDT_PROVIDER_DEFINE(callout_execute); +SDT_PROBE_DEFINE(callout_execute, kernel, , callout_start); +SDT_PROBE_ARGTYPE(callout_execute, kernel, , callout_start, 0, + "struct callout *"); +SDT_PROBE_DEFINE(callout_execute, kernel, , callout_end); +SDT_PROBE_ARGTYPE(callout_execute, kernel, , callout_end, 0, + "struct callout *"); + +static int avg_depth; +SYSCTL_INT(_debug, OID_AUTO, to_avg_depth, CTLFLAG_RD, &avg_depth, 0, + "Average number of items examined per softclock call. Units = 1/1000"); +static int avg_gcalls; +SYSCTL_INT(_debug, OID_AUTO, to_avg_gcalls, CTLFLAG_RD, &avg_gcalls, 0, + "Average number of Giant callouts made per softclock call. Units = 1/1000"); +static int avg_lockcalls; +SYSCTL_INT(_debug, OID_AUTO, to_avg_lockcalls, CTLFLAG_RD, &avg_lockcalls, 0, + "Average number of lock callouts made per softclock call. Units = 1/1000"); +static int avg_mpcalls; +SYSCTL_INT(_debug, OID_AUTO, to_avg_mpcalls, CTLFLAG_RD, &avg_mpcalls, 0, + "Average number of MP callouts made per softclock call. Units = 1/1000"); +/* + * TODO: + * allocate more timeout table slots when table overflows. + */ int callwheelsize, callwheelbits, callwheelmask; +pthread_cond_t callout_cv; + struct callout_cpu { - struct mtx cc_lock; + pthread_mutex_t cc_lock; struct callout *cc_callout; struct callout_tailq *cc_callwheel; struct callout_list cc_callfree; @@ -81,13 +108,377 @@ struct callout_cpu cc_cpu; #define CC_CPU(cpu) &cc_cpu #define CC_SELF() &cc_cpu #endif -#define CC_LOCK(cc) mtx_lock(&(cc)->cc_lock) -#define CC_UNLOCK(cc) mtx_unlock(&(cc)->cc_lock) +#define CC_LOCK(cc) pthread_mutex_lock(&(cc)->cc_lock) +#define CC_UNLOCK(cc) pthread_mutex_unlock(&(cc)->cc_lock) static int timeout_cpu; MALLOC_DEFINE(M_CALLOUT, "callout", "Callout datastructures"); +/** + * Locked by cc_lock: + * cc_curr - If a callout is in progress, it is curr_callout. + * If curr_callout is non-NULL, threads waiting in + * callout_drain() will be woken up as soon as the + * relevant callout completes. + * cc_cancel - Changing to 1 with both callout_lock and c_lock held + * guarantees that the current callout will not run. + * The softclock() function sets this to 0 before it + * drops callout_lock to acquire c_lock, and it calls + * the handler only if curr_cancelled is still 0 after + * c_lock is successfully acquired. + * cc_waiting - If a thread is waiting in callout_drain(), then + * callout_wait is nonzero. Set only when + * curr_callout is non-NULL. + */ + +/* + * kern_timeout_callwheel_alloc() - kernel low level callwheel initialization + * + * This code is called very early in the kernel initialization sequence, + * and may be called more then once. + */ +caddr_t +kern_timeout_callwheel_alloc(caddr_t v) +{ + struct callout_cpu *cc; + + timeout_cpu = PCPU_GET(cpuid); + cc = CC_CPU(timeout_cpu); + /* + * Calculate callout wheel size + */ + for (callwheelsize = 1, callwheelbits = 0; + callwheelsize < ncallout; + callwheelsize <<= 1, ++callwheelbits) + ; + callwheelmask = callwheelsize - 1; + + cc->cc_callout = (struct callout *)v; + v = (caddr_t)(cc->cc_callout + ncallout); + cc->cc_callwheel = (struct callout_tailq *)v; + v = (caddr_t)(cc->cc_callwheel + callwheelsize); + return(v); +} + +static void +callout_cpu_init(struct callout_cpu *cc) +{ + struct callout *c; + int i; + + pthread_mutex_init(&cc->cc_lock, NULL); + SLIST_INIT(&cc->cc_callfree); + for (i = 0; i < callwheelsize; i++) { + TAILQ_INIT(&cc->cc_callwheel[i]); + } + if (cc->cc_callout == NULL) + return; + for (i = 0; i < ncallout; i++) { + c = &cc->cc_callout[i]; + callout_init(c, 0); + c->c_flags = CALLOUT_LOCAL_ALLOC; + SLIST_INSERT_HEAD(&cc->cc_callfree, c, c_links.sle); + } +} + +/* + * kern_timeout_callwheel_init() - initialize previously reserved callwheel + * space. + * + * This code is called just once, after the space reserved for the + * callout wheel has been finalized. + */ +void +kern_timeout_callwheel_init(void) +{ + callout_cpu_init(CC_CPU(timeout_cpu)); +} + +/* + * Start standard softclock thread. + */ +void *softclock_ih; + +static void +start_softclock(void *dummy) +{ + struct callout_cpu *cc; +#ifdef SMP + int cpu; +#endif + cc = CC_CPU(timeout_cpu); + if (swi_add(&clk_intr_event, "clock", softclock, cc, SWI_CLOCK, + INTR_MPSAFE, &softclock_ih)) + panic("died while creating standard software ithreads"); + cc->cc_cookie = softclock_ih; +#ifdef SMP + for (cpu = 0; cpu <= mp_maxid; cpu++) { + if (cpu == timeout_cpu) + continue; + if (CPU_ABSENT(cpu)) + continue; + cc = CC_CPU(cpu); + if (swi_add(NULL, "clock", softclock, cc, SWI_CLOCK, + INTR_MPSAFE, &cc->cc_cookie)) + panic("died while creating standard software ithreads"); + cc->cc_callout = NULL; /* Only cpu0 handles timeout(). */ + cc->cc_callwheel = malloc( + sizeof(struct callout_tailq) * callwheelsize, M_CALLOUT, + M_WAITOK); + callout_cpu_init(cc); + } +#endif +} + +SYSINIT(start_softclock, SI_SUB_SOFTINTR, SI_ORDER_FIRST, start_softclock, NULL); + +void +callout_tick(void) +{ + struct callout_cpu *cc; + int need_softclock; + int bucket; + + /* + * Process callouts at a very low cpu priority, so we don't keep the + * relatively high clock interrupt priority any longer than necessary. + */ + need_softclock = 0; + cc = CC_SELF(); + pthread_mutex_lock(&cc->cc_lock); + for (; (cc->cc_softticks - ticks) < 0; cc->cc_softticks++) { + bucket = cc->cc_softticks & callwheelmask; + if (!TAILQ_EMPTY(&cc->cc_callwheel[bucket])) { + need_softclock = 1; + break; + } + } + pthread_mutex_unlock(&cc->cc_lock); + /* + * swi_sched acquires the thread lock, so we don't want to call it + * with cc_lock held; incorrect locking order. + */ + if (need_softclock) + swi_sched(cc->cc_cookie, 0); +} + +static struct callout_cpu * +callout_lock(struct callout *c) +{ + struct callout_cpu *cc; + int cpu; + + for (;;) { + cpu = c->c_cpu; + cc = CC_CPU(cpu); + CC_LOCK(cc); + if (cpu == c->c_cpu) + break; + CC_UNLOCK(cc); + } + return (cc); +} + +/* + * The callout mechanism is based on the work of Adam M. Costello and + * George Varghese, published in a technical report entitled "Redesigning + * the BSD Callout and Timer Facilities" and modified slightly for inclusion + * in FreeBSD by Justin T. Gibbs. The original work on the data structures + * used in this implementation was published by G. Varghese and T. Lauck in + * the paper "Hashed and Hierarchical Timing Wheels: Data Structures for + * the Efficient Implementation of a Timer Facility" in the Proceedings of + * the 11th ACM Annual Symposium on Operating Systems Principles, + * Austin, Texas Nov 1987. + */ + +/* + * Software (low priority) clock interrupt. + * Run periodic events from timeout queue. + */ +void +softclock(void *arg) +{ + struct callout_cpu *cc; + struct callout *c; + struct callout_tailq *bucket; + int curticks; + int steps; /* #steps since we last allowed interrupts */ + int depth; + int mpcalls; + int lockcalls; + int gcalls; +#ifdef DIAGNOSTIC + struct bintime bt1, bt2; + struct timespec ts2; + static uint64_t maxdt = 36893488147419102LL; /* 2 msec */ + static timeout_t *lastfunc; +#endif + +#ifndef MAX_SOFTCLOCK_STEPS +#define MAX_SOFTCLOCK_STEPS 100 /* Maximum allowed value of steps. */ +#endif /* MAX_SOFTCLOCK_STEPS */ + + mpcalls = 0; + lockcalls = 0; + gcalls = 0; + depth = 0; + steps = 0; + cc = (struct callout_cpu *)arg; + CC_LOCK(cc); + while (cc->cc_softticks != ticks) { + /* + * cc_softticks may be modified by hard clock, so cache + * it while we work on a given bucket. + */ + curticks = cc->cc_softticks; + cc->cc_softticks++; + bucket = &cc->cc_callwheel[curticks & callwheelmask]; + c = TAILQ_FIRST(bucket); + while (c) { + depth++; + if (c->c_time != curticks) { + c = TAILQ_NEXT(c, c_links.tqe); + ++steps; + if (steps >= MAX_SOFTCLOCK_STEPS) { + cc->cc_next = c; + /* Give interrupts a chance. */ + CC_UNLOCK(cc); + ; /* nothing */ + CC_LOCK(cc); + c = cc->cc_next; + steps = 0; + } + } else { + void (*c_func)(void *); + void *c_arg; + struct lock_class *class; + struct lock_object *c_lock; + int c_flags, sharedlock; + + cc->cc_next = TAILQ_NEXT(c, c_links.tqe); + TAILQ_REMOVE(bucket, c, c_links.tqe); + class = (c->c_lock != NULL) ? + LOCK_CLASS(c->c_lock) : NULL; + sharedlock = (c->c_flags & CALLOUT_SHAREDLOCK) ? + 0 : 1; + c_lock = c->c_lock; + c_func = c->c_func; + c_arg = c->c_arg; + c_flags = c->c_flags; + if (c->c_flags & CALLOUT_LOCAL_ALLOC) { + c->c_flags = CALLOUT_LOCAL_ALLOC; + } else { + c->c_flags = + (c->c_flags & ~CALLOUT_PENDING); + } + cc->cc_curr = c; + cc->cc_cancel = 0; + CC_UNLOCK(cc); + if (c_lock != NULL) { + class->lc_lock(c_lock, sharedlock); + /* + * The callout may have been cancelled + * while we switched locks. + */ + if (cc->cc_cancel) { + class->lc_unlock(c_lock); + goto skip; + } + /* The callout cannot be stopped now. */ + cc->cc_cancel = 1; + + if (c_lock == &Giant.lock_object) { + gcalls++; + CTR3(KTR_CALLOUT, + "callout %p func %p arg %p", + c, c_func, c_arg); + } else { + lockcalls++; + CTR3(KTR_CALLOUT, "callout lock" + " %p func %p arg %p", + c, c_func, c_arg); + } + } else { + mpcalls++; + CTR3(KTR_CALLOUT, + "callout mpsafe %p func %p arg %p", + c, c_func, c_arg); + } +#ifdef DIAGNOSTIC + binuptime(&bt1); +#endif + THREAD_NO_SLEEPING(); + SDT_PROBE(callout_execute, kernel, , + callout_start, c, 0, 0, 0, 0); + c_func(c_arg); + SDT_PROBE(callout_execute, kernel, , + callout_end, c, 0, 0, 0, 0); + THREAD_SLEEPING_OK(); +#ifdef DIAGNOSTIC + binuptime(&bt2); + bintime_sub(&bt2, &bt1); + if (bt2.frac > maxdt) { + if (lastfunc != c_func || + bt2.frac > maxdt * 2) { + bintime2timespec(&bt2, &ts2); + printf( + "Expensive timeout(9) function: %p(%p) %jd.%09ld s\n", + c_func, c_arg, + (intmax_t)ts2.tv_sec, + ts2.tv_nsec); + } + maxdt = bt2.frac; + lastfunc = c_func; + } +#endif + CTR1(KTR_CALLOUT, "callout %p finished", c); + if ((c_flags & CALLOUT_RETURNUNLOCKED) == 0) + class->lc_unlock(c_lock); + skip: + CC_LOCK(cc); + /* + * If the current callout is locally + * allocated (from timeout(9)) + * then put it on the freelist. + * + * Note: we need to check the cached + * copy of c_flags because if it was not + * local, then it's not safe to deref the + * callout pointer. + */ + if (c_flags & CALLOUT_LOCAL_ALLOC) { + KASSERT(c->c_flags == + CALLOUT_LOCAL_ALLOC, + ("corrupted callout")); + c->c_func = NULL; + SLIST_INSERT_HEAD(&cc->cc_callfree, c, + c_links.sle); + } + cc->cc_curr = NULL; + if (cc->cc_waiting) { + /* + * There is someone waiting + * for the callout to complete. + */ + cc->cc_waiting = 0; + CC_UNLOCK(cc); + pthread_cond_broadcast(&callout_cv); + CC_LOCK(cc); + } + steps = 0; + c = cc->cc_next; + } + } + } + avg_depth += (depth * 1000 - avg_depth) >> 8; + avg_mpcalls += (mpcalls * 1000 - avg_mpcalls) >> 8; + avg_lockcalls += (lockcalls * 1000 - avg_lockcalls) >> 8; + avg_gcalls += (gcalls * 1000 - avg_gcalls) >> 8; + cc->cc_next = NULL; + CC_UNLOCK(cc); +} + /* * timeout -- * Execute a function after a specified length of time. @@ -129,12 +520,134 @@ timeout(ftn, arg, to_ticks) return (handle); } +void +untimeout(ftn, arg, handle) + timeout_t *ftn; + void *arg; + struct callout_handle handle; +{ + struct callout_cpu *cc; + /* + * Check for a handle that was initialized + * by callout_handle_init, but never used + * for a real timeout. + */ + if (handle.callout == NULL) + return; + + cc = callout_lock(handle.callout); + if (handle.callout->c_func == ftn && handle.callout->c_arg == arg) + callout_stop(handle.callout); + CC_UNLOCK(cc); +} + +void +callout_handle_init(struct callout_handle *handle) +{ + handle->callout = NULL; +} + +/* + * New interface; clients allocate their own callout structures. + * + * callout_reset() - establish or change a timeout + * callout_stop() - disestablish a timeout + * callout_init() - initialize a callout structure so that it can + * safely be passed to callout_reset() and callout_stop() + * + * defines three convenience macros: + * + * callout_active() - returns truth if callout has not been stopped, + * drained, or deactivated since the last time the callout was + * reset. + * callout_pending() - returns truth if callout is still waiting for timeout + * callout_deactivate() - marks the callout as having been serviced + */ int callout_reset_on(struct callout *c, int to_ticks, void (*ftn)(void *), void *arg, int cpu) { - + struct callout_cpu *cc; + int cancelled = 0; + + /* + * Don't allow migration of pre-allocated callouts lest they + * become unbalanced. + */ + if (c->c_flags & CALLOUT_LOCAL_ALLOC) + cpu = c->c_cpu; +retry: + cc = callout_lock(c); + if (cc->cc_curr == c) { + /* + * We're being asked to reschedule a callout which is + * currently in progress. If there is a lock then we + * can cancel the callout if it has not really started. + */ + if (c->c_lock != NULL && !cc->cc_cancel) + cancelled = cc->cc_cancel = 1; + if (cc->cc_waiting) { + /* + * Someone has called callout_drain to kill this + * callout. Don't reschedule. + */ + CTR4(KTR_CALLOUT, "%s %p func %p arg %p", + cancelled ? "cancelled" : "failed to cancel", + c, c->c_func, c->c_arg); + CC_UNLOCK(cc); + return (cancelled); + } + } + if (c->c_flags & CALLOUT_PENDING) { + if (cc->cc_next == c) { + cc->cc_next = TAILQ_NEXT(c, c_links.tqe); + } + TAILQ_REMOVE(&cc->cc_callwheel[c->c_time & callwheelmask], c, + c_links.tqe); + + cancelled = 1; + c->c_flags &= ~(CALLOUT_ACTIVE | CALLOUT_PENDING); + } + /* + * If the lock must migrate we have to check the state again as + * we can't hold both the new and old locks simultaneously. + */ + if (c->c_cpu != cpu) { + c->c_cpu = cpu; + CC_UNLOCK(cc); + goto retry; + } + + if (to_ticks <= 0) + to_ticks = 1; + + c->c_arg = arg; + c->c_flags |= (CALLOUT_ACTIVE | CALLOUT_PENDING); + c->c_func = ftn; + c->c_time = ticks + to_ticks; + TAILQ_INSERT_TAIL(&cc->cc_callwheel[c->c_time & callwheelmask], + c, c_links.tqe); + CTR5(KTR_CALLOUT, "%sscheduled %p func %p arg %p in %d", + cancelled ? "re" : "", c, c->c_func, c->c_arg, to_ticks); + CC_UNLOCK(cc); + + return (cancelled); +} + +/* + * Common idioms that can be optimized in the future. + */ +int +callout_schedule_on(struct callout *c, int to_ticks, int cpu) +{ + return callout_reset_on(c, to_ticks, c->c_func, c->c_arg, cpu); +} + +int +callout_schedule(struct callout *c, int to_ticks) +{ + return callout_reset_on(c, to_ticks, c->c_func, c->c_arg, c->c_cpu); } int @@ -142,9 +655,95 @@ _callout_stop_safe(c, safe) struct callout *c; int safe; { - -} + struct callout_cpu *cc; + struct lock_class *class; + int use_lock, sq_locked; + + /* + * Some old subsystems don't hold Giant while running a callout_stop(), + * so just discard this check for the moment. + */ + if (!safe && c->c_lock != NULL) { + if (c->c_lock == &Giant.lock_object) + use_lock = mtx_owned(&Giant); + else { + use_lock = 1; + class = LOCK_CLASS(c->c_lock); + class->lc_assert(c->c_lock, LA_XLOCKED); + } + } else + use_lock = 0; + + sq_locked = 0; +again: + cc = callout_lock(c); + /* + * If the callout isn't pending, it's not on the queue, so + * don't attempt to remove it from the queue. We can try to + * stop it by other means however. + */ + if (!(c->c_flags & CALLOUT_PENDING)) { + c->c_flags &= ~CALLOUT_ACTIVE; + + /* + * If it wasn't on the queue and it isn't the current + * callout, then we can't stop it, so just bail. + */ + if (cc->cc_curr != c) { + CTR3(KTR_CALLOUT, "failed to stop %p func %p arg %p", + c, c->c_func, c->c_arg); + CC_UNLOCK(cc); + return (0); + } + + if (safe) { + /* + * The current callout is running (or just + * about to run) and blocking is allowed, so + * just wait for the current invocation to + * finish. + */ + while (cc->cc_curr == c) { + pthread_cond_wait(&callout_cv, &cc->cc_lock); + } + } else if (use_lock && !cc->cc_cancel) { + /* + * The current callout is waiting for its + * lock which we hold. Cancel the callout + * and return. After our caller drops the + * lock, the callout will be skipped in + * softclock(). + */ + cc->cc_cancel = 1; + CTR3(KTR_CALLOUT, "cancelled %p func %p arg %p", + c, c->c_func, c->c_arg); + CC_UNLOCK(cc); + return (1); + } + CTR3(KTR_CALLOUT, "failed to stop %p func %p arg %p", + c, c->c_func, c->c_arg); + CC_UNLOCK(cc); + return (0); + } + + c->c_flags &= ~(CALLOUT_ACTIVE | CALLOUT_PENDING); + + if (cc->cc_next == c) { + cc->cc_next = TAILQ_NEXT(c, c_links.tqe); + } + TAILQ_REMOVE(&cc->cc_callwheel[c->c_time & callwheelmask], c, + c_links.tqe); + CTR3(KTR_CALLOUT, "cancelled %p func %p arg %p", + c, c->c_func, c->c_arg); + + if (c->c_flags & CALLOUT_LOCAL_ALLOC) { + c->c_func = NULL; + SLIST_INSERT_HEAD(&cc->cc_callfree, c, c_links.sle); + } + CC_UNLOCK(cc); + return (1); +} void callout_init(c, mpsafe) @@ -168,4 +767,16 @@ _callout_init_lock(c, lock, flags) struct lock_object *lock; int flags; { + bzero(c, sizeof *c); + c->c_lock = lock; + KASSERT((flags & ~(CALLOUT_RETURNUNLOCKED | CALLOUT_SHAREDLOCK)) == 0, + ("callout_init_lock: bad flags %d", flags)); + KASSERT(lock != NULL || (flags & CALLOUT_RETURNUNLOCKED) == 0, + ("callout_init_lock: CALLOUT_RETURNUNLOCKED with no lock")); + KASSERT(lock == NULL || !(LOCK_CLASS(lock)->lc_flags & + (LC_SPINLOCK | LC_SLEEPABLE)), ("%s: invalid lock class", + __func__)); + c->c_flags = flags & (CALLOUT_RETURNUNLOCKED | CALLOUT_SHAREDLOCK); + c->c_cpu = timeout_cpu; } + From owner-svn-src-user@FreeBSD.ORG Tue Jan 12 07:34:24 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 040EE106566C; Tue, 12 Jan 2010 07:34:24 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id E79558FC15; Tue, 12 Jan 2010 07:34:23 +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 o0C7YNb0016219; Tue, 12 Jan 2010 07:34:23 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0C7YN5Q016216; Tue, 12 Jan 2010 07:34:23 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201001120734.o0C7YN5Q016216@svn.freebsd.org> From: Ed Schouten Date: Tue, 12 Jan 2010 07:34:23 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202141 - user/ed/utmpx/lib/libulog X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 12 Jan 2010 07:34:24 -0000 Author: ed Date: Tue Jan 12 07:34:23 2010 New Revision: 202141 URL: http://svn.freebsd.org/changeset/base/202141 Log: Since ut_id is binary, just use a hash function to generate ut_id. I also wanted to include ut_pid into the hash as well, effectively only allowing ulog_logout() to be called by the same pid, but in practice this doesn't work, because ulog_log{in,out}_pseudo() spawn a process. I could use the parent process ID, though... Modified: user/ed/utmpx/lib/libulog/Makefile user/ed/utmpx/lib/libulog/ulog_login.c Modified: user/ed/utmpx/lib/libulog/Makefile ============================================================================== --- user/ed/utmpx/lib/libulog/Makefile Tue Jan 12 07:33:33 2010 (r202140) +++ user/ed/utmpx/lib/libulog/Makefile Tue Jan 12 07:34:23 2010 (r202141) @@ -19,6 +19,9 @@ MLINKS+=ulog_login.3 ulog_login_pseudo.3 utempter_remove_added_record.3 removeFromUtmp.3 \ utempter_remove_record.3 removeLineFromUtmp.3 +DPADD= ${LIBMD} +LDADD= -lmd + VERSION_DEF= ${.CURDIR}/../libc/Versions.def SYMBOL_MAPS= ${.CURDIR}/Symbol.map Modified: user/ed/utmpx/lib/libulog/ulog_login.c ============================================================================== --- user/ed/utmpx/lib/libulog/ulog_login.c Tue Jan 12 07:33:33 2010 (r202140) +++ user/ed/utmpx/lib/libulog/ulog_login.c Tue Jan 12 07:34:23 2010 (r202141) @@ -27,28 +27,37 @@ #include __FBSDID("$FreeBSD$"); +#include #include #include +#include #include #include #include #include "ulog.h" static void -ulog_genid(struct utmpx *utx, const char *line) +ulog_fill(struct utmpx *utx, const char *line) { - size_t s, d; + SHA_CTX c; + char id[SHA_DIGEST_LENGTH]; - /* - * Generate an ut_id based on the TTY name. Use a reverse order - * to prevent the limited space we have to be wasted on prefixes - * like "tty" and "pts/". It also makes sure aliasing because - * of cropping of "pts/1000" and "pts/1001" is less likely. - * Prepend an 'u' to indicate it was done by libulog. - */ - utx->ut_id[0] = 'u'; - for (s = strlen(line), d = 1; s > 0 && d < sizeof utx->ut_id; s--, d++) - utx->ut_id[d] = line[s - 1]; + /* Remove /dev/ component. */ + if (strncmp(line, _PATH_DEV, sizeof _PATH_DEV - 1) == 0) + line += sizeof _PATH_DEV - 1; + + memset(utx, 0, sizeof *utx); + + utx->ut_pid = getpid(); + gettimeofday(&utx->ut_tv, NULL); + strncpy(utx->ut_line, line, sizeof utx->ut_line); + + SHA1_Init(&c); + SHA1_Update(&c, "libulog", 7); + SHA1_Update(&c, utx->ut_line, sizeof utx->ut_line); + SHA_Final(id, &c); + + memcpy(utx->ut_id, id, MIN(sizeof utx->ut_id, sizeof id)); } void @@ -56,21 +65,11 @@ ulog_login(const char *line, const char { struct utmpx utx; - /* Remove /dev/ component. */ - if (strncmp(line, _PATH_DEV, sizeof _PATH_DEV - 1) == 0) - line += sizeof _PATH_DEV - 1; - - memset(&utx, 0, sizeof utx); - + ulog_fill(&utx, line); utx.ut_type = USER_PROCESS; - utx.ut_pid = getpid(); - ulog_genid(&utx, line); - strncpy(utx.ut_line, line, sizeof utx.ut_line); strncpy(utx.ut_user, user, sizeof utx.ut_user); if (host != NULL) strncpy(utx.ut_host, host, sizeof utx.ut_host); - gettimeofday(&utx.ut_tv, NULL); - pututxline(&utx); } @@ -79,16 +78,7 @@ ulog_logout(const char *line) { struct utmpx utx; - /* Remove /dev/ component. */ - if (strncmp(line, _PATH_DEV, sizeof _PATH_DEV - 1) == 0) - line += sizeof _PATH_DEV - 1; - - memset(&utx, 0, sizeof utx); - + ulog_fill(&utx, line); utx.ut_type = DEAD_PROCESS; - utx.ut_pid = getpid(); - ulog_genid(&utx, line); - gettimeofday(&utx.ut_tv, NULL); - pututxline(&utx); } From owner-svn-src-user@FreeBSD.ORG Tue Jan 12 09:06:36 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 94E881065679; Tue, 12 Jan 2010 09:06:36 +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 840618FC13; Tue, 12 Jan 2010 09:06:36 +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 o0C96aWx036887; Tue, 12 Jan 2010 09:06:36 GMT (envelope-from luigi@svn.freebsd.org) Received: (from luigi@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0C96ade036886; Tue, 12 Jan 2010 09:06:36 GMT (envelope-from luigi@svn.freebsd.org) Message-Id: <201001120906.o0C96ade036886@svn.freebsd.org> From: Luigi Rizzo Date: Tue, 12 Jan 2010 09:06:36 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202145 - user/luigi/ipfw3-head/sys/netinet/ipfw X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 12 Jan 2010 09:06:36 -0000 Author: luigi Date: Tue Jan 12 09:06:36 2010 New Revision: 202145 URL: http://svn.freebsd.org/changeset/base/202145 Log: add support for hash tables Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c Tue Jan 12 07:55:02 2010 (r202144) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c Tue Jan 12 09:06:36 2010 (r202145) @@ -291,16 +291,170 @@ heap_free(struct dn_heap *h) bzero(h, sizeof(*h) ); } +/* + * hash table +*/ + +struct dn_ht * +dn_ht_init(struct dn_ht *ht, int buckets, int ofs, + int (*h)(void *, uintptr_t arg), + int (*match)(void *, void *, uintptr_t arg), + void *(*new)(void *, uintptr_t arg), uintptr_t arg) +{ + int l; + + if (h == NULL) + return NULL; + if (buckets < 1 || buckets > 65536) + return NULL; + if (ht) { /* see if we can reuse */ + if (buckets <= ht->buckets) { + ht->buckets = buckets; + } else { + /* free pointers if not allocated inline */ + if (ht->ht != (void *)(ht + 1)) + free(ht->ht, M_DN_HEAP); + free(ht, M_DN_HEAP); + ht = NULL; + } + } + if (ht == NULL) { + l = sizeof(*ht) + buckets * sizeof(void **); + ht = malloc(l, M_DN_HEAP, M_NOWAIT); + } + if (ht) { + ht->ht = (void **)(ht + 1); + ht->buckets = buckets; + ht->ofs = ofs; + ht->hash = h; + ht->match = match; + ht->new = new; + ht->arg = arg; + } + return ht; +} + +/* lookup and optionally create element */ +void * +dn_ht_find(struct dn_ht *ht, void *obj, int create) +{ + int i; + void *p; + + i = (ht->buckets == 1) ? 0 : ht->hash(obj, ht->arg) % ht->buckets; + // log(1, "find %p in bucket %d\n", obj, i); + for (p = ht->ht[i]; p; p = *(void **)((char *)p + ht->ofs)) { + if (ht->match(p, obj, ht->arg)) + break; + } + if (p == NULL && create) { + p = ht->new(obj, ht->arg); + if (p) { + ht->entries++; + *(void **)((char *)p + ht->ofs) = ht->ht[i]; + ht->ht[i] = p; + } + } + return p; +} + +int +dn_ht_scan(struct dn_ht *ht, int (*fn)(void *, uintptr_t), uintptr_t arg) +{ + int i, ret, found = 0; + void *p, **prev; + + for (i = 0; i < ht->buckets; i++) { + prev = &ht->ht[i]; + while ( (p = *prev) != NULL) { + ret = fn(p, arg); + if (ret & HEAP_SCAN_DEL) { + found++; + ht->entries--; + *prev = *(void **)((char *)p + ht->ofs); + } + if (ret & HEAP_SCAN_END) + return found; + prev = (void **)((char *)p + ht->ofs); + } + } + return found; +} + + #ifndef _KERNEL /* - * testing code for the heap + * testing code for the heap and hash table */ +#include + +struct x { + struct x *ht_link; + char buf[0]; +}; + +int hfn(void *_x, uintptr_t arg) +{ + char *p = _x; + return p[0]; +} + +void *newfn(void *_x, uintptr_t arg) +{ + char *s = _x; + struct x *p = malloc(sizeof(*p) + 1 + strlen(s), + M_DN_HEAP, 0); + if (p) + strcpy(p->buf, s); + return p; +} + +int matchfn(void *_x, void *_obj, uintptr_t arg) +{ + struct x *x = _x; + return (strcmp(x->buf, _obj) == 0); +} + +char *strings[] = { + "undici", "unico", "doppio", "devoto", + "uno", "due", "tre", "quattro", "cinque", "sei", + "uno", "due", "tre", "quattro", "cinque", "sei", + NULL, +}; + +int doprint(void *_x, uintptr_t arg) +{ + struct x *x = _x; + printf("found element <%s>\n", x->buf); + return arg; +} + +static void +test_hash() +{ + char **p; + struct dn_ht *h = dn_ht_init(NULL, 10, 0, hfn, matchfn, newfn, + 0); + + for (p = strings; *p; p++) { + dn_ht_find(h, *p, 1); + } + dn_ht_scan(h, doprint, 0); + for (p = strings; *p; p++) { +// dn_ht_scan(h, doprint, HEAP_SCAN_DEL); + dn_ht_find(h, *p, 1); + } +} + int main(int argc, char *argv[]) { struct dn_heap h; int i, n, n2, n3; + test_hash(); + return 0; + /* n = elements, n2 = cycles */ n = (argc > 1) ? atoi(argv[1]) : 0; if (n <= 0 || n > 1000000) Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h Tue Jan 12 07:55:02 2010 (r202144) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h Tue Jan 12 09:06:36 2010 (r202145) @@ -83,4 +83,31 @@ enum { */ int heap_scan(struct dn_heap *, int (*)(void *, uintptr_t), uintptr_t); +/*--- generic hash table support ---*/ +struct dn_ht { + int buckets; /* how many buckets */ + int entries; /* how many entries */ + int ofs; /* offset of link field */ + uintptr_t arg; /* arg to hash function */ + int (*hash)(void *, uintptr_t arg); + int (*match)(void *, void *, uintptr_t arg); + void *(*new)(void *, uintptr_t arg); /* object create function */ + void **ht; /* bucket heads */ +}; + +struct dn_ht *dn_ht_init(struct dn_ht *, int buckets, int ofs, + int (*h)(void *, uintptr_t arg), + int (*match)(void *, void *, uintptr_t arg), + void *(*new)(void *, uintptr_t arg), + uintptr_t arg); + +/* lookup and optionally create element */ +void *dn_ht_find(struct dn_ht *, void *obj, int create); + +enum { + DN_HT_SCAN_DEL = 1, + DN_HT_SCAN_END = 2, +}; +int dn_ht_scan(struct dn_ht *, int (*)(void *, uintptr_t), uintptr_t); + #endif /* _IP_DN_HEAP_H */ From owner-svn-src-user@FreeBSD.ORG Tue Jan 12 09:07:55 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 67D031065670; Tue, 12 Jan 2010 09:07:55 +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 576418FC14; Tue, 12 Jan 2010 09:07:55 +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 o0C97tQ3037222; Tue, 12 Jan 2010 09:07:55 GMT (envelope-from luigi@svn.freebsd.org) Received: (from luigi@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0C97tUe037219; Tue, 12 Jan 2010 09:07:55 GMT (envelope-from luigi@svn.freebsd.org) Message-Id: <201001120907.o0C97tUe037219@svn.freebsd.org> From: Luigi Rizzo Date: Tue, 12 Jan 2010 09:07:55 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202146 - user/luigi/ipfw3-head/sys/netinet/ipfw X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 12 Jan 2010 09:07:55 -0000 Author: luigi Date: Tue Jan 12 09:07:55 2010 New Revision: 202146 URL: http://svn.freebsd.org/changeset/base/202146 Log: move the tagging out of the main function. add a flag for schedulers to indicate whether they can handle multiple queues or not. Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h Tue Jan 12 09:06:36 2010 (r202145) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h Tue Jan 12 09:07:55 2010 (r202146) @@ -32,6 +32,7 @@ #ifndef _DN_SCHED_H #define _DN_SCHED_H +#define DN_MULTIQUEUE 0x01 /* * Descriptor for the scheduler. * Contains all function pointers for a given scheduler @@ -39,7 +40,8 @@ * in a global list of schedulers. */ struct dn_sched { - int type; /* the scheduler type */ + uint32_t type; /* the scheduler type */ + uint32_t flags; /* DN_MULTIQUEUE if supports multiple queues */ const char *name; /* scheduler name */ int ref_count; /* XXX number of instances in the system */ Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Tue Jan 12 09:06:36 2010 (r202145) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Tue Jan 12 09:07:55 2010 (r202146) @@ -739,6 +739,27 @@ ipdn_locate_flowset(int fs_nr) return (fs); } +static inline int +tag_mbuf(struct mbuf *m, int dir, struct ip_fw_args *fwa) +{ + struct dn_pkt_tag *dt; + struct m_tag *mtag; + + mtag = m_tag_get(PACKET_TAG_DUMMYNET, + sizeof(*dt), M_NOWAIT | M_ZERO); + if (mtag == NULL) + return 1; /* Cannot allocate packet header. */ + m_tag_prepend(m, mtag); /* Attach to mbuf chain. */ + dt = (struct dn_pkt_tag *)(mtag + 1); + dt->rule = fwa->rule; + dt->rule.info &= IPFW_ONEPASS; /* only keep this info */ + dt->dn_dir = dir; + dt->ifp = fwa->oif; + /* dt->output tame is updated as we move through */ + dt->output_time = curr_time; + return 0; +} + /* * dummynet hook for packets. * We use the argument to locate the flowset fs and the sched_set sch @@ -762,6 +783,7 @@ dummynet_io(struct mbuf **m0, int dir, s ((fwa->rule.info & IPFW_IS_PIPE) ? DN_PIPEOFFSET : 0); DUMMYNET_LOCK(); io_pkt++; + now = curr_time; /* XXX locate_flowset could be optimised with a direct ref. */ fs = ipdn_locate_flowset(fs_id); if (fs == NULL) @@ -772,24 +794,13 @@ dummynet_io(struct mbuf **m0, int dir, s si = find_sch_inst(fs->sched, &(fwa->f_id)); if (si == NULL) goto dropit; - - /* tag the mbuf */ - { - struct dn_pkt_tag *dt; - struct m_tag *mtag; - mtag = m_tag_get(PACKET_TAG_DUMMYNET, - sizeof(*dt), M_NOWAIT | M_ZERO); - if (mtag == NULL) - goto dropit; /* Cannot allocate packet header. */ - m_tag_prepend(m, mtag); /* Attach to mbuf chain. */ - dt = (struct dn_pkt_tag *)(mtag + 1); - dt->rule = fwa->rule; - dt->rule.info &= IPFW_ONEPASS; /* only keep this info */ - dt->dn_dir = dir; - dt->ifp = fwa->oif; - /* dt->output tame is updated as we move through */ - dt->output_time = now = curr_time; - } + if (tag_mbuf(m, dir, fwa)) + goto dropit; + /* + * if the scheduler has a single queue (e.g. FIFO) then + * call directly with NULL queue. Otherwise find a queue + * and pass it. + */ if (fs->kflags & DN_HAVE_MASK) do_mask(&fs->fs.flow_mask, &(fwa->f_id)); if (fs->sched->fp->enqueue(si, fs, m, &(fwa->f_id))) { From owner-svn-src-user@FreeBSD.ORG Tue Jan 12 09:55:25 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 784B310656A8; Tue, 12 Jan 2010 09:55:25 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 4F0478FC0C; Tue, 12 Jan 2010 09:55:25 +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 o0C9tPnt047683; Tue, 12 Jan 2010 09:55:25 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0C9tPZf047681; Tue, 12 Jan 2010 09:55:25 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201001120955.o0C9tPZf047681@svn.freebsd.org> From: Ed Schouten Date: Tue, 12 Jan 2010 09:55:25 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202147 - user/ed/utmpx/lib/libc/gen X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 12 Jan 2010 09:55:25 -0000 Author: ed Date: Tue Jan 12 09:55:25 2010 New Revision: 202147 URL: http://svn.freebsd.org/changeset/base/202147 Log: Fix allocation policy of utx.active. It is a bad idea to always overwrite the first DEAD_PROCESS/invalid entry we see, because there may be another DEAD_PROCESS entry further on whose ut_id value matches the record we want to add, making getutxid() return multiple records. Be sure to scan the file for an exact match and only overwrite DEAD_PROCESS/invalid entries when no exact match was found. This still keeps the file size to a minimum, because the maximum size of the file will be limited to the highest amount of logins at a certain moment in time. Modified: user/ed/utmpx/lib/libc/gen/pututxline.c Modified: user/ed/utmpx/lib/libc/gen/pututxline.c ============================================================================== --- user/ed/utmpx/lib/libc/gen/pututxline.c Tue Jan 12 09:07:55 2010 (r202146) +++ user/ed/utmpx/lib/libc/gen/pututxline.c Tue Jan 12 09:55:25 2010 (r202147) @@ -61,6 +61,7 @@ utx_active_add(const struct futx *fu) { int fd; struct futx fe; + off_t partial = -1; /* * Register user login sessions. Overwrite entries of sessions @@ -78,15 +79,30 @@ utx_active_add(const struct futx *fu) case USER_PROCESS: case INIT_PROCESS: case LOGIN_PROCESS: - if (memcmp(fu->fu_id, fe.fu_id, sizeof fe.fu_id) != 0) - continue; + case DEAD_PROCESS: + /* Overwrite when ut_id matches. */ + if (memcmp(fu->fu_id, fe.fu_id, sizeof fe.fu_id) == 0) { + lseek(fd, -sizeof fe, SEEK_CUR); + goto exact; + } + if (fe.fu_type != DEAD_PROCESS) + break; /* FALLTHROUGH */ default: - lseek(fd, -sizeof fe, SEEK_CUR); - goto found; + /* Allow us to overwrite unused records. */ + if (partial == -1) + partial = lseek(fd, 0, SEEK_CUR); + break; } } -found: + + /* + * No exact match found. Use the partial match. If no partial + * match was found, just append a new record. + */ + if (partial != -1) + lseek(fd, partial, SEEK_SET); +exact: _write(fd, fu, sizeof *fu); lockf(fd, F_ULOCK, 0); _close(fd); From owner-svn-src-user@FreeBSD.ORG Tue Jan 12 10:06:32 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id BD645106566C; Tue, 12 Jan 2010 10:06:32 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id AD9E38FC16; Tue, 12 Jan 2010 10:06:32 +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 o0CA6W0n050253; Tue, 12 Jan 2010 10:06:32 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0CA6Wgf050251; Tue, 12 Jan 2010 10:06:32 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201001121006.o0CA6Wgf050251@svn.freebsd.org> From: Ed Schouten Date: Tue, 12 Jan 2010 10:06:32 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202148 - user/ed/utmpx/lib/libc/gen X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 12 Jan 2010 10:06:32 -0000 Author: ed Date: Tue Jan 12 10:06:32 2010 New Revision: 202148 URL: http://svn.freebsd.org/changeset/base/202148 Log: Fix an off-by-one introduced in the previous commit. When receiving a partial match, we should overwrite the record itself. Because we call lseek() afterwards, we get the offset of the next to it. Modified: user/ed/utmpx/lib/libc/gen/pututxline.c Modified: user/ed/utmpx/lib/libc/gen/pututxline.c ============================================================================== --- user/ed/utmpx/lib/libc/gen/pututxline.c Tue Jan 12 09:55:25 2010 (r202147) +++ user/ed/utmpx/lib/libc/gen/pututxline.c Tue Jan 12 10:06:32 2010 (r202148) @@ -91,7 +91,7 @@ utx_active_add(const struct futx *fu) default: /* Allow us to overwrite unused records. */ if (partial == -1) - partial = lseek(fd, 0, SEEK_CUR); + partial = lseek(fd, 0, SEEK_CUR) - sizeof fe; break; } } From owner-svn-src-user@FreeBSD.ORG Tue Jan 12 10:13:10 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 714C91065676; Tue, 12 Jan 2010 10:13:10 +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 26B738FC1E; Tue, 12 Jan 2010 10:13:10 +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 o0CADASW051758; Tue, 12 Jan 2010 10:13:10 GMT (envelope-from luigi@svn.freebsd.org) Received: (from luigi@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0CADANl051755; Tue, 12 Jan 2010 10:13:10 GMT (envelope-from luigi@svn.freebsd.org) Message-Id: <201001121013.o0CADANl051755@svn.freebsd.org> From: Luigi Rizzo Date: Tue, 12 Jan 2010 10:13:10 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202149 - user/luigi/ipfw3-head/sys/netinet/ipfw X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 12 Jan 2010 10:13:10 -0000 Author: luigi Date: Tue Jan 12 10:13:09 2010 New Revision: 202149 URL: http://svn.freebsd.org/changeset/base/202149 Log: add removal code, fix some bugs Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c Tue Jan 12 10:06:32 2010 (r202148) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c Tue Jan 12 10:13:09 2010 (r202149) @@ -292,9 +292,15 @@ heap_free(struct dn_heap *h) } /* - * hash table -*/ + * hash table support. + */ +/* + * Initialize, allocating bucket pointers inline. + * Recycle previous record if possible. + * If the 'new' function is not supplied, we assume that the + * key passed to ht_find is the same object to be stored in. + */ struct dn_ht * dn_ht_init(struct dn_ht *ht, int buckets, int ofs, int (*h)(void *, uintptr_t arg), @@ -336,19 +342,19 @@ dn_ht_init(struct dn_ht *ht, int buckets /* lookup and optionally create element */ void * -dn_ht_find(struct dn_ht *ht, void *obj, int create) +dn_ht_find(struct dn_ht *ht, void *key, int create) { int i; void *p; - i = (ht->buckets == 1) ? 0 : ht->hash(obj, ht->arg) % ht->buckets; + i = (ht->buckets == 1) ? 0 : ht->hash(key, ht->arg) % ht->buckets; // log(1, "find %p in bucket %d\n", obj, i); for (p = ht->ht[i]; p; p = *(void **)((char *)p + ht->ofs)) { - if (ht->match(p, obj, ht->arg)) + if (ht->match(p, key, ht->arg)) break; } if (p == NULL && create) { - p = ht->new(obj, ht->arg); + p = ht->new ? ht->new(key, ht->arg) : key; if (p) { ht->entries++; *(void **)((char *)p + ht->ofs) = ht->ht[i]; @@ -381,6 +387,29 @@ dn_ht_scan(struct dn_ht *ht, int (*fn)(v return found; } +/* + * remove obj from the table, using key to find the slot. + * Returns obj if found, NULL if not found + */ +void * +dn_ht_remove(struct dn_ht *ht, void *obj, void *key) +{ + int i; + void **pp, *p; + + i = (ht->buckets == 1) ? 0 : ht->hash(obj, ht->arg) % ht->buckets; + // log(1, "find %p in bucket %d\n", obj, i); + for (pp = &ht->ht[i]; (p = *pp); pp = (void **)((char *)p + ht->ofs)) { + if (p != obj) + continue; + /* link in the next element */ + *pp = *(void **)((char *)p + ht->ofs); + *(void **)((char *)p + ht->ofs) = NULL; + ht->entries--; + return obj; + } + return NULL; /* failed */ +} #ifndef _KERNEL /* @@ -393,10 +422,23 @@ struct x { char buf[0]; }; -int hfn(void *_x, uintptr_t arg) +int hfn1(void *_x, uintptr_t arg) { - char *p = _x; - return p[0]; + return *(char *)_x; +} +int matchfn1(void *_x, void *_obj, uintptr_t arg) +{ + return (strcmp(((struct x *)_x)->buf, _obj) == 0); +} + +int hfn2(void *_x, uintptr_t arg) +{ + return ((struct x *)_x)->buf[0]; +} +int matchfn2(void *_x, void *_obj, uintptr_t arg) +{ + return (strcmp(((struct x *)_x)->buf, + ((struct x *)_obj)->buf) == 0); } void *newfn(void *_x, uintptr_t arg) @@ -409,12 +451,6 @@ void *newfn(void *_x, uintptr_t arg) return p; } -int matchfn(void *_x, void *_obj, uintptr_t arg) -{ - struct x *x = _x; - return (strcmp(x->buf, _obj) == 0); -} - char *strings[] = { "undici", "unico", "doppio", "devoto", "uno", "due", "tre", "quattro", "cinque", "sei", @@ -433,17 +469,28 @@ static void test_hash() { char **p; - struct dn_ht *h = dn_ht_init(NULL, 10, 0, hfn, matchfn, newfn, - 0); + struct dn_ht *h; + void *x = NULL; + + /* first, find and allocate */ + h = dn_ht_init(NULL, 10, 0, hfn1, matchfn1, newfn, 0); for (p = strings; *p; p++) { dn_ht_find(h, *p, 1); } dn_ht_scan(h, doprint, 0); + printf("/* second -- find without allocate */\n"); + h = dn_ht_init(NULL, 10, 0, hfn2, matchfn2, NULL, 0); for (p = strings; *p; p++) { -// dn_ht_scan(h, doprint, HEAP_SCAN_DEL); - dn_ht_find(h, *p, 1); + void **y = newfn(*p, 0); + if (x == NULL) + x = y; + dn_ht_find(h, y, 1); } + dn_ht_scan(h, doprint, 0); + printf("remove %p gives %p\n", x, dn_ht_remove(h, x, x)); + printf("remove %p gives %p\n", x, dn_ht_remove(h, x, x)); + dn_ht_scan(h, doprint, 0); } int Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h Tue Jan 12 10:06:32 2010 (r202148) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h Tue Jan 12 10:13:09 2010 (r202149) @@ -98,11 +98,12 @@ struct dn_ht { struct dn_ht *dn_ht_init(struct dn_ht *, int buckets, int ofs, int (*h)(void *, uintptr_t arg), int (*match)(void *, void *, uintptr_t arg), - void *(*new)(void *, uintptr_t arg), + void *(*new)(void *, uintptr_t arg), uintptr_t arg); /* lookup and optionally create element */ -void *dn_ht_find(struct dn_ht *, void *obj, int create); +void *dn_ht_find(struct dn_ht *, void *key, int create); +void *dn_ht_remove(struct dn_ht *, void *obj, void *key); enum { DN_HT_SCAN_DEL = 1, From owner-svn-src-user@FreeBSD.ORG Tue Jan 12 13:45:40 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 7F6C2106566B; Tue, 12 Jan 2010 13:45:40 +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 6CB2D8FC0A; Tue, 12 Jan 2010 13:45:40 +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 o0CDjeRg002502; Tue, 12 Jan 2010 13:45:40 GMT (envelope-from luigi@svn.freebsd.org) Received: (from luigi@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0CDjeFZ002493; Tue, 12 Jan 2010 13:45:40 GMT (envelope-from luigi@svn.freebsd.org) Message-Id: <201001121345.o0CDjeFZ002493@svn.freebsd.org> From: Luigi Rizzo Date: Tue, 12 Jan 2010 13:45:40 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202151 - user/luigi/ipfw3-head/sys/netinet/ipfw X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 12 Jan 2010 13:45:40 -0000 Author: luigi Date: Tue Jan 12 13:45:40 2010 New Revision: 202151 URL: http://svn.freebsd.org/changeset/base/202151 Log: save snapshot Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c Tue Jan 12 11:11:25 2010 (r202150) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c Tue Jan 12 13:45:40 2010 (r202151) @@ -303,14 +303,16 @@ heap_free(struct dn_heap *h) */ struct dn_ht * dn_ht_init(struct dn_ht *ht, int buckets, int ofs, - int (*h)(void *, uintptr_t arg), - int (*match)(void *, void *, uintptr_t arg), - void *(*new)(void *, uintptr_t arg), uintptr_t arg) + int (*h)(uintptr_t, int, void *), + int (*match)(void *, uintptr_t, int, void *), + void *(*new)(uintptr_t, int, void *), void *arg) { int l; - if (h == NULL) + if (h == NULL || match == NULL) { + printf("missing hash or match function"); return NULL; + } if (buckets < 1 || buckets > 65536) return NULL; if (ht) { /* see if we can reuse */ @@ -340,21 +342,29 @@ dn_ht_init(struct dn_ht *ht, int buckets return ht; } -/* lookup and optionally create element */ +/* lookup and optionally create or delete element */ void * -dn_ht_find(struct dn_ht *ht, void *key, int create) +dn_ht_find(struct dn_ht *ht, uintptr_t key, int flags) { int i; - void *p; + void **pp, *p; - i = (ht->buckets == 1) ? 0 : ht->hash(key, ht->arg) % ht->buckets; + i = (ht->buckets == 1) ? 0 : + (ht->hash(key, flags, ht->arg) % ht->buckets); // log(1, "find %p in bucket %d\n", obj, i); - for (p = ht->ht[i]; p; p = *(void **)((char *)p + ht->ofs)) { - if (ht->match(p, key, ht->arg)) + for (pp = &ht->ht[i]; (p = *pp); pp = (void **)((char *)p + ht->ofs)) { + if (ht->match(p, key, flags, ht->arg)) break; } - if (p == NULL && create) { - p = ht->new ? ht->new(key, ht->arg) : key; + if (p) { + if (flags & DNHT_REMOVE) { + /* link in the next element */ + *pp = *(void **)((char *)p + ht->ofs); + *(void **)((char *)p + ht->ofs) = NULL; + ht->entries--; + } + } else if (flags & DNHT_INSERT) { + p = ht->new ? ht->new(key, flags, ht->arg) : (void *)key; if (p) { ht->entries++; *(void **)((char *)p + ht->ofs) = ht->ht[i]; @@ -365,7 +375,7 @@ dn_ht_find(struct dn_ht *ht, void *key, } int -dn_ht_scan(struct dn_ht *ht, int (*fn)(void *, uintptr_t), uintptr_t arg) +dn_ht_scan(struct dn_ht *ht, int (*fn)(void *, void *), void *arg) { int i, ret, found = 0; void *p, **prev; @@ -387,30 +397,6 @@ dn_ht_scan(struct dn_ht *ht, int (*fn)(v return found; } -/* - * remove obj from the table, using key to find the slot. - * Returns obj if found, NULL if not found - */ -void * -dn_ht_remove(struct dn_ht *ht, void *obj, void *key) -{ - int i; - void **pp, *p; - - i = (ht->buckets == 1) ? 0 : ht->hash(obj, ht->arg) % ht->buckets; - // log(1, "find %p in bucket %d\n", obj, i); - for (pp = &ht->ht[i]; (p = *pp); pp = (void **)((char *)p + ht->ofs)) { - if (p != obj) - continue; - /* link in the next element */ - *pp = *(void **)((char *)p + ht->ofs); - *(void **)((char *)p + ht->ofs) = NULL; - ht->entries--; - return obj; - } - return NULL; /* failed */ -} - #ifndef _KERNEL /* * testing code for the heap and hash table @@ -422,30 +408,23 @@ struct x { char buf[0]; }; -int hfn1(void *_x, uintptr_t arg) +int hf(uintptr_t key, int flags, void *arg) { - return *(char *)_x; -} -int matchfn1(void *_x, void *_obj, uintptr_t arg) -{ - return (strcmp(((struct x *)_x)->buf, _obj) == 0); + return (flags & DNHT_KEY_IS_OBJ) ? + ((struct x *)key)->buf[0] : *(char *)key; } -int hfn2(void *_x, uintptr_t arg) +int matchf(void *obj, uintptr_t key, int flags, void *arg) { - return ((struct x *)_x)->buf[0]; -} -int matchfn2(void *_x, void *_obj, uintptr_t arg) -{ - return (strcmp(((struct x *)_x)->buf, - ((struct x *)_obj)->buf) == 0); + char *s = (flags & DNHT_KEY_IS_OBJ) ? + ((struct x *)key)->buf : (char *)key; + return (strcmp(((struct x *)obj)->buf, s) == 0); } -void *newfn(void *_x, uintptr_t arg) +void *newfn(uintptr_t key, int flags, void *arg) { - char *s = _x; - struct x *p = malloc(sizeof(*p) + 1 + strlen(s), - M_DN_HEAP, 0); + char *s = (char *)key; + struct x *p = malloc(sizeof(*p) + 1 + strlen(s), M_DN_HEAP, 0); if (p) strcpy(p->buf, s); return p; @@ -470,26 +449,37 @@ test_hash() { char **p; struct dn_ht *h; - void *x = NULL; + uintptr_t x = 0; + uintptr_t x1 = 0; /* first, find and allocate */ - h = dn_ht_init(NULL, 10, 0, hfn1, matchfn1, newfn, 0); + h = dn_ht_init(NULL, 10, 0, hf, matchf, newfn, 0); for (p = strings; *p; p++) { - dn_ht_find(h, *p, 1); + dn_ht_find(h, (uintptr_t)*p, DNHT_INSERT); } dn_ht_scan(h, doprint, 0); printf("/* second -- find without allocate */\n"); - h = dn_ht_init(NULL, 10, 0, hfn2, matchfn2, NULL, 0); + h = dn_ht_init(NULL, 10, 0, hf, matchf, NULL, 0); for (p = strings; *p; p++) { - void **y = newfn(*p, 0); - if (x == NULL) - x = y; - dn_ht_find(h, y, 1); + void **y = newfn((uintptr_t)*p, 0, NULL); + if (x == 0) + x = (uintptr_t)y; + else { + if (x1 == 0) + x1 = (uintptr_t)*p; + } + dn_ht_find(h, (uintptr_t)y, DNHT_INSERT | DNHT_KEY_IS_OBJ); } dn_ht_scan(h, doprint, 0); - printf("remove %p gives %p\n", x, dn_ht_remove(h, x, x)); - printf("remove %p gives %p\n", x, dn_ht_remove(h, x, x)); + printf("remove %p gives %p\n", (void *)x, + dn_ht_find(h, x, DNHT_KEY_IS_OBJ | DNHT_REMOVE)); + printf("remove %p gives %p\n", (void *)x, + dn_ht_find(h, x, DNHT_KEY_IS_OBJ | DNHT_REMOVE)); + printf("remove %p gives %p\n", (void *)x, + dn_ht_find(h, x1, DNHT_REMOVE)); + printf("remove %p gives %p\n", (void *)x, + dn_ht_find(h, x1, DNHT_REMOVE)); dn_ht_scan(h, doprint, 0); } Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h Tue Jan 12 11:11:25 2010 (r202150) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h Tue Jan 12 13:45:40 2010 (r202151) @@ -88,27 +88,32 @@ struct dn_ht { int buckets; /* how many buckets */ int entries; /* how many entries */ int ofs; /* offset of link field */ - uintptr_t arg; /* arg to hash function */ - int (*hash)(void *, uintptr_t arg); - int (*match)(void *, void *, uintptr_t arg); - void *(*new)(void *, uintptr_t arg); /* object create function */ + void *arg; /* argument to the three functions */ + int (*hash)(uintptr_t, int, void *arg); + int (*match)(void *_el, uintptr_t key, int, void *); + void *(*new)(uintptr_t, int, void *); void **ht; /* bucket heads */ }; struct dn_ht *dn_ht_init(struct dn_ht *, int buckets, int ofs, - int (*h)(void *, uintptr_t arg), - int (*match)(void *, void *, uintptr_t arg), - void *(*new)(void *, uintptr_t arg), - uintptr_t arg); + int (*hash)(uintptr_t, int, void *), + int (*match)(void *, uintptr_t, int, void *), + void *(*new)(uintptr_t, int, void *), void *arg); -/* lookup and optionally create element */ -void *dn_ht_find(struct dn_ht *, void *key, int create); -void *dn_ht_remove(struct dn_ht *, void *obj, void *key); +/* lookup and optionally create or remove element. Flags described below */ +void *dn_ht_find(struct dn_ht *, uintptr_t key, int flags); -enum { - DN_HT_SCAN_DEL = 1, - DN_HT_SCAN_END = 2, +enum { /* flags values. + * first two are returned by the scan callback to indicate + * to delete the matching element or to end the scan + */ + DNHT_SCAN_DEL = 0x0001, + DNHT_SCAN_END = 0x0002, + DNHT_KEY_IS_OBJ = 0x0004, /* key is the obj pointer */ + DNHT_INSERT = 0x0008, /* insert if not found */ + DNHT_UNIQUE = 0x0010, /* report error if already there */ + DNHT_REMOVE = 0x0020, /* remove on find */ }; -int dn_ht_scan(struct dn_ht *, int (*)(void *, uintptr_t), uintptr_t); +int dn_ht_scan(struct dn_ht *, int (*)(void *, void *), void *); #endif /* _IP_DN_HEAP_H */ Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h Tue Jan 12 11:11:25 2010 (r202150) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h Tue Jan 12 13:45:40 2010 (r202151) @@ -115,8 +115,8 @@ struct dn_sched { * drain_queue called to free all idle queues, or possibly all of * them (this is a subset of delete_scheduler_instance) */ - int (*enqueue)(struct new_sch_inst *, struct new_fsk *, - struct mbuf *, struct ipfw_flow_id *); + int (*enqueue)(struct new_sch_inst *, struct new_queue *, + struct mbuf *); struct mbuf * (*dequeue)(struct new_sch_inst *); /* config or destroy the scheduler template */ Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c Tue Jan 12 11:11:25 2010 (r202150) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c Tue Jan 12 13:45:40 2010 (r202151) @@ -61,43 +61,11 @@ struct fifo_si { }; static int -fifo_enqueue(struct new_sch_inst *_si, struct new_fsk *f, - struct mbuf *m, struct ipfw_flow_id *id) +fifo_enqueue(struct new_sch_inst *_si, struct new_queue *q, struct mbuf *m) { - /* - * The system pass to the enqueue() function 4 parameters: - * - s: scheduler instance which the packet belongs - * - f: flowset scheduler private data - * - m: the packet - * - id: flow id of the packet, the mask is applyed by system - * - * The scheduler should save all data needs into variables in the - * scheduler instance. In the FIFO scheduling algorithm there is only - * one queue, so a queue should be saved in the scheduler instance. - * When the first packet arrives, the queue doesn't exist and the - * scheduler must create it calling the dn_create_queue() function. - * To really enqueue the packet, the scheduler must call the - * dn_queue_packet() function that insert the packet in the queue passes. - * If for some reason (for example the queue is full) the packet can't - * be enqueued, dn_queue_packet() returns 1. - * - * See the enqueue() function for wf2q+ scheduler algorithm for - * another examples of enqueue() - */ - - /* Access to specific scheduler instance data */ - struct fifo_si *si = (struct fifo_si *)(_si+1); - - if (si->q == NULL) { - si->q = dn_create_queue(_si, f, id); - if (si->q == NULL) { - printf("%s dn_create_queue failed\n", __FUNCTION__); - FREE_PKT(m); - return 1; - } - } - /* Now the si->q is valid, so insert the packet in this queue */ - if (dn_queue_packet(si->q, m)) { + /* the queue is actually embedded here */ + q = (struct new_queue *)(_si+1); + if (dn_queue_packet(q, m)) { printf("%s dn_queue_packet failed\n", __FUNCTION__); /* packet was dropped */ return 1; @@ -138,9 +106,9 @@ static int fifo_new_sched(struct new_schk *s, struct new_sch_inst *_si) { /* This scheduler instance only has a queue pointer. */ - struct fifo_si *si = (struct fifo_si *)(_si + 1); + struct new_queue *q = (struct new_queue *)(_si + 1); - si->q = NULL; + q->si = _si; return 0; } @@ -154,8 +122,7 @@ static struct dn_sched fifo_desc = { .type = DN_SCHED_FIFO, .name = "FIFO", - .sch_inst_len = sizeof(struct fifo_si), - .queue_len = sizeof(struct new_queue), + .sch_inst_len = sizeof(struct new_queue), .enqueue = fifo_enqueue, .dequeue = fifo_dequeue, Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c Tue Jan 12 11:11:25 2010 (r202150) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c Tue Jan 12 13:45:40 2010 (r202151) @@ -62,42 +62,12 @@ struct fifo_si { }; static int -fifo_enqueue(struct new_sch_inst *_si, struct new_fsk *f, - struct mbuf *m, struct ipfw_flow_id *id) +fifo_enqueue(struct new_sch_inst *_si, struct new_queue *q, struct mbuf *m) { - /* - * The system pass to the enqueue() function 4 parameters: - * - s: scheduler instance which the packet belongs - * - f: flowset scheduler private data - * - m: the packet - * - id: flow id of the packet, the mask is applyed by system - * - * The scheduler should save all data needs into variables in the - * scheduler instance. In the FIFO scheduling algorithm there is only - * one queue, so a queue should be saved in the scheduler instance. - * When the first packet arrives, the queue doesn't exist and the - * scheduler must create it calling the dn_create_queue() function. - * To really enqueue the packet, the scheduler must call the - * dn_queue_packet() function that insert the packet in the queue passes. - * If for some reason (for example the queue is full) the packet can't - * be enqueued, dn_queue_packet() returns 1. - * - * See the enqueue() function for wf2q+ scheduler algorithm for - * another examples of enqueue() - */ - - /* Access to specific scheduler instance data */ - struct fifo_si *si = (struct fifo_si *)(_si+1); - - if (si->q == NULL) { - si->q = dn_create_queue(_si, f, id); - if (si->q == NULL) { - FREE_PKT(m); - return 1; - } - } - /* Now the si->q is valid, so insert the packet in this queue */ - if (dn_queue_packet(si->q, m)) { + /* the queue is actually embedded here */ + q = (struct new_queue *)(_si+1); + if (dn_queue_packet(q, m)) { + printf("%s dn_queue_packet failed\n", __FUNCTION__); /* packet was dropped */ return 1; } @@ -137,14 +107,14 @@ static int fifo_new_sched(struct new_schk *s, struct new_sch_inst *_si) { /* This scheduler instance only has a queue pointer. */ - struct fifo_si *si = (struct fifo_si *)(_si + 1); + struct new_queue *q = (struct new_queue *)(_si + 1); - si->q = NULL; + q->si = _si; return 0; } /* - * WF2Q(fake) scheduler descriptor + * FIFO scheduler descriptor * contains the type of the scheduler, the name, the size of the various * structures and function pointers. If a function is not implemented, * the pointer is initialized to NULL @@ -153,8 +123,7 @@ static struct dn_sched fifo_desc = { .type = DN_SCHED_WF2QP, .name = "WF2Q+", - .sch_inst_len = sizeof(struct fifo_si), - .queue_len = sizeof(struct new_queue), + .sch_inst_len = sizeof(struct new_queue), .enqueue = fifo_enqueue, .dequeue = fifo_dequeue, Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Tue Jan 12 11:11:25 2010 (r202150) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Tue Jan 12 13:45:40 2010 (r202151) @@ -84,7 +84,7 @@ struct dn_parms dn_cfg = { .red_lookup_depth = 256, /* RED - default lookup table depth */ .red_avg_pkt_size = 512, /* RED - default medium packet size */ .red_max_pkt_size = 1500, /* RED - default max packet size */ - .hmask = (1<<4) - 1, + .buckets = 16, }; static long tick_last; /* Last tick duration (usec). */ @@ -320,189 +320,8 @@ extra_bits(struct mbuf *m, struct new_pi return bits; } -/* Do masking depending of flow id */ -static struct ipfw_flow_id * -do_mask(struct ipfw_flow_id *mask, struct ipfw_flow_id *id) -{ - int is_v6 = IS_IP6_FLOW_ID(id); - id->dst_port &= mask->dst_port; - id->src_port &= mask->src_port; - id->proto &= mask->proto; - id->flags = 0; /* we don't care about this one */ - if (is_v6) { - APPLY_MASK(&id->dst_ip6, &mask->dst_ip6); - APPLY_MASK(&id->src_ip6, &mask->src_ip6); - id->flow_id6 &= mask->flow_id6; - } else { - id->dst_ip &= mask->dst_ip; - id->src_ip &= mask->src_ip; - } - return id; -} - -/* - * Calculate the hash of a flow id. - * XXX we may want a better hash function - */ -static int -do_hash(struct ipfw_flow_id *id) -{ - int i; - int is_v6 = IS_IP6_FLOW_ID(id); - - if (is_v6) { - uint32_t *d = (uint32_t *)&id->dst_ip6; - uint32_t *s = (uint32_t *)&id->src_ip6; - i = (d[0] & 0xffff)^ - (d[1] & 0xffff)^ - (d[2] & 0xffff)^ - (d[3] & 0xffff)^ - - ((d[0] >> 15) & 0xffff)^ - ((d[1] >> 15) & 0xffff)^ - ((d[2] >> 15) & 0xffff)^ - ((d[3] >> 15) & 0xffff)^ - - ((s[0] << 1) & 0xfffff)^ - ((s[1] << 1) & 0xfffff)^ - ((s[2] << 1) & 0xfffff)^ - ((s[3] << 1) & 0xfffff)^ - - ((s[0] << 16) & 0xffff)^ - ((s[1] << 16) & 0xffff)^ - ((s[2] << 16) & 0xffff)^ - ((s[3] << 16) & 0xffff)^ - - (id->dst_port << 1) ^ (id->src_port) ^ - (id->proto ) ^ - (id->flow_id6); - } else { - i = ( (id->dst_ip) & 0xffff ) ^ - ( (id->dst_ip >> 15) & 0xffff ) ^ - ( (id->src_ip << 1) & 0xffff ) ^ - ( (id->src_ip >> 16 ) & 0xffff ) ^ - (id->dst_port << 1) ^ (id->src_port) ^ - (id->proto ); - } - return i; -} - -/* - * Like bcmp, returns 0 if ids match, 1 otherwise. - */ -static int -flow_id_cmp(struct ipfw_flow_id *id1, struct ipfw_flow_id *id2) -{ - int is_v6 = IS_IP6_FLOW_ID(id1); - if (is_v6 != IS_IP6_FLOW_ID(id2)) - return 1; /* a ipv4 and a ipv6 flow */ - - if (!is_v6 && id1->dst_ip == id2->dst_ip && - id1->src_ip == id2->src_ip && - id1->dst_port == id2->dst_port && - id1->src_port == id2->src_port && - id1->proto == id2->proto && - id1->flags == id2->flags) - return 0; - - if (is_v6 && - !bcmp(&id1->dst_ip6,&id2->dst_ip6, sizeof(id1->dst_ip6)) && - !bcmp(&id1->src_ip6,&id2->src_ip6, sizeof(id1->src_ip6)) && - id1->dst_port == id2->dst_port && - id1->src_port == id2->src_port && - id1->proto == id2->proto && - id1->flags == id2->flags && - id1->flow_id6 == id2->flow_id6) - return 0; - - /* Masks differ */ - return 1; -} - -/* - * Create a new scheduler instance for the scheduler 'sch_t'. - * Allocate memory for instance, delay line and scheduler private data. - */ -static struct new_sch_inst * -create_si(struct new_schk *s, int slot) -{ - struct new_sch_inst *si; - int ret; - int l = sizeof(*si) + s->fp->sch_inst_len; - - si = malloc(l, M_DUMMYNET, M_NOWAIT | M_ZERO); - if (si == NULL) - goto error; - /* XXX note we set the length only for the initial part which - * is passed up to userland. - */ - set_oid(&si->ni.oid, DN_SCH_I, 0, sizeof(struct new_inst)); - set_oid(&(si->dline.oid), DN_DELAY_LINE, 0, sizeof(struct delay_line)); - si->ni.oid.id = si->dline.oid.id = -1; /* mark outside scheduler */ - - si->sched = s; - si->dline.si = si; - - if (s->fp->new_sched) { - ret = s->fp->new_sched(s, si); - if (ret) { - printf("%s: new_sched error %d\n", __FUNCTION__, ret); - goto error; - } - } - - /* Initialize list of queues attached here */ - SLIST_INIT(&si->ql_list); - - /* Put entry in front of the hash list of the parent. */ - SLIST_INSERT_HEAD(&s->ht[slot], si, next); - si->ni.hash_slot = slot; - dn_cfg.si_count++; - return si; - -error: - if (si) - free(si, M_DUMMYNET); - return NULL; -} - -/* - * Find the scheduler instance for this packet. If we need to apply - * a mask, do on a local copy of the flow_id to preserve the original. - */ -static struct new_sch_inst * -find_sch_inst(struct new_schk *s, struct ipfw_flow_id *id) -{ - struct new_sch_inst *si; - struct ipfw_flow_id id_t; - int i; - - if ( 0 == (s->sch.flags & DN_HAVE_MASK) ) { - i = 0; - si = SLIST_FIRST(&s->ht[0]); - } else { - id_t = *id; - do_mask(&s->sch.sched_mask, &id_t); - i = do_hash(&id_t); - i = i % s->ht_slots; - /* finally, scan the current hash bucket for a match */ - searches++; - SLIST_FOREACH(si, &s->ht[i], next) { - search_steps++; - if (!flow_id_cmp(&id_t, &si->ni.id)) - break; /* found */ - } - } - - if (si == NULL) { /* no match, allocate a new entry */ - si = create_si(s, i); - if (si && s->sch.flags & DN_HAVE_MASK) - si->ni.id = id_t; - } - return si; -} /* * Send traffic from a scheduler instance due by 'now'. @@ -731,12 +550,7 @@ dummynet_send(struct mbuf *m) struct new_fsk * ipdn_locate_flowset(int fs_nr) { - struct new_fsk *fs = NULL; - - SLIST_FOREACH(fs, &dn_cfg.fshash[HASH(fs_nr)], next) - if (fs->fs.fs_nr == fs_nr) - break; - return (fs); + return dn_ht_find(dn_cfg.fshash, fs_nr, 0); } static inline int @@ -777,6 +591,7 @@ dummynet_io(struct mbuf **m0, int dir, s struct mbuf *m = *m0; struct new_fsk *fs = NULL; struct new_sch_inst *si; + struct new_queue *q; dn_key now; /* save a copy of curr_time */ int fs_id = (fwa->rule.info & IPFW_INFO_MASK) + @@ -790,8 +605,8 @@ dummynet_io(struct mbuf **m0, int dir, s goto dropit; /* This queue/pipe does not exist! */ if (fs->sched == NULL) /* should not happen */ goto dropit; - /* find_sch_inst can be fast */ - si = find_sch_inst(fs->sched, &(fwa->f_id)); + /* dn_si_find can be fast */ + si = ipdn_si_find(fs->sched, &(fwa->f_id)); if (si == NULL) goto dropit; if (tag_mbuf(m, dir, fwa)) @@ -801,9 +616,15 @@ dummynet_io(struct mbuf **m0, int dir, s * call directly with NULL queue. Otherwise find a queue * and pass it. */ - if (fs->kflags & DN_HAVE_MASK) - do_mask(&fs->fs.flow_mask, &(fwa->f_id)); - if (fs->sched->fp->enqueue(si, fs, m, &(fwa->f_id))) { + if (fs->sched->fp->flags & DN_MULTIQUEUE) { + q = dn_ht_find(fs->qht, (uintptr_t)&(fwa->f_id), + DNHT_INSERT); + if (q == NULL) + goto dropit; + } else { + q = NULL; + } + if (fs->sched->fp->enqueue(si, q, m)) { printf("%s dropped by enqueue\n", __FUNCTION__); /* packet was dropped by enqueue() */ *m0 = NULL; Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h Tue Jan 12 11:11:25 2010 (r202150) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h Tue Jan 12 13:45:40 2010 (r202151) @@ -77,11 +77,10 @@ struct dn_parms { int fsk_count; int queue_count; - int hmask; /* mask for hashsize, must be 2^n-1 */ - /* fhash and schedhash are hmask+1 entries */ - struct new_fsk_head fsunlinked; - struct new_fsk_head *fshash; - struct new_schk_head *schedhash; + int buckets; /* for the two hash tables */ + struct dn_ht *fshash; + struct dn_ht *schedhash; + struct new_fsk_head fsunlinked; /* use sch_chain */ }; static inline void @@ -111,7 +110,7 @@ struct delay_line { * The kernel side of a flowset. Contains: * - configuration parameters (fs, cmdline); * - kernel info (kflags) - * - link field for the hash chain (next) + * - link field for the hash chain * - reference to the scheduler; * - a refcount (from queues) * - link field for a list of fsk attached to sched (used when sched @@ -123,17 +122,20 @@ struct delay_line { */ struct new_fsk { /* kernel side of a flowset */ struct new_fs fs; - SLIST_ENTRY(new_fsk) next; /* hash chain list */ + SLIST_ENTRY(new_fsk) fsk_next; /* hash chain list */ int kflags; /* kernel-side flags */ /* * Scheduler-specific parameters for this flowset * (for examples, the weight parameter of wf2q+ algorithm goes here) */ - struct dn_id *cfg; + int weight; + int quantum; /* Number of queues attached to this flowset */ int refcnt; + /* hash table of queues, or just our queue if we have no mask */ + struct dn_ht *qht; /* Scheduler associated with this flowset */ struct new_schk *sched; SLIST_ENTRY(new_fsk) sch_chain; /* list of fsk attached to sched */ @@ -150,19 +152,14 @@ struct new_schk { * how many instances are in the heap and can be used * as a reference count. */ - SLIST_ENTRY(new_schk) next; /* List of all templates */ + SLIST_ENTRY(new_schk) schk_next; /* List of all templates */ struct new_fsk_head fsk_list; /* all fsk linked to me */ struct new_pipe pipe; /* the pipe is embedded */ struct dn_id *cfg; /* extra config arguments */ - /* Hash table contains all scheduler instances associated with - * this scheduler. We scan the list when we need to destroy - * the instances. - */ - int ht_slots; /* number of slots */ - struct new_sch_inst_head *ht; - struct new_sch_inst_head h0; /* used if malloc fails */ + /* Hash table of all children. Used to apply the sched_mask */ + struct dn_ht *siht; int kflags; @@ -189,7 +186,7 @@ SLIST_HEAD(new_queue_head, new_queue); */ struct new_sch_inst { struct new_inst ni; /* oid, id and stats */ - SLIST_ENTRY(new_sch_inst) next; /* next item in the bucket */ + SLIST_ENTRY(new_sch_inst) si_next; /* next item in the bucket */ struct delay_line dline; struct new_schk *sched; /* the template */ int kflags; /* DN_SCHED_ACTIVE */ @@ -224,5 +221,6 @@ dn_create_queue(struct new_sch_inst *si, struct ipfw_flow_id *id); +struct new_sch_inst *ipdn_si_find(struct new_schk *s, struct ipfw_flow_id *id); #endif /* _IP_DN_PRIVATE_H */ Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Tue Jan 12 11:11:25 2010 (r202150) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Tue Jan 12 13:45:40 2010 (r202151) @@ -67,7 +67,6 @@ static int ip_dn_ctl(struct sockopt *sop #define DN_C_FS 0x08 #define DN_C_QUEUE 0x10 - static int config_pipe(struct new_pipe *p, struct dn_id *arg); static int config_profile(struct new_profile *p, struct dn_id *arg); static int config_fs(struct new_fs *p, struct dn_id *arg); @@ -122,13 +121,152 @@ static __inline void dn_free_pkts(struct } } +/*---- flow_id mask, hash and compare functions ---*/ +static struct ipfw_flow_id * +flow_id_mask(struct ipfw_flow_id *mask, struct ipfw_flow_id *id) +{ + int is_v6 = IS_IP6_FLOW_ID(id); + + id->dst_port &= mask->dst_port; + id->src_port &= mask->src_port; + id->proto &= mask->proto; + id->flags = 0; /* we don't care about this one */ + if (is_v6) { + APPLY_MASK(&id->dst_ip6, &mask->dst_ip6); + APPLY_MASK(&id->src_ip6, &mask->src_ip6); + id->flow_id6 &= mask->flow_id6; + } else { + id->dst_ip &= mask->dst_ip; + id->src_ip &= mask->src_ip; + } + + return id; +} + +/* XXX we may want a better hash function */ +static int +flow_id_hash(struct ipfw_flow_id *id) +{ + int i; + int is_v6 = IS_IP6_FLOW_ID(id); + +#define M 0xffff + if (is_v6) { + uint32_t *d = (uint32_t *)&id->dst_ip6; + uint32_t *s = (uint32_t *)&id->src_ip6; + i = (d[0] & M) ^ (d[1] & M) ^ + (d[2] & M) ^ (d[3] & M) ^ + + ((d[0] >> 15) & M) ^ ((d[1] >> 15) & M) ^ + ((d[2] >> 15) & M) ^ ((d[3] >> 15) & M) ^ + + ((s[0] << 1) & M) ^ ((s[1] << 1) & M) ^ + ((s[2] << 1) & M) ^ ((s[3] << 1) & M) ^ + + ((s[0] << 16) & M) ^ ((s[1] << 16) & M) ^ + ((s[2] << 16) & M) ^ ((s[3] << 16) & M) ^ + + (id->dst_port << 1) ^ (id->src_port) ^ + (id->proto ) ^ (id->flow_id6); + } else { + i = ( (id->dst_ip) & M ) ^ + ( (id->dst_ip >> 15) & M ) ^ + ( (id->src_ip << 1) & M ) ^ + ( (id->src_ip >> 16 ) & M ) ^ + (id->dst_port << 1) ^ (id->src_port) ^ + (id->proto ); + } +#undef M + return i; +} + +/* Like bcmp, returns 0 if ids match, 1 otherwise. */ +static int +flow_id_cmp(struct ipfw_flow_id *id1, struct ipfw_flow_id *id2) +{ + int is_v6 = IS_IP6_FLOW_ID(id1); + if (is_v6 != IS_IP6_FLOW_ID(id2)) + return 1; /* a ipv4 and a ipv6 flow */ + + if (!is_v6 && id1->dst_ip == id2->dst_ip && + id1->src_ip == id2->src_ip && + id1->dst_port == id2->dst_port && + id1->src_port == id2->src_port && + id1->proto == id2->proto && + id1->flags == id2->flags) + return 0; + + if (is_v6 && + !bcmp(&id1->dst_ip6,&id2->dst_ip6, sizeof(id1->dst_ip6)) && + !bcmp(&id1->src_ip6,&id2->src_ip6, sizeof(id1->src_ip6)) && + id1->dst_port == id2->dst_port && + id1->src_port == id2->src_port && + id1->proto == id2->proto && + id1->flags == id2->flags && + id1->flow_id6 == id2->flow_id6) + return 0; + + /* Masks differ */ + return 1; +} + +/*--- support functions for the sch_inst hashtable ----*/ + /* - * Delete a scheduler instance and all the queues. - * Also remove from the heap. + * create a new instance for the given 'key' + * Allocate memory for instance, delay line and scheduler private data. + */ +static void * +si_new(uintptr_t key, int flags, void *arg) +{ + struct new_schk *s = arg; + struct new_sch_inst *si; + int l = sizeof(*si) + s->fp->sch_inst_len; + + si = malloc(l, M_DUMMYNET, M_NOWAIT | M_ZERO); + if (si == NULL) + goto error; + /* XXX note we set the length only for the initial part which + * is passed up to userland. + */ + set_oid(&si->ni.oid, DN_SCH_I, 0, sizeof(struct new_inst)); + set_oid(&(si->dline.oid), DN_DELAY_LINE, 0, sizeof(struct delay_line)); + si->ni.oid.id = si->dline.oid.id = -1; /* mark outside scheduler */ + + si->sched = s; + si->dline.si = si; + + if (s->fp->new_sched) { + int ret = s->fp->new_sched(s, si); + if (ret) { + printf("%s: new_sched error %d\n", __FUNCTION__, ret); + goto error; + } + } + + /* Initialize list of queues attached here */ + SLIST_INIT(&si->ql_list); + if (s->sch.flags & DN_HAVE_MASK) + si->ni.id = *(struct ipfw_flow_id *)key; + + dn_cfg.si_count++; + return si; + +error: + if (si) + free(si, M_DUMMYNET); + return NULL; +} + +/* + * Delete a scheduler instance and all the queues. This is a callback + * for the hashtable scan. + * Also remove from the system heap. */ static int -destroy_si(struct new_sch_inst *si) +si_destroy(void *_si, void *arg) { + struct new_sch_inst *si = _si; struct new_schk *s = si->sched; struct delay_line *dl = &si->dline; struct new_queue *q; @@ -150,24 +288,40 @@ destroy_si(struct new_sch_inst *si) } /* - * support to delete a flowset. - * if active (sched != NULL and ! DN_DELETE), put in the unlinked - * (otherwise it is already there). - * Then check refcnt and free when it becomes 0 + * Find the scheduler instance for this packet. If we need to apply + * a mask, do on a local copy of the flow_id to preserve the original. + */ +struct new_sch_inst * +ipdn_si_find(struct new_schk *s, struct ipfw_flow_id *id) +{ + struct new_sch_inst *si; + + if ( 0 == (s->sch.flags & DN_HAVE_MASK) ) { + if (s->siht == NULL) + s->siht = si_new((uintptr_t)id, 0, s); + si = (struct new_sch_inst *)s->siht; + } else { + struct ipfw_flow_id id_t = *id; + flow_id_mask(&s->sch.sched_mask, &id_t); + si = dn_ht_find(s->siht, (uintptr_t)&id_t, DNHT_INSERT); + } + return si; +} + +/*---- support functions for flowset hash table ----*/ +/* + * support to delete a flowset. Mark as delete, + * then check refcnt and free when it becomes 0 */ static void destroy_fs(struct new_fsk *fs) { struct new_schk *s = fs->sched; - if (fs->sched && (fs->kflags & DN_DELETE) == 0) { - SLIST_REMOVE(&dn_cfg.fshash[HASH(fs->fs.fs_nr)], - fs, new_fsk, next); - SLIST_INSERT_HEAD(&dn_cfg.fsunlinked, fs, next); - } fs->kflags |= DN_DELETE; if (fs->refcnt != 0) return; + fs->sched = NULL; dn_cfg.fsk_count--; SLIST_REMOVE(&s->fsk_list, fs, new_fsk, sch_chain); } @@ -177,9 +331,11 @@ create_fs(void) { struct new_fsk *fs; + // XXX we could use the hashtable support fs = malloc(sizeof(*fs), M_DUMMYNET, M_NOWAIT | M_ZERO); if (fs) { - SLIST_INSERT_HEAD(&dn_cfg.fsunlinked, fs, next); + dn_ht_find(dn_cfg.fshash, (uintptr_t)fs, + DNHT_KEY_IS_OBJ | DNHT_INSERT | DNHT_UNIQUE); dn_cfg.fsk_count++; } return fs; @@ -187,6 +343,7 @@ create_fs(void) /* * helper for schedulers. Creates a queue + * XXX actually, maybe only flowsets use this ? */ struct new_queue * dn_create_queue(struct new_sch_inst *si, struct new_fsk *fs, @@ -238,18 +395,9 @@ dn_delete_queue(struct new_queue *q, int static struct new_schk * destroy_schk(struct new_schk *s) { - int i; - struct new_sch_inst *si; struct dn_sched *fp = s->fp; -printf("%s slots %d\n", __FUNCTION__, s->ht_slots); - for (i = 0; i < s->ht_slots; i++) { - struct new_sch_inst_head *h = &s->ht[i]; - while ((si = SLIST_FIRST(h)) != NULL) { - SLIST_REMOVE_HEAD(h, next); - destroy_si(si); - } - } + dn_ht_scan(s->siht, si_destroy, NULL); if (fp->destroy) *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-src-user@FreeBSD.ORG Tue Jan 12 14:43:35 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 75812106566C; Tue, 12 Jan 2010 14:43:35 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 64BFB8FC0A; Tue, 12 Jan 2010 14:43:35 +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 o0CEhZLW015226; Tue, 12 Jan 2010 14:43:35 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0CEhZ9i015225; Tue, 12 Jan 2010 14:43:35 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201001121443.o0CEhZ9i015225@svn.freebsd.org> From: Ed Schouten Date: Tue, 12 Jan 2010 14:43:35 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202152 - user/ed/utmpx/lib/libc/gen X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 12 Jan 2010 14:43:35 -0000 Author: ed Date: Tue Jan 12 14:43:34 2010 New Revision: 202152 URL: http://svn.freebsd.org/changeset/base/202152 Log: According to lockf(3): File locks are released on first close by the locking process of any file descriptor for the file. No need to call it then. Modified: user/ed/utmpx/lib/libc/gen/pututxline.c Modified: user/ed/utmpx/lib/libc/gen/pututxline.c ============================================================================== --- user/ed/utmpx/lib/libc/gen/pututxline.c Tue Jan 12 13:45:40 2010 (r202151) +++ user/ed/utmpx/lib/libc/gen/pututxline.c Tue Jan 12 14:43:34 2010 (r202152) @@ -104,7 +104,6 @@ utx_active_add(const struct futx *fu) lseek(fd, partial, SEEK_SET); exact: _write(fd, fu, sizeof *fu); - lockf(fd, F_ULOCK, 0); _close(fd); } @@ -142,13 +141,11 @@ utx_active_remove(struct futx *fu) /* Terminate session. */ lseek(fd, -sizeof fe, SEEK_CUR); _write(fd, fu, sizeof *fu); - lockf(fd, F_ULOCK, 0); _close(fd); return (0); } } - lockf(fd, F_ULOCK, 0); _close(fd); return (1); } @@ -192,7 +189,6 @@ utx_lastlogin_add(const struct futx *fu) } _write(fd, fu, sizeof *fu); done: - lockf(fd, F_ULOCK, 0); _close(fd); } From owner-svn-src-user@FreeBSD.ORG Tue Jan 12 15:15:55 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A43131065679; Tue, 12 Jan 2010 15:15:55 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 9337B8FC23; Tue, 12 Jan 2010 15:15:55 +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 o0CFFtkn022383; Tue, 12 Jan 2010 15:15:55 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0CFFtGx022380; Tue, 12 Jan 2010 15:15:55 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201001121515.o0CFFtGx022380@svn.freebsd.org> From: Ed Schouten Date: Tue, 12 Jan 2010 15:15:55 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202153 - user/ed/utmpx/lib/libulog X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 12 Jan 2010 15:15:55 -0000 Author: ed Date: Tue Jan 12 15:15:55 2010 New Revision: 202153 URL: http://svn.freebsd.org/changeset/base/202153 Log: Fix man page refs. Modified: user/ed/utmpx/lib/libulog/ulog_login.3 user/ed/utmpx/lib/libulog/utempter_add_record.3 Modified: user/ed/utmpx/lib/libulog/ulog_login.3 ============================================================================== --- user/ed/utmpx/lib/libulog/ulog_login.3 Tue Jan 12 14:43:34 2010 (r202152) +++ user/ed/utmpx/lib/libulog/ulog_login.3 Tue Jan 12 15:15:55 2010 (r202153) @@ -90,13 +90,10 @@ and .Fn ulog_logout_pseudo functions spawn a privileged process to perform the actual logging. .Sh SEE ALSO -.Xr getuid 3 , -.Xr login 3 , -.Xr logout 3 , .Xr posix_openpt 2 , +.Xr getuid 3 , .Xr ptsname 3 , -.Xr ulog_getutxent 3 , -.Xr utmp 5 +.Xr pututxline 3 .Sh HISTORY These functions appeared in .Fx 9.0 . Modified: user/ed/utmpx/lib/libulog/utempter_add_record.3 ============================================================================== --- user/ed/utmpx/lib/libulog/utempter_add_record.3 Tue Jan 12 14:43:34 2010 (r202152) +++ user/ed/utmpx/lib/libulog/utempter_add_record.3 Tue Jan 12 15:15:55 2010 (r202153) @@ -98,9 +98,8 @@ and .Fn utempter_remove_record always return a value of 0. .Sh SEE ALSO -.Xr ulog_login_pseudo 3 , -.Xr ulog_setutxfile 3 , -.Xr utmp 5 +.Xr pututxline 3 , +.Xr ulog_login_pseudo 3 .Sh HISTORY These functions appeared in .Fx 9.0 . From owner-svn-src-user@FreeBSD.ORG Tue Jan 12 17:34:11 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 202471065670; Tue, 12 Jan 2010 17:34:11 +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 0EBB08FC0A; Tue, 12 Jan 2010 17:34:11 +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 o0CHYA3H053047; Tue, 12 Jan 2010 17:34:10 GMT (envelope-from luigi@svn.freebsd.org) Received: (from luigi@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0CHYAfU053045; Tue, 12 Jan 2010 17:34:10 GMT (envelope-from luigi@svn.freebsd.org) Message-Id: <201001121734.o0CHYAfU053045@svn.freebsd.org> From: Luigi Rizzo Date: Tue, 12 Jan 2010 17:34:10 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202158 - user/luigi/ipfw3-head/release/picobsd/build X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 12 Jan 2010 17:34:11 -0000 Author: luigi Date: Tue Jan 12 17:34:10 2010 New Revision: 202158 URL: http://svn.freebsd.org/changeset/base/202158 Log: remove some logverbose Modified: user/luigi/ipfw3-head/release/picobsd/build/picobsd Modified: user/luigi/ipfw3-head/release/picobsd/build/picobsd ============================================================================== --- user/luigi/ipfw3-head/release/picobsd/build/picobsd Tue Jan 12 17:03:55 2010 (r202157) +++ user/luigi/ipfw3-head/release/picobsd/build/picobsd Tue Jan 12 17:34:10 2010 (r202158) @@ -889,7 +889,7 @@ fill_floppy_image() { if [ ${mfs_start} -gt 0 -a ${mfs_size} -ge ${imgsize} ] ; then mfs_ofs=$((${mfs_start} + 8192)) log "Preload kernel with file ${c_fs} at ${mfs_ofs}" - logverbose "`ls -l ${c_fs}` to fit in ${mfs_size}" + log "`ls -l ${c_fs}` to fit in ${mfs_size}" dd if=${c_fs} ibs=8192 iseek=1 of=kernel obs=${mfs_ofs} \ oseek=1 conv=notrunc # 2> /dev/null else @@ -944,7 +944,7 @@ fill_floppy_image() { ls -l ${c_img} ${c_label} -f `pwd`/${c_img} - logverbose "after disklabel" + log "after disklabel" ) echo "BUILDDIR ${BUILDDIR}" @@ -958,7 +958,7 @@ fill_floppy_image() { dd if=${b2} iseek=1 ibs=276 2> /dev/null | \ dd of=${BUILDDIR}/${c_img} oseek=1 obs=788 conv=notrunc 2>/dev/null - logverbose "done floppy image" + log "done floppy image" # XXX (log "Fixing permissions"; cd ${dst}; chown -R root *) rm -rf ${BUILDDIR}/floppy.tree || true # cleanup # df -ik ${dst} | colrm 70 > .build.reply From owner-svn-src-user@FreeBSD.ORG Tue Jan 12 21:27:38 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 7C06B106566C; Tue, 12 Jan 2010 21:27:38 +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 6A26E8FC14; Tue, 12 Jan 2010 21:27:38 +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 o0CLRcPh005329; Tue, 12 Jan 2010 21:27:38 GMT (envelope-from luigi@svn.freebsd.org) Received: (from luigi@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0CLRcKU005321; Tue, 12 Jan 2010 21:27:38 GMT (envelope-from luigi@svn.freebsd.org) Message-Id: <201001122127.o0CLRcKU005321@svn.freebsd.org> From: Luigi Rizzo Date: Tue, 12 Jan 2010 21:27:38 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202174 - in user/luigi/ipfw3-head/sys/netinet: . ipfw X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 12 Jan 2010 21:27:38 -0000 Author: luigi Date: Tue Jan 12 21:27:38 2010 New Revision: 202174 URL: http://svn.freebsd.org/changeset/base/202174 Log: snapshot for today Modified: user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Modified: user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h Tue Jan 12 21:17:36 2010 (r202173) +++ user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h Tue Jan 12 21:27:38 2010 (r202174) @@ -46,8 +46,7 @@ struct dn_id { uint16_t len; /* total len including this header */ uint8_t type; uint8_t subtype; - uint32_t id; /* identifier in the sequence */ - struct dn_id *next; /* link field, for kernel */ + uintptr_t id; /* generic id or pointer */ }; /* @@ -189,7 +188,7 @@ struct new_inst { struct new_sch { struct dn_id oid; int sched_nr; /* N, scheduler number */ - int bucket; /* number of buckets for the instances */ + int buckets; /* number of buckets for the instances */ int flags; /* have_mask, ... */ char type[16]; /* null terminated */ Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c Tue Jan 12 21:17:36 2010 (r202173) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c Tue Jan 12 21:27:38 2010 (r202174) @@ -77,14 +77,14 @@ heap_init(struct dn_heap *h, int new_siz struct dn_heap_entry *p; if (h->size >= new_size ) { - printf("%s: Bogus call, have %d want %d\n", + printf("--- %s: Bogus call, have %d want %d\n", __func__, h->size, new_size); return 0; } new_size = (new_size + HEAP_INCREMENT ) & ~HEAP_INCREMENT; p = malloc(new_size * sizeof(*p), M_DN_HEAP, M_NOWAIT); if (p == NULL) { - printf("%s, resize %d failed\n", __func__, new_size ); + printf("--- %s, resize %d failed\n", __func__, new_size ); return 1; /* error */ } if (h->size > 0) { @@ -159,7 +159,7 @@ heap_extract(struct dn_heap *h, void *ob int child, father, max = h->elements - 1; if (max < 0) { - printf("%s: empty heap 0x%p\n", __FUNCTION__, h); + printf("--- %s: empty heap 0x%p\n", __FUNCTION__, h); return; } if (obj == NULL) @@ -309,8 +309,9 @@ dn_ht_init(struct dn_ht *ht, int buckets { int l; + // printf("%s buckets %d ofs %d\n", __FUNCTION__, buckets, ofs); if (h == NULL || match == NULL) { - printf("missing hash or match function"); + printf("--- missing hash or match function"); return NULL; } if (buckets < 1 || buckets > 65536) @@ -328,7 +329,7 @@ dn_ht_init(struct dn_ht *ht, int buckets } if (ht == NULL) { l = sizeof(*ht) + buckets * sizeof(void **); - ht = malloc(l, M_DN_HEAP, M_NOWAIT); + ht = malloc(l, M_DN_HEAP, M_NOWAIT | M_ZERO); } if (ht) { ht->ht = (void **)(ht + 1); @@ -353,7 +354,10 @@ dn_ht_find(struct dn_ht *ht, uintptr_t k (ht->hash(key, flags, ht->arg) % ht->buckets); // log(1, "find %p in bucket %d\n", obj, i); for (pp = &ht->ht[i]; (p = *pp); pp = (void **)((char *)p + ht->ofs)) { - if (ht->match(p, key, flags, ht->arg)) + if (flags & DNHT_MATCH_PTR) { + if (key == (uintptr_t)p) + break; + } else if (ht->match(p, key, flags, ht->arg)) /* found match */ break; } if (p) { @@ -364,7 +368,10 @@ dn_ht_find(struct dn_ht *ht, uintptr_t k ht->entries--; } } else if (flags & DNHT_INSERT) { + // printf("%s before calling new, bucket %d ofs %d\n", + // __FUNCTION__, i, ht->ofs); p = ht->new ? ht->new(key, flags, ht->arg) : (void *)key; + // printf("%s new returns %p\n", __FUNCTION__, p); if (p) { ht->entries++; *(void **)((char *)p + ht->ofs) = ht->ht[i]; @@ -374,24 +381,33 @@ dn_ht_find(struct dn_ht *ht, uintptr_t k return p; } +/* + * do a scan with the option to delete the object. Extract next before + * running the callback because the element may be destroyed there. + */ int dn_ht_scan(struct dn_ht *ht, int (*fn)(void *, void *), void *arg) { int i, ret, found = 0; - void *p, **prev; + void **curp, *cur, *next; + // printf("%p ht %p fn %p\n", __FUNCTION__, ht, fn); + if (ht == NULL || fn == NULL) + return 0; for (i = 0; i < ht->buckets; i++) { - prev = &ht->ht[i]; - while ( (p = *prev) != NULL) { - ret = fn(p, arg); + curp = &ht->ht[i]; + while ( (cur = *curp) != NULL) { + next = *(void **)((char *)cur + ht->ofs); + ret = fn(cur, arg); if (ret & HEAP_SCAN_DEL) { found++; ht->entries--; - *prev = *(void **)((char *)p + ht->ofs); + *curp = next; + } else { + curp = (void **)((char *)cur + ht->ofs); } if (ret & HEAP_SCAN_END) return found; - prev = (void **)((char *)p + ht->ofs); } } return found; @@ -437,11 +453,11 @@ char *strings[] = { NULL, }; -int doprint(void *_x, uintptr_t arg) +int doprint(void *_x, void *arg) { struct x *x = _x; printf("found element <%s>\n", x->buf); - return arg; + return (int)arg; } static void Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h Tue Jan 12 21:17:36 2010 (r202173) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h Tue Jan 12 21:27:38 2010 (r202174) @@ -110,9 +110,10 @@ enum { /* flags values. DNHT_SCAN_DEL = 0x0001, DNHT_SCAN_END = 0x0002, DNHT_KEY_IS_OBJ = 0x0004, /* key is the obj pointer */ - DNHT_INSERT = 0x0008, /* insert if not found */ - DNHT_UNIQUE = 0x0010, /* report error if already there */ - DNHT_REMOVE = 0x0020, /* remove on find */ + DNHT_MATCH_PTR = 0x0008, /* match by pointer, not match() */ + DNHT_INSERT = 0x0010, /* insert if not found */ + DNHT_UNIQUE = 0x0020, /* report error if already there */ + DNHT_REMOVE = 0x0040, /* remove on find */ }; int dn_ht_scan(struct dn_ht *, int (*)(void *, void *), void *); Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c Tue Jan 12 21:17:36 2010 (r202173) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c Tue Jan 12 21:27:38 2010 (r202174) @@ -36,7 +36,6 @@ #include /* flow_id */ #include #include -//#include #include #include @@ -55,27 +54,20 @@ * */ -/* A scheduler instance of a FIFO scheduler requires only a queue. */ -struct fifo_si { - struct new_queue *q; -}; - static int fifo_enqueue(struct new_sch_inst *_si, struct new_queue *q, struct mbuf *m) { - /* the queue is actually embedded here */ - q = (struct new_queue *)(_si+1); - if (dn_queue_packet(q, m)) { - printf("%s dn_queue_packet failed\n", __FUNCTION__); - /* packet was dropped */ - return 1; - } - - /* Ok, the packet is now in the queue. - * The dequeue() function will be called when the scheduler - * instance has credit to transmit packets - */ - return 0; + int ret; + struct new_fsk *fs = (struct new_fsk *)q; /* q contains the fs */ + q = (struct new_queue *)(_si+1); + q->fs = fs; + ret = dn_queue_packet(q, m); + q->fs = NULL; + if (ret) { + printf("%s dn_queue_packet dropped\n", __FUNCTION__); + return 1; + } + return 0; } static struct mbuf * @@ -93,10 +85,9 @@ fifo_dequeue(struct new_sch_inst *_si) */ /* Access scheduler instance private data */ - struct fifo_si *si = (struct fifo_si *)(_si + 1); - struct new_queue *q = si->q; + struct new_queue *q = (struct new_queue *)(_si + 1); - if (q == NULL || q->mq.head == NULL) + if (q->mq.head == NULL) return NULL; return dn_return_packet(q); Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c Tue Jan 12 21:17:36 2010 (r202173) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c Tue Jan 12 21:27:38 2010 (r202174) @@ -37,7 +37,6 @@ #include /* flow_id */ #include #include -//#include #include #include @@ -56,16 +55,13 @@ * */ -/* A scheduler instance of a FIFO scheduler requires only a queue. */ -struct fifo_si { - struct new_queue *q; -}; - static int fifo_enqueue(struct new_sch_inst *_si, struct new_queue *q, struct mbuf *m) { - /* the queue is actually embedded here */ + struct new_fsk *fs = (struct new_fsk *)q; + /* the queue is actually the flowset. */ q = (struct new_queue *)(_si+1); + q->fs = fs; if (dn_queue_packet(q, m)) { printf("%s dn_queue_packet failed\n", __FUNCTION__); /* packet was dropped */ @@ -94,10 +90,9 @@ fifo_dequeue(struct new_sch_inst *_si) */ /* Access scheduler instance private data */ - struct fifo_si *si = (struct fifo_si *)(_si + 1); - struct new_queue *q = si->q; + struct new_queue *q = (struct new_queue *)(_si + 1); - if (q == NULL || q->mq.head == NULL) + if (q->mq.head == NULL) return NULL; return dn_return_packet(q); Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Tue Jan 12 21:17:36 2010 (r202173) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Tue Jan 12 21:27:38 2010 (r202174) @@ -237,10 +237,13 @@ mq_append(struct mq *q, struct mbuf *m) int dn_queue_packet(struct new_queue *q, struct mbuf* m) { - struct new_fs *f = &(q->fs->fs); - struct new_inst *ni = &q->si->ni; - uint64_t len = m->m_pkthdr.len; - + struct new_fs *f; + struct new_inst *ni; + uint64_t len; + + f = &(q->fs->fs); + ni = &q->si->ni; + len = m->m_pkthdr.len; /* Update statistics, then check reasons to drop pkt. */ q->ni.tot_bytes += len; q->ni.tot_pkts++; @@ -622,7 +625,7 @@ dummynet_io(struct mbuf **m0, int dir, s if (q == NULL) goto dropit; } else { - q = NULL; + q = (void *)fs; } if (fs->sched->fp->enqueue(si, q, m)) { printf("%s dropped by enqueue\n", __FUNCTION__); Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Tue Jan 12 21:17:36 2010 (r202173) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Tue Jan 12 21:27:38 2010 (r202174) @@ -147,36 +147,26 @@ flow_id_mask(struct ipfw_flow_id *mask, static int flow_id_hash(struct ipfw_flow_id *id) { - int i; - int is_v6 = IS_IP6_FLOW_ID(id); + uint32_t i; -#define M 0xffff - if (is_v6) { + if (IS_IP6_FLOW_ID(id)) { uint32_t *d = (uint32_t *)&id->dst_ip6; uint32_t *s = (uint32_t *)&id->src_ip6; - i = (d[0] & M) ^ (d[1] & M) ^ - (d[2] & M) ^ (d[3] & M) ^ - - ((d[0] >> 15) & M) ^ ((d[1] >> 15) & M) ^ - ((d[2] >> 15) & M) ^ ((d[3] >> 15) & M) ^ - - ((s[0] << 1) & M) ^ ((s[1] << 1) & M) ^ - ((s[2] << 1) & M) ^ ((s[3] << 1) & M) ^ - - ((s[0] << 16) & M) ^ ((s[1] << 16) & M) ^ - ((s[2] << 16) & M) ^ ((s[3] << 16) & M) ^ - + i = (d[0] ) ^ (d[1]) ^ + (d[2] ) ^ (d[3]) ^ + (d[0] >> 15) ^ (d[1] >> 15) ^ + (d[2] >> 15) ^ (d[3] >> 15) ^ + (s[0] << 1) ^ (s[1] << 1) ^ + (s[2] << 1) ^ (s[3] << 1) ^ + (s[0] << 16) ^ (s[1] << 16) ^ + (s[2] << 16) ^ (s[3] << 16) ^ (id->dst_port << 1) ^ (id->src_port) ^ (id->proto ) ^ (id->flow_id6); } else { - i = ( (id->dst_ip) & M ) ^ - ( (id->dst_ip >> 15) & M ) ^ - ( (id->src_ip << 1) & M ) ^ - ( (id->src_ip >> 16 ) & M ) ^ - (id->dst_port << 1) ^ (id->src_port) ^ - (id->proto ); + i = (id->dst_ip) ^ (id->dst_ip >> 15) ^ + (id->src_ip << 1) ^ (id->src_ip >> 16) ^ + (id->dst_port << 1) ^ (id->src_port) ^ (id->proto); } -#undef M return i; } @@ -212,6 +202,32 @@ flow_id_cmp(struct ipfw_flow_id *id1, st /*--- support functions for the sch_inst hashtable ----*/ +static int +si_hash(uintptr_t key, int flags, void *arg) +{ + /* compute the hash slot from the flow id */ + struct ipfw_flow_id *id = (flags & DNHT_KEY_IS_OBJ) ? + &((struct new_sch_inst *)key)->ni.id : + (struct ipfw_flow_id *)key; + return flow_id_hash(id); +} + +static int +si_match(void *obj, uintptr_t key, int flags, void *arg) +{ + struct new_sch_inst *o; + struct ipfw_flow_id *id2; + + if (flags & DNHT_KEY_IS_OBJ) { + /* compare pointers */ + id2 = &((struct new_sch_inst *)key)->ni.id; + } else { + id2 = (struct ipfw_flow_id *)key; + } + o = (struct new_sch_inst *)obj; + return flow_id_cmp(&o->ni.id, id2) == 0; +} + /* * create a new instance for the given 'key' * Allocate memory for instance, delay line and scheduler private data. @@ -247,7 +263,7 @@ si_new(uintptr_t key, int flags, void *a /* Initialize list of queues attached here */ SLIST_INIT(&si->ql_list); if (s->sch.flags & DN_HAVE_MASK) - si->ni.id = *(struct ipfw_flow_id *)key; + si->ni.id = *(struct ipfw_flow_id *)key; dn_cfg.si_count++; return si; @@ -259,9 +275,8 @@ error: } /* - * Delete a scheduler instance and all the queues. This is a callback - * for the hashtable scan. - * Also remove from the system heap. + * Callback for the hashtable scan. + * Remove si and delay line from the system heap, destroy all queues. */ static int si_destroy(void *_si, void *arg) @@ -313,34 +328,23 @@ ipdn_si_find(struct new_schk *s, struct * support to delete a flowset. Mark as delete, * then check refcnt and free when it becomes 0 */ -static void -destroy_fs(struct new_fsk *fs) +static int +destroy_fs(void *obj, void *arg) { + struct new_fsk *fs = obj; struct new_schk *s = fs->sched; fs->kflags |= DN_DELETE; - if (fs->refcnt != 0) - return; - fs->sched = NULL; - dn_cfg.fsk_count--; - SLIST_REMOVE(&s->fsk_list, fs, new_fsk, sch_chain); -} - -static struct new_fsk * -create_fs(void) -{ - struct new_fsk *fs; - - // XXX we could use the hashtable support - fs = malloc(sizeof(*fs), M_DUMMYNET, M_NOWAIT | M_ZERO); - if (fs) { - dn_ht_find(dn_cfg.fshash, (uintptr_t)fs, - DNHT_KEY_IS_OBJ | DNHT_INSERT | DNHT_UNIQUE); - dn_cfg.fsk_count++; + if (fs->refcnt == 0) { + fs->sched = NULL; + dn_cfg.fsk_count--; + SLIST_REMOVE(&s->fsk_list, fs, new_fsk, sch_chain); + free(fs, M_DUMMYNET); } - return fs; + return HEAP_SCAN_DEL; } + /* * helper for schedulers. Creates a queue * XXX actually, maybe only flowsets use this ? @@ -382,82 +386,51 @@ dn_delete_queue(struct new_queue *q, int SLIST_REMOVE(&q->si->ql_list, q, new_queue, ql_next); if (q->mq.head) dn_free_pkts(q->mq.head); - if (fs->sched->fp->free_queue) + if (fs && fs->sched->fp->free_queue) fs->sched->fp->free_queue(q); free(q, M_DUMMYNET); - fs->refcnt--; dn_cfg.queue_count--; - if (fs->refcnt == 0 && fs->kflags & DN_DELETE) - destroy_fs(fs); + if (fs) { + fs->refcnt--; + if (fs->refcnt == 0 && fs->kflags & DN_DELETE) + destroy_fs(fs, NULL); + } return 0; } +/* destroy all scheduler instances but not the main scheduler */ static struct new_schk * -destroy_schk(struct new_schk *s) +schk_flush(struct new_schk *s) { - struct dn_sched *fp = s->fp; - dn_ht_scan(s->siht, si_destroy, NULL); - if (fp->destroy) - fp->destroy(s, 1); - free(s, M_DUMMYNET); - dn_cfg.schk_count--; + if (s->sch.flags & DN_HAVE_MASK) { + dn_ht_scan(s->siht, si_destroy, NULL); + } else if (s->siht) + si_destroy(s->siht, NULL); return NULL; } - -static int -si_hash(uintptr_t key, int flags, void *arg) -{ - struct ipfw_flow_id *id = (flags & DNHT_KEY_IS_OBJ) ? - &((struct new_sch_inst *)key)->ni.id : - (struct ipfw_flow_id *)key; - return flow_id_hash(id); -} - - +/* callback to flush credit for the pipe */ static int -si_match(void *obj, uintptr_t key, int flags, void *arg) +reset_credit(void *_si, void *arg) { - struct new_sch_inst *o; - struct ipfw_flow_id *id2; + struct new_sch_inst *si = _si; + struct new_pipe *p = &si->sched->pipe; - if (flags & DNHT_KEY_IS_OBJ) { - id2 = &((struct new_sch_inst *)key)->ni.id; - } else { - id2 = (struct ipfw_flow_id *)key; - } - o = (struct new_sch_inst *)obj; - return flow_id_cmp(&o->ni.id, id2) == 0; + si->credit = p->burst + (dn_cfg.io_fast ? p->bandwidth : 0); + return 0; } -static struct new_schk * -create_schk(struct dn_sched *fp, struct new_sch *sch) +static void +schk_reset_credit(struct new_schk *s) { - struct new_schk *s; - int l = sizeof(*s) + fp->schk_len; - - s = malloc(l, M_DUMMYNET, M_NOWAIT | M_ZERO); - if (s) { - set_oid(&s->pipe.oid, DN_PIPE, 0, sizeof(s->pipe)); - s->fp = fp; - SLIST_INIT(&s->fsk_list); - /* initialize the hash table if needed. Otherwise, - * ht points to the single instance we own - */ - if (sch->flags & DN_HAVE_MASK) { - s->siht = dn_ht_init(NULL, s->sch.buckets, - offsetof(struct new_sch_inst, si_next), - si_hash, /* hash */ - si_match,/* MATCH */ - si_new, /* new */ - s /* arg */ ); - } - dn_cfg.schk_count++; - } - return s; + if (s->sch.flags & DN_HAVE_MASK) { + dn_ht_scan(s->siht, reset_credit, NULL); + } else if (s->siht) + reset_credit(s->siht, NULL); } + static int copy_obj(char **start, char *end, void *_o) { @@ -493,7 +466,7 @@ copy_data_helper(void *_o, void *_arg) return HEAP_SCAN_END; } if (a->flags & DN_C_SCH_INST) { - printf("scan sched instances"); + printf("XXX todo: scan sched instances\n"); } } if (a->type == DN_FS) { /* scanning flowsets */ @@ -504,24 +477,27 @@ copy_data_helper(void *_o, void *_arg) return 0; } +/* callback for sched delete */ +static int +schk_del_cb(void *obj, void *arg) +{ + schk_flush((struct new_schk *)obj); + free(obj, M_DUMMYNET); + return HEAP_SCAN_DEL; +} + /* * Delete all objects: - * - mark as shutting down; - * - delete the heap; - * - scan scheduler instances and remove all queues. - * - remove all schedulers. - * - remove all flowsets */ static void dummynet_flush(void) { DUMMYNET_LOCK(); - - /* Free all schedulers. Instances only go away this way. */ - /* XXX implement delete functions */ - dn_ht_scan(dn_cfg.schedhash, NULL, 0); - dn_ht_scan(dn_cfg.fshash, NULL, 0); + printf("%s start\n", __FUNCTION__); + /* first mark flowsets as delete, then go after queues */ + dn_ht_scan(dn_cfg.fshash, destroy_fs, 0); + dn_ht_scan(dn_cfg.schedhash, schk_del_cb, 0); /* Reinitialize system heap... */ heap_init(&dn_cfg.system_heap, 16); @@ -592,7 +568,8 @@ do_config(void *p, int l) return err; } -static struct new_schk * +static inline +struct new_schk * locate_scheduler(int i) { return dn_ht_find(dn_cfg.schedhash, i, 0); @@ -602,46 +579,20 @@ locate_scheduler(int i) static void update_fs(struct new_schk *s) { + printf("%s to be implemented\n", __FUNCTION__); #if 0 // XXX to be completed - struct new_fsk *fs, *tmp; - /* first, scan the existing ones */ - SLIST_FOREACH(fs, &s->fsk_list, sch_chain) { - fs->sched = s; - // XXX do we re-run the config ? - } - /* XXX we need a list of unlinked schedulers to - * optimize this step */ - SLIST_FOREACH_SAFE(fs, &dn_cfg.fshash, next, tmp) { - if (fs->fs.sched_nr != s->sch.sched_nr) - continue; - fs->sched = s; - dn_ht_remove(dn_cfg.fsunlinked, fs, 0); - SLIST_INSERT_HEAD(&s->fsk_list, fs, sch_chain); - dn_ht_find(dn_cfg.fsunlinked, fs, 0); - SLIST_INSERT_HEAD(&dn_cfg.fshash[HASH(fs->fs.fs_nr)], fs, next); - // XXX do we re-run the config ? - } + scan the children of s and see if they still apply. + scan fsunlinked and link all schedulers to s; #endif } -/* callback to flush credit for the pipe */ -static int -reset_credit(void *_si, void *arg) -{ - struct new_sch_inst *si = _si; - struct new_pipe *p = &si->sched->pipe; - - si->credit = p->burst + (dn_cfg.io_fast ? p->bandwidth : 0); - return 0; -} - /* * Setup pipe parameters. */ static int config_pipe(struct new_pipe *p, struct dn_id *arg) { - struct new_schk *sch; + struct new_schk *s; int i; if (p->oid.len < sizeof(*p)) { @@ -663,17 +614,16 @@ config_pipe(struct new_pipe *p, struct d p->burst *= 8 * hz; DUMMYNET_LOCK(); - sch = locate_scheduler(i); - if (sch == NULL) { + s = locate_scheduler(i); + if (s == NULL) { DUMMYNET_UNLOCK(); - printf("%s invalid scheduler number %d\n", __FUNCTION__, - i); + printf("%s sched %d not found\n", __FUNCTION__, i); return EINVAL; } - sch->pipe.delay = p->delay; - sch->pipe.bandwidth = p->bandwidth; - sch->pipe.burst = p->burst; - dn_ht_scan(sch->siht, reset_credit, NULL); + s->pipe.delay = p->delay; + s->pipe.bandwidth = p->bandwidth; + s->pipe.burst = p->burst; + schk_reset_credit(s); dn_cfg.id++; DUMMYNET_UNLOCK(); return 0; @@ -689,9 +639,6 @@ config_sched(struct new_sch *nsch, struc struct new_schk *s; struct dn_sched *fp; int i, is_new; - struct new_fsk_head fsk_list; - - SLIST_INIT(&fsk_list); if (nsch->oid.len != sizeof(*nsch)) { printf("%s: bad sched len\n", __FUNCTION__); @@ -700,6 +647,7 @@ config_sched(struct new_sch *nsch, struc i = nsch->sched_nr; if (i <= 0 || i > DN_MAXID) return EINVAL; + printf("%s i %d\n", __FUNCTION__, i); /* XXX other sanity checks */ fp = load_scheduler(nsch->oid.subtype, nsch->type); if (fp == NULL) { @@ -707,40 +655,41 @@ config_sched(struct new_sch *nsch, struc return EINVAL; } nsch->oid.subtype = fp->type; + nsch->oid.id = (uintptr_t)fp; /* used for */ DUMMYNET_LOCK(); - s = locate_scheduler(i); + // printf("%s i %d before ht_find\n", __FUNCTION__, i); + s = dn_ht_find(dn_cfg.schedhash, (uintptr_t)nsch, + DNHT_KEY_IS_OBJ | DNHT_INSERT); + // printf("%s i %d after ht_find\n", __FUNCTION__, i); + if (s == NULL) { + printf("cannot allocate scheduler\n"); + return ENOMEM; + } printf("%s type %s old %p\n", __FUNCTION__, fp->name, s); /* Handle the following cases * 1. non existing before: - * create and setup + * initialize * 2. existing before, type changed - * destroy (perhaps preserve pipe), then #1 + * destroy queues, then #1 * 3. existing before, same type. * update parameters and pipe */ - if (s && s->fp != fp) { /* type changed, hard delete */ - dn_ht_find(dn_cfg.schedhash, (uintptr_t)s, - DNHT_KEY_IS_OBJ | DNHT_REMOVE); - /* preserve old pipe ? */ - s = destroy_schk(s); - } - if (s) { /* case 3 */ - is_new = 0; - } else { /* case 1 */ - s = create_schk(fp, nsch); - if (s == NULL) - return ENOMEM; - s->pipe.pipe_nr = i; - dn_ht_find(dn_cfg.schedhash, (uintptr_t)s, - DNHT_KEY_IS_OBJ | DNHT_INSERT); + is_new = 0; + if (s->fp == NULL) { /* new scheduler, nothing to clean up */ is_new = 1; + } else if (s->fp != fp) { /* type changed, flush queues. */ + // XXX we should reallocate the private data area. + // how do we do it ? + /* preserve old pipe ? */ + schk_flush(s); } - s->sch = *nsch; + /* complete initialization */ + s->fp = fp; s->cfg = arg; /* call init function */ if (s->fp->config) - s->fp->config(s, is_new); - dn_ht_scan(s->siht, reset_credit, NULL); + s->fp->config(s, 1); + schk_reset_credit(s); if (is_new) update_fs(s); dn_cfg.id++; @@ -757,7 +706,7 @@ config_fs(struct new_fs *nfs, struct dn_ { struct new_fsk *fs; struct new_schk *s; - int i, s_changed; + int i; if (nfs->oid.len < sizeof(*nfs)) { printf("%s: short flowset\n", __FUNCTION__); @@ -766,6 +715,7 @@ config_fs(struct new_fs *nfs, struct dn_ i = nfs->fs_nr; if (i <= 0 || i > DN_MAXID) return EINVAL; + printf("%s i %d\n", __FUNCTION__, i); /* XXX other sanity checks */ if (nfs->flags & DN_QSIZE_IS_BYTES) { if (nfs->qsize > dn_cfg.pipe_byte_limit) @@ -778,31 +728,25 @@ config_fs(struct new_fs *nfs, struct dn_ } DUMMYNET_LOCK(); - fs = ipdn_locate_flowset(i); +again: + fs = dn_ht_find(dn_cfg.fshash, i, DNHT_INSERT); if (fs == NULL) { - fs = create_fs(); - if (fs == NULL) { - DUMMYNET_UNLOCK(); - return ENOMEM; - } + DUMMYNET_UNLOCK(); + return ENOMEM; } fs->fs = *nfs; /* update config */ - /* copy values, check if scheduler exists and mark active */ s = locate_scheduler(nfs->sched_nr); - s_changed = s == NULL || fs->sched == NULL || fs->sched->fp != s->fp; - /* - * Handle the following cases - * 1. same scheduler as before (either none or the same) - * do nothing - * 2. No scheduler before, have one now: - * link to the new scheduler - * 3. scheduler before, none now - * leave the queues with the old scheduler ? - * in case, simply remove them from the fht - * 4. scheduler before, different one now - * do #3 then #2 - */ + if (fs->sched == NULL) { /* no scheduler before, link */ + if (s) { + fs->sched = s; + // XXX remove_from_unlinked(fs); + } + } else if (fs->sched != s) { + /* scheduler changed. Mark old fs and recreate */ + fs->kflags |= DN_DELETE; + goto again; + } dn_cfg.id++; DUMMYNET_UNLOCK(); return 0; @@ -1020,6 +964,12 @@ ip_dn_ctl(struct sockopt *sopt) return error ; } +/* + * Scheduler hash. When searching by index we pass sched_nr, + * otherwise we pass struct new_sch * which is the first field in + * struct new_schk so we can cast it. We need this info during the + * create phase, where we put the dn_sched * in oid.id + */ static int schk_hash(uintptr_t key, int flags, void *arg) { @@ -1029,6 +979,53 @@ schk_hash(uintptr_t key, int flags, void } static int +schk_match(void *obj, uintptr_t key, int flags, void *arg) +{ + int i = ((flags & DNHT_KEY_IS_OBJ) == 0) ? key : + ((struct new_schk *)key)->sch.sched_nr; + return ((struct new_schk *)obj)->sch.sched_nr == i; +} + +/* + * Create the entry and intialize with the sched hash if needed. + * XXX how do we tell between an old and a brand new thing ? + * perhaps do not initialize s->fp ? + */ +static void * +schk_new(uintptr_t key, int flags, void *arg) +{ + struct new_schk *s; + struct new_sch *sch = (struct new_sch *)key; + struct dn_sched *fp = (struct dn_sched *)sch->oid.id; + int l = sizeof(*s) + fp->schk_len; + +// printf("%s key %p fp %p\n", __FUNCTION__, sch, fp); + s = malloc(l, M_DUMMYNET, M_NOWAIT | M_ZERO); + if (s == NULL) + return NULL; + set_oid(&s->pipe.oid, DN_PIPE, 0, sizeof(s->pipe)); + s->sch = *sch; // copy initial values + s->pipe.pipe_nr = sch->sched_nr; + SLIST_INIT(&s->fsk_list); + /* initialize the hash table if needed. Otherwise, + * ht points to the single instance we own + */ + if (sch->flags & DN_HAVE_MASK) { + s->siht = dn_ht_init(NULL, s->sch.buckets, + offsetof(struct new_sch_inst, si_next), + si_hash, /* hash */ + si_match,/* MATCH */ + si_new, /* new */ + s /* arg */ ); + } + dn_cfg.schk_count++; + return s; +} + +/* + * flowset hash support + */ +static int fsk_hash(uintptr_t key, int flags, void *arg) { int i = ((flags & DNHT_KEY_IS_OBJ) == 0) ? key : @@ -1037,6 +1034,28 @@ fsk_hash(uintptr_t key, int flags, void return ( (i>>8)^(i>>4)^i ); } +/* matck skips those marked as deleted */ +static int +fsk_match(void *obj, uintptr_t key, int flags, void *arg) +{ + struct new_fsk *fs = obj; + int i = ((flags & DNHT_KEY_IS_OBJ) == 0) ? key : + ((struct new_fsk *)key)->fs.fs_nr; + return !(fs->kflags & DN_DELETE) && fs->fs.fs_nr == i; +} + +static void * +fsk_new(uintptr_t key, int flags, void *arg) +{ + struct new_fsk *fs; + + fs = malloc(sizeof(*fs), M_DUMMYNET, M_NOWAIT | M_ZERO); + if (fs) + dn_cfg.fsk_count++; + SLIST_INSERT_HEAD(&dn_cfg.fsunlinked, fs, sch_chain); + return fs; +} + static void ip_dn_init(void) { @@ -1048,19 +1067,16 @@ ip_dn_init(void) if (bootverbose) printf("DUMMYNET with IPv6 initialized (100131)\n"); - /* create hash tables */ + /* create hash tables for schedulers and flowsets. + * In both we search by key and by pointer. + * Insertion in schedhash uses externally allocated objects. + */ dn_cfg.schedhash = dn_ht_init(NULL, dn_cfg.buckets, offsetof(struct new_schk, schk_next), - schk_hash, - NULL, /* match */ - NULL, /* new */ - NULL); + schk_hash, schk_match, schk_new, NULL); dn_cfg.fshash = dn_ht_init(NULL, dn_cfg.buckets, offsetof(struct new_fsk, fsk_next), - fsk_hash, - NULL, /* match */ - NULL, /* new */ - NULL); + fsk_hash, fsk_match, fsk_new, NULL); SLIST_INIT(&dn_cfg.fsunlinked); SLIST_INIT(&list_of_scheduler); @@ -1109,8 +1125,8 @@ dummynet_modevent(module_t mod, int type switch (type) { case MOD_LOAD: if (ip_dn_io_ptr) { - printf("DUMMYNET already loaded\n"); - return EEXIST ; + printf("DUMMYNET already loaded\n"); + return EEXIST ; } ip_dn_init(); break; @@ -1171,7 +1187,6 @@ unload_descriptor(struct dn_sched *s) printf("%s %s called\n", __FUNCTION__, s->name); DUMMYNET_LOCK(); - SLIST_FOREACH_SAFE(r, &list_of_scheduler, next, tmp) { if (strcmp(s->name, r->name) != 0) continue; From owner-svn-src-user@FreeBSD.ORG Tue Jan 12 22:06:54 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 3EC1E106566C; Tue, 12 Jan 2010 22:06:54 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 23B5C8FC14; Tue, 12 Jan 2010 22:06:54 +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 o0CM6sFc014048; Tue, 12 Jan 2010 22:06:54 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0CM6s7Z014046; Tue, 12 Jan 2010 22:06:54 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201001122206.o0CM6s7Z014046@svn.freebsd.org> From: Ed Schouten Date: Tue, 12 Jan 2010 22:06:54 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202177 - user/ed/utmpx/lib/libc/gen X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 12 Jan 2010 22:06:54 -0000 Author: ed Date: Tue Jan 12 22:06:53 2010 New Revision: 202177 URL: http://svn.freebsd.org/changeset/base/202177 Log: Several improvements to the handling of the utmpx files. - Just use O_EXLOCK instead of calling lockf() by hand. This will already provide exclusive file access. - Let the functions use stdio instead of operating on the file descriptors directly. When utmp and lastlogin files get a bit bigger, it will read chunks of 4K instead of 197 bytes at a time. Modified: user/ed/utmpx/lib/libc/gen/pututxline.c Modified: user/ed/utmpx/lib/libc/gen/pututxline.c ============================================================================== --- user/ed/utmpx/lib/libc/gen/pututxline.c Tue Jan 12 21:45:03 2010 (r202176) +++ user/ed/utmpx/lib/libc/gen/pututxline.c Tue Jan 12 22:06:53 2010 (r202177) @@ -31,35 +31,43 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include #include "utxdb.h" #include "un-namespace.h" -static int +static FILE * futx_open(const char *file) { int fd; + FILE *fp; struct stat sb; - fd = _open(file, O_CREAT|O_RDWR, 0644); + fd = _open(file, O_CREAT|O_RDWR|O_EXLOCK, 0644); if (fd < 0) - return (-1); + return (NULL); /* Safety check: never use broken files. */ if (_fstat(fd, &sb) != -1 && sb.st_size % sizeof(struct futx) != 0) { _close(fd); - return (-1); + return (NULL); + } + + fp = fdopen(fd, "r+"); + if (fp == NULL) { + _close(fd); + return (NULL); } - return (fd); + return (fp); } static void utx_active_add(const struct futx *fu) { - int fd; + FILE *fp; struct futx fe; off_t partial = -1; @@ -67,14 +75,10 @@ utx_active_add(const struct futx *fu) * Register user login sessions. Overwrite entries of sessions * that have already been terminated. */ - fd = futx_open(_PATH_UTX_ACTIVE); - if (fd < 0) - return; - if (lockf(fd, F_LOCK, 0) == -1) { - _close(fd); + fp = futx_open(_PATH_UTX_ACTIVE); + if (fp == NULL) return; - } - while (_read(fd, &fe, sizeof fe) == sizeof fe) { + while (fread(&fe, sizeof fe, 1, fp) == 1) { switch (fe.fu_type) { case USER_PROCESS: case INIT_PROCESS: @@ -82,7 +86,7 @@ utx_active_add(const struct futx *fu) case DEAD_PROCESS: /* Overwrite when ut_id matches. */ if (memcmp(fu->fu_id, fe.fu_id, sizeof fe.fu_id) == 0) { - lseek(fd, -sizeof fe, SEEK_CUR); + fseeko(fp, -sizeof fe, SEEK_CUR); goto exact; } if (fe.fu_type != DEAD_PROCESS) @@ -91,7 +95,7 @@ utx_active_add(const struct futx *fu) default: /* Allow us to overwrite unused records. */ if (partial == -1) - partial = lseek(fd, 0, SEEK_CUR) - sizeof fe; + partial = fseeko(fp, 0, SEEK_CUR) - sizeof fe; break; } } @@ -101,29 +105,25 @@ utx_active_add(const struct futx *fu) * match was found, just append a new record. */ if (partial != -1) - lseek(fd, partial, SEEK_SET); + fseeko(fp, partial, SEEK_SET); exact: - _write(fd, fu, sizeof *fu); - _close(fd); + fwrite(fu, sizeof *fu, 1, fp); + fclose(fp); } static int utx_active_remove(struct futx *fu) { - int fd; + FILE *fp; struct futx fe; /* * Remove user login sessions, having the same ut_id. */ - fd = futx_open(_PATH_UTX_ACTIVE); - if (fd < 0) - return (0); - if (lockf(fd, F_LOCK, 0) == -1) { - _close(fd); + fp = futx_open(_PATH_UTX_ACTIVE); + if (fp == NULL) return (0); - } - while (_read(fd, &fe, sizeof fe) == sizeof fe) { + while (fread(&fe, sizeof fe, 1, fp) == 1) { switch (fe.fu_type) { case USER_PROCESS: case INIT_PROCESS: @@ -139,14 +139,14 @@ utx_active_remove(struct futx *fu) fu->fu_tv = fe.fu_tv; /* Terminate session. */ - lseek(fd, -sizeof fe, SEEK_CUR); - _write(fd, fu, sizeof *fu); - _close(fd); + fseeko(fp, -sizeof fe, SEEK_CUR); + fwrite(fu, sizeof *fu, 1, fp); + fclose(fp); return (0); } } - _close(fd); + fclose(fp); return (1); } @@ -160,7 +160,7 @@ utx_active_purge(void) static void utx_lastlogin_add(const struct futx *fu) { - int fd; + FILE *fp; struct futx fe; /* @@ -168,14 +168,10 @@ utx_lastlogin_add(const struct futx *fu) * current user already has an entry. If not, append a new * entry. */ - fd = futx_open(_PATH_UTX_LASTLOGIN); - if (fd < 0) - return; - if (lockf(fd, F_LOCK, 0) == -1) { - _close(fd); + fp = futx_open(_PATH_UTX_LASTLOGIN); + if (fp == NULL) return; - } - while (_read(fd, &fe, sizeof fe) == sizeof fe) { + while (fread(&fe, sizeof fe, 1, fp) == 1) { if (strncmp(fu->fu_user, fe.fu_user, sizeof fe.fu_user) != 0) continue; @@ -184,12 +180,12 @@ utx_lastlogin_add(const struct futx *fu) goto done; /* Found a previous lastlogin entry for this user. */ - lseek(fd, -sizeof fe, SEEK_CUR); + fseeko(fp, -sizeof fe, SEEK_CUR); break; } - _write(fd, fu, sizeof *fu); + fwrite(fu, sizeof *fu, 1, fp); done: - _close(fd); + fclose(fp); } static void From owner-svn-src-user@FreeBSD.ORG Tue Jan 12 23:33:15 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 097021065672; Tue, 12 Jan 2010 23:33:15 +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 EB8908FC12; Tue, 12 Jan 2010 23:33:14 +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 o0CNXEoW033219; Tue, 12 Jan 2010 23:33:14 GMT (envelope-from luigi@svn.freebsd.org) Received: (from luigi@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0CNXEqw033215; Tue, 12 Jan 2010 23:33:14 GMT (envelope-from luigi@svn.freebsd.org) Message-Id: <201001122333.o0CNXEqw033215@svn.freebsd.org> From: Luigi Rizzo Date: Tue, 12 Jan 2010 23:33:14 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202180 - user/luigi/ipfw3-head/sys/netinet/ipfw X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 12 Jan 2010 23:33:15 -0000 Author: luigi Date: Tue Jan 12 23:33:14 2010 New Revision: 202180 URL: http://svn.freebsd.org/changeset/base/202180 Log: mostly formatting changes. pipe flush still not working Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h Tue Jan 12 22:28:59 2010 (r202179) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h Tue Jan 12 23:33:14 2010 (r202180) @@ -143,10 +143,8 @@ SLIST_HEAD(dn_sched_head, dn_sched); * to be used by schedulers. */ -/* - * delete a queue, which we assume nobody references - */ -int dn_delete_queue(struct new_queue *q, int extract); +/* delete a queue, which we assume nobody references */ +int dn_delete_queue(struct new_queue *q); /* Allocate an hash table. * Returns the pointer to the table @@ -196,16 +194,15 @@ struct new_queue * dn_q_hash_id(struct i static __inline struct mbuf* dn_return_packet(struct new_queue *q) { - struct mbuf *m = q->mq.head; - KASSERT(m != NULL, ("empty queue to dn_return_packet")); - q->mq.head = m->m_nextpkt; - q->ni.length--; - q->si->ni.len_bytes -= m->m_pkthdr.len; - q->si->ni.len_bytes -= m->m_pkthdr.len; - if (q->mq.head == NULL && q->fs && q->fs->kflags & DN_DELETE) { - dn_delete_queue(q, 1 /* remove from ql_list */); - } - return m; + struct mbuf *m = q->mq.head; + KASSERT(m != NULL, ("empty queue to dn_return_packet")); + q->mq.head = m->m_nextpkt; + q->ni.length--; + q->si->ni.len_bytes -= m->m_pkthdr.len; + q->si->ni.len_bytes -= m->m_pkthdr.len; + if (q->mq.head == NULL && q->fs && q->fs->kflags & DN_DELETE) + dn_delete_queue(q); + return m; } int dn_sched_modevent(module_t mod, int cmd, void *arg); Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h Tue Jan 12 22:28:59 2010 (r202179) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h Tue Jan 12 23:33:14 2010 (r202180) @@ -46,11 +46,10 @@ extern struct mtx dummynet_mtx; #define DUMMYNET_UNLOCK() mtx_unlock(&dummynet_mtx) #define DUMMYNET_LOCK_ASSERT() mtx_assert(&dummynet_mtx, MA_OWNED) -#define HASH(num) ((((num) >> 8) ^ ((num) >> 4) ^ (num)) & dn_cfg.hmask) - SLIST_HEAD(new_schk_head, new_schk); SLIST_HEAD(new_sch_inst_head, new_sch_inst); SLIST_HEAD(new_fsk_head, new_fsk); +SLIST_HEAD(new_queue_head, new_queue); /* * global configuration parameters. @@ -68,19 +67,20 @@ struct dn_parms { long pipe_slot_limit; int io_fast; - struct timeval prev_t; - struct dn_heap system_heap; + struct timeval prev_t; /* last time dummynet_tick ran */ + struct dn_heap system_heap; /* scheduled events */ - /* how many objects we have -- useful for reporting space */ + /* counters of objects -- used for reporting space */ int schk_count; int si_count; int fsk_count; int queue_count; - int buckets; /* for the two hash tables */ + int buckets; /* for the hash tables below */ struct dn_ht *fshash; struct dn_ht *schedhash; - struct new_fsk_head fsunlinked; /* use sch_chain */ + /* list of flowsets without a scheduler -- use sch_chain */ + struct new_fsk_head fsunlinked; }; static inline void @@ -91,14 +91,13 @@ set_oid(struct dn_id *o, int type, int s o->len = len; }; -struct mq { +struct mq { /* a basic queue of packets*/ struct mbuf *head, *tail; }; /* - * Delay line, contains all packets that will be sent out - * at certain time. - * Every scheduler instance has a delay line + * Delay line, contains all packets on output from a pipe. + * Every scheduler instance has one. */ struct delay_line { struct dn_id oid; @@ -107,77 +106,64 @@ struct delay_line { }; /* - * The kernel side of a flowset. Contains: - * - configuration parameters (fs, cmdline); - * - kernel info (kflags) - * - link field for the hash chain - * - reference to the scheduler; - * - a refcount (from queues) - * - link field for a list of fsk attached to sched (used when sched - * is deleted or reconfigured); - * The flowset does not know which queues are linked to it. - * When we remove a flowset, move it to the unlinked list and - * set the kflag. When the refcnt is 0 it can go away. - * the sched_nr to 0 + * The kernel side of a flowset. In addition to the user parameters + * and kernel flags, it is linked in a hash table of flowsets, + * and in a list of children of their parent scheduler. + * It also contains a hash table of children queues (or one, if + * there is no flow_mask). + * When we remove a flowset, mark as DN_DELETE so it can go away + * when the hash table will be empty. + * XXX refcnt is redundant. */ struct new_fsk { /* kernel side of a flowset */ struct new_fs fs; - SLIST_ENTRY(new_fsk) fsk_next; /* hash chain list */ - int kflags; /* kernel-side flags */ - /* - * Scheduler-specific parameters for this flowset - * (for examples, the weight parameter of wf2q+ algorithm goes here) - */ - int weight; - int quantum; - - /* Number of queues attached to this flowset */ - int refcnt; + SLIST_ENTRY(new_fsk) fsk_next; /* hash chain list */ + int kflags; /* kernel-side flags */ + int refcnt; /* entries in qht */ /* hash table of queues, or just our queue if we have no mask */ struct dn_ht *qht; - /* Scheduler associated with this flowset */ - struct new_schk *sched; - SLIST_ENTRY(new_fsk) sch_chain; /* list of fsk attached to sched */ + struct new_schk *sched; /* Sched we are linked to */ + SLIST_ENTRY(new_fsk) sch_chain; /* list of fsk attached to sched */ +}; + +/* + * The child of a flowset, is in a hash table + */ +struct new_queue { + struct new_inst ni; /* oid, flow_id, stats */ + struct mq mq; /* packets queue */ + SLIST_ENTRY(new_queue) ql__next; /* hash chain list */ + SLIST_ENTRY(new_queue) si_chain; /* linked list to sch_inst */ + struct new_sch_inst *si; /* owner scheduler instance */ + struct new_fsk *fs; /* parent flowset. */ + /* If fs->kflags & DN_DELETE, remove the queue when empty. */ }; +/* + * The kernel side of a scheduler. Contains the userland config, + * a pipe, pointer to extra config arguments from command line, + * kernel flags, and a pointer to the scheduler methods. + * It is stored in a hash table, and holds a list of all + * flowsets and scheduler instances. + */ struct new_schk { struct new_sch sch; + int kflags; + struct dn_sched *fp; /* Pointer to scheduler functions */ + struct new_pipe pipe; /* the pipe is embedded */ + struct dn_id *cfg; /* extra config arguments */ - /* This structure is in a list of schedulers where we do - * the lookup when necessary. 'next' is the link field. - * Also, all instances of this scheduler may be in a heap used - * to fetch them when they are ready. 'inst_counter' counts - * how many instances are in the heap and can be used - * as a reference count. - */ - SLIST_ENTRY(new_schk) schk_next; /* List of all templates */ - struct new_fsk_head fsk_list; /* all fsk linked to me */ + SLIST_ENTRY(new_schk) schk_next; /* hash chain list */ - struct new_pipe pipe; /* the pipe is embedded */ - struct dn_id *cfg; /* extra config arguments */ + struct new_fsk_head fsk_list; /* all fsk linked to me */ - /* Hash table of all children. Used to apply the sched_mask */ + /* Hash table of all instances (through sched_mask) */ struct dn_ht *siht; - int kflags; - - struct dn_sched *fp; /* Pointer to scheduler functions */ }; -/* The packets queue associated with a scheduler instance */ -struct new_queue { - struct new_inst ni; /* oid, flow_id, stats */ - struct mq mq; /* packets queue */ - - SLIST_ENTRY(new_queue) ql_next; /* linked list to sch_inst */ - struct new_sch_inst *si; /* owner scheduler instance */ - - struct new_fsk *fs; /* parent flowset. */ - /* If fs->kflags & DN_DELETE, remove the queue when empty. */ -}; -SLIST_HEAD(new_queue_head, new_queue); /* * Scheduler instance. Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Tue Jan 12 22:28:59 2010 (r202179) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Tue Jan 12 23:33:14 2010 (r202180) @@ -294,8 +294,7 @@ si_destroy(void *_si, void *arg) heap_extract(&dn_cfg.system_heap, dl); dn_free_pkts(dl->mq.head); while ( (q = SLIST_FIRST(&si->ql_list)) ) { - SLIST_REMOVE_HEAD(&si->ql_list, ql_next); - dn_delete_queue(q, 0); + dn_delete_queue(q); } free(si, M_DUMMYNET); dn_cfg.si_count--; @@ -336,10 +335,12 @@ destroy_fs(void *obj, void *arg) fs->kflags |= DN_DELETE; if (fs->refcnt == 0) { - fs->sched = NULL; dn_cfg.fsk_count--; - SLIST_REMOVE(&s->fsk_list, fs, new_fsk, sch_chain); + if (fs->sched) + SLIST_REMOVE(&s->fsk_list, fs, new_fsk, sch_chain); + fs->sched = NULL; free(fs, M_DUMMYNET); + printf("%s free done\n", __FUNCTION__); } return HEAP_SCAN_DEL; } @@ -369,7 +370,7 @@ dn_create_queue(struct new_sch_inst *si, if (si->sched->fp->new_queue) si->sched->fp->new_queue(q); - SLIST_INSERT_HEAD(&si->ql_list, q, ql_next); + SLIST_INSERT_HEAD(&si->ql_list, q, si_chain); dn_cfg.queue_count++; return q; } @@ -378,12 +379,12 @@ dn_create_queue(struct new_sch_inst *si, * Delete a queue (helper for the schedulers) */ int -dn_delete_queue(struct new_queue *q, int extract) +dn_delete_queue(struct new_queue *q) { struct new_fsk *fs = q->fs; - if (extract) - SLIST_REMOVE(&q->si->ql_list, q, new_queue, ql_next); + if (SLIST_FIRST(&q->si->ql_list)) + SLIST_REMOVE(&q->si->ql_list, q, new_queue, si_chain); if (q->mq.head) dn_free_pkts(q->mq.head); if (fs && fs->sched->fp->free_queue) @@ -430,7 +431,6 @@ schk_reset_credit(struct new_schk *s) reset_credit(s->siht, NULL); } - static int copy_obj(char **start, char *end, void *_o) { @@ -443,7 +443,7 @@ copy_obj(char **start, char *end, void * return 0; } -/* copy data, return 1 when full */ +/* argument for copy data, return 1 when full */ struct copy_args { char **start; char *end; @@ -497,6 +497,7 @@ dummynet_flush(void) printf("%s start\n", __FUNCTION__); /* first mark flowsets as delete, then go after queues */ dn_ht_scan(dn_cfg.fshash, destroy_fs, 0); + printf("%s destroy_fs done\n", __FUNCTION__); dn_ht_scan(dn_cfg.schedhash, schk_del_cb, 0); /* Reinitialize system heap... */ @@ -568,8 +569,7 @@ do_config(void *p, int l) return err; } -static inline -struct new_schk * +static inline struct new_schk * locate_scheduler(int i) { return dn_ht_find(dn_cfg.schedhash, i, 0); @@ -602,7 +602,7 @@ config_pipe(struct new_pipe *p, struct d i = p->pipe_nr; if (i <= 0 || i > DN_MAXID) return EINVAL; - printf("%s %d\n", __FUNCTION__, i); + // printf("%s %d\n", __FUNCTION__, i); /* * The config program passes parameters as follows: * bw = bits/second (0 means no limits), @@ -647,7 +647,7 @@ config_sched(struct new_sch *nsch, struc i = nsch->sched_nr; if (i <= 0 || i > DN_MAXID) return EINVAL; - printf("%s i %d\n", __FUNCTION__, i); + // printf("%s i %d\n", __FUNCTION__, i); /* XXX other sanity checks */ fp = load_scheduler(nsch->oid.subtype, nsch->type); if (fp == NULL) { @@ -680,7 +680,7 @@ config_sched(struct new_sch *nsch, struc } else if (s->fp != fp) { /* type changed, flush queues. */ // XXX we should reallocate the private data area. // how do we do it ? - /* preserve old pipe ? */ + /* preserve old pipe */ schk_flush(s); } /* complete initialization */ @@ -770,6 +770,7 @@ config_profile(struct new_profile *pf, s if (i <= 0 || i > DN_MAXID) return EINVAL; /* XXX other sanity checks */ + DUMMYNET_LOCK(); s = locate_scheduler(i); @@ -938,7 +939,7 @@ ip_dn_ctl(struct sockopt *sopt) error = EINVAL; break; - case IP_DUMMYNET3 : /* remove a pipe or queue */ + case IP_DUMMYNET3 : if (sopt->sopt_dir == SOPT_GET) { error = dummynet_get(sopt); break; @@ -964,7 +965,7 @@ ip_dn_ctl(struct sockopt *sopt) return error ; } -/* +/*------------------------------------------------------------ * Scheduler hash. When searching by index we pass sched_nr, * otherwise we pass struct new_sch * which is the first field in * struct new_schk so we can cast it. We need this info during the @@ -1013,16 +1014,13 @@ schk_new(uintptr_t key, int flags, void if (sch->flags & DN_HAVE_MASK) { s->siht = dn_ht_init(NULL, s->sch.buckets, offsetof(struct new_sch_inst, si_next), - si_hash, /* hash */ - si_match,/* MATCH */ - si_new, /* new */ - s /* arg */ ); + si_hash, si_match, si_new, s); } dn_cfg.schk_count++; return s; } -/* +/*------------------------------------------------------- * flowset hash support */ static int @@ -1034,7 +1032,7 @@ fsk_hash(uintptr_t key, int flags, void return ( (i>>8)^(i>>4)^i ); } -/* matck skips those marked as deleted */ +/* match skips entries those marked as deleted */ static int fsk_match(void *obj, uintptr_t key, int flags, void *arg) { @@ -1050,9 +1048,10 @@ fsk_new(uintptr_t key, int flags, void * struct new_fsk *fs; fs = malloc(sizeof(*fs), M_DUMMYNET, M_NOWAIT | M_ZERO); - if (fs) + if (fs) { dn_cfg.fsk_count++; - SLIST_INSERT_HEAD(&dn_cfg.fsunlinked, fs, sch_chain); + SLIST_INSERT_HEAD(&dn_cfg.fsunlinked, fs, sch_chain); + } return fs; } From owner-svn-src-user@FreeBSD.ORG Wed Jan 13 07:17:17 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 21BAD1065670; Wed, 13 Jan 2010 07:17:17 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id D51C68FC16; Wed, 13 Jan 2010 07:17:16 +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 o0D7HG9l035268; Wed, 13 Jan 2010 07:17:16 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0D7HGlj035266; Wed, 13 Jan 2010 07:17:16 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201001130717.o0D7HGlj035266@svn.freebsd.org> From: Ed Schouten Date: Wed, 13 Jan 2010 07:17:16 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202183 - user/ed/utmpx/lib/libc/gen X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 13 Jan 2010 07:17:17 -0000 Author: ed Date: Wed Jan 13 07:17:16 2010 New Revision: 202183 URL: http://svn.freebsd.org/changeset/base/202183 Log: Just use an iovec instead of copying things around unnecessary. Modified: user/ed/utmpx/lib/libc/gen/pututxline.c Modified: user/ed/utmpx/lib/libc/gen/pututxline.c ============================================================================== --- user/ed/utmpx/lib/libc/gen/pututxline.c Wed Jan 13 06:47:27 2010 (r202182) +++ user/ed/utmpx/lib/libc/gen/pututxline.c Wed Jan 13 07:17:16 2010 (r202183) @@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include +#include #include #include #include @@ -211,12 +212,9 @@ utx_lastlogin_upgrade(void) static void utx_log_add(const struct futx *fu) { - struct { - uint16_t len; - struct futx data; - } __packed r; - size_t l; - int f; + int fd; + uint16_t l; + struct iovec vec[2]; /* * Append an entry to the log file. We only need to append @@ -224,15 +222,18 @@ utx_log_add(const struct futx *fu) * zero-bytes. Prepend a length field, indicating the length of * the record, excluding the length field itself. */ - for (l = sizeof *fu; l > 0 && ((char *)fu)[l - 1] == '\0'; l--); - r.len = htobe16(l); - memcpy(&r.data, fu, l); + for (l = sizeof *fu; l > 0 && ((const char *)fu)[l - 1] == '\0'; l--); + vec[0].iov_base = &l; + vec[0].iov_len = sizeof l; + vec[1].iov_base = __DECONST(void*, fu); + vec[1].iov_len = l; + l = htobe16(l); - f = _open(_PATH_UTX_LOG, O_CREAT|O_WRONLY|O_APPEND, 0644); - if (f < 0) + fd = _open(_PATH_UTX_LOG, O_CREAT|O_WRONLY|O_APPEND, 0644); + if (fd < 0) return; - _write(f, &r, sizeof r.len + l); - _close(f); + _writev(fd, vec, 2); + _close(fd); } struct utmpx * From owner-svn-src-user@FreeBSD.ORG Wed Jan 13 08:21:19 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B5CB5106566C; Wed, 13 Jan 2010 08:21:19 +0000 (UTC) (envelope-from kmacy@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id A43948FC16; Wed, 13 Jan 2010 08:21: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 o0D8LJIM049378; Wed, 13 Jan 2010 08:21:19 GMT (envelope-from kmacy@svn.freebsd.org) Received: (from kmacy@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0D8LJwV049376; Wed, 13 Jan 2010 08:21:19 GMT (envelope-from kmacy@svn.freebsd.org) Message-Id: <201001130821.o0D8LJwV049376@svn.freebsd.org> From: Kip Macy Date: Wed, 13 Jan 2010 08:21:19 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202184 - user/kmacy/releng_8_rump/lib/libunet X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 13 Jan 2010 08:21:19 -0000 Author: kmacy Date: Wed Jan 13 08:21:19 2010 New Revision: 202184 URL: http://svn.freebsd.org/changeset/base/202184 Log: - copy in kern_intr.c as unet_kern_intr.c - eliminate cpu binding - remove some unneeded references to scheduler code Modified: user/kmacy/releng_8_rump/lib/libunet/unet_kern_intr.c Modified: user/kmacy/releng_8_rump/lib/libunet/unet_kern_intr.c ============================================================================== --- user/kmacy/releng_8_rump/lib/libunet/unet_kern_intr.c Wed Jan 13 07:17:16 2010 (r202183) +++ user/kmacy/releng_8_rump/lib/libunet/unet_kern_intr.c Wed Jan 13 08:21:19 2010 (r202184) @@ -1,3 +1,29 @@ +/*- + * Copyright (c) 1997, Stefan Esser + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + #include __FBSDID("$FreeBSD$"); @@ -26,10 +52,249 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include +#include +#include +#include +#ifdef DDB +#include +#include +#endif + + +#include + +/* + * Describe an interrupt thread. There is one of these per interrupt event. + */ +struct intr_thread { + struct intr_event *it_event; + struct thread *it_thread; /* Kernel thread. */ + int it_flags; /* (j) IT_* flags. */ + int it_need; /* Needs service. */ +}; + +/* Interrupt thread flags kept in it_flags */ +#define IT_DEAD 0x000001 /* Thread is waiting to exit. */ + +struct intr_entropy { + struct thread *td; + uintptr_t event; +}; + + +void +critical_enter(void) +{ +/* grab hashed lock */ +} + +void +critical_exit(void) +{ +} + struct intr_event *clk_intr_event; +struct intr_event *tty_intr_event; +void *vm_ih; +struct proc *intrproc; + +static MALLOC_DEFINE(M_ITHREAD, "ithread", "Interrupt Threads"); + +static int intr_storm_threshold = 1000; +static TAILQ_HEAD(, intr_event) event_list = + TAILQ_HEAD_INITIALIZER(event_list); +static struct mtx event_lock; +MTX_SYSINIT(intr_event_list, &event_lock, "intr event list", MTX_DEF); + +static void intr_event_update(struct intr_event *ie); +#ifdef INTR_FILTER +static int intr_event_schedule_thread(struct intr_event *ie, + struct intr_thread *ithd); +static int intr_filter_loop(struct intr_event *ie, + struct trapframe *frame, struct intr_thread **ithd); +static struct intr_thread *ithread_create(const char *name, + struct intr_handler *ih); +#else +static int intr_event_schedule_thread(struct intr_event *ie); +static struct intr_thread *ithread_create(const char *name); +#endif +static void ithread_destroy(struct intr_thread *ithread); +static void ithread_execute_handlers(struct proc *p, + struct intr_event *ie); +#ifdef INTR_FILTER +static void priv_ithread_execute_handler(struct proc *p, + struct intr_handler *ih); +#endif +static void ithread_loop(void *); +static void ithread_update(struct intr_thread *ithd); +static void start_softintr(void *); + +/* Map an interrupt type to an ithread priority. */ +u_char +intr_priority(enum intr_type flags) +{ + u_char pri; + + flags &= (INTR_TYPE_TTY | INTR_TYPE_BIO | INTR_TYPE_NET | + INTR_TYPE_CAM | INTR_TYPE_MISC | INTR_TYPE_CLK | INTR_TYPE_AV); + switch (flags) { + case INTR_TYPE_TTY: + pri = PI_TTYLOW; + break; + case INTR_TYPE_BIO: + /* + * XXX We need to refine this. BSD/OS distinguishes + * between tape and disk priorities. + */ + pri = PI_DISK; + break; + case INTR_TYPE_NET: + pri = PI_NET; + break; + case INTR_TYPE_CAM: + pri = PI_DISK; /* XXX or PI_CAM? */ + break; + case INTR_TYPE_AV: /* Audio/video */ + pri = PI_AV; + break; + case INTR_TYPE_CLK: + pri = PI_REALTIME; + break; + case INTR_TYPE_MISC: + pri = PI_DULL; /* don't care */ + break; + default: + /* We didn't specify an interrupt level. */ + panic("intr_priority: no interrupt type in flags"); + } + + return pri; +} + +/* + * Update an ithread based on the associated intr_event. + */ +static void +ithread_update(struct intr_thread *ithd) +{ + struct intr_event *ie; + struct thread *td; + u_char pri; + + ie = ithd->it_event; + td = ithd->it_thread; + + /* Determine the overall priority of this event. */ + if (TAILQ_EMPTY(&ie->ie_handlers)) + pri = PRI_MAX_ITHD; + else + pri = TAILQ_FIRST(&ie->ie_handlers)->ih_pri; + + /* Update name and priority. */ + strlcpy(td->td_name, ie->ie_fullname, sizeof(td->td_name)); + + /* XXX set priority */ +} + +/* + * Regenerate the full name of an interrupt event and update its priority. + */ +static void +intr_event_update(struct intr_event *ie) +{ + struct intr_handler *ih; + char *last; + int missed, space; + + /* Start off with no entropy and just the name of the event. */ + mtx_assert(&ie->ie_lock, MA_OWNED); + strlcpy(ie->ie_fullname, ie->ie_name, sizeof(ie->ie_fullname)); + ie->ie_flags &= ~IE_ENTROPY; + missed = 0; + space = 1; + + /* Run through all the handlers updating values. */ + TAILQ_FOREACH(ih, &ie->ie_handlers, ih_next) { + if (strlen(ie->ie_fullname) + strlen(ih->ih_name) + 1 < + sizeof(ie->ie_fullname)) { + strcat(ie->ie_fullname, " "); + strcat(ie->ie_fullname, ih->ih_name); + space = 0; + } else + missed++; + if (ih->ih_flags & IH_ENTROPY) + ie->ie_flags |= IE_ENTROPY; + } + /* + * If the handler names were too long, add +'s to indicate missing + * names. If we run out of room and still have +'s to add, change + * the last character from a + to a *. + */ + last = &ie->ie_fullname[sizeof(ie->ie_fullname) - 2]; + while (missed-- > 0) { + if (strlen(ie->ie_fullname) + 1 == sizeof(ie->ie_fullname)) { + if (*last == '+') { + *last = '*'; + break; + } else + *last = '+'; + } else if (space) { + strcat(ie->ie_fullname, " +"); + space = 0; + } else + strcat(ie->ie_fullname, "+"); + } + + /* + * If this event has an ithread, update it's priority and + * name. + */ + if (ie->ie_thread != NULL) + ithread_update(ie->ie_thread); + CTR2(KTR_INTR, "%s: updated %s", __func__, ie->ie_fullname); +} + +int +intr_event_create(struct intr_event **event, void *source, int flags, int irq, + void (*pre_ithread)(void *), void (*post_ithread)(void *), + void (*post_filter)(void *), int (*assign_cpu)(void *, u_char), + const char *fmt, ...) +{ + struct intr_event *ie; + va_list ap; + + /* The only valid flag during creation is IE_SOFT. */ + if ((flags & ~IE_SOFT) != 0) + return (EINVAL); + ie = malloc(sizeof(struct intr_event), M_ITHREAD, M_WAITOK | M_ZERO); + ie->ie_source = source; + ie->ie_pre_ithread = pre_ithread; + ie->ie_post_ithread = post_ithread; + ie->ie_post_filter = post_filter; + ie->ie_assign_cpu = assign_cpu; + ie->ie_flags = flags; + ie->ie_irq = irq; + ie->ie_cpu = NOCPU; + TAILQ_INIT(&ie->ie_handlers); + mtx_init(&ie->ie_lock, "intr event", NULL, MTX_DEF); + + va_start(ap, fmt); + vsnprintf(ie->ie_name, sizeof(ie->ie_name), fmt, ap); + va_end(ap); + strlcpy(ie->ie_fullname, ie->ie_name, sizeof(ie->ie_fullname)); + mtx_lock(&event_lock); + TAILQ_INSERT_TAIL(&event_list, ie, ie_list); + mtx_unlock(&event_lock); + if (event != NULL) + *event = ie; + CTR2(KTR_INTR, "%s: created %s", __func__, ie->ie_name); + return (0); +} /* * Bind an interrupt event to the specified CPU. Note that not all @@ -43,9 +308,590 @@ int intr_event_bind(struct intr_event *ie, u_char cpu) { - return (ENOTSUP); + return (EOPNOTSUPP); +} + +static struct intr_event * +intr_lookup(int irq) +{ + struct intr_event *ie; + + mtx_lock(&event_lock); + TAILQ_FOREACH(ie, &event_list, ie_list) + if (ie->ie_irq == irq && + (ie->ie_flags & IE_SOFT) == 0 && + TAILQ_FIRST(&ie->ie_handlers) != NULL) + break; + mtx_unlock(&event_lock); + return (ie); +} + +int +intr_event_destroy(struct intr_event *ie) +{ + + mtx_lock(&event_lock); + mtx_lock(&ie->ie_lock); + if (!TAILQ_EMPTY(&ie->ie_handlers)) { + mtx_unlock(&ie->ie_lock); + mtx_unlock(&event_lock); + return (EBUSY); + } + TAILQ_REMOVE(&event_list, ie, ie_list); +#ifndef notyet + if (ie->ie_thread != NULL) { + ithread_destroy(ie->ie_thread); + ie->ie_thread = NULL; + } +#endif + mtx_unlock(&ie->ie_lock); + mtx_unlock(&event_lock); + mtx_destroy(&ie->ie_lock); + free(ie, M_ITHREAD); + return (0); +} + +#ifndef INTR_FILTER +static struct intr_thread * +ithread_create(const char *name) +{ + struct intr_thread *ithd; + struct thread *td; + int error; + + ithd = malloc(sizeof(struct intr_thread), M_ITHREAD, M_WAITOK | M_ZERO); + + error = kproc_kthread_add(ithread_loop, ithd, &intrproc, + &td, RFSTOPPED | RFHIGHPID, + 0, "intr", "%s", name); + if (error) + panic("kproc_create() failed with %d", error); + td->td_pflags |= TDP_ITHREAD; + ithd->it_thread = td; + CTR2(KTR_INTR, "%s: created %s", __func__, name); + return (ithd); +} +#else +static struct intr_thread * +ithread_create(const char *name, struct intr_handler *ih) +{ + struct intr_thread *ithd; + struct thread *td; + int error; + + ithd = malloc(sizeof(struct intr_thread), M_ITHREAD, M_WAITOK | M_ZERO); + + error = kproc_kthread_add(ithread_loop, ih, &intrproc, + &td, RFSTOPPED | RFHIGHPID, + 0, "intr", "%s", name); + if (error) + panic("kproc_create() failed with %d", error); + td->td_pflags |= TDP_ITHREAD; + ithd->it_thread = td; + CTR2(KTR_INTR, "%s: created %s", __func__, name); + return (ithd); +} +#endif + +static void +ithread_destroy(struct intr_thread *ithread) +{ + ; + +} + +#ifndef INTR_FILTER +int +intr_event_add_handler(struct intr_event *ie, const char *name, + driver_filter_t filter, driver_intr_t handler, void *arg, u_char pri, + enum intr_type flags, void **cookiep) +{ + struct intr_handler *ih, *temp_ih; + struct intr_thread *it; + + if (ie == NULL || name == NULL || (handler == NULL && filter == NULL)) + return (EINVAL); + + /* Allocate and populate an interrupt handler structure. */ + ih = malloc(sizeof(struct intr_handler), M_ITHREAD, M_WAITOK | M_ZERO); + ih->ih_filter = filter; + ih->ih_handler = handler; + ih->ih_argument = arg; + ih->ih_name = name; + ih->ih_event = ie; + ih->ih_pri = pri; + if (flags & INTR_EXCL) + ih->ih_flags = IH_EXCLUSIVE; + if (flags & INTR_MPSAFE) + ih->ih_flags |= IH_MPSAFE; + if (flags & INTR_ENTROPY) + ih->ih_flags |= IH_ENTROPY; + + /* We can only have one exclusive handler in a event. */ + mtx_lock(&ie->ie_lock); + if (!TAILQ_EMPTY(&ie->ie_handlers)) { + if ((flags & INTR_EXCL) || + (TAILQ_FIRST(&ie->ie_handlers)->ih_flags & IH_EXCLUSIVE)) { + mtx_unlock(&ie->ie_lock); + free(ih, M_ITHREAD); + return (EINVAL); + } + } + + /* Add the new handler to the event in priority order. */ + TAILQ_FOREACH(temp_ih, &ie->ie_handlers, ih_next) { + if (temp_ih->ih_pri > ih->ih_pri) + break; + } + if (temp_ih == NULL) + TAILQ_INSERT_TAIL(&ie->ie_handlers, ih, ih_next); + else + TAILQ_INSERT_BEFORE(temp_ih, ih, ih_next); + intr_event_update(ie); + + /* Create a thread if we need one. */ + while (ie->ie_thread == NULL && handler != NULL) { + if (ie->ie_flags & IE_ADDING_THREAD) + msleep(ie, &ie->ie_lock, 0, "ithread", 0); + else { + ie->ie_flags |= IE_ADDING_THREAD; + mtx_unlock(&ie->ie_lock); + it = ithread_create("intr: newborn"); + mtx_lock(&ie->ie_lock); + ie->ie_flags &= ~IE_ADDING_THREAD; + ie->ie_thread = it; + it->it_event = ie; + ithread_update(it); + wakeup(ie); + } + } + CTR3(KTR_INTR, "%s: added %s to %s", __func__, ih->ih_name, + ie->ie_name); + mtx_unlock(&ie->ie_lock); + + if (cookiep != NULL) + *cookiep = ih; + return (0); +} +#else +int +intr_event_add_handler(struct intr_event *ie, const char *name, + driver_filter_t filter, driver_intr_t handler, void *arg, u_char pri, + enum intr_type flags, void **cookiep) +{ + struct intr_handler *ih, *temp_ih; + struct intr_thread *it; + + if (ie == NULL || name == NULL || (handler == NULL && filter == NULL)) + return (EINVAL); + + /* Allocate and populate an interrupt handler structure. */ + ih = malloc(sizeof(struct intr_handler), M_ITHREAD, M_WAITOK | M_ZERO); + ih->ih_filter = filter; + ih->ih_handler = handler; + ih->ih_argument = arg; + ih->ih_name = name; + ih->ih_event = ie; + ih->ih_pri = pri; + if (flags & INTR_EXCL) + ih->ih_flags = IH_EXCLUSIVE; + if (flags & INTR_MPSAFE) + ih->ih_flags |= IH_MPSAFE; + if (flags & INTR_ENTROPY) + ih->ih_flags |= IH_ENTROPY; + + /* We can only have one exclusive handler in a event. */ + mtx_lock(&ie->ie_lock); + if (!TAILQ_EMPTY(&ie->ie_handlers)) { + if ((flags & INTR_EXCL) || + (TAILQ_FIRST(&ie->ie_handlers)->ih_flags & IH_EXCLUSIVE)) { + mtx_unlock(&ie->ie_lock); + free(ih, M_ITHREAD); + return (EINVAL); + } + } + + /* Add the new handler to the event in priority order. */ + TAILQ_FOREACH(temp_ih, &ie->ie_handlers, ih_next) { + if (temp_ih->ih_pri > ih->ih_pri) + break; + } + if (temp_ih == NULL) + TAILQ_INSERT_TAIL(&ie->ie_handlers, ih, ih_next); + else + TAILQ_INSERT_BEFORE(temp_ih, ih, ih_next); + intr_event_update(ie); + + /* For filtered handlers, create a private ithread to run on. */ + if (filter != NULL && handler != NULL) { + mtx_unlock(&ie->ie_lock); + it = ithread_create("intr: newborn", ih); + mtx_lock(&ie->ie_lock); + it->it_event = ie; + ih->ih_thread = it; + ithread_update(it); // XXX - do we really need this?!?!? + } else { /* Create the global per-event thread if we need one. */ + while (ie->ie_thread == NULL && handler != NULL) { + if (ie->ie_flags & IE_ADDING_THREAD) + msleep(ie, &ie->ie_lock, 0, "ithread", 0); + else { + ie->ie_flags |= IE_ADDING_THREAD; + mtx_unlock(&ie->ie_lock); + it = ithread_create("intr: newborn", ih); + mtx_lock(&ie->ie_lock); + ie->ie_flags &= ~IE_ADDING_THREAD; + ie->ie_thread = it; + it->it_event = ie; + ithread_update(it); + wakeup(ie); + } + } + } + CTR3(KTR_INTR, "%s: added %s to %s", __func__, ih->ih_name, + ie->ie_name); + mtx_unlock(&ie->ie_lock); + + if (cookiep != NULL) + *cookiep = ih; + return (0); +} +#endif + +/* + * Return the ie_source field from the intr_event an intr_handler is + * associated with. + */ +void * +intr_handler_source(void *cookie) +{ + struct intr_handler *ih; + struct intr_event *ie; + + ih = (struct intr_handler *)cookie; + if (ih == NULL) + return (NULL); + ie = ih->ih_event; + KASSERT(ie != NULL, + ("interrupt handler \"%s\" has a NULL interrupt event", + ih->ih_name)); + return (ie->ie_source); +} + +#ifndef INTR_FILTER +int +intr_event_remove_handler(void *cookie) +{ + struct intr_handler *handler = (struct intr_handler *)cookie; + struct intr_event *ie; +#ifdef INVARIANTS + struct intr_handler *ih; +#endif +#ifdef notyet + int dead; +#endif + + if (handler == NULL) + return (EINVAL); + ie = handler->ih_event; + KASSERT(ie != NULL, + ("interrupt handler \"%s\" has a NULL interrupt event", + handler->ih_name)); + mtx_lock(&ie->ie_lock); + CTR3(KTR_INTR, "%s: removing %s from %s", __func__, handler->ih_name, + ie->ie_name); +#ifdef INVARIANTS + TAILQ_FOREACH(ih, &ie->ie_handlers, ih_next) + if (ih == handler) + goto ok; + mtx_unlock(&ie->ie_lock); + panic("interrupt handler \"%s\" not found in interrupt event \"%s\"", + ih->ih_name, ie->ie_name); +ok: +#endif + /* + * If there is no ithread, then just remove the handler and return. + * XXX: Note that an INTR_FAST handler might be running on another + * CPU! + */ + if (ie->ie_thread == NULL) { + TAILQ_REMOVE(&ie->ie_handlers, handler, ih_next); + mtx_unlock(&ie->ie_lock); + free(handler, M_ITHREAD); + return (0); + } + + /* + * If the interrupt thread is already running, then just mark this + * handler as being dead and let the ithread do the actual removal. + * + * During a cold boot while cold is set, msleep() does not sleep, + * so we have to remove the handler here rather than letting the + * thread do it. + */ + thread_lock(ie->ie_thread->it_thread); + if (!TD_AWAITING_INTR(ie->ie_thread->it_thread) && !cold) { + handler->ih_flags |= IH_DEAD; + + /* + * Ensure that the thread will process the handler list + * again and remove this handler if it has already passed + * it on the list. + */ + ie->ie_thread->it_need = 1; + } else + TAILQ_REMOVE(&ie->ie_handlers, handler, ih_next); + thread_unlock(ie->ie_thread->it_thread); + while (handler->ih_flags & IH_DEAD) + msleep(handler, &ie->ie_lock, 0, "iev_rmh", 0); + intr_event_update(ie); +#ifdef notyet + /* + * XXX: This could be bad in the case of ppbus(8). Also, I think + * this could lead to races of stale data when servicing an + * interrupt. + */ + dead = 1; + TAILQ_FOREACH(ih, &ie->ie_handlers, ih_next) { + if (!(ih->ih_flags & IH_FAST)) { + dead = 0; + break; + } + } + if (dead) { + ithread_destroy(ie->ie_thread); + ie->ie_thread = NULL; + } +#endif + mtx_unlock(&ie->ie_lock); + free(handler, M_ITHREAD); + return (0); +} + +static int +intr_event_schedule_thread(struct intr_event *ie) +{ + struct intr_entropy entropy; + struct intr_thread *it; + struct thread *td; + struct thread *ctd; + struct proc *p; + + /* + * If no ithread or no handlers, then we have a stray interrupt. + */ + if (ie == NULL || TAILQ_EMPTY(&ie->ie_handlers) || + ie->ie_thread == NULL) + return (EINVAL); + + ctd = curthread; + it = ie->ie_thread; + td = it->it_thread; + p = td->td_proc; + + /* + * If any of the handlers for this ithread claim to be good + * sources of entropy, then gather some. + */ + if (harvest.interrupt && ie->ie_flags & IE_ENTROPY) { + CTR3(KTR_INTR, "%s: pid %d (%s) gathering entropy", __func__, + p->p_pid, td->td_name); + entropy.event = (uintptr_t)ie; + entropy.td = ctd; + random_harvest(&entropy, sizeof(entropy), 2, 0, + RANDOM_INTERRUPT); + } + + KASSERT(p != NULL, ("ithread %s has no process", ie->ie_name)); + + /* + * Set it_need to tell the thread to keep running if it is already + * running. Then, lock the thread and see if we actually need to + * put it on the runqueue. + */ + it->it_need = 1; +#ifdef notyet + /* XXX */ + thread_lock(td); + if (TD_AWAITING_INTR(td)) { + CTR3(KTR_INTR, "%s: schedule pid %d (%s)", __func__, p->p_pid, + td->td_name); + TD_CLR_IWAIT(td); + sched_add(td, SRQ_INTR); + } else { + CTR5(KTR_INTR, "%s: pid %d (%s): it_need %d, state %d", + __func__, p->p_pid, td->td_name, it->it_need, td->td_state); + } + thread_unlock(td); +#endif + return (0); +} +#else +int +intr_event_remove_handler(void *cookie) +{ + struct intr_handler *handler = (struct intr_handler *)cookie; + struct intr_event *ie; + struct intr_thread *it; +#ifdef INVARIANTS + struct intr_handler *ih; +#endif +#ifdef notyet + int dead; +#endif + + if (handler == NULL) + return (EINVAL); + ie = handler->ih_event; + KASSERT(ie != NULL, + ("interrupt handler \"%s\" has a NULL interrupt event", + handler->ih_name)); + mtx_lock(&ie->ie_lock); + CTR3(KTR_INTR, "%s: removing %s from %s", __func__, handler->ih_name, + ie->ie_name); +#ifdef INVARIANTS + TAILQ_FOREACH(ih, &ie->ie_handlers, ih_next) + if (ih == handler) + goto ok; + mtx_unlock(&ie->ie_lock); + panic("interrupt handler \"%s\" not found in interrupt event \"%s\"", + ih->ih_name, ie->ie_name); +ok: +#endif + /* + * If there are no ithreads (per event and per handler), then + * just remove the handler and return. + * XXX: Note that an INTR_FAST handler might be running on another CPU! + */ + if (ie->ie_thread == NULL && handler->ih_thread == NULL) { + TAILQ_REMOVE(&ie->ie_handlers, handler, ih_next); + mtx_unlock(&ie->ie_lock); + free(handler, M_ITHREAD); + return (0); + } + + /* Private or global ithread? */ + it = (handler->ih_thread) ? handler->ih_thread : ie->ie_thread; + /* + * If the interrupt thread is already running, then just mark this + * handler as being dead and let the ithread do the actual removal. + * + * During a cold boot while cold is set, msleep() does not sleep, + * so we have to remove the handler here rather than letting the + * thread do it. + */ + thread_lock(it->it_thread); + if (!TD_AWAITING_INTR(it->it_thread) && !cold) { + handler->ih_flags |= IH_DEAD; + + /* + * Ensure that the thread will process the handler list + * again and remove this handler if it has already passed + * it on the list. + */ + it->it_need = 1; + } else + TAILQ_REMOVE(&ie->ie_handlers, handler, ih_next); + thread_unlock(it->it_thread); + while (handler->ih_flags & IH_DEAD) + msleep(handler, &ie->ie_lock, 0, "iev_rmh", 0); + /* + * At this point, the handler has been disconnected from the event, + * so we can kill the private ithread if any. + */ + if (handler->ih_thread) { + ithread_destroy(handler->ih_thread); + handler->ih_thread = NULL; + } + intr_event_update(ie); +#ifdef notyet + /* + * XXX: This could be bad in the case of ppbus(8). Also, I think + * this could lead to races of stale data when servicing an + * interrupt. + */ + dead = 1; + TAILQ_FOREACH(ih, &ie->ie_handlers, ih_next) { + if (handler != NULL) { + dead = 0; + break; + } + } + if (dead) { + ithread_destroy(ie->ie_thread); + ie->ie_thread = NULL; + } +#endif + mtx_unlock(&ie->ie_lock); + free(handler, M_ITHREAD); + return (0); +} + +static int +intr_event_schedule_thread(struct intr_event *ie, struct intr_thread *it) +{ + struct intr_entropy entropy; + struct thread *td; + struct thread *ctd; + struct proc *p; + + /* + * If no ithread or no handlers, then we have a stray interrupt. + */ + if (ie == NULL || TAILQ_EMPTY(&ie->ie_handlers) || it == NULL) + return (EINVAL); + + ctd = curthread; + td = it->it_thread; + p = td->td_proc; + + /* + * If any of the handlers for this ithread claim to be good + * sources of entropy, then gather some. + */ + if (harvest.interrupt && ie->ie_flags & IE_ENTROPY) { + CTR3(KTR_INTR, "%s: pid %d (%s) gathering entropy", __func__, + p->p_pid, td->td_name); + entropy.event = (uintptr_t)ie; + entropy.td = ctd; + random_harvest(&entropy, sizeof(entropy), 2, 0, + RANDOM_INTERRUPT); + } + + KASSERT(p != NULL, ("ithread %s has no process", ie->ie_name)); + + /* + * Set it_need to tell the thread to keep running if it is already + * running. Then, lock the thread and see if we actually need to + * put it on the runqueue. + */ + it->it_need = 1; + thread_lock(td); + if (TD_AWAITING_INTR(td)) { + CTR3(KTR_INTR, "%s: schedule pid %d (%s)", __func__, p->p_pid, + td->td_name); + TD_CLR_IWAIT(td); + sched_add(td, SRQ_INTR); + } else { + CTR5(KTR_INTR, "%s: pid %d (%s): it_need %d, state %d", + __func__, p->p_pid, td->td_name, it->it_need, td->td_state); + } + thread_unlock(td); + + return (0); } +#endif +/* + * Allow interrupt event binding for software interrupt handlers -- a no-op, + * since interrupts are generated in software rather than being directed by + * a PIC. + */ +static int +swi_assign_cpu(void *arg, u_char cpu) +{ + + return (0); +} /* * Add a software interrupt handler to a specified event. If a given event @@ -55,7 +901,36 @@ int swi_add(struct intr_event **eventp, const char *name, driver_intr_t handler, void *arg, int pri, enum intr_type flags, void **cookiep) { - panic(""); + struct intr_event *ie; + int error; + + if (flags & INTR_ENTROPY) + return (EINVAL); + + ie = (eventp != NULL) ? *eventp : NULL; + + if (ie != NULL) { + if (!(ie->ie_flags & IE_SOFT)) + return (EINVAL); + } else { + error = intr_event_create(&ie, NULL, IE_SOFT, 0, + NULL, NULL, NULL, swi_assign_cpu, "swi%d:", pri); + if (error) + return (error); + if (eventp != NULL) + *eventp = ie; + } + error = intr_event_add_handler(ie, name, NULL, handler, arg, + (pri * RQ_PPQ) + PI_SOFT, flags, cookiep); + if (error) + return (error); + if (pri == SWI_CLOCK) { + struct proc *p; + p = ie->ie_thread->it_thread->td_proc; + PROC_LOCK(p); + p->p_flag |= P_NOLOAD; + PROC_UNLOCK(p); + } return (0); } @@ -65,6 +940,527 @@ swi_add(struct intr_event **eventp, cons void swi_sched(void *cookie, int flags) { + struct intr_handler *ih = (struct intr_handler *)cookie; + struct intr_event *ie = ih->ih_event; + int error; + + CTR3(KTR_INTR, "swi_sched: %s %s need=%d", ie->ie_name, ih->ih_name, + ih->ih_need); + + /* + * Set ih_need for this handler so that if the ithread is already + * running it will execute this handler on the next pass. Otherwise, + * it will execute it the next time it runs. + */ + atomic_store_rel_int(&ih->ih_need, 1); + + if (!(flags & SWI_DELAY)) { + PCPU_INC(cnt.v_soft); +#ifdef INTR_FILTER + error = intr_event_schedule_thread(ie, ie->ie_thread); +#else + error = intr_event_schedule_thread(ie); +#endif + KASSERT(error == 0, ("stray software interrupt")); + } +} + +/* + * Remove a software interrupt handler. Currently this code does not + * remove the associated interrupt event if it becomes empty. Calling code + * may do so manually via intr_event_destroy(), but that's not really + * an optimal interface. + */ +int +swi_remove(void *cookie) +{ + + return (intr_event_remove_handler(cookie)); +} + +#ifdef INTR_FILTER +static void +priv_ithread_execute_handler(struct proc *p, struct intr_handler *ih) +{ + struct intr_event *ie; + + ie = ih->ih_event; + /* + * If this handler is marked for death, remove it from + * the list of handlers and wake up the sleeper. + */ + if (ih->ih_flags & IH_DEAD) { + mtx_lock(&ie->ie_lock); + TAILQ_REMOVE(&ie->ie_handlers, ih, ih_next); + ih->ih_flags &= ~IH_DEAD; + wakeup(ih); + mtx_unlock(&ie->ie_lock); + return; + } + + /* Execute this handler. */ + CTR6(KTR_INTR, "%s: pid %d exec %p(%p) for %s flg=%x", + __func__, p->p_pid, (void *)ih->ih_handler, ih->ih_argument, + ih->ih_name, ih->ih_flags); + + if (!(ih->ih_flags & IH_MPSAFE)) + mtx_lock(&Giant); + ih->ih_handler(ih->ih_argument); + if (!(ih->ih_flags & IH_MPSAFE)) + mtx_unlock(&Giant); +} +#endif + +/* + * This is a public function for use by drivers that mux interrupt + * handlers for child devices from their interrupt handler. + */ +void +intr_event_execute_handlers(struct proc *p, struct intr_event *ie) +{ + struct intr_handler *ih, *ihn; + + TAILQ_FOREACH_SAFE(ih, &ie->ie_handlers, ih_next, ihn) { + /* + * If this handler is marked for death, remove it from + * the list of handlers and wake up the sleeper. *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-src-user@FreeBSD.ORG Wed Jan 13 12:21:58 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id EBF8A1065679; Wed, 13 Jan 2010 12:21:58 +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 D930A8FC12; Wed, 13 Jan 2010 12:21:58 +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 o0DCLw7V005550; Wed, 13 Jan 2010 12:21:58 GMT (envelope-from luigi@svn.freebsd.org) Received: (from luigi@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0DCLwis005541; Wed, 13 Jan 2010 12:21:58 GMT (envelope-from luigi@svn.freebsd.org) Message-Id: <201001131221.o0DCLwis005541@svn.freebsd.org> From: Luigi Rizzo Date: Wed, 13 Jan 2010 12:21:58 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202186 - user/luigi/ipfw3-head/sys/netinet/ipfw X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 13 Jan 2010 12:21:59 -0000 Author: luigi Date: Wed Jan 13 12:21:58 2010 New Revision: 202186 URL: http://svn.freebsd.org/changeset/base/202186 Log: some documentation and API fixes Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c Wed Jan 13 08:53:23 2010 (r202185) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c Wed Jan 13 12:21:58 2010 (r202186) @@ -71,8 +71,8 @@ MALLOC_DEFINE(M_DN_HEAP, "dummynet", "du #define HEAP_SWAP(a, b, buffer) { buffer = a ; a = b ; b = buffer ; } #define HEAP_INCREMENT 15 -int -heap_init(struct dn_heap *h, int new_size) +static int +heap_resize(struct dn_heap *h, int new_size) { struct dn_heap_entry *p; @@ -96,6 +96,16 @@ heap_init(struct dn_heap *h, int new_siz return 0; } +int +heap_init(struct dn_heap *h, int size, int ofs) +{ + if (heap_resize(h, size)) + return 1; + h->elements = 0; + h->ofs = ofs; + return 0; +} + /* * Insert element in heap. Normally, p != NULL, we insert p in * a new position and bubble up. If p == NULL, then the element is @@ -106,16 +116,18 @@ heap_init(struct dn_heap *h, int new_siz * If ofs > 0 the position (index, int) of the element in the heap is * also stored in the element itself at the given offset in bytes. */ -#define SET_OFFSET(heap, node) \ - if (heap->ofs > 0) \ - *((int *)((char *)(heap->p[node].object) + heap->ofs)) = node; +#define SET_OFFSET(h, i) do { \ + if (h->ofs > 0) \ + *((int32_t *)((char *)(h->p[i].object) + h->ofs)) = i; \ + } while (0) /* * RESET_OFFSET is used for sanity checks. It sets ofs * to an invalid value. */ -#define RESET_OFFSET(heap, node) \ - if (heap->ofs > 0) \ - *((int *)((char *)(heap->p[node].object) + heap->ofs)) = -1; +#define RESET_OFFSET(h, i) do { \ + if (h->ofs > 0) \ + *((int32_t *)((char *)(h->p[i].object) + h->ofs)) = -1; \ + } while (0) int heap_insert(struct dn_heap *h, uint64_t key1, void *p) @@ -123,12 +135,13 @@ heap_insert(struct dn_heap *h, uint64_t int son = h->elements; //log("%s key %llu p %p\n", __FUNCTION__, key1, p); - if (p == NULL) /* data already there, set starting point */ + if (p == NULL) { /* data already there, set starting point */ son = key1; - else {/* insert new element at the end, possibly resize */ + } else { /* insert new element at the end, possibly resize */ son = h->elements; if (son == h->size) /* need resize... */ - if (heap_init(h, h->elements+1) ) + // XXX expand by 16 or so + if (heap_resize(h, h->elements+16) ) return 1; /* failure... */ h->p[son].object = p; h->p[son].key = key1; @@ -170,7 +183,7 @@ heap_extract(struct dn_heap *h, void *ob __FUNCTION__, h); father = *((int *)((char *)obj + h->ofs)); if (father < 0 || father >= h->elements) { - panic("%s: heap_extract, father %d out of bound 0..%d\n", + panic("%s: father %d out of bound 0..%d\n", __FUNCTION__, father, h->elements); } } @@ -208,33 +221,32 @@ heap_extract(struct dn_heap *h, void *ob static void heap_move(struct dn_heap *h, uint64_t new_key, void *object) { - int temp; - int i; - int max = h->elements-1; - struct dn_heap_entry buf; + int temp, i, max = h->elements-1; + struct dn_heap_entry *p, buf; if (h->ofs <= 0) panic("cannot move items on this heap"); + p = h->p; /* shortcut */ i = *((int *)((char *)object + h->ofs)); - if (DN_KEY_LT(new_key, h->p[i].key) ) { /* must move up */ - h->p[i].key = new_key; + if (DN_KEY_LT(new_key, p[i].key) ) { /* must move up */ + p[i].key = new_key; for (; i>0 && - DN_KEY_LT(new_key, h->p[(temp = HEAP_FATHER(i))].key); + DN_KEY_LT(new_key, p[(temp = HEAP_FATHER(i))].key); i = temp ) { /* bubble up */ - HEAP_SWAP(h->p[i], h->p[temp], buf); + HEAP_SWAP(p[i], p[temp], buf); SET_OFFSET(h, i); } } else { /* must move down */ - h->p[i].key = new_key; + p[i].key = new_key; while ( (temp = HEAP_LEFT(i)) <= max ) { /* found left child */ - if ((temp != max) && - DN_KEY_GT(h->p[temp].key, h->p[temp+1].key)) + if (temp != max && + DN_KEY_LT(p[temp+1].key, p[temp].key)) temp++; /* select child with min key */ - if (DN_KEY_GT(new_key, h->p[temp].key)) { + if (DN_KEY_LT(>p[temp].key, new_key)) { /* go down */ - HEAP_SWAP(h->p[i], h->p[temp], buf); + HEAP_SWAP(p[i], p[temp], buf); SET_OFFSET(h, i); } else break; @@ -295,6 +307,16 @@ heap_free(struct dn_heap *h) * hash table support. */ +struct dn_ht { + int buckets; /* how many buckets */ + int entries; /* how many entries */ + int ofs; /* offset of link field */ + void *arg; /* argument to the three functions */ + int (*hash)(uintptr_t, int, void *arg); + int (*match)(void *_el, uintptr_t key, int, void *); + void *(*new)(uintptr_t, int, void *); + void **ht; /* bucket heads */ +}; /* * Initialize, allocating bucket pointers inline. * Recycle previous record if possible. @@ -343,6 +365,16 @@ dn_ht_init(struct dn_ht *ht, int buckets return ht; } +void +dn_ht_free(struct dn_ht *ht, int flags) +{ + if (ht == NULL) + return; + if (ht->ht && ht->ht != (void *)(ht + 1)) + free(ht->ht, M_DN_HEAP); + free(ht, M_DN_HEAP); +} + /* lookup and optionally create or delete element */ void * dn_ht_find(struct dn_ht *ht, uintptr_t key, int flags) @@ -517,7 +549,7 @@ main(int argc, char *argv[]) n = 1000000; n3 = (argc > 3) ? atoi(argv[3]) : 0; bzero(&h, sizeof(h)); - heap_init(&h, n); + heap_init(&h, n, -1); while (n2-- > 0) { uint64_t prevk = 0; for (i=0; i < n; i++) Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h Wed Jan 13 08:53:23 2010 (r202185) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h Wed Jan 13 12:21:58 2010 (r202186) @@ -1,5 +1,5 @@ /*- - * Copyright (c) 1998-2002 Luigi Rizzo, Universita` di Pisa + * Copyright (c) 1998-2010 Luigi Rizzo, Universita` di Pisa * All rights reserved * * Redistribution and use in source and binary forms, with or without @@ -31,77 +31,137 @@ #define DN_KEY_LT(a,b) ((int64_t)((a)-(b)) < 0) #define DN_KEY_LEQ(a,b) ((int64_t)((a)-(b)) <= 0) -#define DN_KEY_GT(a,b) ((int64_t)((a)-(b)) > 0) -#define DN_KEY_GEQ(a,b) ((int64_t)((a)-(b)) >= 0) /* - * A heap entry is made of a key and a pointer to the actual - * object stored in the heap. - * The heap is an array of dn_heap_entry entries, dynamically allocated. - * Current size is "size", with "elements" actually in use. - * The heap normally supports only ordered insert and extract from the top. - * If we want to extract an object from the middle of the heap, we - * have to know where the object itself is located in the heap (or we - * need to scan the whole array). To this purpose, an object has a - * field (int) which contains the index of the object itself into the - * heap. When the object is moved, the field must also be updated. - * The offset of the index in the object is stored in the 'ofs' - * field in the heap descriptor. The assumption is that this offset - * is non-zero if we want to support extract from the middle. + * This module implements a binary heap supporting random extraction. + * + * A heap entry contains an uint64_t key and a pointer to object. + * DN_KEY_LT(a,b) returns true if key 'a' is smaller than 'b' + * + * The heap is a struct dn_heap plus a dynamically allocated + * array of dn_heap_entry entries. 'size' represents the size of + * the array, 'elements' count entries in use. The topmost + * element has the smallest key. + * The heap supports ordered insert, and extract from the top. + * To extract an object from the middle of the heap, we the object + * must reserve an 'int32_t' to store the position of the object + * in the heap itself, and the location of this field must be + * passed as an argument to heap_init() -- use -1 if the feature + * is not used. */ struct dn_heap_entry { - uint64_t key; /* sorting key. Topmost element is smallest one */ + uint64_t key; /* sorting key, smallest comes first */ void *object; /* object pointer */ -} ; +}; struct dn_heap { int size; /* the size of the array */ int elements; /* elements in use */ - int ofs; /* XXX if > 0 this is the offset of direct ptr to obj */ - struct dn_heap_entry *p; /* really an array of "size" entries */ -} ; + int ofs; /* offset in the object of heap index */ + struct dn_heap_entry *p; /* array of "size" entries */ +}; -/* HEAP_TOP returns the pointer to the top element of the heap */ -#define HEAP_TOP(h) ((h)->p) -#define SET_HEAP_OFS(h, n) do { (h)->ofs = n; } while (0) -int heap_init(struct dn_heap *h, int size); -int heap_insert (struct dn_heap *h, uint64_t key1, void *p); -void heap_extract(struct dn_heap *h, void *obj); -/* void heapify(struct dn_heap *h); */ -void heap_free(struct dn_heap *h); enum { HEAP_SCAN_DEL = 1, HEAP_SCAN_END = 2, }; + /* - * heap_scan scans the entire heap calling fn on each entry. - * fn() can return a combination of HEAP_SCAN_DEL and HEAP_SCAN_END, - * where HEAP_SCAN_DEL means the current element must be removed, - * and HEAP_SCAN_END means no further entry need to be analysed. - * At the end, heap_scan calls heapify() if records are deleted. - * The function returns the number of matching elements. + * heap_init() reinitializes the heap setting the size and the offset + * of the index for random extraction (use -1 if not used). + * The 'elements' counter is set to 0. + * + * SET_HEAP_OFS() indicates where, in the object, is stored the index + * for random extractions from the heap. + * + * heap_free() frees the memory associated to a heap. + * + * heap_insert() adds a key-pointer pair to the heap + * + * HEAP_TOP() returns a pointer to the top element of the heap, + * but makes no checks on its existance (XXX should we change ?) + * + * heap_extract() removes the entry at the top, returing the pointer. + * (the key should have been read before). + * + * heap_scan() invokes a callback on each entry of the heap. + * The callback can return a combination of HEAP_SCAN_DEL and + * HEAP_SCAN_END. HEAP_SCAN_DEL means the current element must + * be removed, and HEAP_SCAN_END means to terminate the scan. + * heap_scan() returns the number of elements removed. + * Because the order is not guaranteed, we should use heap_scan() + * only as a last resort mechanism. */ +#define HEAP_TOP(h) ((h)->p) +#define SET_HEAP_OFS(h, n) do { (h)->ofs = n; } while (0) +int heap_init(struct dn_heap *h, int size, int ofs); +int heap_insert(struct dn_heap *h, uint64_t key1, void *p); +void heap_extract(struct dn_heap *h, void *obj); +void heap_free(struct dn_heap *h); int heap_scan(struct dn_heap *, int (*)(void *, uintptr_t), uintptr_t); -/*--- generic hash table support ---*/ -struct dn_ht { - int buckets; /* how many buckets */ - int entries; /* how many entries */ - int ofs; /* offset of link field */ - void *arg; /* argument to the three functions */ - int (*hash)(uintptr_t, int, void *arg); - int (*match)(void *_el, uintptr_t key, int, void *); - void *(*new)(uintptr_t, int, void *); - void **ht; /* bucket heads */ -}; +/*------------------------------------------------------ + * This module implements a generic hash table with support for + * running callbacks on the entire table. To avoid allocating + * memory during hash table operations, objects must reserve + * space for a link field. XXX if the heap is moderately full, + * an SLIST suffices, and we can tolerate the cost of a hash + * computation on each removal. + * + * dn_ht_init() initializes the table, setting the number of + * buckets, the offset of the link field, the main callbacks, + * and an extra argument passed to the callbacks together + * with 'flags' which is defined below. Callbacks are: + * + * hash(key, flags, arg) called to return a bucket index. + * match(obj, key, flags, arg) called to determine if key + * matches the current 'obj' in the heap + * new(key, flags, arg) optional, used to allocate a new + * object during insertions. + * + * dn_ht_free() frees the heap, optionally unlinking elements + * (XXX unlink is optional and serves only to avoid stale + * pointers in the objects. Probably useless.) + * + * dn_ht_find() is the main lookup function, which can also be + * used to insert or delete elements in the hash table. + * + * dn_ht_scan() is used to invoke a callback on all entries of + * the heap, or possibly on just one bucket. The callback + * is invoked with a pointer to the object, and must return + * one of DNHT_SCAN_DEL or DNHT_SCAN_END to request the + * removal of the object from the heap and the end of the + * scan, respectively. + * + * A combination of flags can be used to modify the operation + * of the dn_ht_find(), and of the callbacks: + * + * DNHT_KEY_IS_OBJ means the key is the object pointer. + * It is usally of interest for the hash and match functions. + * + * DNHT_MATCH_PTR during a lookup, match pointers instead + * of calling match(). Normally used when removing specific + * entries. XXX should it imply DNHT_KEY_IS_OBJ ? + * + * DNHT_INSERT insert the element if not found. + * Calls new() to allocates a new object unless + * DNHT_KEY_IS_OBJ is set. + * + * DNHT_UNIQUE only insert if object not found. + * XXX should it imply DNHT_INSERT ? + * + * DNHT_REMOVE remove objects if we find them. + */ +struct dn_ht; /* should be opaque */ struct dn_ht *dn_ht_init(struct dn_ht *, int buckets, int ofs, int (*hash)(uintptr_t, int, void *), int (*match)(void *, uintptr_t, int, void *), void *(*new)(uintptr_t, int, void *), void *arg); -/* lookup and optionally create or remove element. Flags described below */ void *dn_ht_find(struct dn_ht *, uintptr_t key, int flags); +int dn_ht_scan(struct dn_ht *, int (*)(void *, void *), void *); +void dn_ht_free(struct dn_ht *, int flags); enum { /* flags values. * first two are returned by the scan callback to indicate @@ -115,6 +175,5 @@ enum { /* flags values. DNHT_UNIQUE = 0x0020, /* report error if already there */ DNHT_REMOVE = 0x0040, /* remove on find */ }; -int dn_ht_scan(struct dn_ht *, int (*)(void *, void *), void *); #endif /* _IP_DN_HEAP_H */ Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h Wed Jan 13 08:53:23 2010 (r202185) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h Wed Jan 13 12:21:58 2010 (r202186) @@ -57,84 +57,56 @@ struct dn_sched { size_t schk_len; /* + per-instance parameters, such as timestamps, - * ccontainers for queues, etc; + * containers for queues, etc; */ size_t sch_inst_len; - /* + per-flowset parameters, such as individual weights, - * priorities, queue limits, slot sizes... - */ - size_t fs_len; // fs_arg - - /* + per-queue parameters (what for ?) - */ - size_t queue_len; // queue_arg + size_t queue_len; /* per-queue parameters (e.g. S,F) */ SLIST_ENTRY(dn_sched) next; /* Next scheduler in the list */ /* * Methods implemented by the scheduler: - * enqueue enqueue packet 'm' on scheduler 's'. 'id' is - * the flow id of the packet, 'f' contains - * flowset-specific data. Must returns 1 if the packet - * is NOT enqueued. + * enqueue enqueue packet 'm' on scheduler 's', queue 'q'. + * q is NULL for !MULTIQUEUE. + * Return 0 on success, 1 on drop (packet consumed anyways). * * dequeue Called when scheduler instance 's' can * dequeue a packet. Return NULL if none are available. * XXX what about non work-conserving ? * - * config called on 'sched X config ...' - * updates the field sch_arg + * config called on 'sched X config ...', normally writes + * in the area of size sch_arg * * destroy called on 'sched delete', frees everything * in sch_arg (other parts are handled by more specific * functions) * - * new_sched called when a new instance is - * created by find_scheduler. - * Updates sch_runtime - * - * free_sched called when deleting an instance - * cleans everything linked to sch_runtime - * - * new_fs called on 'queue XX config', create fs_arg - * if the reconfigure flag is set, it means that - * the fs_arg already exists and need to be update - * - * free_fs called on 'queue XX delete', frees things in - * fs_arg. Also called on a 'queue XX config' if the - * scheduler is different from what was previously. - * - * new_queue called to link a new queue to sch_runtime - * can be used to set queue variables e.g. virtual times, - * update sum of weights, etc. + * new_sched called when a new instance is created, e.g. + * to create the local queue for !MULTIQUEUE, set V or + * copy parameters for WFQ, and so on. * - * free_queue called to unlink a queue from sch_runtime - * possibly update sum of weights, etc. + * free_sched called when deleting an instance, cleans + * extra data in the per-instance area. * - * drain_queue called to free all idle queues, or possibly all of - * them (this is a subset of delete_scheduler_instance) + * new_queue called to set the per-queue parameters, + * e.g. S and F, adjust sum of weights in the parent, etc. + * + * free_queue actions related to a queue removal, e.g. undo + * all the above. */ int (*enqueue)(struct new_sch_inst *, struct new_queue *, struct mbuf *); struct mbuf * (*dequeue)(struct new_sch_inst *); - /* config or destroy the scheduler template */ int (*config)(struct new_schk *, int reconfigure); int (*destroy)(struct new_schk*, int delete); - /* create, drain or destroy a new scheduler instance */ int (*new_sched)(struct new_schk *, struct new_sch_inst *); int (*free_sched)(struct new_sch_inst *); - /* init or deinit a flowset attached to this scheduler */ - int (*new_fs)(void *command, struct dn_id *g, int reconfigure); - int (*free_fs)(struct new_fsk *); - - /* init or destroy a queue attached to this scheduler */ int (*new_queue)(struct new_queue *q); int (*free_queue)(struct new_queue *q); - }; SLIST_HEAD(dn_sched_head, dn_sched); @@ -142,54 +114,13 @@ SLIST_HEAD(dn_sched_head, dn_sched); * Additionally, dummynet exports some variables, functions and macros * to be used by schedulers. */ - /* delete a queue, which we assume nobody references */ int dn_delete_queue(struct new_queue *q); - -/* Allocate an hash table. - * Returns the pointer to the table - * - rq_size: the returned size of table - * - rq_elements: the number of elements present in the table - * - bucket: the desidered size of the table - */ -struct new_queue ** dn_alloc_hash_queue(int *rq_size, int *rq_elements, - int bucket); - -/* Delete all packets from queue 'q' */ -int dn_purge_queue(struct new_queue *q); - -/* Really enqueue the packet 'm' into queue 'q'. - * If the packet is dropped, the function returns 1 - */ -int dn_queue_packet(struct new_queue *q, struct mbuf* m); - -/* Drop a packet 'm' that belong to queue 'q' - * NOTE: q should be NULL if the queue doesn't exist - */ -int dn_drop_packet(struct new_queue *q, struct mbuf* m); - -/* Returns the index of array of hash table. - * The hash is done using flowset pointer and the flow id of the packet. - * - id: flow id - * - f: pointer to the flowset (private data) - * - rq_size: size of the hash table - */ -int dn_i_hash_id(struct ipfw_flow_id *id, struct dn_id *f, int rq_size); - -/* Returns the queue that match the flowid at the index i, if exists. - * Returns NULL if the queue doesn't exist. - * - id: flow id of the packet - * - i: index of the hash table - * - rq: pointer to the hash table - * - f: pointer to flowset scheduler specific data. Used to access to - * the flowset generic data - */ -struct new_queue * dn_q_hash_id(struct ipfw_flow_id *id, int i, - struct new_queue **rq, struct dn_id *f); +int dn_queue_packet(struct new_queue *q, struct mbuf* m, int drop); /* * Extract the head of a queue, update stats. Must be the very last - * thing done on a queue as the queue itself may go away. + * thing done on a dequeue as the queue itself may go away. */ static __inline struct mbuf* dn_return_packet(struct new_queue *q) @@ -211,8 +142,7 @@ int dn_sched_modevent(module_t mod, int static moduledata_t name##_mod = { \ #name, dn_sched_modevent, dnsched \ }; \ - DECLARE_MODULE(name, name##_mod, SI_SUB_DRIVERS, \ - SI_ORDER_MIDDLE); \ + DECLARE_MODULE(name, name##_mod, \ + SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY); \ MODULE_DEPEND(name, dummynet, 3, 3, 3); - #endif /* _DN_SCHED_H */ Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c Wed Jan 13 08:53:23 2010 (r202185) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c Wed Jan 13 12:21:58 2010 (r202186) @@ -60,8 +60,8 @@ fifo_enqueue(struct new_sch_inst *_si, s int ret; struct new_fsk *fs = (struct new_fsk *)q; /* q contains the fs */ q = (struct new_queue *)(_si+1); - q->fs = fs; - ret = dn_queue_packet(q, m); + q->fs = fs; // XXX revise + ret = dn_queue_packet(q, m, 0); q->fs = NULL; if (ret) { printf("%s dn_queue_packet dropped\n", __FUNCTION__); Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c Wed Jan 13 08:53:23 2010 (r202185) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c Wed Jan 13 12:21:58 2010 (r202186) @@ -62,11 +62,8 @@ fifo_enqueue(struct new_sch_inst *_si, s /* the queue is actually the flowset. */ q = (struct new_queue *)(_si+1); q->fs = fs; - if (dn_queue_packet(q, m)) { - printf("%s dn_queue_packet failed\n", __FUNCTION__); - /* packet was dropped */ + if (dn_queue_packet(q, m, 0)) return 1; - } /* Ok, the packet is now in the queue. * The dequeue() function will be called when the scheduler Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Wed Jan 13 08:53:23 2010 (r202185) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Wed Jan 13 12:21:58 2010 (r202186) @@ -31,8 +31,6 @@ #include __FBSDID("$FreeBSD$"); -#define DUMMYNET_DEBUG - #include "opt_inet6.h" #include @@ -71,11 +69,6 @@ __FBSDID("$FreeBSD$"); */ static dn_key curr_time = 0 ; /* current simulation time */ -/* statistics on number of queue searches and search steps */ -static long searches, search_steps ; -static int pipe_expire = 1 ; /* expire queue if empty */ -static int dn_max_ratio = 16 ; /* max queues/buckets ratio */ - struct dn_parms dn_cfg = { .pipe_slot_limit = 100, /* Foot shooting limit for pipe queues. */ .pipe_byte_limit = 1024 * 1024, @@ -104,28 +97,6 @@ static unsigned long io_pkt_drop; * The heap is checked at every tick and all entities with expired events * are extracted. */ - -/* - * The key for the heap is used for two different values: - * - * 1. timer ticks- max 10K/second, so 32 bits are enough; - * - * 2. virtual times. These increase in steps of len/x, where len is the - * packet length, and x is either the weight of the flow, or the - * sum of all weights. - * If we limit to max 1000 flows and a max weight of 100, then - * x needs 17 bits. The packet size is 16 bits, so we can easily - * overflow if we do not allow errors. - * So we use a key "dn_key" which is 64 bits. Some macros are used to - * compare key values and handle wraparounds. - * MAX64 returns the largest of two key values. - * MY_M is used as a shift count when doing fixed point arithmetic - * (a better name would be useful...). - * XXX With this scaling, max 1000 flows, max weight 100, 1Gbit/s, the - * virtual time wraps every 15 days. - */ -#define MAX64(x,y) (( (int64_t) ( (y)-(x) )) > 0 ) ? (y) : (x) -#define MY_M 16 /* shift for fixed point arithmetic */ MALLOC_DEFINE(M_DUMMYNET, "dummynet", "dummynet heap"); @@ -138,15 +109,6 @@ SYSCTL_DECL(_net_inet_ip); SYSCTL_NODE(_net_inet_ip, OID_AUTO, dummynet, CTLFLAG_RW, 0, "Dummynet"); SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, hash_size, CTLFLAG_RW, &dn_cfg.hash_size, 0, "Default hash table size"); -SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, searches, - CTLFLAG_RD, &searches, 0, "Number of queue searches"); -SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, search_steps, - CTLFLAG_RD, &search_steps, 0, "Number of queue search steps"); -SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, expire, - CTLFLAG_RW, &pipe_expire, 0, "Expire queue if empty"); -SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, max_chain_len, - CTLFLAG_RW, &dn_max_ratio, 0, - "Max ratio between dynamic queues and buckets"); SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, red_lookup_depth, CTLFLAG_RD, &dn_cfg.red_lookup_depth, 0, "Depth of RED lookup table"); SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, red_avg_pkt_size, @@ -230,15 +192,16 @@ mq_append(struct mq *q, struct mbuf *m) } /* - * Enqueue a packet in q, subject to space and queue management policy. + * Enqueue a packet in q, subject to space and queue management policy + * (whose parameters are in q->fs). * Update stats for the queue and the scheduler. * Return 0 on success, 1 on drop. The packet is consumed anyways. */ int -dn_queue_packet(struct new_queue *q, struct mbuf* m) +dn_queue_packet(struct new_queue *q, struct mbuf* m, int drop) { struct new_fs *f; - struct new_inst *ni; + struct new_inst *ni; /* stats for scheduler instance */ uint64_t len; f = &(q->fs->fs); @@ -249,6 +212,8 @@ dn_queue_packet(struct new_queue *q, str q->ni.tot_pkts++; ni->tot_bytes += len; ni->tot_pkts++; + if (drop) + goto drop; if (f->plr && random() < f->plr) goto drop; if (f->flags & DN_QSIZE_BYTES) { @@ -293,7 +258,7 @@ transmit_event(struct mq *q, struct dela } if (m != NULL) { dline->oid.subtype = 1; /* in heap */ - heap_insert(&dn_cfg.system_heap, pkt->output_time, dline); + heap_insert(&dn_cfg.evheap, pkt->output_time, dline); } } @@ -377,7 +342,7 @@ serve_sched(struct mq *q, struct new_sch if (m) dn_tag_get(m)->output_time += t; si->kflags |= DN_ACTIVE; - heap_insert(&dn_cfg.system_heap, now + t, si); + heap_insert(&dn_cfg.evheap, now + t, si); } if (delay_line_idle && done) transmit_event(q, &si->dline, now); @@ -392,69 +357,67 @@ serve_sched(struct mq *q, struct new_sch void dummynet_task(void *context, int pending) { - struct timeval t; - struct mq q = { NULL, NULL }; /* queue to accumulate results */ + struct timeval t; + struct mq q = { NULL, NULL }; /* queue to accumulate results */ - DUMMYNET_LOCK(); + DUMMYNET_LOCK(); - /* Update number of lost(coalesced) ticks. */ - tick_lost += pending - 1; - - getmicrouptime(&t); - /* Last tick duration (usec). */ - tick_last = (t.tv_sec - dn_cfg.prev_t.tv_sec) * 1000000 + - (t.tv_usec - dn_cfg.prev_t.tv_usec); - /* Last tick vs standard tick difference (usec). */ - tick_delta = (tick_last * hz - 1000000) / hz; - /* Accumulated tick difference (usec). */ - tick_delta_sum += tick_delta; - - dn_cfg.prev_t = t; - - /* - * Adjust curr_time if the accumulated tick difference is - * greater than the 'standard' tick. Since curr_time should - * be monotonically increasing, we do positive adjustments - * as required, and throttle curr_time in case of negative - * adjustment. - */ - curr_time++; - if (tick_delta_sum - tick >= 0) { - int diff = tick_delta_sum / tick; - - curr_time += diff; - tick_diff += diff; - tick_delta_sum %= tick; - tick_adjustment++; - } else if (tick_delta_sum + tick <= 0) { - curr_time--; - tick_diff--; - tick_delta_sum += tick; - tick_adjustment++; - } + /* Update number of lost(coalesced) ticks. */ + tick_lost += pending - 1; - /* serve pending events, accumulate in q */ - for (;;) { - struct dn_id *p; /* generic parameter to handler */ - - if (dn_cfg.system_heap.elements > 0 && - DN_KEY_LEQ(HEAP_TOP(&dn_cfg.system_heap)->key, curr_time)) { - p = HEAP_TOP(&dn_cfg.system_heap)->object; - heap_extract(&dn_cfg.system_heap, NULL); - } else { - break; - } + getmicrouptime(&t); + /* Last tick duration (usec). */ + tick_last = (t.tv_sec - dn_cfg.prev_t.tv_sec) * 1000000 + + (t.tv_usec - dn_cfg.prev_t.tv_usec); + /* Last tick vs standard tick difference (usec). */ + tick_delta = (tick_last * hz - 1000000) / hz; + /* Accumulated tick difference (usec). */ + tick_delta_sum += tick_delta; + + dn_cfg.prev_t = t; + + /* + * Adjust curr_time if the accumulated tick difference is + * greater than the 'standard' tick. Since curr_time should + * be monotonically increasing, we do positive adjustments + * as required, and throttle curr_time in case of negative + * adjustment. + */ + curr_time++; + if (tick_delta_sum - tick >= 0) { + int diff = tick_delta_sum / tick; + + curr_time += diff; + tick_diff += diff; + tick_delta_sum %= tick; + tick_adjustment++; + } else if (tick_delta_sum + tick <= 0) { + curr_time--; + tick_diff--; + tick_delta_sum += tick; + tick_adjustment++; + } + + /* serve pending events, accumulate in q */ + for (;;) { + struct dn_id *p; /* generic parameter to handler */ - if (p->type == DN_SCH_I) { - serve_sched(&q, (struct new_sch_inst *)p, curr_time); - } else { /* extracted a delay line */ - transmit_event(&q, (struct delay_line *)p, curr_time); + if (dn_cfg.evheap.elements == 0 || + DN_KEY_LT(curr_time, HEAP_TOP(&dn_cfg.evheap)->key)) + break; + p = HEAP_TOP(&dn_cfg.evheap)->object; + heap_extract(&dn_cfg.evheap, NULL); + + if (p->type == DN_SCH_I) { + serve_sched(&q, (struct new_sch_inst *)p, curr_time); + } else { /* extracted a delay line */ + transmit_event(&q, (struct delay_line *)p, curr_time); + } } - } - DUMMYNET_UNLOCK(); - dn_reschedule(); - if (q.head != NULL) - dummynet_send(q.head); + DUMMYNET_UNLOCK(); + dn_reschedule(); + if (q.head != NULL) + dummynet_send(q.head); } /* Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h Wed Jan 13 08:53:23 2010 (r202185) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h Wed Jan 13 12:21:58 2010 (r202186) @@ -68,7 +68,7 @@ struct dn_parms { int io_fast; struct timeval prev_t; /* last time dummynet_tick ran */ - struct dn_heap system_heap; /* scheduled events */ + struct dn_heap evheap; /* scheduled events */ /* counters of objects -- used for reporting space */ int schk_count; Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Wed Jan 13 08:53:23 2010 (r202185) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Wed Jan 13 12:21:58 2010 (r202186) @@ -287,11 +287,11 @@ si_destroy(void *_si, void *arg) struct new_queue *q; if (si->kflags & DN_ACTIVE) /* is in the heap */ - heap_extract(&dn_cfg.system_heap, si); + heap_extract(&dn_cfg.evheap, si); if (s->fp->free_sched) s->fp->free_sched(si); if (dl->oid.subtype) /* is in the heap */ - heap_extract(&dn_cfg.system_heap, dl); + heap_extract(&dn_cfg.evheap, dl); dn_free_pkts(dl->mq.head); while ( (q = SLIST_FIRST(&si->ql_list)) ) { dn_delete_queue(q); @@ -501,8 +501,7 @@ dummynet_flush(void) dn_ht_scan(dn_cfg.schedhash, schk_del_cb, 0); /* Reinitialize system heap... */ - heap_init(&dn_cfg.system_heap, 16); - SET_HEAP_OFS(&dn_cfg.system_heap, offsetof(struct dn_id, id)); + heap_init(&dn_cfg.evheap, 16, offsetof(struct dn_id, id)); DUMMYNET_UNLOCK(); } @@ -1111,7 +1110,7 @@ ip_dn_destroy(void) dummynet_flush(); free(dn_cfg.schedhash, M_DUMMYNET); - heap_free(&dn_cfg.system_heap); + heap_free(&dn_cfg.evheap); DUMMYNET_LOCK_DESTROY(); } @@ -1123,6 +1122,7 @@ dummynet_modevent(module_t mod, int type switch (type) { case MOD_LOAD: + printf("%s MODLOAD\n", __FUNCTION__); if (ip_dn_io_ptr) { printf("DUMMYNET already loaded\n"); return EEXIST ; @@ -1217,7 +1217,7 @@ static moduledata_t dummynet_mod = { }; DECLARE_MODULE(dummynet, dummynet_mod, - SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY); + SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY-1); MODULE_DEPEND(dummynet, ipfw, 2, 2, 2); MODULE_VERSION(dummynet, 1); /* end of file */ From owner-svn-src-user@FreeBSD.ORG Wed Jan 13 17:45:40 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 6BAF31065672; Wed, 13 Jan 2010 17:45:40 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 570978FC0A; Wed, 13 Jan 2010 17:45:40 +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 o0DHje4X076943; Wed, 13 Jan 2010 17:45:40 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0DHjdKV076913; Wed, 13 Jan 2010 17:45:39 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201001131745.o0DHjdKV076913@svn.freebsd.org> From: Ed Schouten Date: Wed, 13 Jan 2010 17:45:39 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202189 - in user/ed/utmpx: etc/rc.d games/fortune/datfiles lib/libc/gen lib/libc/net lib/libc/sys lib/libelf lib/libpmc sbin/fsck_ffs sbin/ifconfig share/man/man3 share/man/man4 sys/am... X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 13 Jan 2010 17:45:40 -0000 Author: ed Date: Wed Jan 13 17:45:39 2010 New Revision: 202189 URL: http://svn.freebsd.org/changeset/base/202189 Log: Merge HEAD, so I can cherry pick my changes that need to go in to HEAD. Added: user/ed/utmpx/share/man/man4/uhso.4 - copied unchanged from r202188, head/share/man/man4/uhso.4 user/ed/utmpx/sys/dev/usb/net/uhso.c - copied unchanged from r202188, head/sys/dev/usb/net/uhso.c user/ed/utmpx/sys/modules/usb/uhso/ - copied from r202188, head/sys/modules/usb/uhso/ user/ed/utmpx/usr.sbin/uhsoctl/ - copied from r202188, head/usr.sbin/uhsoctl/ Modified: user/ed/utmpx/games/fortune/datfiles/freebsd-tips user/ed/utmpx/lib/libc/gen/Makefile.inc user/ed/utmpx/lib/libc/gen/sem_init.3 user/ed/utmpx/lib/libc/gen/sem_new.c user/ed/utmpx/lib/libc/gen/sem_open.3 user/ed/utmpx/lib/libc/net/sctp_bindx.3 user/ed/utmpx/lib/libc/net/sctp_connectx.3 user/ed/utmpx/lib/libc/net/sctp_getaddrlen.3 user/ed/utmpx/lib/libc/net/sctp_getassocid.3 user/ed/utmpx/lib/libc/net/sctp_getpaddrs.3 user/ed/utmpx/lib/libc/net/sctp_opt_info.3 user/ed/utmpx/lib/libc/net/sctp_recvmsg.3 user/ed/utmpx/lib/libc/net/sctp_send.3 user/ed/utmpx/lib/libc/net/sctp_sendmsg.3 user/ed/utmpx/lib/libc/sys/sctp_generic_recvmsg.2 user/ed/utmpx/lib/libc/sys/sctp_generic_sendmsg.2 user/ed/utmpx/lib/libc/sys/sctp_peeloff.2 user/ed/utmpx/lib/libelf/elf.3 user/ed/utmpx/lib/libpmc/libpmc.c user/ed/utmpx/sbin/fsck_ffs/pass2.c user/ed/utmpx/sbin/ifconfig/ifieee80211.c user/ed/utmpx/share/man/man3/pthread_affinity_np.3 user/ed/utmpx/share/man/man3/pthread_attr_affinity_np.3 user/ed/utmpx/share/man/man4/Makefile user/ed/utmpx/share/man/man4/ath.4 user/ed/utmpx/share/man/man4/cpufreq.4 user/ed/utmpx/share/man/man4/snd_hda.4 user/ed/utmpx/share/man/man4/vge.4 user/ed/utmpx/sys/amd64/amd64/local_apic.c user/ed/utmpx/sys/boot/forth/loader.conf user/ed/utmpx/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c user/ed/utmpx/sys/compat/linux/linux_file.c user/ed/utmpx/sys/compat/linux/linux_misc.c user/ed/utmpx/sys/compat/linux/linux_uid16.c user/ed/utmpx/sys/compat/svr4/svr4_misc.c user/ed/utmpx/sys/conf/NOTES user/ed/utmpx/sys/conf/files user/ed/utmpx/sys/dev/aic7xxx/aic79xx_pci.c user/ed/utmpx/sys/dev/ath/ath_hal/ar5210/ar5210_reset.c user/ed/utmpx/sys/dev/ath/if_ath.c user/ed/utmpx/sys/dev/ct/ct_isa.c user/ed/utmpx/sys/dev/mly/mly.c user/ed/utmpx/sys/dev/mxge/eth_z8e.h user/ed/utmpx/sys/dev/mxge/ethp_z8e.h user/ed/utmpx/sys/dev/mxge/if_mxge.c user/ed/utmpx/sys/dev/mxge/rss_eth_z8e.h user/ed/utmpx/sys/dev/mxge/rss_ethp_z8e.h user/ed/utmpx/sys/dev/sound/pci/hda/hdac.c user/ed/utmpx/sys/dev/sound/pci/hda/hdac_private.h user/ed/utmpx/sys/dev/sound/pcm/dsp.c user/ed/utmpx/sys/dev/sound/pcm/mixer.c user/ed/utmpx/sys/dev/usb/usbdevs user/ed/utmpx/sys/fs/tmpfs/tmpfs.h user/ed/utmpx/sys/fs/tmpfs/tmpfs_vfsops.c user/ed/utmpx/sys/i386/i386/local_apic.c user/ed/utmpx/sys/i386/ibcs2/ibcs2_misc.c user/ed/utmpx/sys/kern/kern_jail.c user/ed/utmpx/sys/kern/kern_mib.c user/ed/utmpx/sys/kern/kern_prot.c user/ed/utmpx/sys/kern/subr_param.c user/ed/utmpx/sys/kern/vfs_syscalls.c user/ed/utmpx/sys/mips/conf/AR71XX (contents, props changed) user/ed/utmpx/sys/mips/conf/MALTA64 (contents, props changed) user/ed/utmpx/sys/mips/conf/SWARM (contents, props changed) user/ed/utmpx/sys/mips/rmi/ehcireg.h (contents, props changed) user/ed/utmpx/sys/mips/rmi/ehcivar.h (contents, props changed) user/ed/utmpx/sys/mips/rmi/pcibus.c (contents, props changed) user/ed/utmpx/sys/mips/rmi/pcibus.h (contents, props changed) user/ed/utmpx/sys/mips/rmi/uart_bus_xlr_iodi.c (contents, props changed) user/ed/utmpx/sys/mips/rmi/xlr_i2c.c (contents, props changed) user/ed/utmpx/sys/mips/rmi/xls_ehci.c (contents, props changed) user/ed/utmpx/sys/modules/usb/Makefile user/ed/utmpx/sys/net80211/ieee80211_mesh.c user/ed/utmpx/sys/net80211/ieee80211_mesh.h user/ed/utmpx/sys/rpc/authunix_prot.c user/ed/utmpx/sys/security/audit/audit_arg.c user/ed/utmpx/sys/sys/syscallsubr.h user/ed/utmpx/sys/sys/systm.h user/ed/utmpx/sys/ufs/ffs/ffs_alloc.c user/ed/utmpx/sys/ufs/ffs/fs.h user/ed/utmpx/sys/ufs/ufs/ufs_lookup.c user/ed/utmpx/tools/tools/ath/athdecode/main.c user/ed/utmpx/usr.sbin/Makefile Directory Properties: user/ed/utmpx/ (props changed) user/ed/utmpx/contrib/one-true-awk/ (props changed) user/ed/utmpx/etc/rc.d/static_arp (props changed) user/ed/utmpx/sys/conf/ldscript.mips.mips64 (props changed) user/ed/utmpx/sys/conf/ldscript.mips.octeon1.32 (props changed) user/ed/utmpx/sys/conf/ldscript.mips.octeon1.64 (props changed) user/ed/utmpx/sys/conf/ldscript.mips.octeon1.n32 (props changed) user/ed/utmpx/sys/dev/cfe/cfe_env.c (props changed) user/ed/utmpx/sys/dev/flash/mx25l.c (props changed) user/ed/utmpx/sys/dev/flash/mx25lreg.h (props changed) user/ed/utmpx/sys/dev/siba/siba/ (props changed) user/ed/utmpx/sys/dev/siba/siba_cc.c (props changed) user/ed/utmpx/sys/mips/adm5120/adm5120_machdep.c (props changed) user/ed/utmpx/sys/mips/adm5120/adm5120reg.h (props changed) user/ed/utmpx/sys/mips/adm5120/admpci.c (props changed) user/ed/utmpx/sys/mips/adm5120/console.c (props changed) user/ed/utmpx/sys/mips/adm5120/files.adm5120 (props changed) user/ed/utmpx/sys/mips/adm5120/if_admsw.c (props changed) user/ed/utmpx/sys/mips/adm5120/if_admswreg.h (props changed) user/ed/utmpx/sys/mips/adm5120/if_admswvar.h (props changed) user/ed/utmpx/sys/mips/adm5120/obio.c (props changed) user/ed/utmpx/sys/mips/adm5120/obiovar.h (props changed) user/ed/utmpx/sys/mips/adm5120/std.adm5120 (props changed) user/ed/utmpx/sys/mips/adm5120/uart_bus_adm5120.c (props changed) user/ed/utmpx/sys/mips/adm5120/uart_cpu_adm5120.c (props changed) user/ed/utmpx/sys/mips/adm5120/uart_dev_adm5120.c (props changed) user/ed/utmpx/sys/mips/adm5120/uart_dev_adm5120.h (props changed) user/ed/utmpx/sys/mips/alchemy/ (props changed) user/ed/utmpx/sys/mips/alchemy/files.alchemy (props changed) user/ed/utmpx/sys/mips/alchemy/std.alchemy (props changed) user/ed/utmpx/sys/mips/atheros/ (props changed) user/ed/utmpx/sys/mips/atheros/apb.c (props changed) user/ed/utmpx/sys/mips/atheros/apbvar.h (props changed) user/ed/utmpx/sys/mips/atheros/ar71xx_bus_space_reversed.c (props changed) user/ed/utmpx/sys/mips/atheros/ar71xx_bus_space_reversed.h (props changed) user/ed/utmpx/sys/mips/atheros/ar71xx_ehci.c (props changed) user/ed/utmpx/sys/mips/atheros/ar71xx_machdep.c (props changed) user/ed/utmpx/sys/mips/atheros/ar71xx_ohci.c (props changed) user/ed/utmpx/sys/mips/atheros/ar71xx_pci.c (props changed) user/ed/utmpx/sys/mips/atheros/ar71xx_pci_bus_space.c (props changed) user/ed/utmpx/sys/mips/atheros/ar71xx_pci_bus_space.h (props changed) user/ed/utmpx/sys/mips/atheros/ar71xx_spi.c (props changed) user/ed/utmpx/sys/mips/atheros/ar71xx_wdog.c (props changed) user/ed/utmpx/sys/mips/atheros/ar71xxreg.h (props changed) user/ed/utmpx/sys/mips/atheros/files.ar71xx (props changed) user/ed/utmpx/sys/mips/atheros/if_arge.c (props changed) user/ed/utmpx/sys/mips/atheros/if_argevar.h (props changed) user/ed/utmpx/sys/mips/atheros/uart_bus_ar71xx.c (props changed) user/ed/utmpx/sys/mips/atheros/uart_cpu_ar71xx.c (props changed) user/ed/utmpx/sys/mips/cavium/ (props changed) user/ed/utmpx/sys/mips/cavium/files.octeon1 (props changed) user/ed/utmpx/sys/mips/cavium/std.octeon1 (props changed) user/ed/utmpx/sys/mips/conf/.cvsignore (props changed) user/ed/utmpx/sys/mips/conf/ADM5120 (props changed) user/ed/utmpx/sys/mips/conf/ADM5120.hints (props changed) user/ed/utmpx/sys/mips/conf/ALCHEMY (props changed) user/ed/utmpx/sys/mips/conf/AR71XX.hints (props changed) user/ed/utmpx/sys/mips/conf/DEFAULTS (props changed) user/ed/utmpx/sys/mips/conf/IDT (props changed) user/ed/utmpx/sys/mips/conf/IDT.hints (props changed) user/ed/utmpx/sys/mips/conf/MALTA (props changed) user/ed/utmpx/sys/mips/conf/MALTA.hints (props changed) user/ed/utmpx/sys/mips/conf/OCTEON1 (props changed) user/ed/utmpx/sys/mips/conf/OCTEON1-32 (props changed) user/ed/utmpx/sys/mips/conf/OCTEON1.hints (props changed) user/ed/utmpx/sys/mips/conf/QEMU (props changed) user/ed/utmpx/sys/mips/conf/SENTRY5 (props changed) user/ed/utmpx/sys/mips/conf/SENTRY5.hints (props changed) user/ed/utmpx/sys/mips/conf/SWARM.hints (props changed) user/ed/utmpx/sys/mips/conf/XLR (props changed) user/ed/utmpx/sys/mips/idt/files.idt (props changed) user/ed/utmpx/sys/mips/idt/idt_machdep.c (props changed) user/ed/utmpx/sys/mips/idt/idtpci.c (props changed) user/ed/utmpx/sys/mips/idt/idtreg.h (props changed) user/ed/utmpx/sys/mips/idt/if_kr.c (props changed) user/ed/utmpx/sys/mips/idt/if_krreg.h (props changed) user/ed/utmpx/sys/mips/idt/obio.c (props changed) user/ed/utmpx/sys/mips/idt/obiovar.h (props changed) user/ed/utmpx/sys/mips/idt/std.idt (props changed) user/ed/utmpx/sys/mips/idt/uart_bus_rc32434.c (props changed) user/ed/utmpx/sys/mips/idt/uart_cpu_rc32434.c (props changed) user/ed/utmpx/sys/mips/include/_align.h (props changed) user/ed/utmpx/sys/mips/include/_bus.h (props changed) user/ed/utmpx/sys/mips/include/_bus_octeon.h (props changed) user/ed/utmpx/sys/mips/include/_inttypes.h (props changed) user/ed/utmpx/sys/mips/include/_limits.h (props changed) user/ed/utmpx/sys/mips/include/_stdint.h (props changed) user/ed/utmpx/sys/mips/include/_types.h (props changed) user/ed/utmpx/sys/mips/include/archtype.h (props changed) user/ed/utmpx/sys/mips/include/asm.h (props changed) user/ed/utmpx/sys/mips/include/asmacros.h (props changed) user/ed/utmpx/sys/mips/include/atomic.h (props changed) user/ed/utmpx/sys/mips/include/bootinfo.h (props changed) user/ed/utmpx/sys/mips/include/bswap.h (props changed) user/ed/utmpx/sys/mips/include/bus.h (props changed) user/ed/utmpx/sys/mips/include/bus_dma.h (props changed) user/ed/utmpx/sys/mips/include/cache.h (props changed) user/ed/utmpx/sys/mips/include/cache_mipsNN.h (props changed) user/ed/utmpx/sys/mips/include/cache_r4k.h (props changed) user/ed/utmpx/sys/mips/include/cdefs.h (props changed) user/ed/utmpx/sys/mips/include/clock.h (props changed) user/ed/utmpx/sys/mips/include/clockvar.h (props changed) user/ed/utmpx/sys/mips/include/cpu.h (props changed) user/ed/utmpx/sys/mips/include/cpufunc.h (props changed) user/ed/utmpx/sys/mips/include/cpuinfo.h (props changed) user/ed/utmpx/sys/mips/include/cpuregs.h (props changed) user/ed/utmpx/sys/mips/include/cputypes.h (props changed) user/ed/utmpx/sys/mips/include/db_machdep.h (props changed) user/ed/utmpx/sys/mips/include/defs.h (props changed) user/ed/utmpx/sys/mips/include/elf.h (props changed) user/ed/utmpx/sys/mips/include/endian.h (props changed) user/ed/utmpx/sys/mips/include/exec.h (props changed) user/ed/utmpx/sys/mips/include/float.h (props changed) user/ed/utmpx/sys/mips/include/floatingpoint.h (props changed) user/ed/utmpx/sys/mips/include/fls64.h (props changed) user/ed/utmpx/sys/mips/include/fpu.h (props changed) user/ed/utmpx/sys/mips/include/frame.h (props changed) user/ed/utmpx/sys/mips/include/gdb_machdep.h (props changed) user/ed/utmpx/sys/mips/include/hwfunc.h (props changed) user/ed/utmpx/sys/mips/include/ieee.h (props changed) user/ed/utmpx/sys/mips/include/ieeefp.h (props changed) user/ed/utmpx/sys/mips/include/in_cksum.h (props changed) user/ed/utmpx/sys/mips/include/intr_machdep.h (props changed) user/ed/utmpx/sys/mips/include/iodev.h (props changed) user/ed/utmpx/sys/mips/include/kdb.h (props changed) user/ed/utmpx/sys/mips/include/limits.h (props changed) user/ed/utmpx/sys/mips/include/locore.h (props changed) user/ed/utmpx/sys/mips/include/md_var.h (props changed) user/ed/utmpx/sys/mips/include/memdev.h (props changed) user/ed/utmpx/sys/mips/include/metadata.h (props changed) user/ed/utmpx/sys/mips/include/minidump.h (props changed) user/ed/utmpx/sys/mips/include/mips_opcode.h (props changed) user/ed/utmpx/sys/mips/include/mp_watchdog.h (props changed) user/ed/utmpx/sys/mips/include/mutex.h (props changed) user/ed/utmpx/sys/mips/include/param.h (props changed) user/ed/utmpx/sys/mips/include/pcb.h (props changed) user/ed/utmpx/sys/mips/include/pci_cfgreg.h (props changed) user/ed/utmpx/sys/mips/include/pcpu.h (props changed) user/ed/utmpx/sys/mips/include/pmap.h (props changed) user/ed/utmpx/sys/mips/include/pmc_mdep.h (props changed) user/ed/utmpx/sys/mips/include/ppireg.h (props changed) user/ed/utmpx/sys/mips/include/proc.h (props changed) user/ed/utmpx/sys/mips/include/profile.h (props changed) user/ed/utmpx/sys/mips/include/psl.h (props changed) user/ed/utmpx/sys/mips/include/pte.h (props changed) user/ed/utmpx/sys/mips/include/ptrace.h (props changed) user/ed/utmpx/sys/mips/include/queue.h (props changed) user/ed/utmpx/sys/mips/include/reg.h (props changed) user/ed/utmpx/sys/mips/include/regdef.h (props changed) user/ed/utmpx/sys/mips/include/regnum.h (props changed) user/ed/utmpx/sys/mips/include/reloc.h (props changed) user/ed/utmpx/sys/mips/include/resource.h (props changed) user/ed/utmpx/sys/mips/include/rm7000.h (props changed) user/ed/utmpx/sys/mips/include/runq.h (props changed) user/ed/utmpx/sys/mips/include/segments.h (props changed) user/ed/utmpx/sys/mips/include/setjmp.h (props changed) user/ed/utmpx/sys/mips/include/sf_buf.h (props changed) user/ed/utmpx/sys/mips/include/sigframe.h (props changed) user/ed/utmpx/sys/mips/include/signal.h (props changed) user/ed/utmpx/sys/mips/include/smp.h (props changed) user/ed/utmpx/sys/mips/include/stdarg.h (props changed) user/ed/utmpx/sys/mips/include/sysarch.h (props changed) user/ed/utmpx/sys/mips/include/timerreg.h (props changed) user/ed/utmpx/sys/mips/include/trap.h (props changed) user/ed/utmpx/sys/mips/include/ucontext.h (props changed) user/ed/utmpx/sys/mips/include/varargs.h (props changed) user/ed/utmpx/sys/mips/include/vmparam.h (props changed) user/ed/utmpx/sys/mips/malta/files.malta (props changed) user/ed/utmpx/sys/mips/malta/gt.c (props changed) user/ed/utmpx/sys/mips/malta/gt_pci.c (props changed) user/ed/utmpx/sys/mips/malta/gtreg.h (props changed) user/ed/utmpx/sys/mips/malta/gtvar.h (props changed) user/ed/utmpx/sys/mips/malta/malta_machdep.c (props changed) user/ed/utmpx/sys/mips/malta/maltareg.h (props changed) user/ed/utmpx/sys/mips/malta/obio.c (props changed) user/ed/utmpx/sys/mips/malta/obiovar.h (props changed) user/ed/utmpx/sys/mips/malta/std.malta (props changed) user/ed/utmpx/sys/mips/malta/uart_bus_maltausart.c (props changed) user/ed/utmpx/sys/mips/malta/uart_cpu_maltausart.c (props changed) user/ed/utmpx/sys/mips/malta/yamon.c (props changed) user/ed/utmpx/sys/mips/malta/yamon.h (props changed) user/ed/utmpx/sys/mips/mips/autoconf.c (props changed) user/ed/utmpx/sys/mips/mips/bus_space_generic.c (props changed) user/ed/utmpx/sys/mips/mips/busdma_machdep.c (props changed) user/ed/utmpx/sys/mips/mips/cache.c (props changed) user/ed/utmpx/sys/mips/mips/cache_mipsNN.c (props changed) user/ed/utmpx/sys/mips/mips/copystr.S (props changed) user/ed/utmpx/sys/mips/mips/cpu.c (props changed) user/ed/utmpx/sys/mips/mips/db_disasm.c (props changed) user/ed/utmpx/sys/mips/mips/db_interface.c (props changed) user/ed/utmpx/sys/mips/mips/db_trace.c (props changed) user/ed/utmpx/sys/mips/mips/dump_machdep.c (props changed) user/ed/utmpx/sys/mips/mips/elf64_machdep.c (props changed) user/ed/utmpx/sys/mips/mips/elf_machdep.c (props changed) user/ed/utmpx/sys/mips/mips/elf_trampoline.c (props changed) user/ed/utmpx/sys/mips/mips/exception.S (props changed) user/ed/utmpx/sys/mips/mips/fp.S (props changed) user/ed/utmpx/sys/mips/mips/gdb_machdep.c (props changed) user/ed/utmpx/sys/mips/mips/genassym.c (props changed) user/ed/utmpx/sys/mips/mips/in_cksum.c (props changed) user/ed/utmpx/sys/mips/mips/inckern.S (props changed) user/ed/utmpx/sys/mips/mips/intr_machdep.c (props changed) user/ed/utmpx/sys/mips/mips/locore.S (props changed) user/ed/utmpx/sys/mips/mips/machdep.c (props changed) user/ed/utmpx/sys/mips/mips/mainbus.c (props changed) user/ed/utmpx/sys/mips/mips/mem.c (props changed) user/ed/utmpx/sys/mips/mips/mp_machdep.c (props changed) user/ed/utmpx/sys/mips/mips/nexus.c (props changed) user/ed/utmpx/sys/mips/mips/pm_machdep.c (props changed) user/ed/utmpx/sys/mips/mips/pmap.c (props changed) user/ed/utmpx/sys/mips/mips/psraccess.S (props changed) user/ed/utmpx/sys/mips/mips/ptrace_machdep.c (props changed) user/ed/utmpx/sys/mips/mips/stack_machdep.c (props changed) user/ed/utmpx/sys/mips/mips/support.S (props changed) user/ed/utmpx/sys/mips/mips/swtch.S (props changed) user/ed/utmpx/sys/mips/mips/sys_machdep.c (props changed) user/ed/utmpx/sys/mips/mips/tick.c (props changed) user/ed/utmpx/sys/mips/mips/tlb.S (props changed) user/ed/utmpx/sys/mips/mips/trap.c (props changed) user/ed/utmpx/sys/mips/mips/uio_machdep.c (props changed) user/ed/utmpx/sys/mips/mips/vm_machdep.c (props changed) user/ed/utmpx/sys/mips/rmi/ (props changed) user/ed/utmpx/sys/mips/rmi/Makefile.msgring (props changed) user/ed/utmpx/sys/mips/rmi/board.c (props changed) user/ed/utmpx/sys/mips/rmi/board.h (props changed) user/ed/utmpx/sys/mips/rmi/bus_space_rmi.c (props changed) user/ed/utmpx/sys/mips/rmi/clock.c (props changed) user/ed/utmpx/sys/mips/rmi/clock.h (props changed) user/ed/utmpx/sys/mips/rmi/debug.h (props changed) user/ed/utmpx/sys/mips/rmi/dev/ (props changed) user/ed/utmpx/sys/mips/rmi/dev/sec/desc.h (props changed) user/ed/utmpx/sys/mips/rmi/dev/sec/rmilib.c (props changed) user/ed/utmpx/sys/mips/rmi/dev/sec/rmilib.h (props changed) user/ed/utmpx/sys/mips/rmi/dev/sec/rmisec.c (props changed) user/ed/utmpx/sys/mips/rmi/dev/sec/stats.h (props changed) user/ed/utmpx/sys/mips/rmi/dev/xlr/atx_cpld.h (props changed) user/ed/utmpx/sys/mips/rmi/dev/xlr/rge.c (props changed) user/ed/utmpx/sys/mips/rmi/dev/xlr/rge.h (props changed) user/ed/utmpx/sys/mips/rmi/dev/xlr/xgmac_mdio.h (props changed) user/ed/utmpx/sys/mips/rmi/files.xlr (props changed) user/ed/utmpx/sys/mips/rmi/interrupt.h (props changed) user/ed/utmpx/sys/mips/rmi/intr_machdep.c (props changed) user/ed/utmpx/sys/mips/rmi/iodi.c (props changed) user/ed/utmpx/sys/mips/rmi/iomap.h (props changed) user/ed/utmpx/sys/mips/rmi/msgring.c (props changed) user/ed/utmpx/sys/mips/rmi/msgring.cfg (props changed) user/ed/utmpx/sys/mips/rmi/msgring.h (props changed) user/ed/utmpx/sys/mips/rmi/msgring_xls.c (props changed) user/ed/utmpx/sys/mips/rmi/msgring_xls.cfg (props changed) user/ed/utmpx/sys/mips/rmi/on_chip.c (props changed) user/ed/utmpx/sys/mips/rmi/perfmon.h (props changed) user/ed/utmpx/sys/mips/rmi/perfmon_kern.c (props changed) user/ed/utmpx/sys/mips/rmi/perfmon_percpu.c (props changed) user/ed/utmpx/sys/mips/rmi/perfmon_utils.h (props changed) user/ed/utmpx/sys/mips/rmi/perfmon_xlrconfig.h (props changed) user/ed/utmpx/sys/mips/rmi/pic.h (props changed) user/ed/utmpx/sys/mips/rmi/rmi_mips_exts.h (props changed) user/ed/utmpx/sys/mips/rmi/rootfs_list.txt (props changed) user/ed/utmpx/sys/mips/rmi/shared_structs.h (props changed) user/ed/utmpx/sys/mips/rmi/shared_structs_func.h (props changed) user/ed/utmpx/sys/mips/rmi/shared_structs_offsets.h (props changed) user/ed/utmpx/sys/mips/rmi/std.xlr (props changed) user/ed/utmpx/sys/mips/rmi/tick.c (props changed) user/ed/utmpx/sys/mips/rmi/uart_cpu_mips_xlr.c (props changed) user/ed/utmpx/sys/mips/rmi/xlr_boot1_console.c (props changed) user/ed/utmpx/sys/mips/rmi/xlr_csum_nocopy.S (props changed) user/ed/utmpx/sys/mips/rmi/xlr_machdep.c (props changed) user/ed/utmpx/sys/mips/rmi/xlr_pci.c (props changed) user/ed/utmpx/sys/mips/rmi/xlrconfig.h (props changed) user/ed/utmpx/sys/mips/sentry5/files.sentry5 (props changed) user/ed/utmpx/sys/mips/sentry5/obio.c (props changed) user/ed/utmpx/sys/mips/sentry5/obiovar.h (props changed) user/ed/utmpx/sys/mips/sentry5/s5_machdep.c (props changed) user/ed/utmpx/sys/mips/sentry5/s5reg.h (props changed) user/ed/utmpx/sys/mips/sentry5/uart_bus_sbusart.c (props changed) user/ed/utmpx/sys/mips/sentry5/uart_cpu_sbusart.c (props changed) user/ed/utmpx/sys/mips/sibyte/ (props changed) user/ed/utmpx/sys/mips/sibyte/files.sibyte (props changed) Modified: user/ed/utmpx/games/fortune/datfiles/freebsd-tips ============================================================================== --- user/ed/utmpx/games/fortune/datfiles/freebsd-tips Wed Jan 13 17:29:55 2010 (r202188) +++ user/ed/utmpx/games/fortune/datfiles/freebsd-tips Wed Jan 13 17:45:39 2010 (r202189) @@ -50,18 +50,6 @@ If you are in the C shell and have just be able to run it unless you first type "rehash". -- Dru % -If you are running xterm, the default TERM variable will be 'xterm'. If you -set this environment variable to 'xterm-color' instead, a lot of programs will -use colors. You can do this by - - TERM=xterm-color; export TERM - -in Bourne-derived shells, and - - setenv TERM xterm-color - -in csh-derived shells. -% If you do not want to get beeps in X11 (X Windows), you can turn them off with xset b off Modified: user/ed/utmpx/lib/libc/gen/Makefile.inc ============================================================================== --- user/ed/utmpx/lib/libc/gen/Makefile.inc Wed Jan 13 17:29:55 2010 (r202188) +++ user/ed/utmpx/lib/libc/gen/Makefile.inc Wed Jan 13 17:45:39 2010 (r202189) @@ -18,7 +18,7 @@ SRCS+= __getosreldate.c __xuname.c \ gethostname.c getloadavg.c getlogin.c getmntinfo.c getnetgrent.c \ getosreldate.c getpagesize.c getpagesizes.c \ getpeereid.c getprogname.c getpwent.c getttyent.c \ - getutxent.c getusershell.c getvfsbyname.c glob.c \ + getusershell.c getutxent.c getvfsbyname.c glob.c \ initgroups.c isatty.c isinf.c isnan.c jrand48.c lcong48.c \ lockf.c lrand48.c mrand48.c nftw.c nice.c \ nlist.c nrand48.c opendir.c \ Modified: user/ed/utmpx/lib/libc/gen/sem_init.3 ============================================================================== --- user/ed/utmpx/lib/libc/gen/sem_init.3 Wed Jan 13 17:29:55 2010 (r202188) +++ user/ed/utmpx/lib/libc/gen/sem_init.3 Wed Jan 13 17:45:39 2010 (r202189) @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 7, 2010 +.Dd January 9, 2010 .Dt SEM_INIT 3 .Os .Sh NAME @@ -52,7 +52,7 @@ A non-zero value for specifies a shared semaphore that can be used by multiple processes, the semaphore should be located in shared memory region (see .Xr mmap 2 , -.Xr shm_open 2 , +.Xr shm_open 2 , and .Xr shmget 2 ) , any process having read and write access to address Modified: user/ed/utmpx/lib/libc/gen/sem_new.c ============================================================================== --- user/ed/utmpx/lib/libc/gen/sem_new.c Wed Jan 13 17:29:55 2010 (r202188) +++ user/ed/utmpx/lib/libc/gen/sem_new.c Wed Jan 13 17:45:39 2010 (r202189) @@ -147,13 +147,13 @@ _sem_open(const char *name, int flags, . if (name[0] != '/') { errno = EINVAL; - return (NULL); + return (SEM_FAILED); } name++; if (flags & ~(O_CREAT|O_EXCL)) { errno = EINVAL; - return (NULL); + return (SEM_FAILED); } _pthread_once(&once, sem_module_init); @@ -275,6 +275,7 @@ _sem_close(sem_t *sem) return (0); } _pthread_mutex_unlock(&sem_llock); + errno = EINVAL; return (-1); } Modified: user/ed/utmpx/lib/libc/gen/sem_open.3 ============================================================================== --- user/ed/utmpx/lib/libc/gen/sem_open.3 Wed Jan 13 17:29:55 2010 (r202188) +++ user/ed/utmpx/lib/libc/gen/sem_open.3 Wed Jan 13 17:45:39 2010 (r202189) @@ -27,7 +27,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 15, 2003 +.Dd January 9, 2010 .Dt SEM_OPEN 3 .Os .Sh NAME @@ -61,8 +61,8 @@ and This implementation places strict requirements on the value of .Fa name : it must begin with a slash -.Pq Ql / , -contain no other slash characters. +.Pq Ql / +and contain no other slash characters. .Pp The following bits may be set in the .Fa oflag Modified: user/ed/utmpx/lib/libc/net/sctp_bindx.3 ============================================================================== --- user/ed/utmpx/lib/libc/net/sctp_bindx.3 Wed Jan 13 17:29:55 2010 (r202188) +++ user/ed/utmpx/lib/libc/net/sctp_bindx.3 Wed Jan 13 17:45:39 2010 (r202189) @@ -90,7 +90,7 @@ The call returns 0 on success and -1 upo .Sh ERRORS The .Fn sctp_bindx -can return the following errors. +function can return the following errors: .Bl -tag -width Er .It Bq Er EINVAL This value is returned if the Modified: user/ed/utmpx/lib/libc/net/sctp_connectx.3 ============================================================================== --- user/ed/utmpx/lib/libc/net/sctp_connectx.3 Wed Jan 13 17:29:55 2010 (r202188) +++ user/ed/utmpx/lib/libc/net/sctp_connectx.3 Wed Jan 13 17:45:39 2010 (r202189) @@ -44,7 +44,7 @@ .In sys/socket.h .In netinet/sctp.h .Ft int -.Fn sctp_connectx "int s" "struct sockaddr *" "int addrcnt" "sctp_assoc_t *" +.Fn sctp_connectx "int sd" "struct sockaddr *addrs" "int addrcnt" "sctp_assoc_t *id" .Sh DESCRIPTION The .Fn sctp_connectx @@ -75,7 +75,7 @@ the extra addresses sent in the call will be silently discarded from the association. On successful completion the provided -.Fa "sctp_assoc_t *" +.Fa id will be filled in with the association identification of the newly forming association. @@ -84,7 +84,7 @@ The call returns 0 on success and -1 upo .Sh ERRORS The .Fn sctp_connectx -can return the following errors. +function can return the following errors: .Bl -tag -width Er .It Bq Er EINVAL An address listed has an invalid family or no Modified: user/ed/utmpx/lib/libc/net/sctp_getaddrlen.3 ============================================================================== --- user/ed/utmpx/lib/libc/net/sctp_getaddrlen.3 Wed Jan 13 17:29:55 2010 (r202188) +++ user/ed/utmpx/lib/libc/net/sctp_getaddrlen.3 Wed Jan 13 17:45:39 2010 (r202189) @@ -76,7 +76,7 @@ system expects for the specific address .Sh ERRORS The .Fn sctp_getaddrlen -function can return the following errors. +function can return the following errors: .Bl -tag -width Er .It Bq Er EINVAL The address family specified does NOT exist. Modified: user/ed/utmpx/lib/libc/net/sctp_getassocid.3 ============================================================================== --- user/ed/utmpx/lib/libc/net/sctp_getassocid.3 Wed Jan 13 17:29:55 2010 (r202188) +++ user/ed/utmpx/lib/libc/net/sctp_getassocid.3 Wed Jan 13 17:45:39 2010 (r202189) @@ -58,7 +58,7 @@ The call returns the association id upon .Sh ERRORS The .Fn sctp_getassocid -function can return the following errors. +function can return the following errors: .Bl -tag -width Er .It Bq Er ENOENT The address does not have an association setup to it. Modified: user/ed/utmpx/lib/libc/net/sctp_getpaddrs.3 ============================================================================== --- user/ed/utmpx/lib/libc/net/sctp_getpaddrs.3 Wed Jan 13 17:29:55 2010 (r202188) +++ user/ed/utmpx/lib/libc/net/sctp_getpaddrs.3 Wed Jan 13 17:45:39 2010 (r202189) @@ -33,7 +33,7 @@ .\" $FreeBSD$ .\" .Dd December 15, 2006 -.Dt SCTP_GETPADDR 3 +.Dt SCTP_GETPADDRS 3 .Os .Sh NAME .Nm sctp_getpaddrs , @@ -64,7 +64,7 @@ array of socket addresses returned in th .Fa addrs upon success. .Pp -After the caller is through the function +After the caller is finished, the function .Fn sctp_freepaddrs or .Fn sctp_freeladdrs @@ -76,7 +76,7 @@ the number of addresses returned in .Fa addrs upon success. .Sh ERRORS -The functions can return the following errors. +The functions can return the following errors: .Bl -tag -width Er .It Bq Er EINVAL An address listed has an invalid family or no Modified: user/ed/utmpx/lib/libc/net/sctp_opt_info.3 ============================================================================== --- user/ed/utmpx/lib/libc/net/sctp_opt_info.3 Wed Jan 13 17:29:55 2010 (r202188) +++ user/ed/utmpx/lib/libc/net/sctp_opt_info.3 Wed Jan 13 17:45:39 2010 (r202189) @@ -45,7 +45,7 @@ .In sys/socket.h .In netinet/sctp.h .Ft int -.Fn sctp_opt_info "int s" "sctp_assoc_t" "int opt" "void *arg" "socklen_t *size" +.Fn sctp_opt_info "int sd" "sctp_assoc_t id" "int opt" "void *arg" "socklen_t *size" .Sh DESCRIPTION The .Fn sctp_opt_info @@ -90,7 +90,7 @@ socket options. .Sh ERRORS The .Fn sctp_opt_info -function can return the following errors. +function can return the following errors: .Bl -tag -width Er .It Bq Er EINVAL The argument Modified: user/ed/utmpx/lib/libc/net/sctp_recvmsg.3 ============================================================================== --- user/ed/utmpx/lib/libc/net/sctp_recvmsg.3 Wed Jan 13 17:29:55 2010 (r202188) +++ user/ed/utmpx/lib/libc/net/sctp_recvmsg.3 Wed Jan 13 17:45:39 2010 (r202189) @@ -160,7 +160,7 @@ struct sctp_sndrcvinfo { .Pp The .Fa sinfo->sinfo_ppid -is an opaque 32 bit value that is passed transparently +field is an opaque 32 bit value that is passed transparently through the stack from the peer endpoint. Note that the stack passes this value without regard to byte order. @@ -180,12 +180,13 @@ as soon as possible. When this flag is absent the message was delivered in order within the stream it was received. .Pp +The .Fa sinfo->sinfo_stream -is the SCTP stream that the message was received on. +field is the SCTP stream that the message was received on. Streams in SCTP are reliable (or partially reliable) flows of ordered messages. .Pp -The +The .Fa sinfo->sinfo_context field is used only if the local application set an association level context with the @@ -197,7 +198,7 @@ association. .Pp The .Fa sinfo->sinfo_ssn -will hold the stream sequence number assigned +field will hold the stream sequence number assigned by the peer endpoint if the message is .Em not unordered. @@ -205,7 +206,7 @@ For unordered messages this field holds .Pp The .Fa sinfo->sinfo_tsn -holds a transport sequence number (TSN) that was assigned +field holds a transport sequence number (TSN) that was assigned to this message by the peer endpoint. For messages that fit in or less than the path MTU this will be the only TSN assigned. @@ -215,12 +216,12 @@ message. .Pp The .Fa sinfo->sinfo_cumtsn -holds the current cumulative acknowledgment point of +field holds the current cumulative acknowledgment point of the transport association. Note that this may be larger or smaller than the TSN assigned to the message itself. .Pp -The +The .Fa sinfo->sinfo_assoc_id is the unique association identification that was assigned to the association. @@ -232,10 +233,10 @@ setting various socket options on the sp (see .Xr sctp 4 ) . .Pp -The +The .Fa sinfo->info_timetolive field is not used by -.Fa sctp_recvmsg . +.Fn sctp_recvmsg . .Sh RETURN VALUES The call returns the number of characters sent, or -1 if an error occurred. Modified: user/ed/utmpx/lib/libc/net/sctp_send.3 ============================================================================== --- user/ed/utmpx/lib/libc/net/sctp_send.3 Wed Jan 13 17:29:55 2010 (r202188) +++ user/ed/utmpx/lib/libc/net/sctp_send.3 Wed Jan 13 17:45:39 2010 (r202189) @@ -294,7 +294,7 @@ if an error occurred. The .Fn sctp_send system call -fail if: +fails if: .Bl -tag -width Er .It Bq Er EBADF An invalid descriptor was specified. Modified: user/ed/utmpx/lib/libc/net/sctp_sendmsg.3 ============================================================================== --- user/ed/utmpx/lib/libc/net/sctp_sendmsg.3 Wed Jan 13 17:29:55 2010 (r202188) +++ user/ed/utmpx/lib/libc/net/sctp_sendmsg.3 Wed Jan 13 17:45:39 2010 (r202189) @@ -271,7 +271,7 @@ if an error occurred. The .Fn sctp_sendmsg system call -fail if: +fails if: .Bl -tag -width Er .It Bq Er EBADF An invalid descriptor was specified. @@ -324,7 +324,7 @@ is not connected and is a one-to-one sty .Xr sendmsg 3 , .Xr sctp 4 .Sh BUGS -Because in the one-to-many style socket the +Because in the one-to-many style socket .Fn sctp_sendmsg or .Fn sctp_sendmsgx Modified: user/ed/utmpx/lib/libc/sys/sctp_generic_recvmsg.2 ============================================================================== --- user/ed/utmpx/lib/libc/sys/sctp_generic_recvmsg.2 Wed Jan 13 17:29:55 2010 (r202188) +++ user/ed/utmpx/lib/libc/sys/sctp_generic_recvmsg.2 Wed Jan 13 17:45:39 2010 (r202189) @@ -36,7 +36,7 @@ .Os .Sh NAME .Nm sctp_generic_recvmsg -.Nd receive data from a peer. +.Nd receive data from a peer .Sh LIBRARY .Lb libc .Sh SYNOPSIS @@ -46,16 +46,20 @@ .Ft int .Fn sctp_generic_recvmsg "int s" "struct iovec *iov" "int iovlen" "struct sockaddr *from" "socklen_t *fromlen" "struct sctp_sndrcvinfo *sinfo" "int *msgflags" .Sh DESCRIPTION -The .Fn sctp_generic_recvmsg -is the true system calls used by the -.Fn sctp_recvmsg -function call. This call is more efficient since it is a -true system calls but it is specific to FreeBSD and -can be expected NOT to be present on any other Operating -System. For detailed useage please see either the -.Fn sctp_recvmsg -function call. +is the true system call used by the +.Xr sctp_recvmsg 3 +function call. +This call is more efficient since it is a +true system call but it is specific to +.Fx +and can be expected +.Em not +to be present on any other operating +system. +For detailed usage please see the +.Xr sctp_recvmsg 3 +function call. .Sh RETURN VALUES The call returns the number of bytes read on success and -1 upon failure. .Sh ERRORS Modified: user/ed/utmpx/lib/libc/sys/sctp_generic_sendmsg.2 ============================================================================== --- user/ed/utmpx/lib/libc/sys/sctp_generic_sendmsg.2 Wed Jan 13 17:29:55 2010 (r202188) +++ user/ed/utmpx/lib/libc/sys/sctp_generic_sendmsg.2 Wed Jan 13 17:45:39 2010 (r202189) @@ -37,7 +37,7 @@ .Sh NAME .Nm sctp_generic_sendmsg .Nm sctp_generic_sendmsg_iov -.Nd send data to a peer. +.Nd send data to a peer .Sh LIBRARY .Lb libc .Sh SYNOPSIS @@ -49,21 +49,25 @@ .Ft int .Fn sctp_generic_sendmsg_iov "int s" "struct iovec *iov" "int iovlen" "struct sockaddr *to" "struct sctp_sndrcvinfo *sinfo" "int flags" .Sh DESCRIPTION -The .Fn sctp_generic_sendmsg and .Fn sctp_generic_sendmsg_iov are the true system calls used by the -.Fn sctp_sendmsg +.Xr sctp_sendmsg 3 and -.Fn sctp_send -function calls. These are more efficient since they are -true system calls but they are specific to FreeBSD and -can be expected NOT to be present on any other Operating -System. For detailed useage please see either the -.Fn sctp_send +.Xr sctp_send 3 +function calls. +These are more efficient since they are +true system calls but they are specific to +.Fx +and can be expected +.Em not +to be present on any other operating +system. +For detailed usage please see either the +.Xr sctp_send 3 or -.Fn sctp_sendmsg +.Xr sctp_sendmsg 3 function calls. .Sh RETURN VALUES The call returns the number of bytes written on success and -1 upon failure. Modified: user/ed/utmpx/lib/libc/sys/sctp_peeloff.2 ============================================================================== --- user/ed/utmpx/lib/libc/sys/sctp_peeloff.2 Wed Jan 13 17:29:55 2010 (r202188) +++ user/ed/utmpx/lib/libc/sys/sctp_peeloff.2 Wed Jan 13 17:45:39 2010 (r202189) @@ -36,7 +36,7 @@ .Os .Sh NAME .Nm sctp_peeloff -.Nd detach an association from a one-to-many socket to its on fd +.Nd detach an association from a one-to-many socket to its own fd .Sh LIBRARY .Lb libc .Sh SYNOPSIS @@ -58,7 +58,7 @@ upon success. .Sh ERRORS The .Fn sctp_peeloff -can return the following errors. +system call can return the following errors: .Bl -tag -width Er .It Bq Er ENOTCONN The Modified: user/ed/utmpx/lib/libelf/elf.3 ============================================================================== --- user/ed/utmpx/lib/libelf/elf.3 Wed Jan 13 17:29:55 2010 (r202188) +++ user/ed/utmpx/lib/libelf/elf.3 Wed Jan 13 17:45:39 2010 (r202189) @@ -379,7 +379,6 @@ See .It Dv SHT_SUNW_move Ta Dv ELF_T_MOVE Ta ELF move records. .It Dv SHT_SUNW_syminfo Ta Dv ELF_T_SYMINFO Ta Additional symbol flags. .El -.TE .Ss Functional Grouping This section contains a brief overview of the available functionality in the ELF library. Modified: user/ed/utmpx/lib/libpmc/libpmc.c ============================================================================== --- user/ed/utmpx/lib/libpmc/libpmc.c Wed Jan 13 17:29:55 2010 (r202188) +++ user/ed/utmpx/lib/libpmc/libpmc.c Wed Jan 13 17:45:39 2010 (r202189) @@ -2543,6 +2543,7 @@ pmc_init(void) break; case PMC_CPU_INTEL_CORE: PMC_MDEP_INIT(core); + pmc_class_table[n] = &core_class_table_descr; break; case PMC_CPU_INTEL_CORE2: case PMC_CPU_INTEL_CORE2EXTREME: Modified: user/ed/utmpx/sbin/fsck_ffs/pass2.c ============================================================================== --- user/ed/utmpx/sbin/fsck_ffs/pass2.c Wed Jan 13 17:29:55 2010 (r202188) +++ user/ed/utmpx/sbin/fsck_ffs/pass2.c Wed Jan 13 17:45:39 2010 (r202189) @@ -36,12 +36,14 @@ static const char sccsid[] = "@(#)pass2. __FBSDID("$FreeBSD$"); #include +#include #include #include #include #include +#include #include #include @@ -49,6 +51,8 @@ __FBSDID("$FreeBSD$"); #define MINDIRSIZE (sizeof (struct dirtemplate)) +static int fix_extraneous(struct inoinfo *, struct inodesc *); +static int deleteentry(struct inodesc *); static int blksort(const void *, const void *); static int pass2check(struct inodesc *); @@ -212,9 +216,48 @@ pass2(void) inoinfo(inp->i_parent)->ino_linkcnt--; continue; } - fileerror(inp->i_parent, inp->i_number, - "BAD INODE NUMBER FOR '..'"); - if (reply("FIX") == 0) + /* + * Here we have: + * inp->i_number is directory with bad ".." in it. + * inp->i_dotdot is current value of "..". + * inp->i_parent is directory to which ".." should point. + */ + getpathname(pathbuf, inp->i_parent, inp->i_number); + printf("BAD INODE NUMBER FOR '..' in DIR I=%d (%s)\n", + inp->i_number, pathbuf); + getpathname(pathbuf, inp->i_dotdot, inp->i_dotdot); + printf("CURRENTLY POINTS TO I=%d (%s), ", inp->i_dotdot, + pathbuf); + getpathname(pathbuf, inp->i_parent, inp->i_parent); + printf("SHOULD POINT TO I=%d (%s)", inp->i_parent, pathbuf); + if (cursnapshot != 0) { + /* + * We need to: + * setcwd(inp->i_number); + * setdotdot(inp->i_dotdot, inp->i_parent); + */ + cmd.value = inp->i_number; + if (sysctlbyname("vfs.ffs.setcwd", 0, 0, + &cmd, sizeof cmd) == -1) { + /* kernel lacks support for these functions */ + printf(" (IGNORED)\n"); + continue; + } + cmd.value = inp->i_dotdot; /* verify same value */ + cmd.size = inp->i_parent; /* new parent */ + if (sysctlbyname("vfs.ffs.setdotdot", 0, 0, + &cmd, sizeof cmd) == -1) { + printf(" (FIX FAILED: %s)\n", strerror(errno)); + continue; + } + printf(" (FIXED)\n"); + inoinfo(inp->i_parent)->ino_linkcnt--; + inp->i_dotdot = inp->i_parent; + continue; + } + if (preen) + printf(" (FIXED)\n"); + else if (reply("FIX") == 0) continue; inoinfo(inp->i_dotdot)->ino_linkcnt++; inoinfo(inp->i_parent)->ino_linkcnt--; @@ -236,8 +279,6 @@ pass2check(struct inodesc *idesc) union dinode *dp; const char *errmsg; struct direct proto; - char namebuf[MAXPATHLEN + 1]; - char pathbuf[MAXPATHLEN + 1]; /* * check for "." @@ -416,27 +457,12 @@ again: case DFOUND: inp = getinoinfo(dirp->d_ino); - if (inp->i_parent != 0 && idesc->id_entryno > 2) { - getpathname(pathbuf, idesc->id_number, - idesc->id_number); - getpathname(namebuf, dirp->d_ino, dirp->d_ino); - pwarn("%s%s%s %s %s\n", pathbuf, - (strcmp(pathbuf, "/") == 0 ? "" : "/"), - dirp->d_name, - "IS AN EXTRANEOUS HARD LINK TO DIRECTORY", - namebuf); - if (cursnapshot != 0) - break; - if (preen) { - printf(" (REMOVED)\n"); - n = 1; - break; - } - if ((n = reply("REMOVE")) == 1) + if (idesc->id_entryno > 2) { + if (inp->i_parent == 0) + inp->i_parent = idesc->id_number; + else if ((n = fix_extraneous(inp, idesc)) == 1) break; } - if (idesc->id_entryno > 2) - inp->i_parent = idesc->id_number; /* FALLTHROUGH */ case FSTATE: @@ -462,6 +488,143 @@ again: return (ret|KEEPON|ALTERED); } +static int +fix_extraneous(struct inoinfo *inp, struct inodesc *idesc) +{ + char *cp; + struct inodesc dotdesc; + char oldname[MAXPATHLEN + 1]; + char newname[MAXPATHLEN + 1]; + + /* + * If we have not yet found "..", look it up now so we know + * which inode the directory itself believes is its parent. + */ + if (inp->i_dotdot == 0) { + memset(&dotdesc, 0, sizeof(struct inodesc)); + dotdesc.id_type = DATA; + dotdesc.id_number = idesc->id_dirp->d_ino; + dotdesc.id_func = findino; + dotdesc.id_name = strdup(".."); + if ((ckinode(ginode(dotdesc.id_number), &dotdesc) & FOUND)) + inp->i_dotdot = dotdesc.id_parent; + } + /* + * We have the previously found old name (inp->i_parent) and the + * just found new name (idesc->id_number). We have five cases: + * 1) ".." is missing - can remove either name, choose to delete + * new one and let fsck create ".." pointing to old name. + * 2) Both new and old are in same directory, choose to delete + * the new name and let fsck fix ".." if it is wrong. + * 3) ".." does not point to the new name, so delete it and let + * fsck fix ".." to point to the old one if it is wrong. + * 4) ".." points to the old name only, so delete the new one. + * 5) ".." points to the new name only, so delete the old one. + * + * For cases 1-4 we eliminate the new name; + * for case 5 we eliminate the old name. + */ + if (inp->i_dotdot == 0 || /* Case 1 */ + idesc->id_number == inp->i_parent || /* Case 2 */ + inp->i_dotdot != idesc->id_number || /* Case 3 */ + inp->i_dotdot == inp->i_parent) { /* Case 4 */ + getpathname(newname, idesc->id_number, idesc->id_number); + if (strcmp(newname, "/") != 0) + strcat (newname, "/"); + strcat(newname, idesc->id_dirp->d_name); + getpathname(oldname, inp->i_number, inp->i_number); + pwarn("%s IS AN EXTRANEOUS HARD LINK TO DIRECTORY %s", + newname, oldname); + if (cursnapshot != 0) { + /* + * We need to + * setcwd(idesc->id_number); + * unlink(idesc->id_dirp->d_name); + */ + cmd.value = idesc->id_number; + if (sysctlbyname("vfs.ffs.setcwd", 0, 0, + &cmd, sizeof cmd) == -1) { + printf(" (IGNORED)\n"); + return (0); + } + cmd.value = (intptr_t)idesc->id_dirp->d_name; + cmd.size = inp->i_number; /* verify same name */ + if (sysctlbyname("vfs.ffs.unlink", 0, 0, + &cmd, sizeof cmd) == -1) { + printf(" (UNLINK FAILED: %s)\n", + strerror(errno)); + return (0); + } + printf(" (REMOVED)\n"); + return (0); + } + if (preen) { + printf(" (REMOVED)\n"); + return (1); + } + return (reply("REMOVE")); + } + /* + * None of the first four cases above, so must be case (5). + * Eliminate the old name and make the new the name the parent. + */ + getpathname(oldname, inp->i_parent, inp->i_number); + getpathname(newname, inp->i_number, inp->i_number); + pwarn("%s IS AN EXTRANEOUS HARD LINK TO DIRECTORY %s", oldname, + newname); + if (cursnapshot != 0) { + /* + * We need to + * setcwd(inp->i_parent); + * unlink(last component of oldname pathname); + */ + cmd.value = inp->i_parent; + if (sysctlbyname("vfs.ffs.setcwd", 0, 0, + &cmd, sizeof cmd) == -1) { + printf(" (IGNORED)\n"); + return (0); + } + if ((cp = rindex(oldname, '/')) == NULL) { + printf(" (IGNORED)\n"); + return (0); + } + cmd.value = (intptr_t)(cp + 1); + cmd.size = inp->i_number; /* verify same name */ + if (sysctlbyname("vfs.ffs.unlink", 0, 0, + &cmd, sizeof cmd) == -1) { + printf(" (UNLINK FAILED: %s)\n", + strerror(errno)); + return (0); + } + printf(" (REMOVED)\n"); + inp->i_parent = idesc->id_number; /* reparent to correct dir */ + return (0); + } + if (!preen && !reply("REMOVE")) + return (0); + memset(&dotdesc, 0, sizeof(struct inodesc)); + dotdesc.id_type = DATA; + dotdesc.id_number = inp->i_parent; /* directory in which name appears */ + dotdesc.id_parent = inp->i_number; /* inode number in entry to delete */ + dotdesc.id_func = deleteentry; + if ((ckinode(ginode(dotdesc.id_number), &dotdesc) & FOUND) && preen) + printf(" (REMOVED)\n"); + inp->i_parent = idesc->id_number; /* reparent to correct directory */ + inoinfo(inp->i_number)->ino_linkcnt++; /* name gone, return reference */ + return (0); +} + +static int +deleteentry(struct inodesc *idesc) +{ + struct direct *dirp = idesc->id_dirp; + + if (idesc->id_entryno++ < 2 || dirp->d_ino != idesc->id_parent) + return (KEEPON); + dirp->d_ino = 0; + return (ALTERED|STOP|FOUND); +} + /* * Routine to sort disk blocks. */ Modified: user/ed/utmpx/sbin/ifconfig/ifieee80211.c ============================================================================== --- user/ed/utmpx/sbin/ifconfig/ifieee80211.c Wed Jan 13 17:29:55 2010 (r202188) +++ user/ed/utmpx/sbin/ifconfig/ifieee80211.c Wed Jan 13 17:45:39 2010 (r202189) @@ -3429,9 +3429,9 @@ get_chaninfo(const struct ieee80211_chan else if (IEEE80211_IS_CHAN_B(c)) strlcat(buf, " 11b", bsize); if (IEEE80211_IS_CHAN_HALF(c)) - strlcat(buf, "/10Mhz", bsize); + strlcat(buf, "/10MHz", bsize); if (IEEE80211_IS_CHAN_QUARTER(c)) - strlcat(buf, "/5Mhz", bsize); + strlcat(buf, "/5MHz", bsize); if (IEEE80211_IS_CHAN_TURBO(c)) strlcat(buf, " Turbo", bsize); if (precise) { @@ -3453,7 +3453,7 @@ print_chaninfo(const struct ieee80211_ch { char buf[14]; - printf("Channel %3u : %u%c Mhz%-14.14s", + printf("Channel %3u : %u%c MHz%-14.14s", ieee80211_mhz2ieee(c->ic_freq, c->ic_flags), c->ic_freq, IEEE80211_IS_CHAN_PASSIVE(c) ? '*' : ' ', get_chaninfo(c, verb, buf, sizeof(buf))); @@ -3562,7 +3562,7 @@ list_channels(int s, int allchans) static void print_txpow(const struct ieee80211_channel *c) { - printf("Channel %3u : %u Mhz %3.1f reg %2d ", + printf("Channel %3u : %u MHz %3.1f reg %2d ", c->ic_ieee, c->ic_freq, c->ic_maxpower/2., c->ic_maxregpower); } @@ -4244,7 +4244,7 @@ ieee80211_status(int s) c = getcurchan(s); if (c->ic_freq != IEEE80211_CHAN_ANY) { char buf[14]; - printf(" channel %d (%u Mhz%s)", c->ic_ieee, c->ic_freq, + printf(" channel %d (%u MHz%s)", c->ic_ieee, c->ic_freq, get_chaninfo(c, 1, buf, sizeof(buf))); } else if (verbose) printf(" channel UNDEF"); Modified: user/ed/utmpx/share/man/man3/pthread_affinity_np.3 ============================================================================== --- user/ed/utmpx/share/man/man3/pthread_affinity_np.3 Wed Jan 13 17:29:55 2010 (r202188) +++ user/ed/utmpx/share/man/man3/pthread_affinity_np.3 Wed Jan 13 17:45:39 2010 (r202189) @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 8, 2010 +.Dd January 12, 2010 .Dt PTHREAD_AFFINITY_NP 3 .Os .Sh NAME @@ -44,17 +44,17 @@ .Fn pthread_getaffinity_np and .Fn pthread_setaffinity_np -allow the manipulation of sets of CPUs available to specified thread. +allow the manipulation of sets of CPUs available to the specified thread. .Pp Masks of type .Ft cpuset_t are composed using the -.Xr CPU_SET 2 +.Xr CPU_SET 3 macros. The kernel tolerates large sets as long as all CPUs specified in the set exist. Sets smaller than the kernel uses generate an error on calls to -.Fn pthread_getaffinity_np +.Fn pthread_getaffinity_np even if the result set would fit within the user supplied set. Calls to .Fn pthread_setaffinity_np @@ -75,14 +75,13 @@ retrieves the mask from the thread specified by .Fa td , and stores it in the space provided by -.Fa cpumaskp . +.Fa cpusetp . .Pp .Fn pthread_setaffinity_np attempts to set the mask for the thread specified by .Fa td to the value in -.Fa cpumaskp . -.Pp +.Fa cpusetp . .Sh RETURN VALUES If successful, the .Fn pthread_getaffinity_np @@ -105,7 +104,7 @@ call would leave a thread without a vali does not overlap with the thread's anonymous mask. .It Bq Er EFAULT The -.Fa cpumaskp +.Fa cpusetp pointer passed was invalid. .It Bq Er ESRCH The thread specified by the @@ -127,7 +126,7 @@ operation. .Xr CPU_SET 3 , .Xr pthread 3 , .Xr pthread_attr_get_affinity_np 3 , -.Xr pthread_attr_set_affinity_np 3 . +.Xr pthread_attr_set_affinity_np 3 .Sh STANDARDS The .Nm pthread_getaffinity_np Modified: user/ed/utmpx/share/man/man3/pthread_attr_affinity_np.3 ============================================================================== --- user/ed/utmpx/share/man/man3/pthread_attr_affinity_np.3 Wed Jan 13 17:29:55 2010 (r202188) +++ user/ed/utmpx/share/man/man3/pthread_attr_affinity_np.3 Wed Jan 13 17:45:39 2010 (r202189) @@ -31,7 +31,7 @@ .Sh NAME .Nm pthread_attr_getaffinity_np , .Nm pthread_attr_setaffinity_np -.Nd manage CPU affinity in thread attribute object +.Nd manage CPU affinity in thread attribute objects .Sh LIBRARY .Lb libpthread .Sh SYNOPSIS @@ -41,20 +41,21 @@ .Ft int .Fn pthread_attr_setaffinity_np "pthread_attr_t *pattr" "size_t cpusetsize" "const cpuset_t *cpusetp" .Sh DESCRIPTION +The .Fn pthread_attr_getaffinity_np and .Fn pthread_attr_setaffinity_np -allow the manipulation of sets of CPUs available to specified thread attribute object. +functions allow the manipulation of sets of CPUs available to the specified thread attribute object. .Pp Masks of type .Ft cpuset_t are composed using the -.Xr CPU_SET 2 +.Xr CPU_SET 3 macros. The kernel tolerates large sets as long as all CPUs specified in the set exist. Sets smaller than the kernel uses generate an error on calls to -.Fn pthread_attr_getaffinity_np +.Fn pthread_attr_getaffinity_np even if the result set would fit within the user supplied set. Calls to .Fn pthread_attr_setaffinity_np @@ -75,14 +76,13 @@ retrieves the mask from the thread attribute object specified by .Fa pattr , and stores it in the space provided by -.Fa cpumaskp . +.Fa cpusetp . .Pp .Fn pthread_attr_setaffinity_np -set the mask for the thread attribute object specified by +sets the mask for the thread attribute object specified by .Fa pattr to the value in -.Fa cpumaskp . -.Pp +.Fa cpusetp . .Sh RETURN VALUES If successful, the .Fn pthread_attr_getaffinity_np @@ -101,7 +101,8 @@ functions will fail if: .It Bq Er EINVAL The .Fa pattr -or the attribute specified by it is NULL. +or the attribute specified by it is +.Dv NULL . .El .Pp The @@ -111,7 +112,8 @@ function will fail if: .It Bq Er EINVAL The .Fa pattr -or the attribute specified by it is NULL. +or the attribute specified by it is +.Dv NULL . .It Bq Er ENOMEM Insufficient memory exists to store the cpuset mask. .El @@ -122,7 +124,7 @@ Insufficient memory exists to store the .Xr cpuset_setid 2 , .Xr CPU_SET 3 , .Xr pthread_get_affinity_np 3 , -.Xr pthread_set_affinity_np 3 . +.Xr pthread_set_affinity_np 3 .Sh STANDARDS The .Nm pthread_attr_getaffinity_np Modified: user/ed/utmpx/share/man/man4/Makefile ============================================================================== --- user/ed/utmpx/share/man/man4/Makefile Wed Jan 13 17:29:55 2010 (r202188) +++ user/ed/utmpx/share/man/man4/Makefile Wed Jan 13 17:45:39 2010 (r202189) @@ -424,6 +424,7 @@ MAN= aac.4 \ ugen.4 \ uhci.4 \ uhid.4 \ + uhso.4 \ uipaq.4 \ ukbd.4 \ ulpt.4 \ Modified: user/ed/utmpx/share/man/man4/ath.4 ============================================================================== --- user/ed/utmpx/share/man/man4/ath.4 Wed Jan 13 17:29:55 2010 (r202188) +++ user/ed/utmpx/share/man/man4/ath.4 Wed Jan 13 17:45:39 2010 (r202189) @@ -249,7 +249,7 @@ This should not happen. An invalid transmit rate was specified for an outgoing frame. The frame is discarded. This should not happen. -.It "ath%d: ath_chan_set: unable to reset channel %u (%u Mhz)" +.It "ath%d: ath_chan_set: unable to reset channel %u (%u MHz)" The Atheros Hardware Access Layer was unable to reset the hardware when switching channels during scanning. This should not happen. Modified: user/ed/utmpx/share/man/man4/cpufreq.4 ============================================================================== --- user/ed/utmpx/share/man/man4/cpufreq.4 Wed Jan 13 17:29:55 2010 (r202188) +++ user/ed/utmpx/share/man/man4/cpufreq.4 Wed Jan 13 17:45:39 2010 (r202189) @@ -234,7 +234,7 @@ The driver should set unknown or irrelev All the following elements for each setting should be returned: .Bd -literal struct cf_setting { - int freq; /* CPU clock in Mhz or 100ths of a percent. */ + int freq; /* CPU clock in MHz or 100ths of a percent. */ int volts; /* Voltage in mV. */ int power; /* Power consumed in mW. */ int lat; /* Transition latency in us. */ Modified: user/ed/utmpx/share/man/man4/snd_hda.4 ============================================================================== --- user/ed/utmpx/share/man/man4/snd_hda.4 Wed Jan 13 17:29:55 2010 (r202188) +++ user/ed/utmpx/share/man/man4/snd_hda.4 Wed Jan 13 17:45:39 2010 (r202189) @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 13, 2009 +.Dd January 12, 2010 .Dt SND_HDA 4 .Os .Sh NAME @@ -125,12 +125,14 @@ such as .Dq Li nofixedrate , will do the opposite and takes precedence. Options can be separated by whitespace and commas. +.Pp .Dq Li GPIO Ns s are a codec's General Purpose I/O pins which system integrators sometimes use to control external muters, amplifiers and so on. If you have no sound, or sound volume is not adequate, you may have to experiment a bit with the GPIO setup to find the optimal setup for your system. +.Pp The .Dq Li ivref Ns Ar X and @@ -178,6 +180,11 @@ A unique, per-association number used to particular association. Sequence numbers can be specified as numeric values from 0 to 15. .Pp +For output assotiations sequence numbers encode speaker pairs positions: +0 - Front, 1 - Center/LFE, 2 - Back, 3 - Front Wide Center, 4 - Side. +Standard combinations are: (0) - Stereo; (0, 2), (0, 4) - Quadro; +(0, 1, 2), (0, 1, 4) - 5.1; (0, 1, 2, 4) - 7.1. +.Pp The sequence number 15 has a special meaning for output associations. Output pins with this number and device type .Dq Ar Headphones @@ -639,6 +646,3 @@ to control external amplifiers. In some GPIO bits may be needed to make sound work on specific device. .Pp HDMI and DisplayPort audio may also require support from video driver. -.Pp -Due to OSS limitation multichannel (not multidevice) playback is not -supported. Copied: user/ed/utmpx/share/man/man4/uhso.4 (from r202188, head/share/man/man4/uhso.4) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ user/ed/utmpx/share/man/man4/uhso.4 Wed Jan 13 17:45:39 2010 (r202189, copy of r202188, head/share/man/man4/uhso.4) @@ -0,0 +1,115 @@ +.\" Copyright (c) 2009 Fredrik Lindberg +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $FreeBSD$ *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-src-user@FreeBSD.ORG Wed Jan 13 19:46:53 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 7566C106566C; Wed, 13 Jan 2010 19:46:53 +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 6319C8FC1F; Wed, 13 Jan 2010 19:46:53 +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 o0DJkrfP005105; Wed, 13 Jan 2010 19:46:53 GMT (envelope-from luigi@svn.freebsd.org) Received: (from luigi@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0DJkrFE005095; Wed, 13 Jan 2010 19:46:53 GMT (envelope-from luigi@svn.freebsd.org) Message-Id: <201001131946.o0DJkrFE005095@svn.freebsd.org> From: Luigi Rizzo Date: Wed, 13 Jan 2010 19:46:53 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202220 - in user/luigi/ipfw3-head: sbin/ipfw sys/netinet sys/netinet/ipfw X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 13 Jan 2010 19:46:53 -0000 Author: luigi Date: Wed Jan 13 19:46:53 2010 New Revision: 202220 URL: http://svn.freebsd.org/changeset/base/202220 Log: basic glue and packet flow now operational Modified: user/luigi/ipfw3-head/sbin/ipfw/dummynet.c user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Modified: user/luigi/ipfw3-head/sbin/ipfw/dummynet.c ============================================================================== --- user/luigi/ipfw3-head/sbin/ipfw/dummynet.c Wed Jan 13 19:25:03 2010 (r202219) +++ user/luigi/ipfw3-head/sbin/ipfw/dummynet.c Wed Jan 13 19:46:53 2010 (r202220) @@ -739,8 +739,6 @@ ipfw_config_pipe(int ac, char **av) struct dn_id *buf, *base; struct new_sch *sch = NULL; struct new_pipe *p = NULL; - struct new_sch *sch2 = NULL; /* the fifo scheduler */ - struct new_pipe *p2 = NULL; /* the fifo pipe */ struct new_fs *fs = NULL; struct new_profile *pf = NULL; struct new_cmd *cmd = NULL; @@ -766,21 +764,26 @@ ipfw_config_pipe(int ac, char **av) switch (co.do_pipe) { case 1: + /* the WFQ scheduler */ sch = o_next(&buf, sizeof(*sch), DN_SCH); - sch->sched_nr = i + DN_PIPEOFFSET; - sch->oid.subtype = DN_SCHED_FIFO; - p = o_next(&buf, sizeof(*p), DN_PIPE); - p->pipe_nr = i + DN_PIPEOFFSET; + sch->sched_nr = i; + sch->oid.subtype = DN_SCHED_WF2QP; mask = &sch->sched_mask; - fs = o_next(&buf, sizeof(*fs), DN_FS); - fs->fs_nr = i + DN_PIPEOFFSET; - fs->sched_nr = i + DN_PIPEOFFSET; + /* XXX the FIFO scheduler is created from the WFQ one */ - /* sch2 and p2 will be set later */ - sch2 = o_next(&buf, sizeof(*sch2), DN_SCH); - sch2->oid.subtype = DN_SCHED_WF2QP; - p2 = o_next(&buf, sizeof(*p2), DN_PIPE); + /* the WFQ pipe */ + p = o_next(&buf, sizeof(*p), DN_PIPE); + p->pipe_nr = i; + /* XXX the FIFO pipe is created from WFQ pipe */ + /* + * FIFO flowsets N+i are automatically created for + * FIFO schedulers i, but we provide room to pass + * queue parameters + */ + fs = o_next(&buf, sizeof(*fs), DN_FS); + fs->fs_nr = i + 2*DN_MAX_ID; + fs->sched_nr = i + DN_MAX_ID; break; case 2: /* flowset */ @@ -793,12 +796,14 @@ ipfw_config_pipe(int ac, char **av) sch = o_next(&buf, sizeof(*sch), DN_SCH); sch->sched_nr = i; mask = &sch->sched_mask; + /* room in case we have a FIFO scheduler */ + fs = o_next(&buf, sizeof(*fs), DN_FS); + fs->fs_nr = i + DN_MAX_ID; + fs->sched_nr = i; break; } if (p) p->bandwidth = -1; - if (p2) - p2->bandwidth = -1; while (ac > 0) { double d; @@ -1175,15 +1180,6 @@ end_mask: i = do_cmd(IP_DUMMYNET_CONFIGURE, prof, sizeof *prof); } else #endif - if (sch2) { - *sch2 = *sch; - sch2->sched_nr = i; - sch2->oid.subtype = DN_SCHED_WF2QP; - } - if (p2) { - *p2 = *p; - p2->pipe_nr = i; - } i = do_cmd(IP_DUMMYNET3, base, (char *)buf - (char *)base); Modified: user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h Wed Jan 13 19:25:03 2010 (r202219) +++ user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h Wed Jan 13 19:46:53 2010 (r202220) @@ -128,62 +128,48 @@ struct new_pipe { }; /* - * generic text string, in case we need one - */ -struct new_text { - struct dn_id oid; - int len; - char text[0]; /* len bytes, NUL terminated */ -}; - -/* - * A flowset, which is a template for queues. + * A flowset, which is a template for queues. Store here parameters + * from the command line: id, target scheduler, queue sizes, plr, + * flow masks, buckets for the queue hash, and possibly scheduler- + * specific parameters (weight, quantum and so on). */ struct new_fs { struct dn_id oid; - - /* these initial fields are set from the command line - * queue N config mask M pipe P buckets B plr PLR queue QSZ ... - */ - int fs_nr; /* N, the flowset number */ - /* The flowset implicitly created for pipe N is N+offset */ - - int qsize; /* QSZ, queue size in slots or bytes */ + int fs_nr; /* the flowset number */ int flags; /* userland flags */ + int qsize; /* queue size in slots or bytes */ + int plr; /* PLR, pkt loss rate (2^31-1 means 100%) */ + int buckets; /* buckets used for the queue hash table */ - /* Number of buckets used for the hash table in this fs. */ - int bucket; /* B */ - int plr ; /* PLR, pkt loss rate (2^31-1 means 100%) */ - - /* mask to select the appropriate queue */ struct ipfw_flow_id flow_mask; /* M */ - int sched_nr; /* the scheduler we attach to */ + int sched_nr; /* the scheduler we attach to */ /* generic scheduler parameters */ int weight; - int slot_size; + int quantum; + int par[4]; /* other parameters */ }; /* - * An instance descriptor has a type, a flow_id, flags and a few counters. - * so we used this to pass information up to userland. + * new_inst collects flow_id and stats for queues and scheduler + * instances, and is used to pass these info to userland. + * oid.type/oid.subtype describe the object, oid.id is number + * of the parent object. */ struct new_inst { struct dn_id oid; struct ipfw_flow_id id; - uint32_t parent_nr; /* sched or flowset nr */ uint32_t length; /* Queue lenght, in packets */ uint32_t len_bytes; /* Queue lenght, in bytes */ uint32_t drops; - int hash_slot; + int hash_slot; /* XXX do we need it ? */ uint64_t tot_pkts; /* statistics counters */ uint64_t tot_bytes; }; -/* Scheduler template - * All scheduler are linked in a list, there is a 1-1 mapping between - * 'ipfw sched XX ...' commands and sched XX - * (plus there is a FIFO scheduler for each pipe) +/* + * Scheduler template, mostly indicating the name, number, + * sched_mask and buckets. */ struct new_sch { struct dn_id oid; @@ -198,18 +184,13 @@ struct new_sch { /* - * "queue N" and "pipe N" accept 1<=N<=65535. To map the values in - * the same namespace (which we search through a hash table) we add - * an offset to 'pipe N' below. - * 'queue' -> 1..0x0ffff , 'pipe': 0x10001-0x1ffff + * "queue N" and "pipe N" accept 1<=N<=65535. + * So valid names are from 1 to DN_MAXID-1 */ -#define DN_MAXID 0x1ffff -#define DN_PIPEOFFSET 0x10000 +#define DN_MAX_ID 0x10000 -/*---- old parameters ---*/ /* - * The maximum hash table size for queues. This value must be a power - * of 2. + * The maximum hash table size for queues (unused ?) */ #define DN_MAX_HASH_SIZE 65536 Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c Wed Jan 13 19:25:03 2010 (r202219) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c Wed Jan 13 19:46:53 2010 (r202220) @@ -384,7 +384,7 @@ dn_ht_find(struct dn_ht *ht, uintptr_t k i = (ht->buckets == 1) ? 0 : (ht->hash(key, flags, ht->arg) % ht->buckets); - // log(1, "find %p in bucket %d\n", obj, i); + // printf("%s key %p in bucket %d\n", __FUNCTION__, (void *)key, i); for (pp = &ht->ht[i]; (p = *pp); pp = (void **)((char *)p + ht->ofs)) { if (flags & DNHT_MATCH_PTR) { if (key == (uintptr_t)p) @@ -401,7 +401,7 @@ dn_ht_find(struct dn_ht *ht, uintptr_t k } } else if (flags & DNHT_INSERT) { // printf("%s before calling new, bucket %d ofs %d\n", - // __FUNCTION__, i, ht->ofs); + // __FUNCTION__, i, ht->ofs); p = ht->new ? ht->new(key, flags, ht->arg) : (void *)key; // printf("%s new returns %p\n", __FUNCTION__, p); if (p) { Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h Wed Jan 13 19:25:03 2010 (r202219) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h Wed Jan 13 19:46:53 2010 (r202220) @@ -102,7 +102,7 @@ struct dn_sched { int (*config)(struct new_schk *, int reconfigure); int (*destroy)(struct new_schk*, int delete); - int (*new_sched)(struct new_schk *, struct new_sch_inst *); + int (*new_sched)(struct new_sch_inst *); int (*free_sched)(struct new_sch_inst *); int (*new_queue)(struct new_queue *q); Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c Wed Jan 13 19:25:03 2010 (r202219) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c Wed Jan 13 19:46:53 2010 (r202220) @@ -24,6 +24,7 @@ * SUCH DAMAGE. */ +#ifdef _KERNEL #include #include #include @@ -34,11 +35,13 @@ #include #include /* ipfw_rule_ref */ #include /* flow_id */ +#else +#include "dn_test.h" +#endif #include #include #include #include - /* * This file implements a FIFO scheduler. * A FIFO scheduler is a simple scheduler algorithm that can be use to @@ -58,11 +61,8 @@ static int fifo_enqueue(struct new_sch_inst *_si, struct new_queue *q, struct mbuf *m) { int ret; - struct new_fsk *fs = (struct new_fsk *)q; /* q contains the fs */ q = (struct new_queue *)(_si+1); - q->fs = fs; // XXX revise ret = dn_queue_packet(q, m, 0); - q->fs = NULL; if (ret) { printf("%s dn_queue_packet dropped\n", __FUNCTION__); return 1; @@ -94,12 +94,16 @@ fifo_dequeue(struct new_sch_inst *_si) } static int -fifo_new_sched(struct new_schk *s, struct new_sch_inst *_si) +fifo_new_sched(struct new_sch_inst *si) { /* This scheduler instance only has a queue pointer. */ - struct new_queue *q = (struct new_queue *)(_si + 1); + struct new_queue *q = (struct new_queue *)(si + 1); + + set_oid(&q->ni.oid, DN_QUEUE, 0, sizeof(*q)); + // XXX SLIST_INSERT_HEAD(&si->ql_list, q, si_chain); - q->si = _si; + q->si = si; + q->fs = si->sched->fs; return 0; } Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c Wed Jan 13 19:25:03 2010 (r202219) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c Wed Jan 13 19:46:53 2010 (r202220) @@ -56,12 +56,9 @@ */ static int -fifo_enqueue(struct new_sch_inst *_si, struct new_queue *q, struct mbuf *m) +fifo_enqueue(struct new_sch_inst *si, struct new_queue *q, struct mbuf *m) { - struct new_fsk *fs = (struct new_fsk *)q; - /* the queue is actually the flowset. */ - q = (struct new_queue *)(_si+1); - q->fs = fs; + q = (struct new_queue *)(si+1); if (dn_queue_packet(q, m, 0)) return 1; @@ -96,12 +93,13 @@ fifo_dequeue(struct new_sch_inst *_si) } static int -fifo_new_sched(struct new_schk *s, struct new_sch_inst *_si) +wf2q_new_sched(struct new_sch_inst *si) { /* This scheduler instance only has a queue pointer. */ - struct new_queue *q = (struct new_queue *)(_si + 1); + struct new_queue *q = (struct new_queue *)(si + 1); - q->si = _si; + q->si = si; + q->fs = si->sched->fs; return 0; } @@ -120,7 +118,7 @@ static struct dn_sched fifo_desc = { .enqueue = fifo_enqueue, .dequeue = fifo_dequeue, - .new_sched = fifo_new_sched, + .new_sched = wf2q_new_sched, }; DECLARE_DNSCHED_MODULE(dn_wf2qp, &fifo_desc); Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Wed Jan 13 19:25:03 2010 (r202219) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Wed Jan 13 19:46:53 2010 (r202220) @@ -561,7 +561,7 @@ dummynet_io(struct mbuf **m0, int dir, s dn_key now; /* save a copy of curr_time */ int fs_id = (fwa->rule.info & IPFW_INFO_MASK) + - ((fwa->rule.info & IPFW_IS_PIPE) ? DN_PIPEOFFSET : 0); + ((fwa->rule.info & IPFW_IS_PIPE) ? 2*DN_MAX_ID : 0); DUMMYNET_LOCK(); io_pkt++; now = curr_time; @@ -588,7 +588,7 @@ dummynet_io(struct mbuf **m0, int dir, s if (q == NULL) goto dropit; } else { - q = (void *)fs; + q = NULL; } if (fs->sched->fp->enqueue(si, q, m)) { printf("%s dropped by enqueue\n", __FUNCTION__); Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h Wed Jan 13 19:25:03 2010 (r202219) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h Wed Jan 13 19:46:53 2010 (r202220) @@ -158,6 +158,7 @@ struct new_schk { SLIST_ENTRY(new_schk) schk_next; /* hash chain list */ struct new_fsk_head fsk_list; /* all fsk linked to me */ + struct new_fsk *fs; /* flowset for !MULTIQUEUE */ /* Hash table of all instances (through sched_mask) */ struct dn_ht *siht; @@ -187,7 +188,6 @@ struct new_sch_inst { /* kernel-side flags */ enum { - DN_RECONFIGURE = 0x0001, /* (k) */ DN_DELETE = 0x0004, /* destroy when refcnt=0 */ DN_REENQUEUE = 0x0008, /* (k) */ DN_ACTIVE = 0x0010, /* (k) */ Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Wed Jan 13 19:25:03 2010 (r202219) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Wed Jan 13 19:46:53 2010 (r202220) @@ -67,11 +67,6 @@ static int ip_dn_ctl(struct sockopt *sop #define DN_C_FS 0x08 #define DN_C_QUEUE 0x10 -static int config_pipe(struct new_pipe *p, struct dn_id *arg); -static int config_profile(struct new_profile *p, struct dn_id *arg); -static int config_fs(struct new_fs *p, struct dn_id *arg); -static int config_sched(struct new_sch *p, struct dn_id *arg); - /* callout hooks. */ static struct callout dn_timeout; static struct task dn_task; @@ -239,6 +234,7 @@ si_new(uintptr_t key, int flags, void *a struct new_sch_inst *si; int l = sizeof(*si) + s->fp->sch_inst_len; + // printf("%s for sched %d len %d\n", __FUNCTION__, s->sch.sched_nr, l); si = malloc(l, M_DUMMYNET, M_NOWAIT | M_ZERO); if (si == NULL) goto error; @@ -253,7 +249,8 @@ si_new(uintptr_t key, int flags, void *a si->dline.si = si; if (s->fp->new_sched) { - int ret = s->fp->new_sched(s, si); + int ret; + ret = s->fp->new_sched(si); if (ret) { printf("%s: new_sched error %d\n", __FUNCTION__, ret); goto error; @@ -506,67 +503,6 @@ dummynet_flush(void) DUMMYNET_UNLOCK(); } -/* - * Main handler for configuration. Rules of the game: - * - the first object is the command (config, delete, flush, ...) - * - config_pipe must be issued after the corresponding config_sched - * - parameters (DN_TXT) for an object must preceed the object - * processed on a config_sched. - */ -static int -do_config(void *p, int l) -{ - struct dn_id *next, *o; - int err = 0; - struct dn_id *arg = NULL; - - for (o = p; l >= sizeof(*o); o = next) { - struct dn_id *prev = arg; - if (o->len < sizeof(*o) || l < o->len) { - printf("bad len o->len %d len %d\n", o->len, l); - err = EINVAL; - break; - } - l -= o->len; - printf("%s cmd %d len %d left %d\n", - __FUNCTION__, o->type, o->len, l); - next = (struct dn_id *)((char *)o + o->len); - err = 0; - switch (o->type) { - default: - printf("cmd %d not implemented\n", o->type); - break; - - case DN_CMD_CONFIGURE: - break; - - case DN_CMD_FLUSH: - dummynet_flush(); - break; - case DN_TEXT: /* store argument the next block */ - prev = NULL; - arg = o; - break; - case DN_PIPE: - err = config_pipe((struct new_pipe *)o, arg); - break; - case DN_PROFILE: - err = config_profile((struct new_profile *)o, arg); - break; - case DN_SCH: - err = config_sched((struct new_sch *)o, arg); - break; - case DN_FS: - err = config_fs((struct new_fs *)o, arg); - break; - } - if (prev) - arg = NULL; - if (err != 0) - break; - } - return err; -} static inline struct new_schk * locate_scheduler(int i) @@ -586,7 +522,29 @@ update_fs(struct new_schk *s) } /* - * Setup pipe parameters. + * Configuration -- to preserve backward compatibility we use + * the following scheme (N is 65536) + * NUMBER SCHED PIPE FLOWSET + * 1 .. N-1 (1)WFQ (2)WFQ (3)queue + * N+1 .. 2N-1 (4)FIFO (5)FIFO (6)FIFO for sched 1..N-1 + * 2N+1 .. 3N-1 -- -- (7)FIFO for sched N+1..2N-1 + * + * "pipe i config" configures #1, #2 and #3 + * "sched i config" configures #1 and possibly #6 + * "queue i config" configures #3 + * #1 is configured with 'pipe i config' or 'sched i config' + * #2 is configured with 'pipe i config', and created if not + * existing with 'sched i config' + * #3 is configured with 'queue i config' + * #4 is automatically configured after #1, can only be FIFO + * #5 is automatically configured after #2 + * #6 is automatically created when #1 is !MULTIQUEUE, + * and can be updated. + * #7 is automatically configured after #2 + */ + +/* + * configure a pipe */ static int config_pipe(struct new_pipe *p, struct dn_id *arg) @@ -599,7 +557,7 @@ config_pipe(struct new_pipe *p, struct d return EINVAL; } i = p->pipe_nr; - if (i <= 0 || i > DN_MAXID) + if (i <= 0 || i >= DN_MAX_ID) return EINVAL; // printf("%s %d\n", __FUNCTION__, i); /* @@ -607,146 +565,162 @@ config_pipe(struct new_pipe *p, struct d * bw = bits/second (0 means no limits), * delay = ms, must be translated into ticks. * qsize = slots/bytes + * burst ??? */ p->delay = (p->delay * hz) / 1000; /* Scale burst size: bytes -> bits * hz */ p->burst *= 8 * hz; DUMMYNET_LOCK(); + again: s = locate_scheduler(i); if (s == NULL) { DUMMYNET_UNLOCK(); printf("%s sched %d not found\n", __FUNCTION__, i); return EINVAL; } + /* copy all parameters */ s->pipe.delay = p->delay; s->pipe.bandwidth = p->bandwidth; s->pipe.burst = p->burst; schk_reset_credit(s); + if (i < DN_MAX_ID) { /* repeat for the FIFO pipe */ + i += DN_MAX_ID; + goto again; + } dn_cfg.id++; DUMMYNET_UNLOCK(); return 0; } /* - * Configure a scheduler possibly allocating it (and the pipe). - * XXX check link to type etc. + * configure a flowset. Can be called from inside with locked=1, + */ +static struct new_fsk * +config_fs(struct new_fs *nfs, struct dn_id *arg, int locked) +{ + struct new_fsk *fs; + struct new_schk *s; + int i; + + if (nfs->oid.len < sizeof(*nfs)) { + printf("%s: short flowset\n", __FUNCTION__); + return NULL; + } + i = nfs->fs_nr; + // printf("%s fs %d sched %d\n", __FUNCTION__, i, nfs->sched_nr); + if (i <= 0 || i >= 3*DN_MAX_ID) + return NULL; + /* XXX other sanity checks */ + if (nfs->flags & DN_QSIZE_IS_BYTES) { + if (nfs->qsize > dn_cfg.pipe_byte_limit) + nfs->qsize = dn_cfg.pipe_byte_limit; + } else { + if (nfs->qsize == 0) + nfs->qsize = 50; + if (nfs->qsize > dn_cfg.pipe_slot_limit) + nfs->qsize = dn_cfg.pipe_slot_limit; + } + if (!locked) + DUMMYNET_LOCK(); +again: + fs = dn_ht_find(dn_cfg.fshash, i, DNHT_INSERT); + if (fs == NULL) + goto done; + dn_cfg.id++; + fs->fs = *nfs; /* update config */ + s = locate_scheduler(nfs->sched_nr); + if (fs->sched == NULL) { /* no scheduler before */ + if (s) { + /* have a new scheduler, remove from unlinked */ + fs->sched = s; + // XXX remove_from_unlinked(fs); + } + } else if (fs->sched != s) { + /* scheduler changed. Let it die and recreate */ + fs->kflags |= DN_DELETE; + goto again; + } +done: + if (!locked) + DUMMYNET_UNLOCK(); + return fs; +} + +/* + * configure a scheduler and its FIFO variant. + * For !MULTIQUEUE schedulers, also set up the flowset. */ static int config_sched(struct new_sch *nsch, struct dn_id *arg) { struct new_schk *s; struct dn_sched *fp; - int i, is_new; + int i, notify_fs = 0; if (nsch->oid.len != sizeof(*nsch)) { printf("%s: bad sched len\n", __FUNCTION__); return EINVAL; } i = nsch->sched_nr; - if (i <= 0 || i > DN_MAXID) + if (i <= 0 || i >= DN_MAX_ID) return EINVAL; - // printf("%s i %d\n", __FUNCTION__, i); /* XXX other sanity checks */ + DUMMYNET_LOCK(); +again: /* run twice, for wfq and fifo */ + // printf("%s i %d\n", __FUNCTION__, i); fp = load_scheduler(nsch->oid.subtype, nsch->type); if (fp == NULL) { + DUMMYNET_UNLOCK(); printf("invalid scheduler type %d\n", nsch->oid.subtype); return EINVAL; } nsch->oid.subtype = fp->type; - nsch->oid.id = (uintptr_t)fp; /* used for */ - DUMMYNET_LOCK(); - // printf("%s i %d before ht_find\n", __FUNCTION__, i); + nsch->oid.id = (uintptr_t)fp; /* used in schk_new() */ s = dn_ht_find(dn_cfg.schedhash, (uintptr_t)nsch, DNHT_KEY_IS_OBJ | DNHT_INSERT); - // printf("%s i %d after ht_find\n", __FUNCTION__, i); if (s == NULL) { + DUMMYNET_UNLOCK(); printf("cannot allocate scheduler\n"); return ENOMEM; } - printf("%s type %s old %p\n", __FUNCTION__, fp->name, s); - /* Handle the following cases - * 1. non existing before: - * initialize - * 2. existing before, type changed - * destroy queues, then #1 - * 3. existing before, same type. - * update parameters and pipe - */ - is_new = 0; + dn_cfg.id++; if (s->fp == NULL) { /* new scheduler, nothing to clean up */ - is_new = 1; - } else if (s->fp != fp) { /* type changed, flush queues. */ - // XXX we should reallocate the private data area. - // how do we do it ? - /* preserve old pipe */ - schk_flush(s); + notify_fs = 1; + } else if (s->fp != fp) { + printf("sched %d type changed from %s to %s" + " let it drain and reallocate\n", + i, s->fp->name, fp->name); + /* XXX detach flowsets */ + s->kflags = DN_DELETE; + notify_fs = 1; + goto again; } /* complete initialization */ s->fp = fp; s->cfg = arg; - /* call init function */ + // XXX schk_reset_credit(s); + /* create the internal flowset if needed */ + if (!(s->fp->flags & DN_MULTIQUEUE) && !s->fs) { + struct new_fs fs; + + bzero(&fs, sizeof(fs)); + set_oid(&fs.oid, DN_FS, 0, sizeof(fs)); + fs.fs_nr = i + DN_MAX_ID; + fs.sched_nr = i; + s->fs = config_fs(&fs, NULL, 1 /* locked */); + } + /* call init function after the flowset is created */ if (s->fp->config) s->fp->config(s, 1); - schk_reset_credit(s); - if (is_new) - update_fs(s); - dn_cfg.id++; - DUMMYNET_UNLOCK(); - return 0; -} - -/* - * response to a userland request to configure a flowset - * XXX check the allocation of the private area - */ -static int -config_fs(struct new_fs *nfs, struct dn_id *arg) -{ - struct new_fsk *fs; - struct new_schk *s; - int i; - - if (nfs->oid.len < sizeof(*nfs)) { - printf("%s: short flowset\n", __FUNCTION__); - return EINVAL; - } - i = nfs->fs_nr; - if (i <= 0 || i > DN_MAXID) - return EINVAL; - printf("%s i %d\n", __FUNCTION__, i); - /* XXX other sanity checks */ - if (nfs->flags & DN_QSIZE_IS_BYTES) { - if (nfs->qsize > dn_cfg.pipe_byte_limit) - nfs->qsize = dn_cfg.pipe_byte_limit; - } else { - if (nfs->qsize == 0) - nfs->qsize = 50; - if (nfs->qsize > dn_cfg.pipe_slot_limit) - nfs->qsize = dn_cfg.pipe_slot_limit; - } - - DUMMYNET_LOCK(); -again: - fs = dn_ht_find(dn_cfg.fshash, i, DNHT_INSERT); - - if (fs == NULL) { - DUMMYNET_UNLOCK(); - return ENOMEM; - } - fs->fs = *nfs; /* update config */ - s = locate_scheduler(nfs->sched_nr); - if (fs->sched == NULL) { /* no scheduler before, link */ - if (s) { - fs->sched = s; - // XXX remove_from_unlinked(fs); - } - } else if (fs->sched != s) { - /* scheduler changed. Mark old fs and recreate */ - fs->kflags |= DN_DELETE; + if (i < DN_MAX_ID) { /* update the FIFO instance */ + i += DN_MAX_ID; + nsch->sched_nr = i; + nsch->oid.subtype = DN_SCHED_FIFO; goto again; } - dn_cfg.id++; + if (notify_fs) + update_fs(s); DUMMYNET_UNLOCK(); return 0; } @@ -766,7 +740,7 @@ config_profile(struct new_profile *pf, s return EINVAL; } i = pf->pipe_nr; - if (i <= 0 || i > DN_MAXID) + if (i <= 0 || i >= DN_MAX_ID) return EINVAL; /* XXX other sanity checks */ @@ -814,6 +788,67 @@ config_profile(struct new_profile *pf, s return 0; } +/* + * Main handler for configuration. Rules of the game: + * - the first object is the command (config, delete, flush, ...) + * - config_pipe must be issued after the corresponding config_sched + * - parameters (DN_TXT) for an object must preceed the object + * processed on a config_sched. + */ +static int +do_config(void *p, int l) +{ + struct dn_id *next, *o; + int err = 0; + struct dn_id *arg = NULL; + + for (o = p; l >= sizeof(*o); o = next) { + struct dn_id *prev = arg; + if (o->len < sizeof(*o) || l < o->len) { + printf("bad len o->len %d len %d\n", o->len, l); + err = EINVAL; + break; + } + l -= o->len; + printf("%s cmd %d len %d left %d\n", + __FUNCTION__, o->type, o->len, l); + next = (struct dn_id *)((char *)o + o->len); + err = 0; + switch (o->type) { + default: + printf("cmd %d not implemented\n", o->type); + break; + + case DN_CMD_CONFIGURE: + break; + + case DN_CMD_FLUSH: + dummynet_flush(); + break; + case DN_TEXT: /* store argument the next block */ + prev = NULL; + arg = o; + break; + case DN_PIPE: + err = config_pipe((struct new_pipe *)o, arg); + break; + case DN_PROFILE: + err = config_profile((struct new_profile *)o, arg); + break; + case DN_SCH: + err = config_sched((struct new_sch *)o, arg); + break; + case DN_FS: + err = (NULL==config_fs((struct new_fs *)o, arg, 0)); + break; + } + if (prev) + arg = NULL; + if (err != 0) + break; + } + return err; +} static int compute_space(struct dn_id *cmd, int *to_copy) { @@ -975,15 +1010,18 @@ schk_hash(uintptr_t key, int flags, void { int i = ((flags & DNHT_KEY_IS_OBJ) == 0) ? key : ((struct new_schk *)key)->sch.sched_nr; + // printf("%s %d\n", __FUNCTION__, i); return ( (i>>8)^(i>>4)^i ); } static int schk_match(void *obj, uintptr_t key, int flags, void *arg) { + struct new_schk *s = ((struct new_schk *)obj); int i = ((flags & DNHT_KEY_IS_OBJ) == 0) ? key : ((struct new_schk *)key)->sch.sched_nr; - return ((struct new_schk *)obj)->sch.sched_nr == i; + // printf("%s s %p i %d\n", __FUNCTION__, s, i); + return !(s->kflags & DN_DELETE) && (s->sch.sched_nr == i); } /* @@ -999,7 +1037,6 @@ schk_new(uintptr_t key, int flags, void struct dn_sched *fp = (struct dn_sched *)sch->oid.id; int l = sizeof(*s) + fp->schk_len; -// printf("%s key %p fp %p\n", __FUNCTION__, sch, fp); s = malloc(l, M_DUMMYNET, M_NOWAIT | M_ZERO); if (s == NULL) return NULL; @@ -1038,7 +1075,7 @@ fsk_match(void *obj, uintptr_t key, int struct new_fsk *fs = obj; int i = ((flags & DNHT_KEY_IS_OBJ) == 0) ? key : ((struct new_fsk *)key)->fs.fs_nr; - return !(fs->kflags & DN_DELETE) && fs->fs.fs_nr == i; + return !(fs->kflags & DN_DELETE) && (fs->fs.fs_nr == i); } static void * @@ -1122,7 +1159,6 @@ dummynet_modevent(module_t mod, int type switch (type) { case MOD_LOAD: - printf("%s MODLOAD\n", __FUNCTION__); if (ip_dn_io_ptr) { printf("DUMMYNET already loaded\n"); return EEXIST ; @@ -1153,7 +1189,7 @@ load_descriptor(struct dn_sched *d) if (d == NULL) return 1; /* error */ - ip_dn_init(); /* just in case */ + ip_dn_init(); /* just in case, we need the lock */ /* Check that mandatory funcs exists */ if (d->enqueue == NULL || d->dequeue == NULL) { @@ -1173,7 +1209,6 @@ load_descriptor(struct dn_sched *d) SLIST_INSERT_HEAD(&list_of_scheduler, d, next); DUMMYNET_UNLOCK(); printf("dn_sched %s %sloaded\n", d->name, s ? "not ":""); - return s ? 1 : 0; } @@ -1196,7 +1231,8 @@ unload_descriptor(struct dn_sched *s) break; } DUMMYNET_UNLOCK(); - return err; /* scheduler in use */ + printf("dn_sched %s %sunloaded\n", s->name, err ? "not ":""); + return err; } int From owner-svn-src-user@FreeBSD.ORG Wed Jan 13 20:25:46 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 2F30C1065670; Wed, 13 Jan 2010 20:25:46 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 063F68FC0C; Wed, 13 Jan 2010 20:25:46 +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 o0DKPj5n014286; Wed, 13 Jan 2010 20:25:45 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0DKPjOT014285; Wed, 13 Jan 2010 20:25:45 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201001132025.o0DKPjOT014285@svn.freebsd.org> From: Ed Schouten Date: Wed, 13 Jan 2010 20:25:45 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202230 - user/ed/utmpx X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 13 Jan 2010 20:25:46 -0000 Author: ed Date: Wed Jan 13 20:25:45 2010 New Revision: 202230 URL: http://svn.freebsd.org/changeset/base/202230 Log: Remove this branch. This is now part of HEAD. Deleted: user/ed/utmpx/ From owner-svn-src-user@FreeBSD.ORG Thu Jan 14 07:13:06 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 8658D106566C; Thu, 14 Jan 2010 07:13:06 +0000 (UTC) (envelope-from kmacy@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 758378FC08; Thu, 14 Jan 2010 07:13:06 +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 o0E7D6We059379; Thu, 14 Jan 2010 07:13:06 GMT (envelope-from kmacy@svn.freebsd.org) Received: (from kmacy@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0E7D6g2059377; Thu, 14 Jan 2010 07:13:06 GMT (envelope-from kmacy@svn.freebsd.org) Message-Id: <201001140713.o0E7D6g2059377@svn.freebsd.org> From: Kip Macy Date: Thu, 14 Jan 2010 07:13:06 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202276 - user/kmacy/releng_8_rump/lib/libunet X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Jan 2010 07:13:06 -0000 Author: kmacy Date: Thu Jan 14 07:13:06 2010 New Revision: 202276 URL: http://svn.freebsd.org/changeset/base/202276 Log: - define a local thread lock - cull some dead code Modified: user/kmacy/releng_8_rump/lib/libunet/unet_kern_intr.c Modified: user/kmacy/releng_8_rump/lib/libunet/unet_kern_intr.c ============================================================================== --- user/kmacy/releng_8_rump/lib/libunet/unet_kern_intr.c Thu Jan 14 05:37:43 2010 (r202275) +++ user/kmacy/releng_8_rump/lib/libunet/unet_kern_intr.c Thu Jan 14 07:13:06 2010 (r202276) @@ -95,6 +95,11 @@ critical_exit(void) { } +#undef thread_lock +#undef thread_unlock +#define thread_lock(tdp) mtx_lock((tdp)->td_lock) +#define thread_unlock(tdp) mtx_unlock((tdp)->td_lock) + struct intr_event *clk_intr_event; @@ -213,7 +218,6 @@ intr_event_update(struct intr_event *ie) /* Start off with no entropy and just the name of the event. */ mtx_assert(&ie->ie_lock, MA_OWNED); strlcpy(ie->ie_fullname, ie->ie_name, sizeof(ie->ie_fullname)); - ie->ie_flags &= ~IE_ENTROPY; missed = 0; space = 1; @@ -226,8 +230,6 @@ intr_event_update(struct intr_event *ie) space = 0; } else missed++; - if (ih->ih_flags & IH_ENTROPY) - ie->ie_flags |= IE_ENTROPY; } /* @@ -338,12 +340,10 @@ intr_event_destroy(struct intr_event *ie return (EBUSY); } TAILQ_REMOVE(&event_list, ie, ie_list); -#ifndef notyet if (ie->ie_thread != NULL) { ithread_destroy(ie->ie_thread); ie->ie_thread = NULL; } -#endif mtx_unlock(&ie->ie_lock); mtx_unlock(&event_lock); mtx_destroy(&ie->ie_lock); @@ -424,8 +424,6 @@ intr_event_add_handler(struct intr_event ih->ih_flags = IH_EXCLUSIVE; if (flags & INTR_MPSAFE) ih->ih_flags |= IH_MPSAFE; - if (flags & INTR_ENTROPY) - ih->ih_flags |= IH_ENTROPY; /* We can only have one exclusive handler in a event. */ mtx_lock(&ie->ie_lock); @@ -497,8 +495,6 @@ intr_event_add_handler(struct intr_event ih->ih_flags = IH_EXCLUSIVE; if (flags & INTR_MPSAFE) ih->ih_flags |= IH_MPSAFE; - if (flags & INTR_ENTROPY) - ih->ih_flags |= IH_ENTROPY; /* We can only have one exclusive handler in a event. */ mtx_lock(&ie->ie_lock); @@ -586,9 +582,6 @@ intr_event_remove_handler(void *cookie) #ifdef INVARIANTS struct intr_handler *ih; #endif -#ifdef notyet - int dead; -#endif if (handler == NULL) return (EINVAL); @@ -629,7 +622,7 @@ ok: * thread do it. */ thread_lock(ie->ie_thread->it_thread); - if (!TD_AWAITING_INTR(ie->ie_thread->it_thread) && !cold) { + if (!TD_AWAITING_INTR(ie->ie_thread->it_thread)) { handler->ih_flags |= IH_DEAD; /* @@ -638,30 +631,11 @@ ok: * it on the list. */ ie->ie_thread->it_need = 1; - } else - TAILQ_REMOVE(&ie->ie_handlers, handler, ih_next); + } thread_unlock(ie->ie_thread->it_thread); while (handler->ih_flags & IH_DEAD) msleep(handler, &ie->ie_lock, 0, "iev_rmh", 0); intr_event_update(ie); -#ifdef notyet - /* - * XXX: This could be bad in the case of ppbus(8). Also, I think - * this could lead to races of stale data when servicing an - * interrupt. - */ - dead = 1; - TAILQ_FOREACH(ih, &ie->ie_handlers, ih_next) { - if (!(ih->ih_flags & IH_FAST)) { - dead = 0; - break; - } - } - if (dead) { - ithread_destroy(ie->ie_thread); - ie->ie_thread = NULL; - } -#endif mtx_unlock(&ie->ie_lock); free(handler, M_ITHREAD); return (0); @@ -688,19 +662,6 @@ intr_event_schedule_thread(struct intr_e td = it->it_thread; p = td->td_proc; - /* - * If any of the handlers for this ithread claim to be good - * sources of entropy, then gather some. - */ - if (harvest.interrupt && ie->ie_flags & IE_ENTROPY) { - CTR3(KTR_INTR, "%s: pid %d (%s) gathering entropy", __func__, - p->p_pid, td->td_name); - entropy.event = (uintptr_t)ie; - entropy.td = ctd; - random_harvest(&entropy, sizeof(entropy), 2, 0, - RANDOM_INTERRUPT); - } - KASSERT(p != NULL, ("ithread %s has no process", ie->ie_name)); /* @@ -735,9 +696,6 @@ intr_event_remove_handler(void *cookie) #ifdef INVARIANTS struct intr_handler *ih; #endif -#ifdef notyet - int dead; -#endif if (handler == NULL) return (EINVAL); @@ -780,7 +738,7 @@ ok: * thread do it. */ thread_lock(it->it_thread); - if (!TD_AWAITING_INTR(it->it_thread) && !cold) { + if (!TD_AWAITING_INTR(it->it_thread)) { handler->ih_flags |= IH_DEAD; /* @@ -789,8 +747,7 @@ ok: * it on the list. */ it->it_need = 1; - } else - TAILQ_REMOVE(&ie->ie_handlers, handler, ih_next); + } thread_unlock(it->it_thread); while (handler->ih_flags & IH_DEAD) msleep(handler, &ie->ie_lock, 0, "iev_rmh", 0); @@ -803,24 +760,6 @@ ok: handler->ih_thread = NULL; } intr_event_update(ie); -#ifdef notyet - /* - * XXX: This could be bad in the case of ppbus(8). Also, I think - * this could lead to races of stale data when servicing an - * interrupt. - */ - dead = 1; - TAILQ_FOREACH(ih, &ie->ie_handlers, ih_next) { - if (handler != NULL) { - dead = 0; - break; - } - } - if (dead) { - ithread_destroy(ie->ie_thread); - ie->ie_thread = NULL; - } -#endif mtx_unlock(&ie->ie_lock); free(handler, M_ITHREAD); return (0); @@ -844,19 +783,6 @@ intr_event_schedule_thread(struct intr_e td = it->it_thread; p = td->td_proc; - /* - * If any of the handlers for this ithread claim to be good - * sources of entropy, then gather some. - */ - if (harvest.interrupt && ie->ie_flags & IE_ENTROPY) { - CTR3(KTR_INTR, "%s: pid %d (%s) gathering entropy", __func__, - p->p_pid, td->td_name); - entropy.event = (uintptr_t)ie; - entropy.td = ctd; - random_harvest(&entropy, sizeof(entropy), 2, 0, - RANDOM_INTERRUPT); - } - KASSERT(p != NULL, ("ithread %s has no process", ie->ie_name)); /* @@ -904,9 +830,6 @@ swi_add(struct intr_event **eventp, cons struct intr_event *ie; int error; - if (flags & INTR_ENTROPY) - return (EINVAL); - ie = (eventp != NULL) ? *eventp : NULL; if (ie != NULL) { From owner-svn-src-user@FreeBSD.ORG Thu Jan 14 17:30:14 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 5DD8F106566B; Thu, 14 Jan 2010 17:30:14 +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 4BD5C8FC14; Thu, 14 Jan 2010 17:30:14 +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 o0EHUEg2097668; Thu, 14 Jan 2010 17:30:14 GMT (envelope-from luigi@svn.freebsd.org) Received: (from luigi@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0EHUETY097662; Thu, 14 Jan 2010 17:30:14 GMT (envelope-from luigi@svn.freebsd.org) Message-Id: <201001141730.o0EHUETY097662@svn.freebsd.org> From: Luigi Rizzo Date: Thu, 14 Jan 2010 17:30:14 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202291 - in user/luigi/ipfw3-head: sbin/ipfw sys/netinet/ipfw X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Jan 2010 17:30:14 -0000 Author: luigi Date: Thu Jan 14 17:30:13 2010 New Revision: 202291 URL: http://svn.freebsd.org/changeset/base/202291 Log: fix deletion of schedulers Modified: user/luigi/ipfw3-head/sbin/ipfw/dummynet.c user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Modified: user/luigi/ipfw3-head/sbin/ipfw/dummynet.c ============================================================================== --- user/luigi/ipfw3-head/sbin/ipfw/dummynet.c Thu Jan 14 16:49:22 2010 (r202290) +++ user/luigi/ipfw3-head/sbin/ipfw/dummynet.c Thu Jan 14 17:30:13 2010 (r202291) @@ -86,15 +86,21 @@ static struct _s_x dummynet_params[] = { #define O_NEXT(p, len) ((void *)(char *)(p) + len) +static void +oid_fill(struct dn_id *oid, int len, int type) +{ + oid->len = len; + oid->type = type; + oid->subtype = 0; + oid->id = 0; +} + /* make room in the buffer and move the pointer forward */ static void * o_next(struct dn_id **o, int len, int type) { - void *ret = *o; - (*o)->len = len; - (*o)->type = type; - (*o)->subtype = 0; - (*o)->id = 0; + struct dn_id *ret = *o; + oid_fill(ret, len, type); *o = O_NEXT(*o, len); return ret; } @@ -361,25 +367,21 @@ list_pipes(struct dn_id *oid, struct dn_ } /* - * Delete pipe or queue i + * Delete pipe, queue or scheduler i */ int ipfw_delete_pipe(int pipe_or_queue, int i) { -#if 0 - struct dn_pipe p; - - memset(&p, 0, sizeof p); - if (pipe_or_queue == 1) - p.pipe_nr = i; /* pipe */ - else - p.fs.fs_nr = i; /* queue */ - i = do_cmd(IP_DUMMYNET_DEL, &p, sizeof p); + struct dn_id oid; + oid_fill(&oid, sizeof(oid), DN_CMD_DELETE); + oid.subtype = (co.do_pipe == 1) ? DN_PIPE : + ( (co.do_pipe == 2) ? DN_FS : DN_SCH); + oid.id = i; + i = do_cmd(IP_DUMMYNET3, &oid, oid.len); if (i) { i = 1; warn("rule %u: setsockopt(IP_DUMMYNET_DEL)", i); } -#endif return i; } @@ -1180,8 +1182,7 @@ end_mask: i = do_cmd(IP_DUMMYNET_CONFIGURE, prof, sizeof *prof); } else #endif - i = do_cmd(IP_DUMMYNET3, base, - (char *)buf - (char *)base); + i = do_cmd(IP_DUMMYNET3, base, (char *)buf - (char *)base); if (i) err(1, "setsockopt(%s)", "IP_DUMMYNET_CONFIGURE"); @@ -1191,9 +1192,8 @@ void dummynet_flush(void) { struct dn_id oid; - oid.type = DN_CMD_FLUSH; - oid.len = sizeof(oid); - do_cmd(IP_DUMMYNET3, &oid, sizeof(oid)); + oid_fill(&oid, sizeof(oid), DN_CMD_FLUSH); + do_cmd(IP_DUMMYNET3, &oid, oid.len); } void Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c Thu Jan 14 16:49:22 2010 (r202290) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c Thu Jan 14 17:30:13 2010 (r202291) @@ -432,6 +432,7 @@ dn_ht_scan(struct dn_ht *ht, int (*fn)(v next = *(void **)((char *)cur + ht->ofs); ret = fn(cur, arg); if (ret & HEAP_SCAN_DEL) { + printf("element %p removed\n", cur); found++; ht->entries--; *curp = next; Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h Thu Jan 14 16:49:22 2010 (r202290) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h Thu Jan 14 17:30:13 2010 (r202291) @@ -147,6 +147,7 @@ struct new_queue { * kernel flags, and a pointer to the scheduler methods. * It is stored in a hash table, and holds a list of all * flowsets and scheduler instances. + * XXX sch must be at the beginning, see schk_hash(). */ struct new_schk { struct new_sch sch; Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Thu Jan 14 16:49:22 2010 (r202290) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Thu Jan 14 17:30:13 2010 (r202291) @@ -1,4 +1,6 @@ /*- + printf("XXX should delete all fs pointing to me\n"); + printf("XXX should delete all fs pointing to me\n"); * Copyright (c) 1998-2002,2010 Luigi Rizzo, Universita` di Pisa * Portions Copyright (c) 2000 Akamba Corp. * All rights reserved @@ -325,16 +327,19 @@ ipdn_si_find(struct new_schk *s, struct * then check refcnt and free when it becomes 0 */ static int -destroy_fs(void *obj, void *arg) +fsk_destroy_cb(void *obj, void *arg) { struct new_fsk *fs = obj; struct new_schk *s = fs->sched; +printf("%s fs %d sched %d %p refcnt %d\n", __FUNCTION__, + fs->fs.fs_nr, + fs->fs.sched_nr, s, fs->refcnt); fs->kflags |= DN_DELETE; if (fs->refcnt == 0) { dn_cfg.fsk_count--; - if (fs->sched) - SLIST_REMOVE(&s->fsk_list, fs, new_fsk, sch_chain); + // always in a list, possibly the unlinked + // SLIST_REMOVE(&s->fsk_list, fs, new_fsk, sch_chain); fs->sched = NULL; free(fs, M_DUMMYNET); printf("%s free done\n", __FUNCTION__); @@ -391,7 +396,7 @@ dn_delete_queue(struct new_queue *q) if (fs) { fs->refcnt--; if (fs->refcnt == 0 && fs->kflags & DN_DELETE) - destroy_fs(fs, NULL); + fsk_destroy_cb(fs, NULL); } return 0; } @@ -478,7 +483,20 @@ copy_data_helper(void *_o, void *_arg) static int schk_del_cb(void *obj, void *arg) { + struct new_schk *s = obj; + struct new_fsk *fs; + + printf("%s start for %d %p\n", __FUNCTION__, s->sch.sched_nr, s); schk_flush((struct new_schk *)obj); + printf("XXX should delete all fs pointing to me\n"); + while ((fs = SLIST_FIRST(&s->fsk_list))) { + printf("%s unlink flowset %d from sched %d\n", __FUNCTION__, + fs->fs.fs_nr, s->sch.sched_nr); + SLIST_REMOVE_HEAD(&s->fsk_list, sch_chain); + fs->sched = NULL; + printf(" put flowset into fsunlinked\n"); + SLIST_INSERT_HEAD(&dn_cfg.fsunlinked, fs, sch_chain); + } free(obj, M_DUMMYNET); return HEAP_SCAN_DEL; } @@ -493,8 +511,8 @@ dummynet_flush(void) DUMMYNET_LOCK(); printf("%s start\n", __FUNCTION__); /* first mark flowsets as delete, then go after queues */ - dn_ht_scan(dn_cfg.fshash, destroy_fs, 0); - printf("%s destroy_fs done\n", __FUNCTION__); + dn_ht_scan(dn_cfg.fshash, fsk_destroy_cb, 0); + printf("%s fsk_destroy_cb done\n", __FUNCTION__); dn_ht_scan(dn_cfg.schedhash, schk_del_cb, 0); /* Reinitialize system heap... */ @@ -788,6 +806,32 @@ config_profile(struct new_profile *pf, s return 0; } +static int +del_fs(int i) +{ + struct new_fsk *fs = dn_ht_find(dn_cfg.fshash, i, DNHT_REMOVE); + if (fs) { + fsk_destroy_cb(fs, NULL); + return 0; + } else { + printf("%s: %d not found\n", __FUNCTION__, i); + return EINVAL; + } +} + +static int +del_schk(int i) +{ + struct new_schk *s = dn_ht_find(dn_cfg.schedhash, i, DNHT_REMOVE); + if (s) { + schk_del_cb(s, NULL); + return 0; + } else { + printf("%s: %d not found\n", __FUNCTION__, i); + return EINVAL; + } +} + /* * Main handler for configuration. Rules of the game: * - the first object is the command (config, delete, flush, ...) @@ -819,7 +863,32 @@ do_config(void *p, int l) printf("cmd %d not implemented\n", o->type); break; - case DN_CMD_CONFIGURE: + case DN_CMD_CONFIGURE: /* simply a header */ + break; + + case DN_CMD_DELETE: + switch (o->subtype) { + case DN_PIPE: + if ( (err = del_schk(o->id)) ) + break; + if ( (err = del_schk(o->id) + DN_MAX_ID) ) + break; + if ( (err = del_fs(o->id)) ) + break; + if ( (err = del_fs(o->id) + DN_MAX_ID) ) + break; + break; + default: + printf("invalid delete type %d\n", + o->subtype); + err = EINVAL; + break; + + case DN_FS: + if ( (err = del_fs(o->id)) ) + break; + break; + } break; case DN_CMD_FLUSH: @@ -1002,8 +1071,14 @@ ip_dn_ctl(struct sockopt *sopt) /*------------------------------------------------------------ * Scheduler hash. When searching by index we pass sched_nr, * otherwise we pass struct new_sch * which is the first field in - * struct new_schk so we can cast it. We need this info during the - * create phase, where we put the dn_sched * in oid.id + * struct new_schk so we can cast between the two. We use this trick + * because in the create phase we need to pass an additional argument + * (struct dn_sched *)and the hash table API does not support that. + * To work around the problem, we pass a struct new_sch *, store the + * struct dn_sched * in sch->oid.id, and set DNHT_KEY_IS_OBJ but + * not + * XXX the way to remove this restriction is adding an argument to + * the 'find' call, which is passed to the various functions. */ static int schk_hash(uintptr_t key, int flags, void *arg) From owner-svn-src-user@FreeBSD.ORG Thu Jan 14 21:34:12 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A335E1065693; Thu, 14 Jan 2010 21:34:12 +0000 (UTC) (envelope-from dougb@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 940AB8FC18; Thu, 14 Jan 2010 21:34:12 +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 o0ELYCJL052389; Thu, 14 Jan 2010 21:34:12 GMT (envelope-from dougb@svn.freebsd.org) Received: (from dougb@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0ELYCUY052387; Thu, 14 Jan 2010 21:34:12 GMT (envelope-from dougb@svn.freebsd.org) Message-Id: <201001142134.o0ELYCUY052387@svn.freebsd.org> From: Doug Barton Date: Thu, 14 Jan 2010 21:34:12 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202307 - user/dougb/portmaster X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Jan 2010 21:34:12 -0000 Author: dougb Date: Thu Jan 14 21:34:12 2010 New Revision: 202307 URL: http://svn.freebsd.org/changeset/base/202307 Log: Solve the problem of adding "rundeps of build-only deps" to the build-only list in -t by always doing the augmented list, and only doing things relevant to -t after that's done. Modified: user/dougb/portmaster/portmaster Modified: user/dougb/portmaster/portmaster ============================================================================== --- user/dougb/portmaster/portmaster Thu Jan 14 21:30:22 2010 (r202306) +++ user/dougb/portmaster/portmaster Thu Jan 14 21:34:12 2010 (r202307) @@ -1784,31 +1784,27 @@ dependency_check () { fi if [ "$PM_BUILD_ONLY_LIST" = pmp_doing_build_deps ]; then - local rundeps dep run_dl build_only_dl + local rundeps dep varname run_dl build_only_dl rundeps=`pm_make run-depends-list | sort -u` - if [ -z "$RECURSE_THOROUGH" ]; then - for dep in $d_port_list; do - case "$rundeps" in - *${dep}*) -# XXX Need to figure out -t case - varname=`echo ${dep#$pd/} | sed 's#[-+/\.]#_#g'` - rundep_list="$rundep_list $varname" - eval $varname=\"$portdir \$$varname\" - eval ${varname}_p=$dep - eval export $varname ${varname}_p + for dep in $d_port_list; do + case "$rundeps" in + *${dep}*) + varname=`echo ${dep#$pd/} | sed 's#[-+/\.]#_#g'` + rundep_list="$rundep_list $varname" + eval $varname=\"$portdir \$$varname\" + eval ${varname}_p=$dep + eval export $varname ${varname}_p - run_dl="$run_dl $dep" ;; - *) build_only_dl="$build_only_dl $dep" ;; - esac - done + run_dl="$run_dl $dep" ;; + *) build_only_dl="$build_only_dl $dep" ;; + esac + done + if [ -z "$RECURSE_THOROUGH" ]; then d_port_list="$build_only_dl $run_dl" else - for dep in $rundeps; do - run_dl="$run_dl $dep" - done build_only_dl=`pm_make build-depends-list | sort -u` fi From owner-svn-src-user@FreeBSD.ORG Fri Jan 15 00:41:47 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 318AE1065672; Fri, 15 Jan 2010 00:41:47 +0000 (UTC) (envelope-from dougb@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 147A98FC15; Fri, 15 Jan 2010 00:41:47 +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 o0F0fk39094968; Fri, 15 Jan 2010 00:41:46 GMT (envelope-from dougb@svn.freebsd.org) Received: (from dougb@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0F0fks8094967; Fri, 15 Jan 2010 00:41:46 GMT (envelope-from dougb@svn.freebsd.org) Message-Id: <201001150041.o0F0fks8094967@svn.freebsd.org> From: Doug Barton Date: Fri, 15 Jan 2010 00:41:46 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202325 - user/dougb/portmaster X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Jan 2010 00:41:47 -0000 Author: dougb Date: Fri Jan 15 00:41:46 2010 New Revision: 202325 URL: http://svn.freebsd.org/changeset/base/202325 Log: Hopefully this time the yes/no options will be more clear, while still maintaining the [default] notation that portmaster users are familiar with. Modified: user/dougb/portmaster/portmaster Modified: user/dougb/portmaster/portmaster ============================================================================== --- user/dougb/portmaster/portmaster Thu Jan 14 23:27:23 2010 (r202324) +++ user/dougb/portmaster/portmaster Fri Jan 15 00:41:46 2010 (r202325) @@ -571,7 +571,7 @@ IFS=' echo " ===>>> but there is no installed version" echo '' if [ -n "$CHECK_DEPENDS" ]; then - echo -n " ===>>> Delete this dependency data? y/[n] " + echo -n " ===>>> Delete this dependency data? y/n [n] " read answer case "$answer" in [yY]) unset prev_line line ; continue ;; @@ -778,7 +778,7 @@ if [ -n "$CLEAN_DISTFILES" ]; then echo "===>>> Deleting $f" pm_unlink $df else - echo -n "===>>> Delete stale file: ${f}? n/[y] " + echo -n "===>>> Delete stale file: ${f}? y/n [y] " read answer case "$answer" in [nN]*) continue ;; @@ -886,7 +886,7 @@ if [ -n "$CHECK_PORT_DBDIR" ]; then *) [ -n "$PM_VERBOSE" ] && echo '' echo '' echo " ===>>> $dbdir does not seem to be installed" - echo -n " ===>>> Delete ${dir}? y/[n] " + echo -n " ===>>> Delete ${dir}? y/n [n] " read answer case "$answer" in [yY]) pm_rm_s -rf $dir ;; @@ -1267,7 +1267,7 @@ find_and_delete_distfiles () { continue fi - echo -n "===>>> Delete $file? y/[n] " + echo -n "===>>> Delete $file? y/n [n] " read answer case "$answer" in [yY]) pm_unlink $file ;; @@ -1347,7 +1347,7 @@ delete_stale_distfiles () { continue fi - echo -n "===>>> Delete $file? y/[n] " + echo -n "===>>> Delete $file? y/n [n] " read answer case "$answer" in [yY]) pm_unlink $file ;; @@ -1383,7 +1383,7 @@ delete_all_distfiles () { echo '' if [ -n "$dist_list_files" ]; then echo "===>>> However, the list of files in $dist_list" - echo -n " should be current. Delete the files on this list? y/[n] " + echo -n " should be current. Delete the files on this list? y/n [n] " local answer f ; read answer case "$answer" in [yY]) for f in $dist_list_files; do @@ -1404,11 +1404,11 @@ delete_all_distfiles () { delete_all=delete_all else echo "===>>> Delete old and new distfiles for $origin" - echo -n " without prompting? y/[n] " + echo -n " without prompting? y/n [n] " local answer ; read answer case "$answer" in [yY]) delete_all=delete_all2 ;; - *) echo -n "===>>> Delete the current distfiles? y/[n] " + *) echo -n "===>>> Delete the current distfiles? y/n [n] " read answer case "$answer" in [yY]) delete_current=delete_current ;; @@ -1489,7 +1489,7 @@ if [ -n "$EXPUNGE" ]; then dep=${dep%/+CON*} ; echo " ${dep##*/}" done echo '' - echo -n "===>>> Delete this dependency data? y/[n] " + echo -n "===>>> Delete this dependency data? y/n [n] " read answer case "$answer" in [yY]) for f in $deplist; do @@ -1535,7 +1535,7 @@ if [ -n "$CLEAN_STALE" ]; then pkg_info $iport - echo -n "===>>> ${iport} is no longer depended on, delete? y/[n] " + echo -n "===>>> ${iport} is no longer depended on, delete? y/n [n] " read answer case "$answer" in [yY]) if [ -n "$BACKUP" ]; then @@ -1552,7 +1552,7 @@ if [ -n "$CLEAN_STALE" ]; then exec $0 -s $ARGS ;; - *) echo -n " ===>>> Keep listing $iport as a dependency? y/[n] " + *) echo -n " ===>>> Keep listing $iport as a dependency? y/n [n] " read answer case "$answer" in [yY]) no_del_list="${no_del_list}${iport}:" ;; @@ -1600,7 +1600,7 @@ check_interactive () { echo "===>>> +IGNOREME file is present for $1" fi - echo '' ; echo -n "===>>> Update ${1}${update_to}? n/[y] " + echo '' ; echo -n "===>>> Update ${1}${update_to}? y/n [y] " local answer ; read answer case "$answer" in [nN]*) INTERACTIVE_NO="${INTERACTIVE_NO}${1}:" ; return 1 ;; @@ -1950,7 +1950,7 @@ post_config () { echo '' echo "===>>> If you choose to proceed, the following will be done:" echo -e "$build_l" - echo -n "===>>> Proceed? n/[y] " + echo -n "===>>> Proceed? y/n [y] " read answer case "$answer" in [nN]*) safe_exit ;; @@ -2141,13 +2141,13 @@ if [ "$$" -eq "$PM_PARENT_PID" -a -z "$S files=`find $pdb -type f -name PM_UPGRADE_DONE_FLAG` if [ -n "$files" ]; then echo "===>>> There are 'install complete' flags from a previous" - echo -n " -[rf] run of ${0##*/}, delete them? y/[n] " + echo -n " -[rf] run of ${0##*/}, delete them? y/n [n] " read answer case "$answer" in [yY]) [ -n "$PM_SU_VERBOSE" ] && echo "===>>> Deleting 'install complete' flags" pm_find_s $pdb -type f -name PM_UPGRADE_DONE_FLAG -delete ;; - *) echo -n "===>>> Enable the -R option? y/[n] " + *) echo -n "===>>> Enable the -R option? y/n [n] " read answer case "$answer" in [yY]) RESTART=Ropt ; ARGS="-R $ARGS" ;; @@ -2388,7 +2388,7 @@ if [ -e "$pdb/$upg_port/+IGNOREME" ]; th echo '' echo "===>>> $upg_port has an +IGNOREME file" echo '' - echo -n "===>>> Update anyway? y/[n] " + echo -n "===>>> Update anyway? y/n [n] " read answer case "$answer" in [yY]) ;; # Let it build From owner-svn-src-user@FreeBSD.ORG Fri Jan 15 16:24:58 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A9D2E1065670; Fri, 15 Jan 2010 16:24:58 +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 96B5E8FC1A; Fri, 15 Jan 2010 16:24:58 +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 o0FGOwSD025882; Fri, 15 Jan 2010 16:24:58 GMT (envelope-from luigi@svn.freebsd.org) Received: (from luigi@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0FGOwtx025874; Fri, 15 Jan 2010 16:24:58 GMT (envelope-from luigi@svn.freebsd.org) Message-Id: <201001151624.o0FGOwtx025874@svn.freebsd.org> From: Luigi Rizzo Date: Fri, 15 Jan 2010 16:24:58 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202390 - in user/luigi/ipfw3-head: sbin/ipfw sys/netinet/ipfw X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Jan 2010 16:24:58 -0000 Author: luigi Date: Fri Jan 15 16:24:58 2010 New Revision: 202390 URL: http://svn.freebsd.org/changeset/base/202390 Log: another batch of changes, now removals work as well. Modified: user/luigi/ipfw3-head/sbin/ipfw/dummynet.c user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Modified: user/luigi/ipfw3-head/sbin/ipfw/dummynet.c ============================================================================== --- user/luigi/ipfw3-head/sbin/ipfw/dummynet.c Fri Jan 15 16:21:32 2010 (r202389) +++ user/luigi/ipfw3-head/sbin/ipfw/dummynet.c Fri Jan 15 16:24:58 2010 (r202390) @@ -295,49 +295,66 @@ print_extra_delay_parms(struct dn_pipe * } #endif +static void +flush_buf(char *buf) +{ + if (buf[0]) + printf("%s\n", buf); + buf[0] = '\0'; +} + /* + * generic list routine. We expect objects in a specific order, i.e. + * pipe i (int queue); scheduler i; si(i) { flowsets() : queues } * filt is an array of sorted ranges whithin where we list */ static void list_pipes(struct dn_id *oid, struct dn_id *end, int *filt) { - for (; oid != end; oid = O_NEXT(oid, oid->len)) { - struct new_pipe *p = (struct new_pipe *)oid; - //struct dn_flow_set *fs; - //struct dn_flow_queue *q; - - double b = p->bandwidth; - char buf[30]; - char prefix[80]; - char burst[5 + 7]; - - if (oid->type != DN_PIPE) - continue; - /* - * Print rate (or clocking interface) - */ - if (b == 0) - sprintf(buf, "unlimited"); - else if (b >= 1000000) - sprintf(buf, "%7.3f Mbit/s", b/1000000); - else if (b >= 1000) - sprintf(buf, "%7.3f Kbit/s", b/1000); - else - sprintf(buf, "%7.3f bit/s ", b); - - sprintf(prefix, "%05d: %s %4d ms ", - p->pipe_nr, buf, p->delay); + char buf[80]; /* pending buffer */ + buf[0] = '\0'; - // print_flowset_parms(&(p->fs), prefix); - printf("%s", prefix); + for (; oid != end; oid = O_NEXT(oid, oid->len)) { + /* XXX check oid->len */ + if (oid->len < sizeof(*oid)) + errx(1, "invalid oid len %d\n", oid->len); + + switch (oid->type) { + case DN_PIPE: { + struct new_pipe *p = (struct new_pipe *)oid; + double b = p->bandwidth; + char bwbuf[30]; + char burst[5 + 7]; + + flush_buf(buf); + /* data rate */ + if (b == 0) + sprintf(bwbuf, "unlimited"); + else if (b >= 1000000) + sprintf(bwbuf, "%7.3f Mbit/s", b/1000000); + else if (b >= 1000) + sprintf(bwbuf, "%7.3f Kbit/s", b/1000); + else + sprintf(bwbuf, "%7.3f bit/s ", b); - if (humanize_number(burst, sizeof(burst), p->burst, + if (humanize_number(burst, sizeof(burst), p->burst, "Byte", HN_AUTOSCALE, 0) < 0 || co.verbose) - printf("\t burst: %ju Byte\n", p->burst); - else - printf("\t burst: %s\n", burst); + sprintf(burst, "%ju Byte\n", p->burst); + sprintf(buf, "%05d: %s %4d ms burst %s", + p->pipe_nr, bwbuf, p->delay, burst); + // print_flowset_parms(&(p->fs), prefix); + // print_extra_delay_parms(p); + } + break; + case DN_FS: + flush_buf(buf); + printf("XXX flowset unimplemented\n"); + break; + } + } + flush_buf(buf); +} - // print_extra_delay_parms(p); #if 0 q = (struct dn_flow_queue *)(p+1); list_queues(&(p->fs), q); @@ -363,8 +380,6 @@ list_pipes(struct dn_id *oid, struct dn_ list_queues(fs, q); } #endif - } -} /* * Delete pipe, queue or scheduler i Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c Fri Jan 15 16:21:32 2010 (r202389) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c Fri Jan 15 16:24:58 2010 (r202390) @@ -311,7 +311,6 @@ struct dn_ht { int buckets; /* how many buckets */ int entries; /* how many entries */ int ofs; /* offset of link field */ - void *arg; /* argument to the three functions */ int (*hash)(uintptr_t, int, void *arg); int (*match)(void *_el, uintptr_t key, int, void *); void *(*new)(uintptr_t, int, void *); @@ -327,7 +326,7 @@ struct dn_ht * dn_ht_init(struct dn_ht *ht, int buckets, int ofs, int (*h)(uintptr_t, int, void *), int (*match)(void *, uintptr_t, int, void *), - void *(*new)(uintptr_t, int, void *), void *arg) + void *(*new)(uintptr_t, int, void *)) { int l; @@ -360,7 +359,6 @@ dn_ht_init(struct dn_ht *ht, int buckets ht->hash = h; ht->match = match; ht->new = new; - ht->arg = arg; } return ht; } @@ -377,19 +375,19 @@ dn_ht_free(struct dn_ht *ht, int flags) /* lookup and optionally create or delete element */ void * -dn_ht_find(struct dn_ht *ht, uintptr_t key, int flags) +dn_ht_find(struct dn_ht *ht, uintptr_t key, int flags, void *arg) { int i; void **pp, *p; i = (ht->buckets == 1) ? 0 : - (ht->hash(key, flags, ht->arg) % ht->buckets); + (ht->hash(key, flags, arg) % ht->buckets); // printf("%s key %p in bucket %d\n", __FUNCTION__, (void *)key, i); for (pp = &ht->ht[i]; (p = *pp); pp = (void **)((char *)p + ht->ofs)) { if (flags & DNHT_MATCH_PTR) { if (key == (uintptr_t)p) break; - } else if (ht->match(p, key, flags, ht->arg)) /* found match */ + } else if (ht->match(p, key, flags, arg)) /* found match */ break; } if (p) { @@ -402,7 +400,7 @@ dn_ht_find(struct dn_ht *ht, uintptr_t k } else if (flags & DNHT_INSERT) { // printf("%s before calling new, bucket %d ofs %d\n", // __FUNCTION__, i, ht->ofs); - p = ht->new ? ht->new(key, flags, ht->arg) : (void *)key; + p = ht->new ? ht->new(key, flags, arg) : (void *)key; // printf("%s new returns %p\n", __FUNCTION__, p); if (p) { ht->entries++; Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h Fri Jan 15 16:21:32 2010 (r202389) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h Fri Jan 15 16:24:58 2010 (r202390) @@ -109,9 +109,8 @@ int heap_scan(struct dn_heap *, int (*)( * computation on each removal. * * dn_ht_init() initializes the table, setting the number of - * buckets, the offset of the link field, the main callbacks, - * and an extra argument passed to the callbacks together - * with 'flags' which is defined below. Callbacks are: + * buckets, the offset of the link field, the main callbacks. + * Callbacks are: * * hash(key, flags, arg) called to return a bucket index. * match(obj, key, flags, arg) called to determine if key @@ -125,6 +124,7 @@ int heap_scan(struct dn_heap *, int (*)( * * dn_ht_find() is the main lookup function, which can also be * used to insert or delete elements in the hash table. + * The final 'arg' is passed to all callbacks. * * dn_ht_scan() is used to invoke a callback on all entries of * the heap, or possibly on just one bucket. The callback @@ -157,11 +157,11 @@ struct dn_ht; /* should be opaque */ struct dn_ht *dn_ht_init(struct dn_ht *, int buckets, int ofs, int (*hash)(uintptr_t, int, void *), int (*match)(void *, uintptr_t, int, void *), - void *(*new)(uintptr_t, int, void *), void *arg); + void *(*new)(uintptr_t, int, void *)); +void dn_ht_free(struct dn_ht *, int flags); -void *dn_ht_find(struct dn_ht *, uintptr_t key, int flags); +void *dn_ht_find(struct dn_ht *, uintptr_t, int, void *); int dn_ht_scan(struct dn_ht *, int (*)(void *, void *), void *); -void dn_ht_free(struct dn_ht *, int flags); enum { /* flags values. * first two are returned by the scan callback to indicate Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h Fri Jan 15 16:21:32 2010 (r202389) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h Fri Jan 15 16:24:58 2010 (r202390) @@ -108,14 +108,13 @@ struct dn_sched { int (*new_queue)(struct new_queue *q); int (*free_queue)(struct new_queue *q); }; -SLIST_HEAD(dn_sched_head, dn_sched); /* * Additionally, dummynet exports some variables, functions and macros * to be used by schedulers. */ /* delete a queue, which we assume nobody references */ -int dn_delete_queue(struct new_queue *q); +int dn_delete_queue(void *, void *propagate); int dn_queue_packet(struct new_queue *q, struct mbuf* m, int drop); /* @@ -129,10 +128,13 @@ dn_return_packet(struct new_queue *q) KASSERT(m != NULL, ("empty queue to dn_return_packet")); q->mq.head = m->m_nextpkt; q->ni.length--; - q->si->ni.len_bytes -= m->m_pkthdr.len; - q->si->ni.len_bytes -= m->m_pkthdr.len; + q->ni.len_bytes -= m->m_pkthdr.len; + if (q->si) { + q->si->ni.length--; + q->si->ni.len_bytes -= m->m_pkthdr.len; + } if (q->mq.head == NULL && q->fs && q->fs->kflags & DN_DELETE) - dn_delete_queue(q); + dn_delete_queue(q, (void *)1 /* possibly flush flowset */); return m; } Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Fri Jan 15 16:21:32 2010 (r202389) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Fri Jan 15 16:24:58 2010 (r202390) @@ -105,16 +105,29 @@ extern void (*bridge_dn_p)(struct mbuf * #ifdef SYSCTL_NODE SYSCTL_DECL(_net_inet); SYSCTL_DECL(_net_inet_ip); - SYSCTL_NODE(_net_inet_ip, OID_AUTO, dummynet, CTLFLAG_RW, 0, "Dummynet"); + +/* parameters */ SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, hash_size, CTLFLAG_RW, &dn_cfg.hash_size, 0, "Default hash table size"); +SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, pipe_slot_limit, + CTLFLAG_RW, &dn_cfg.pipe_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.pipe_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."); + +/* 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"); 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"); 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"); + +/* time adjustment */ SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, tick_delta, CTLFLAG_RD, &tick_delta, 0, "Last vs standard tick difference (usec)."); SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, tick_delta_sum, @@ -127,8 +140,16 @@ SYSCTL_LONG(_net_inet_ip_dummynet, OID_A SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, tick_lost, CTLFLAG_RD, &tick_lost, 0, "Number of ticks coalesced by dummynet taskqueue."); -SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, io_fast, - CTLFLAG_RW, &dn_cfg.io_fast, 0, "Enable fast dummynet io."); + +/* statistics */ +SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, schk_count, + CTLFLAG_RD, &dn_cfg.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"); +SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, fsk_count, + CTLFLAG_RD, &dn_cfg.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"); SYSCTL_ULONG(_net_inet_ip_dummynet, OID_AUTO, io_pkt, CTLFLAG_RD, &io_pkt, 0, "Number of packets passed to dummynet."); @@ -138,10 +159,6 @@ 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."); -SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, pipe_slot_limit, - CTLFLAG_RW, &dn_cfg.pipe_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.pipe_byte_limit, 0, "Upper limit in bytes for pipe queue."); #endif struct mtx dummynet_mtx; @@ -513,12 +530,6 @@ dummynet_send(struct mbuf *m) } } -struct new_fsk * -ipdn_locate_flowset(int fs_nr) -{ - return dn_ht_find(dn_cfg.fshash, fs_nr, 0); -} - static inline int tag_mbuf(struct mbuf *m, int dir, struct ip_fw_args *fwa) { @@ -557,7 +568,7 @@ dummynet_io(struct mbuf **m0, int dir, s struct mbuf *m = *m0; struct new_fsk *fs = NULL; struct new_sch_inst *si; - struct new_queue *q; + struct new_queue *q = NULL; /* default */ dn_key now; /* save a copy of curr_time */ int fs_id = (fwa->rule.info & IPFW_INFO_MASK) + @@ -566,7 +577,7 @@ dummynet_io(struct mbuf **m0, int dir, s io_pkt++; now = curr_time; /* XXX locate_flowset could be optimised with a direct ref. */ - fs = ipdn_locate_flowset(fs_id); + fs = dn_ht_find(dn_cfg.fshash, fs_id, 0, NULL); if (fs == NULL) goto dropit; /* This queue/pipe does not exist! */ if (fs->sched == NULL) /* should not happen */ @@ -578,13 +589,16 @@ dummynet_io(struct mbuf **m0, int dir, s if (tag_mbuf(m, dir, fwa)) goto dropit; /* - * if the scheduler has a single queue (e.g. FIFO) then - * call directly with NULL queue. Otherwise find a queue - * and pass it. + * If the support multiple queues, find the right one + * (otherwise it will be ignored by enqueue). + * We cannot pass si as an argument :( */ if (fs->sched->fp->flags & DN_MULTIQUEUE) { + struct new_queue template; + template.si = si; + template.fs = fs; q = dn_ht_find(fs->qht, (uintptr_t)&(fwa->f_id), - DNHT_INSERT); + DNHT_INSERT, &template); if (q == NULL) goto dropit; } else { Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h Fri Jan 15 16:21:32 2010 (r202389) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h Fri Jan 15 16:24:58 2010 (r202390) @@ -50,6 +50,7 @@ SLIST_HEAD(new_schk_head, new_schk); SLIST_HEAD(new_sch_inst_head, new_sch_inst); SLIST_HEAD(new_fsk_head, new_fsk); SLIST_HEAD(new_queue_head, new_queue); +SLIST_HEAD(dn_sched_head, dn_sched); /* * global configuration parameters. @@ -80,7 +81,8 @@ struct dn_parms { struct dn_ht *fshash; struct dn_ht *schedhash; /* list of flowsets without a scheduler -- use sch_chain */ - struct new_fsk_head fsunlinked; + struct new_fsk_head fsu; + struct dn_sched_head schedlist; /* list of algorithms */ }; static inline void @@ -128,15 +130,19 @@ struct new_fsk { /* kernel side of a flo }; /* - * The child of a flowset, is in a hash table + * q queue is created as a child of a flowset unless it belongs to + * a !MULTIQUEUE scheduler. It is normally in a hash table in the + * flowset. + * When a scheduler is destroyed we notify all flowsets attached + * to it so queues can be removed. + * When a flowset is deleted we let the queue drain quietly, and + * destroy the flowset when all queues are empty. */ struct new_queue { struct new_inst ni; /* oid, flow_id, stats */ struct mq mq; /* packets queue */ - - SLIST_ENTRY(new_queue) ql__next; /* hash chain list */ - SLIST_ENTRY(new_queue) si_chain; /* linked list to sch_inst */ struct new_sch_inst *si; /* owner scheduler instance */ + SLIST_ENTRY(new_queue) q_next; /* hash chain list for fs */ struct new_fsk *fs; /* parent flowset. */ /* If fs->kflags & DN_DELETE, remove the queue when empty. */ }; Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Fri Jan 15 16:21:32 2010 (r202389) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Fri Jan 15 16:24:58 2010 (r202390) @@ -1,6 +1,4 @@ /*- - printf("XXX should delete all fs pointing to me\n"); - printf("XXX should delete all fs pointing to me\n"); * Copyright (c) 1998-2002,2010 Luigi Rizzo, Universita` di Pisa * Portions Copyright (c) 2000 Akamba Corp. * All rights reserved @@ -69,7 +67,7 @@ static int ip_dn_ctl(struct sockopt *sop #define DN_C_FS 0x08 #define DN_C_QUEUE 0x10 -/* callout hooks. */ +/*---- callout hooks. ----*/ static struct callout dn_timeout; static struct task dn_task; static struct taskqueue *dn_tq = NULL; @@ -86,21 +84,19 @@ dn_reschedule(void) { callout_reset(&dn_timeout, 1, dummynet, NULL); } +/*----- end of callout hooks -----*/ -/* - * Return a scheduler descriptor given the type or name. - */ -static struct dn_sched_head list_of_scheduler; +/* Return a scheduler descriptor given the type or name. */ static struct dn_sched * -load_scheduler(int type, char *name) +find_sched_type(int type, char *name) { struct dn_sched *d = NULL; - SLIST_FOREACH(d, &list_of_scheduler, next) { + SLIST_FOREACH(d, &dn_cfg.schedlist, next) { if (d->type == type || (name && !strcmp(d->name, name))) return d; } - return NULL; /* error */ + return NULL; /* not found */ } /* @@ -196,9 +192,70 @@ flow_id_cmp(struct ipfw_flow_id *id1, st /* Masks differ */ return 1; } +/*--------- end of flow-id mask, hash and compare ---------*/ + +/*--- support functions for the qht hashtable ---- + * Entries are hashed by flow-id + */ +static int +q_hash(uintptr_t key, int flags, void *arg) +{ + /* compute the hash slot from the flow id */ + struct ipfw_flow_id *id = (flags & DNHT_KEY_IS_OBJ) ? + &((struct new_queue *)key)->ni.id : + (struct ipfw_flow_id *)key; + return flow_id_hash(id); +} + +static int +q_match(void *obj, uintptr_t key, int flags, void *arg) +{ + struct new_queue *o; + struct ipfw_flow_id *id2; + + if (flags & DNHT_KEY_IS_OBJ) { + /* compare pointers */ + id2 = &((struct new_queue *)key)->ni.id; + } else { + id2 = (struct ipfw_flow_id *)key; + } + o = (struct new_queue *)obj; + return flow_id_cmp(&o->ni.id, id2) == 0; +} + +/* + * create a new queue instance for the given 'key' + */ +static void * +q_new(uintptr_t key, int flags, void *arg) +{ + struct ipfw_flow_id *id = (struct ipfw_flow_id *)key; + struct new_queue *q, *template = arg; + struct new_fsk *fs = template->fs; + int size = sizeof(*q) + fs->sched->fp->queue_len; + + q = malloc(size, M_DUMMYNET, M_NOWAIT | M_ZERO); + if (q == NULL) { + printf("%s: no memory for new queue\n", __FUNCTION__); + return NULL; + } + + set_oid(&q->ni.oid, DN_QUEUE, 0, size); + q->ni.id = *id; + q->fs = fs; + q->si = template->si; + fs->refcnt++; -/*--- support functions for the sch_inst hashtable ----*/ + if (fs->sched->fp->new_queue) + fs->sched->fp->new_queue(q); + dn_cfg.queue_count++; + return q; +} +/*--- support functions for the sch_inst hashtable ---- + * + * These are hashed by flow-id + */ static int si_hash(uintptr_t key, int flags, void *arg) { @@ -236,7 +293,6 @@ si_new(uintptr_t key, int flags, void *a struct new_sch_inst *si; int l = sizeof(*si) + s->fp->sch_inst_len; - // printf("%s for sched %d len %d\n", __FUNCTION__, s->sch.sched_nr, l); si = malloc(l, M_DUMMYNET, M_NOWAIT | M_ZERO); if (si == NULL) goto error; @@ -258,9 +314,6 @@ si_new(uintptr_t key, int flags, void *a goto error; } } - - /* Initialize list of queues attached here */ - SLIST_INIT(&si->ql_list); if (s->sch.flags & DN_HAVE_MASK) si->ni.id = *(struct ipfw_flow_id *)key; @@ -275,6 +328,8 @@ error: /* * Callback for the hashtable scan. + * We assume that all flowset have been notified and do not + * point to us anymore. * Remove si and delay line from the system heap, destroy all queues. */ static int @@ -283,22 +338,19 @@ si_destroy(void *_si, void *arg) struct new_sch_inst *si = _si; struct new_schk *s = si->sched; struct delay_line *dl = &si->dline; - struct new_queue *q; - if (si->kflags & DN_ACTIVE) /* is in the heap */ + if (dl->oid.subtype) /* remove delay line from event heap */ + heap_extract(&dn_cfg.evheap, dl); + dn_free_pkts(dl->mq.head); /* drain delay line */ + if (si->kflags & DN_ACTIVE) /* remove si from event heap */ heap_extract(&dn_cfg.evheap, si); if (s->fp->free_sched) s->fp->free_sched(si); - if (dl->oid.subtype) /* is in the heap */ - heap_extract(&dn_cfg.evheap, dl); - dn_free_pkts(dl->mq.head); - while ( (q = SLIST_FIRST(&si->ql_list)) ) { - dn_delete_queue(q); - } free(si, M_DUMMYNET); dn_cfg.si_count--; return 0; } +/*---- end of sch_inst hashtable ---------------------*/ /* * Find the scheduler instance for this packet. If we need to apply @@ -316,103 +368,137 @@ ipdn_si_find(struct new_schk *s, struct } else { struct ipfw_flow_id id_t = *id; flow_id_mask(&s->sch.sched_mask, &id_t); - si = dn_ht_find(s->siht, (uintptr_t)&id_t, DNHT_INSERT); + si = dn_ht_find(s->siht, (uintptr_t)&id_t, DNHT_INSERT, s); } return si; } -/*---- support functions for flowset hash table ----*/ -/* - * support to delete a flowset. Mark as delete, - * then check refcnt and free when it becomes 0 +/*------------------------------------------------------- + * flowset hash (fshash) support. Entries are hashed by fs_nr. + * New allocations are put in the fsunlinked list, from which + * they are removed when they point to a specific scheduler. */ static int -fsk_destroy_cb(void *obj, void *arg) +fsk_hash(uintptr_t key, int flags, void *arg) +{ + int i = ((flags & DNHT_KEY_IS_OBJ) == 0) ? key : + ((struct new_fsk *)key)->fs.fs_nr; + + return ( (i>>8)^(i>>4)^i ); +} + +/* match skips entries those marked as deleted */ +static int +fsk_match(void *obj, uintptr_t key, int flags, void *arg) { struct new_fsk *fs = obj; - struct new_schk *s = fs->sched; + int i = ((flags & DNHT_KEY_IS_OBJ) == 0) ? key : + ((struct new_fsk *)key)->fs.fs_nr; + return !(fs->kflags & DN_DELETE) && (fs->fs.fs_nr == i); +} -printf("%s fs %d sched %d %p refcnt %d\n", __FUNCTION__, - fs->fs.fs_nr, - fs->fs.sched_nr, s, fs->refcnt); - fs->kflags |= DN_DELETE; - if (fs->refcnt == 0) { - dn_cfg.fsk_count--; - // always in a list, possibly the unlinked - // SLIST_REMOVE(&s->fsk_list, fs, new_fsk, sch_chain); - fs->sched = NULL; - free(fs, M_DUMMYNET); - printf("%s free done\n", __FUNCTION__); +static void * +fsk_new(uintptr_t key, int flags, void *arg) +{ + struct new_fsk *fs; + + fs = malloc(sizeof(*fs), M_DUMMYNET, M_NOWAIT | M_ZERO); + if (fs) { + dn_cfg.fsk_count++; + SLIST_INSERT_HEAD(&dn_cfg.fsu, fs, sch_chain); } - return HEAP_SCAN_DEL; + return fs; } - /* - * helper for schedulers. Creates a queue - * XXX actually, maybe only flowsets use this ? + * delete a flowset. Mark as delete, and free all when no refcount. + * Return 1 if freed, o otherwise. + * Removal from the hashtable must be done outside this function. */ -struct new_queue * -dn_create_queue(struct new_sch_inst *si, struct new_fsk *fs, - struct ipfw_flow_id *id) -{ - struct new_queue *q; - int size = sizeof(*q) + si->sched->fp->queue_len; +static int +fsk_destroy(struct new_fsk *fs) +{ + struct new_fsk_head *h; - q = malloc(size, M_DUMMYNET, M_NOWAIT | M_ZERO); - if (q == NULL) { - printf("dummynet: no memory for new queue\n"); - return NULL; - } + fs->kflags |= DN_DELETE; + if (fs->refcnt != 0) + return 0; + /* find the container list */ + h = fs->sched ? &fs->sched->fsk_list : &dn_cfg.fsu; + SLIST_REMOVE(h, fs, new_fsk, sch_chain); + dn_cfg.fsk_count--; + fs->sched = NULL; + if (fs->qht) + dn_ht_free(fs->qht, 0); + free(fs, M_DUMMYNET); + return 1; /* can remove from the ht */ +} +/*----- end of flowset hashtable support -------------*/ - set_oid(&q->ni.oid, DN_QUEUE, 0, size); - q->fs = fs; - q->si = si; - fs->refcnt++; +/* + * Destroy all flowsets in a list. Used when deleting a scheduler, + * or for all those in fsunlinked. + * For 'ipfw queue flush' we need a callback. + * (for those + */ +static void +fsk_destroy_list(struct new_fsk_head *h, struct new_fsk *int_fs) +{ + struct new_fsk *fs; - if (si->sched->fp->new_queue) - si->sched->fp->new_queue(q); - SLIST_INSERT_HEAD(&si->ql_list, q, si_chain); - dn_cfg.queue_count++; - return q; + while ((fs = SLIST_FIRST(h))) { + /* remember if the flowset is dying */ + int dying; + if (h == &dn_cfg.fsu) + fs->kflags |= DN_DELETE; + dying = fs->kflags & DN_DELETE; + printf("%s unlink flowset %d\n", + __FUNCTION__, fs->fs.fs_nr); + SLIST_REMOVE_HEAD(h, sch_chain); + if (fs == int_fs) { + /* free the internal flowset. + * XXX maybe do it same as others + */ + free(fs, M_DUMMYNET); + dn_cfg.fsk_count--; + } else if (fs->qht) + dn_ht_scan(fs->qht, dn_delete_queue, NULL); + + /* if not already gone, move to fsunlinked. + * The internal fs is marked DN_DELETE so it + * will go away. Also, we scan all flowsets + * so we are guaranteed that those marked DN_DELETE + * will be deleted. + */ + if (!dying) { + fs->sched = NULL; + SLIST_INSERT_HEAD(&dn_cfg.fsu, fs, sch_chain); + } + } } /* - * Delete a queue (helper for the schedulers) + * Delete a queue (helper for the schedulers and callback) + * Call th */ int -dn_delete_queue(struct new_queue *q) +dn_delete_queue(void *_q, void *foo) { + struct new_queue *q = _q; struct new_fsk *fs = q->fs; - if (SLIST_FIRST(&q->si->ql_list)) - SLIST_REMOVE(&q->si->ql_list, q, new_queue, si_chain); if (q->mq.head) dn_free_pkts(q->mq.head); if (fs && fs->sched->fp->free_queue) fs->sched->fp->free_queue(q); free(q, M_DUMMYNET); dn_cfg.queue_count--; - if (fs) { - fs->refcnt--; - if (fs->refcnt == 0 && fs->kflags & DN_DELETE) - fsk_destroy_cb(fs, NULL); - } + fs->refcnt--; + if (fs->refcnt == 0 && fs->kflags & DN_DELETE) + fsk_destroy(fs); return 0; } -/* destroy all scheduler instances but not the main scheduler */ -static struct new_schk * -schk_flush(struct new_schk *s) -{ - - if (s->sch.flags & DN_HAVE_MASK) { - dn_ht_scan(s->siht, si_destroy, NULL); - } else if (s->siht) - si_destroy(s->siht, NULL); - return NULL; -} - /* callback to flush credit for the pipe */ static int reset_credit(void *_si, void *arg) @@ -470,6 +556,14 @@ copy_data_helper(void *_o, void *_arg) if (a->flags & DN_C_SCH_INST) { printf("XXX todo: scan sched instances\n"); } + if (a->flags & DN_C_FS) { + struct new_fsk *fs = _o; + if (copy_obj(a->start, a->end, &fs->fs)) + return HEAP_SCAN_END; + } + if (a->flags & DN_C_QUEUE) { + printf("XXX todo: scan queue instances\n"); + } } if (a->type == DN_FS) { /* scanning flowsets */ struct new_fsk *fs = _o; @@ -479,25 +573,29 @@ copy_data_helper(void *_o, void *_arg) return 0; } -/* callback for sched delete */ +/* + * callback for sched delete. + * Tell all attached flowsets to remove their queues, + * unlink the flowsets. + */ static int schk_del_cb(void *obj, void *arg) { struct new_schk *s = obj; - struct new_fsk *fs; - printf("%s start for %d %p\n", __FUNCTION__, s->sch.sched_nr, s); - schk_flush((struct new_schk *)obj); - printf("XXX should delete all fs pointing to me\n"); - while ((fs = SLIST_FIRST(&s->fsk_list))) { - printf("%s unlink flowset %d from sched %d\n", __FUNCTION__, - fs->fs.fs_nr, s->sch.sched_nr); - SLIST_REMOVE_HEAD(&s->fsk_list, sch_chain); - fs->sched = NULL; - printf(" put flowset into fsunlinked\n"); - SLIST_INSERT_HEAD(&dn_cfg.fsunlinked, fs, sch_chain); + if (s->fs) { + /* remove the internal flowset from the hashtab */ + dn_ht_find(dn_cfg.fshash, s->fs->fs.fs_nr, DNHT_REMOVE, NULL); + s->fs->kflags |= DN_DELETE; } + fsk_destroy_list(&s->fsk_list, s->fs); + /* we should not have any flowset pointing to us now */ + if (s->sch.flags & DN_HAVE_MASK) { + dn_ht_scan(s->siht, si_destroy, NULL); + } else if (s->siht) + si_destroy(s->siht, NULL); free(obj, M_DUMMYNET); + dn_cfg.schk_count--; return HEAP_SCAN_DEL; } @@ -509,12 +607,10 @@ dummynet_flush(void) { DUMMYNET_LOCK(); - printf("%s start\n", __FUNCTION__); - /* first mark flowsets as delete, then go after queues */ - dn_ht_scan(dn_cfg.fshash, fsk_destroy_cb, 0); - printf("%s fsk_destroy_cb done\n", __FUNCTION__); - dn_ht_scan(dn_cfg.schedhash, schk_del_cb, 0); - + /* all schedulers and related pipes/queues/flowsets */ + dn_ht_scan(dn_cfg.schedhash, schk_del_cb, NULL); + /* all remaining (unlinked) flowsets */ + fsk_destroy_list(&dn_cfg.fsu, NULL); /* Reinitialize system heap... */ heap_init(&dn_cfg.evheap, 16, offsetof(struct dn_id, id)); @@ -525,7 +621,7 @@ dummynet_flush(void) static inline struct new_schk * locate_scheduler(int i) { - return dn_ht_find(dn_cfg.schedhash, i, 0); + return dn_ht_find(dn_cfg.schedhash, i, 0, NULL); } /* update all flowsets which may refer to this scheduler */ @@ -577,7 +673,6 @@ config_pipe(struct new_pipe *p, struct d i = p->pipe_nr; if (i <= 0 || i >= DN_MAX_ID) return EINVAL; - // printf("%s %d\n", __FUNCTION__, i); /* * The config program passes parameters as follows: * bw = bits/second (0 means no limits), @@ -626,7 +721,6 @@ config_fs(struct new_fs *nfs, struct dn_ return NULL; } i = nfs->fs_nr; - // printf("%s fs %d sched %d\n", __FUNCTION__, i, nfs->sched_nr); if (i <= 0 || i >= 3*DN_MAX_ID) return NULL; /* XXX other sanity checks */ @@ -642,7 +736,7 @@ config_fs(struct new_fs *nfs, struct dn_ if (!locked) DUMMYNET_LOCK(); again: - fs = dn_ht_find(dn_cfg.fshash, i, DNHT_INSERT); + fs = dn_ht_find(dn_cfg.fshash, i, DNHT_INSERT, NULL); if (fs == NULL) goto done; dn_cfg.id++; @@ -650,9 +744,16 @@ again: s = locate_scheduler(nfs->sched_nr); if (fs->sched == NULL) { /* no scheduler before */ if (s) { - /* have a new scheduler, remove from unlinked */ + /* have a new scheduler, remove from unlinked + * and add to the list of children of s + */ + SLIST_REMOVE(&dn_cfg.fsu, fs, new_fsk, sch_chain); fs->sched = s; - // XXX remove_from_unlinked(fs); + SLIST_INSERT_HEAD(&s->fsk_list, fs, sch_chain); + if (s->fp->flags & DN_MULTIQUEUE) + fs->qht = dn_ht_init(NULL, nfs->buckets, + offsetof(struct new_queue, q_next), + q_hash, q_match, q_new); } } else if (fs->sched != s) { /* scheduler changed. Let it die and recreate */ @@ -686,23 +787,22 @@ config_sched(struct new_sch *nsch, struc /* XXX other sanity checks */ DUMMYNET_LOCK(); again: /* run twice, for wfq and fifo */ - // printf("%s i %d\n", __FUNCTION__, i); - fp = load_scheduler(nsch->oid.subtype, nsch->type); + fp = find_sched_type(nsch->oid.subtype, nsch->type); if (fp == NULL) { DUMMYNET_UNLOCK(); printf("invalid scheduler type %d\n", nsch->oid.subtype); return EINVAL; } nsch->oid.subtype = fp->type; - nsch->oid.id = (uintptr_t)fp; /* used in schk_new() */ s = dn_ht_find(dn_cfg.schedhash, (uintptr_t)nsch, - DNHT_KEY_IS_OBJ | DNHT_INSERT); + DNHT_KEY_IS_OBJ | DNHT_INSERT, fp); if (s == NULL) { DUMMYNET_UNLOCK(); printf("cannot allocate scheduler\n"); return ENOMEM; } dn_cfg.id++; + notify_fs = 0; if (s->fp == NULL) { /* new scheduler, nothing to clean up */ notify_fs = 1; } else if (s->fp != fp) { @@ -731,14 +831,14 @@ again: /* run twice, for wfq and fifo */ /* call init function after the flowset is created */ if (s->fp->config) s->fp->config(s, 1); + if (notify_fs) + update_fs(s); if (i < DN_MAX_ID) { /* update the FIFO instance */ i += DN_MAX_ID; nsch->sched_nr = i; nsch->oid.subtype = DN_SCHED_FIFO; goto again; } - if (notify_fs) - update_fs(s); DUMMYNET_UNLOCK(); return 0; } @@ -809,12 +909,13 @@ config_profile(struct new_profile *pf, s static int del_fs(int i) { - struct new_fsk *fs = dn_ht_find(dn_cfg.fshash, i, DNHT_REMOVE); + struct new_fsk *fs = dn_ht_find(dn_cfg.fshash, i, DNHT_REMOVE, NULL); + + printf("%s fs %d found %p\n", __FUNCTION__, i, fs); if (fs) { - fsk_destroy_cb(fs, NULL); + fsk_destroy(fs); return 0; } else { - printf("%s: %d not found\n", __FUNCTION__, i); return EINVAL; } } @@ -822,12 +923,12 @@ del_fs(int i) static int del_schk(int i) { - struct new_schk *s = dn_ht_find(dn_cfg.schedhash, i, DNHT_REMOVE); + struct new_schk *s = dn_ht_find(dn_cfg.schedhash, i, DNHT_REMOVE, NULL); + printf("%s sched %d %p\n", __FUNCTION__, i, s); if (s) { schk_del_cb(s, NULL); return 0; } else { - printf("%s: %d not found\n", __FUNCTION__, i); return EINVAL; } } @@ -854,8 +955,6 @@ do_config(void *p, int l) break; } l -= o->len; - printf("%s cmd %d len %d left %d\n", - __FUNCTION__, o->type, o->len, l); next = (struct dn_id *)((char *)o + o->len); err = 0; switch (o->type) { @@ -869,13 +968,10 @@ do_config(void *p, int l) case DN_CMD_DELETE: switch (o->subtype) { case DN_PIPE: + /* delete base and derived schedulers */ if ( (err = del_schk(o->id)) ) break; - if ( (err = del_schk(o->id) + DN_MAX_ID) ) - break; - if ( (err = del_fs(o->id)) ) - break; - if ( (err = del_fs(o->id) + DN_MAX_ID) ) + if ( (err = del_schk(o->id + DN_MAX_ID)) ) break; *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-src-user@FreeBSD.ORG Fri Jan 15 18:31:44 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id C87D01065672; Fri, 15 Jan 2010 18:31:44 +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 B68D98FC19; Fri, 15 Jan 2010 18:31:44 +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 o0FIViqM054939; Fri, 15 Jan 2010 18:31:44 GMT (envelope-from luigi@svn.freebsd.org) Received: (from luigi@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0FIViJF054933; Fri, 15 Jan 2010 18:31:44 GMT (envelope-from luigi@svn.freebsd.org) Message-Id: <201001151831.o0FIViJF054933@svn.freebsd.org> From: Luigi Rizzo Date: Fri, 15 Jan 2010 18:31:44 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202407 - in user/luigi/ipfw3-head: sbin/ipfw sys/netinet sys/netinet/ipfw X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Jan 2010 18:31:45 -0000 Author: luigi Date: Fri Jan 15 18:31:44 2010 New Revision: 202407 URL: http://svn.freebsd.org/changeset/base/202407 Log: move profile to a better place. fix printing of queue parameters Modified: user/luigi/ipfw3-head/sbin/ipfw/dummynet.c user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Modified: user/luigi/ipfw3-head/sbin/ipfw/dummynet.c ============================================================================== --- user/luigi/ipfw3-head/sbin/ipfw/dummynet.c Fri Jan 15 17:55:18 2010 (r202406) +++ user/luigi/ipfw3-head/sbin/ipfw/dummynet.c Fri Jan 15 18:31:44 2010 (r202407) @@ -58,7 +58,7 @@ static struct _s_x dummynet_params[] = { { "proto", TOK_PROTO }, { "weight", TOK_WEIGHT }, { "all", TOK_ALL }, - //{ "mask", TOK_MASK }, + { "mask", TOK_MASK }, /* alias for both */ { "sched_mask", TOK_SCHED_MASK }, { "flow_mask", TOK_FLOW_MASK }, { "droptail", TOK_DROPTAIL }, @@ -68,7 +68,7 @@ static struct _s_x dummynet_params[] = { { "bandwidth", TOK_BW }, { "delay", TOK_DELAY }, { "pipe", TOK_PIPE }, - { "queue", TOK_FLOWSET }, + { "queue", TOK_QUEUE }, { "flowset", TOK_FLOWSET }, { "sched", TOK_SCHED }, { "pri", TOK_PRI }, @@ -245,9 +245,10 @@ list_queues(struct dn_flow_set *fs, stru align_uint64(&q[l].F)); } } +#endif static void -print_flowset_parms(struct dn_flow_set *fs, char *prefix) +print_flowset_parms(struct new_fs *fs, char *prefix) { int l; char qs[30]; @@ -255,7 +256,7 @@ print_flowset_parms(struct dn_flow_set * char red[90]; /* Display RED parameters */ l = fs->qsize; - if (fs->flags_fs & DN_QSIZE_IS_BYTES) { + if (fs->flags & DN_QSIZE_IS_BYTES) { if (l >= 8192) sprintf(qs, "%d KB", l / 1024); else @@ -266,6 +267,7 @@ print_flowset_parms(struct dn_flow_set * sprintf(plr, "plr %f", 1.0 * fs->plr / (double)(0x7fffffff)); else plr[0] = '\0'; +#if 0 if (fs->flags_fs & DN_IS_RED) /* RED parameters */ sprintf(red, "\n\t %cRED w_q %f min_th %d max_th %d max_p %f", @@ -275,14 +277,16 @@ print_flowset_parms(struct dn_flow_set * SCALE_VAL(fs->max_th), 1.0 * fs->max_p / (double)(1 << SCALE_RED)); else +#endif sprintf(red, "droptail"); printf("%s %s%s %d queues (%d buckets) %s\n", - prefix, qs, plr, fs->rq_elements, fs->rq_size, red); + prefix, qs, plr, fs->oid.id, fs->buckets, red); + prefix[0] = '\0'; } static void -print_extra_delay_parms(struct dn_pipe *p) +print_extra_delay_parms(struct new_profile *p) { double loss; if (p->samples_no <= 0) @@ -293,7 +297,6 @@ print_extra_delay_parms(struct dn_pipe * printf("\t profile: name \"%s\" loss %f samples %d\n", p->name, loss, p->samples_no); } -#endif static void flush_buf(char *buf) @@ -311,11 +314,10 @@ flush_buf(char *buf) static void list_pipes(struct dn_id *oid, struct dn_id *end, int *filt) { - char buf[80]; /* pending buffer */ + char buf[160]; /* pending buffer */ buf[0] = '\0'; for (; oid != end; oid = O_NEXT(oid, oid->len)) { - /* XXX check oid->len */ if (oid->len < sizeof(*oid)) errx(1, "invalid oid len %d\n", oid->len); @@ -342,14 +344,15 @@ list_pipes(struct dn_id *oid, struct dn_ sprintf(burst, "%ju Byte\n", p->burst); sprintf(buf, "%05d: %s %4d ms burst %s", p->pipe_nr, bwbuf, p->delay, burst); - // print_flowset_parms(&(p->fs), prefix); - // print_extra_delay_parms(p); } break; + case DN_FS: - flush_buf(buf); - printf("XXX flowset unimplemented\n"); + print_flowset_parms((struct new_fs *)oid, buf); break; + case DN_PROFILE: + flush_buf(buf); + print_extra_delay_parms((struct new_profile *)oid); } } flush_buf(buf); @@ -863,10 +866,12 @@ ipfw_config_pipe(int ac, char **av) case TOK_BUCKETS: NEED(fs, "buckets is only for pipes or flowsets"); NEED1("buckets needs argument\n"); - // XXX fs->rq_size = strtoul(av[0], NULL, 0); + fs->buckets = strtoul(av[0], NULL, 0); ac--; av++; break; + case TOK_FLOW_MASK: + case TOK_SCHED_MASK: case TOK_MASK: NEED(mask, "tok_mask"); NEED1("mask needs mask specifier\n"); Modified: user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h Fri Jan 15 17:55:18 2010 (r202406) +++ user/luigi/ipfw3-head/sys/netinet/ip_dummynet.h Fri Jan 15 18:31:44 2010 (r202407) @@ -119,12 +119,10 @@ struct new_pipe { * The kernel converts this back and forth to bits/tick and ticks. * XXX what about burst ? */ - int32_t pipe_nr ; /* N, number */ - int bandwidth; /* B, really, bits/tick. */ - int delay ; /* D, really, ticks */ - uint64_t burst; /* burst size, scaled. bits*Hz XXX */ - - struct new_profile *profile; + int32_t pipe_nr; + int bandwidth; /* bit/s or bits/tick. */ + int delay; /* ms and ticks */ + uint64_t burst; /* scaled. bits*Hz XXX */ }; /* Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Fri Jan 15 17:55:18 2010 (r202406) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Fri Jan 15 18:31:44 2010 (r202407) @@ -287,16 +287,16 @@ transmit_event(struct mq *q, struct dela * in milliseconds so we need to divide by 1000. */ static uint64_t -extra_bits(struct mbuf *m, struct new_pipe *p) +extra_bits(struct mbuf *m, struct new_schk *s) { int index; uint64_t bits; - struct new_profile *pf = p->profile; + struct new_profile *pf = s->profile; if (!pf || pf->samples_no == 0) return 0; index = random() % pf->samples_no; - bits = div64((uint64_t)pf->samples[index] * p->bandwidth, 1000); + bits = div64((uint64_t)pf->samples[index] * s->pipe.bandwidth, 1000); if (index >= pf->loss_level) { struct dn_pkt_tag *dt = dn_tag_get(m); if (dt) @@ -339,7 +339,7 @@ serve_sched(struct mq *q, struct new_sch uint64_t len_scaled; done++; len_scaled = bw == 0 ? 0 : hz * - (m->m_pkthdr.len * 8 + extra_bits(m, &s->pipe)); + (m->m_pkthdr.len * 8 + extra_bits(m, s)); si->credit -= len_scaled; /* Move packet in the delay line */ dn_tag_get(m)->output_time += s->pipe.delay ; Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h Fri Jan 15 17:55:18 2010 (r202406) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h Fri Jan 15 18:31:44 2010 (r202407) @@ -115,7 +115,7 @@ struct delay_line { * there is no flow_mask). * When we remove a flowset, mark as DN_DELETE so it can go away * when the hash table will be empty. - * XXX refcnt is redundant. + * XXX refcnt is redundant, the info is already in qht->entries */ struct new_fsk { /* kernel side of a flowset */ struct new_fs fs; @@ -160,6 +160,7 @@ struct new_schk { int kflags; struct dn_sched *fp; /* Pointer to scheduler functions */ struct new_pipe pipe; /* the pipe is embedded */ + struct new_profile *profile; struct dn_id *cfg; /* extra config arguments */ SLIST_ENTRY(new_schk) schk_next; /* hash chain list */ Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Fri Jan 15 17:55:18 2010 (r202406) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Fri Jan 15 18:31:44 2010 (r202407) @@ -90,7 +90,7 @@ dn_reschedule(void) static struct dn_sched * find_sched_type(int type, char *name) { - struct dn_sched *d = NULL; + struct dn_sched *d; SLIST_FOREACH(d, &dn_cfg.schedlist, next) { if (d->type == type || (name && !strcmp(d->name, name))) @@ -168,9 +168,10 @@ static int flow_id_cmp(struct ipfw_flow_id *id1, struct ipfw_flow_id *id2) { int is_v6 = IS_IP6_FLOW_ID(id1); + if (is_v6 != IS_IP6_FLOW_ID(id2)) return 1; /* a ipv4 and a ipv6 flow */ - + if (!is_v6 && id1->dst_ip == id2->dst_ip && id1->src_ip == id2->src_ip && id1->dst_port == id2->dst_port && @@ -204,6 +205,7 @@ q_hash(uintptr_t key, int flags, void *a struct ipfw_flow_id *id = (flags & DNHT_KEY_IS_OBJ) ? &((struct new_queue *)key)->ni.id : (struct ipfw_flow_id *)key; + return flow_id_hash(id); } @@ -263,22 +265,19 @@ si_hash(uintptr_t key, int flags, void * struct ipfw_flow_id *id = (flags & DNHT_KEY_IS_OBJ) ? &((struct new_sch_inst *)key)->ni.id : (struct ipfw_flow_id *)key; + return flow_id_hash(id); } static int si_match(void *obj, uintptr_t key, int flags, void *arg) { - struct new_sch_inst *o; + struct new_sch_inst *o = obj; struct ipfw_flow_id *id2; - if (flags & DNHT_KEY_IS_OBJ) { - /* compare pointers */ - id2 = &((struct new_sch_inst *)key)->ni.id; - } else { - id2 = (struct ipfw_flow_id *)key; - } - o = (struct new_sch_inst *)obj; + id2 = (flags & DNHT_KEY_IS_OBJ) ? + &((struct new_sch_inst *)key)->ni.id : + (struct ipfw_flow_id *)key; return flow_id_cmp(&o->ni.id, id2) == 0; } @@ -361,7 +360,7 @@ ipdn_si_find(struct new_schk *s, struct { struct new_sch_inst *si; - if ( 0 == (s->sch.flags & DN_HAVE_MASK) ) { + if (!(s->sch.flags & DN_HAVE_MASK)) { if (s->siht == NULL) s->siht = si_new((uintptr_t)id, 0, s); si = (struct new_sch_inst *)s->siht; @@ -394,6 +393,7 @@ fsk_match(void *obj, uintptr_t key, int struct new_fsk *fs = obj; int i = ((flags & DNHT_KEY_IS_OBJ) == 0) ? key : ((struct new_fsk *)key)->fs.fs_nr; + return !(fs->kflags & DN_DELETE) && (fs->fs.fs_nr == i); } @@ -404,6 +404,7 @@ fsk_new(uintptr_t key, int flags, void * fs = malloc(sizeof(*fs), M_DUMMYNET, M_NOWAIT | M_ZERO); if (fs) { + set_oid(&fs->fs.oid, DN_FS, 0, sizeof(fs->fs)); dn_cfg.fsk_count++; SLIST_INSERT_HEAD(&dn_cfg.fsu, fs, sch_chain); } @@ -523,9 +524,14 @@ static int copy_obj(char **start, char *end, void *_o) { struct dn_id *o = _o; + int have = end - *start; - if (end - *start < o->len) + if (have < o->len) { + printf("%s overflow type %d have %d need %d\n", + __FUNCTION__, o->type, have, o->len); return 1; + } + printf("%s type %d len %d\n", __FUNCTION__, o->type, o->len); bcopy(_o, *start, o->len); *start += o->len; return 0; @@ -542,12 +548,15 @@ struct copy_args { static int copy_data_helper(void *_o, void *_arg) { - struct copy_args *a = (struct copy_args *)_arg; + struct copy_args *a = _arg; + if (a->type == DN_SCH) { /* scanning schedulers */ struct new_schk *s = _o; if (a->flags & DN_C_PIPE) { if (copy_obj(a->start, a->end, &s->pipe)) return HEAP_SCAN_END; + if (s->fs && copy_obj(a->start, a->end, &s->fs->fs)) + return HEAP_SCAN_END; } if (a->flags & DN_C_SCH) { if (copy_obj(a->start, a->end, &s->sch)) @@ -556,19 +565,14 @@ copy_data_helper(void *_o, void *_arg) if (a->flags & DN_C_SCH_INST) { printf("XXX todo: scan sched instances\n"); } - if (a->flags & DN_C_FS) { - struct new_fsk *fs = _o; - if (copy_obj(a->start, a->end, &fs->fs)) - return HEAP_SCAN_END; - } - if (a->flags & DN_C_QUEUE) { - printf("XXX todo: scan queue instances\n"); - } } if (a->type == DN_FS) { /* scanning flowsets */ struct new_fsk *fs = _o; + struct new_fs *ufs = + (struct new_fs *)(*a->start); if (copy_obj(a->start, a->end, &fs->fs)) return HEAP_SCAN_END; + ufs->oid.id = fs->refcnt; } return 0; } @@ -827,6 +831,9 @@ again: /* run twice, for wfq and fifo */ fs.fs_nr = i + DN_MAX_ID; fs.sched_nr = i; s->fs = config_fs(&fs, NULL, 1 /* locked */); + printf("+++ sched %d fs %p len %d ty %d\n", + s->sch.sched_nr, + s->fs, s->fs->fs.oid.len, s->fs->fs.oid.type); } /* call init function after the flowset is created */ if (s->fp->config) @@ -850,7 +857,6 @@ static int config_profile(struct new_profile *pf, struct dn_id *arg) { struct new_schk *s; - struct new_pipe *p; int i; if (pf->oid.len < sizeof(*pf)) { @@ -870,16 +876,15 @@ config_profile(struct new_profile *pf, s printf("%s: no scheduler %d\n", __FUNCTION__, i); return EINVAL; } - p = &s->pipe; dn_cfg.id++; /* * If we had a profile and the new one does not fit, * or it is deleted, then we need to free memory. */ - if (p->profile && (pf->samples_no == 0 || - p->profile->oid.len < pf->oid.len)) { - free(p->profile, M_DUMMYNET); - p->profile = NULL; + if (s->profile && (pf->samples_no == 0 || + s->profile->oid.len < pf->oid.len)) { + free(s->profile, M_DUMMYNET); + s->profile = NULL; } /* * if we have a new profile, possibly allocate memory @@ -887,20 +892,20 @@ config_profile(struct new_profile *pf, s */ if (pf->samples_no > 0) { int olen; - if (p->profile == NULL) - p->profile = malloc(pf->oid.len, + if (s->profile == NULL) + s->profile = malloc(pf->oid.len, M_DUMMYNET, M_NOWAIT | M_ZERO); - if (p->profile == NULL) { + if (s->profile == NULL) { DUMMYNET_UNLOCK(); printf("%s: no memory\n", __FUNCTION__); return ENOMEM; } /* preserve larger length */ - olen = p->profile->oid.len; + olen = s->profile->oid.len; if (olen < pf->oid.len) olen = pf->oid.len; - bcopy(pf, p->profile, pf->oid.len); - p->profile->oid.len = olen; + bcopy(pf, s->profile, pf->oid.len); + s->profile->oid.len = olen; } DUMMYNET_UNLOCK(); return 0; @@ -1018,23 +1023,31 @@ do_config(void *p, int l) static int compute_space(struct dn_id *cmd, int *to_copy) { - int need; + int x = 0, need = 0; - *to_copy = 0; switch (cmd->subtype) { default: return -1; case DN_SCH: /* pipe show */ - *to_copy = DN_C_SCH | DN_C_PIPE | DN_C_SCH_INST | DN_C_QUEUE; - need = dn_cfg.schk_count * - (sizeof(struct new_sch) + sizeof(struct new_pipe)); - need += dn_cfg.si_count * sizeof(struct new_inst); + x = DN_C_SCH | DN_C_PIPE | DN_C_FS | + DN_C_SCH_INST | DN_C_QUEUE; break; case DN_FS: /* queue show */ - *to_copy = DN_C_FS | DN_C_QUEUE; - need = dn_cfg.fsk_count * (sizeof(struct new_fs)); + x = DN_C_FS | DN_C_QUEUE; break; } + *to_copy = x; + if (x & DN_C_SCH) + need += dn_cfg.schk_count * sizeof(struct new_sch); + if (x & DN_C_FS) + need += dn_cfg.fsk_count * sizeof(struct new_fs); + if (x & DN_C_PIPE) + need += dn_cfg.schk_count * sizeof(struct new_pipe); + /* XXX queue space might be variable */ + if (x & DN_C_QUEUE) + need += dn_cfg.queue_count * sizeof(struct new_queue); + if (x & DN_C_SCH_INST) + need += dn_cfg.si_count * sizeof(struct new_inst); return need; } @@ -1092,8 +1105,10 @@ dummynet_get(struct sockopt *sopt) a.flags = to_copy; a.type = DN_SCH; dn_ht_scan(dn_cfg.schedhash, copy_data_helper, &a); +#if 0 // XXX temporarily disable a.type = DN_FS; dn_ht_scan(dn_cfg.fshash, copy_data_helper, &a); +#endif } DUMMYNET_UNLOCK(); error = sooptcopyout(sopt, start, buf - start); From owner-svn-src-user@FreeBSD.ORG Fri Jan 15 23:02:19 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B883E1065697; Fri, 15 Jan 2010 23: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 A7D7C8FC18; Fri, 15 Jan 2010 23: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 o0FN2J10015586; Fri, 15 Jan 2010 23: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 o0FN2JdX015583; Fri, 15 Jan 2010 23:02:19 GMT (envelope-from luigi@svn.freebsd.org) Message-Id: <201001152302.o0FN2JdX015583@svn.freebsd.org> From: Luigi Rizzo Date: Fri, 15 Jan 2010 23:02:19 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202422 - user/luigi/ipfw3-head/sys/netinet/ipfw X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Jan 2010 23:02:19 -0000 Author: luigi Date: Fri Jan 15 23:02:19 2010 New Revision: 202422 URL: http://svn.freebsd.org/changeset/base/202422 Log: add a method to return the number of entries. Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c Fri Jan 15 22:19:51 2010 (r202421) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.c Fri Jan 15 23:02:19 2010 (r202422) @@ -373,6 +373,12 @@ dn_ht_free(struct dn_ht *ht, int flags) free(ht, M_DN_HEAP); } +int +dn_ht_entries(struct dn_ht *ht) +{ + return ht->entries; +} + /* lookup and optionally create or delete element */ void * dn_ht_find(struct dn_ht *ht, uintptr_t key, int flags, void *arg) Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h Fri Jan 15 22:19:51 2010 (r202421) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_heap.h Fri Jan 15 23:02:19 2010 (r202422) @@ -162,6 +162,7 @@ void dn_ht_free(struct dn_ht *, int flag void *dn_ht_find(struct dn_ht *, uintptr_t, int, void *); int dn_ht_scan(struct dn_ht *, int (*)(void *, void *), void *); +int dn_ht_entries(struct dn_ht *); enum { /* flags values. * first two are returned by the scan callback to indicate From owner-svn-src-user@FreeBSD.ORG Fri Jan 15 23:02:46 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id C354E1065692; Fri, 15 Jan 2010 23:02:46 +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 9941E8FC12; Fri, 15 Jan 2010 23:02:46 +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 o0FN2kYo015725; Fri, 15 Jan 2010 23:02:46 GMT (envelope-from luigi@svn.freebsd.org) Received: (from luigi@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0FN2kOW015723; Fri, 15 Jan 2010 23:02:46 GMT (envelope-from luigi@svn.freebsd.org) Message-Id: <201001152302.o0FN2kOW015723@svn.freebsd.org> From: Luigi Rizzo Date: Fri, 15 Jan 2010 23:02:46 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202423 - user/luigi/ipfw3-head/sys/netinet/ipfw X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Jan 2010 23:02:46 -0000 Author: luigi Date: Fri Jan 15 23:02:46 2010 New Revision: 202423 URL: http://svn.freebsd.org/changeset/base/202423 Log: update docs Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dummynet.txt Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dummynet.txt ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dummynet.txt Fri Jan 15 23:02:19 2010 (r202422) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dummynet.txt Fri Jan 15 23:02:46 2010 (r202423) @@ -133,33 +133,22 @@ KERNEL REPRESENTATION DELETE: manual, see new_sch_inst - +--------------+ - +------------+ ptr_sched | fsk_list | - | NEW_FSK |--------------->| NEW_SCHK |<----. - | refcnt | | new_pipe | | - | sch_chain | +--------------+ | - +------------+ | hash table | | - ^ | (m1) | | - | +--------------+ | - | | ..... \ | - -----------+ ... v \ | - | NEW_QUEUE |<-----| -------------- ` | - +-----------+ | | | | | - .... | | new_sch_inst | | | - -----------+ | | | | | - | NEW_QUEUE |<-----| -------------- | | - +-----------+ | v | - | .--------------. -------------- | - | | hash table | | | | - | | (m2) + |<-----| NEW_SCH_INST |_| - | | new_sch_inst | | ql_head | - | `--------------' -------------- - | ^ - | | - `---------------------------------' - -Note that the hash table m2 is not mandatory, a scheduler instance -can use its own struct to store its queues + fshash schedhash + +---------------+ sched +--------------+ + | sched-------------------->| NEW_SCHK| + -<----*sch_chain |<-----------------*fsk_list | + |NEW_FSK |<----. | [new_pipe] | + +---------------+ | +--------------+ + |qht (hash) | | | siht(hash) | + | [new_queue] | | | [new_si] | + | [new_queue] | | | [new_si] | + | ... | | | ... | + | +---------+ | | | +---------+ | + | |new_queue| | | | |new_si | | + | | fs *----------' | | | | + | | si *---------------------->| | | + | +---------+ | | +---------+ | + +---------------+ +--------------+ The following global data structures contain all schedulers and flowsets. From owner-svn-src-user@FreeBSD.ORG Fri Jan 15 23:03:51 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 8E9B6106568F; Fri, 15 Jan 2010 23:03:51 +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 7C8EC8FC0A; Fri, 15 Jan 2010 23:03:51 +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 o0FN3pib016006; Fri, 15 Jan 2010 23:03:51 GMT (envelope-from luigi@svn.freebsd.org) Received: (from luigi@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0FN3pES015999; Fri, 15 Jan 2010 23:03:51 GMT (envelope-from luigi@svn.freebsd.org) Message-Id: <201001152303.o0FN3pES015999@svn.freebsd.org> From: Luigi Rizzo Date: Fri, 15 Jan 2010 23:03:51 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202424 - user/luigi/ipfw3-head/sys/netinet/ipfw X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Jan 2010 23:03:51 -0000 Author: luigi Date: Fri Jan 15 23:03:51 2010 New Revision: 202424 URL: http://svn.freebsd.org/changeset/base/202424 Log: a bit of renaming and cleanup. implement update_fs() -- seems to be working. Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h Fri Jan 15 23:02:46 2010 (r202423) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched.h Fri Jan 15 23:03:51 2010 (r202424) @@ -1,6 +1,5 @@ /* - * Copyright (c) 2010 Riccardo Panicucci, Universita` di Pisa - * Copyright (c) 1998-2002,2010 Luigi Rizzo, Universita` di Pisa + * Copyright (c) 2010 Riccardo Panicucci, Luigi Rizzo, Universita` di Pisa * All rights reserved * * Redistribution and use in source and binary forms, with or without @@ -110,19 +109,22 @@ struct dn_sched { }; /* - * Additionally, dummynet exports some variables, functions and macros - * to be used by schedulers. + * Additionally, dummynet exports some functions and macros + * to be used by schedulers: */ -/* delete a queue, which we assume nobody references */ -int dn_delete_queue(void *, void *propagate); -int dn_queue_packet(struct new_queue *q, struct mbuf* m, int drop); +/* delete a queue, which we assume nobody references. + * if do_free is set, propagate to the flowset and destroy it + * if the refcount becomes 0 + */ +int dn_delete_queue(void *, void *do_free); +int dn_enqueue(struct new_queue *q, struct mbuf* m, int drop); /* * Extract the head of a queue, update stats. Must be the very last * thing done on a dequeue as the queue itself may go away. */ static __inline struct mbuf* -dn_return_packet(struct new_queue *q) +dn_dequeue(struct new_queue *q) { struct mbuf *m = q->mq.head; KASSERT(m != NULL, ("empty queue to dn_return_packet")); @@ -134,7 +136,7 @@ dn_return_packet(struct new_queue *q) q->si->ni.len_bytes -= m->m_pkthdr.len; } if (q->mq.head == NULL && q->fs && q->fs->kflags & DN_DELETE) - dn_delete_queue(q, (void *)1 /* possibly flush flowset */); + dn_delete_queue(q, (void *)1 /* free if possible */); return m; } Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c Fri Jan 15 23:02:46 2010 (r202423) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_fifo.c Fri Jan 15 23:03:51 2010 (r202424) @@ -42,66 +42,34 @@ #include #include #include + /* - * This file implements a FIFO scheduler. - * A FIFO scheduler is a simple scheduler algorithm that can be use to - * scheduling internet packets. - * The scheduler receive a packet (by enqueue() function) and put in in the - * unique queue that manages. - * When the scheduler can transmit, the first packet in the queue is sent - * out (First In First Out) - * The complexity of this algorithm is O(1), all flows use the same queue. - * - * No parameters are required to configure a FIFO scheduler or a - * FIFO flowset. - * + * This file implements a FIFO scheduler for a single queue. + * The queue is allocated as part of the scheduler instance, + * and there is a single flowset is in the template which stores + * queue-related information. + * No parameters are used except queue sizes and management policy. + * Enqueue and dequeue use the default library functions. */ - static int -fifo_enqueue(struct new_sch_inst *_si, struct new_queue *q, struct mbuf *m) +fifo_enqueue(struct new_sch_inst *si, struct new_queue *q, struct mbuf *m) { - int ret; - q = (struct new_queue *)(_si+1); - ret = dn_queue_packet(q, m, 0); - if (ret) { - printf("%s dn_queue_packet dropped\n", __FUNCTION__); - return 1; - } - return 0; + return dn_enqueue((struct new_queue *)(si+1), m, 0); } static struct mbuf * -fifo_dequeue(struct new_sch_inst *_si) +fifo_dequeue(struct new_sch_inst *si) { - /* - * The dequeue() function is called by the system when the scheduler - * instance can transmit packets. The dequeue() is called until the - * instance has credit and packet to send. - * If the scheduler wants to dequeue a packet, it should call the - * dn_return_packet() function, that take a packet pkt and the relative - * queue and update. - * If the queue is empty, no packet can be send and the dequeue() must - * return NULL. - */ - - /* Access scheduler instance private data */ - struct new_queue *q = (struct new_queue *)(_si + 1); - - if (q->mq.head == NULL) - return NULL; - - return dn_return_packet(q); + return dn_dequeue((struct new_queue *)(si + 1)); } static int fifo_new_sched(struct new_sch_inst *si) { - /* This scheduler instance only has a queue pointer. */ + /* This scheduler instance contains the queue */ struct new_queue *q = (struct new_queue *)(si + 1); - set_oid(&q->ni.oid, DN_QUEUE, 0, sizeof(*q)); - // XXX SLIST_INSERT_HEAD(&si->ql_list, q, si_chain); - + set_oid(&q->ni.oid, DN_QUEUE, sizeof(*q)); q->si = si; q->fs = si->sched->fs; return 0; @@ -109,20 +77,18 @@ fifo_new_sched(struct new_sch_inst *si) /* * FIFO scheduler descriptor - * contains the type of the scheduler, the name, the size of the various - * structures and function pointers. If a function is not implemented, - * the pointer is initialized to NULL + * contains the type of the scheduler, the name, the size of extra + * data structures, and function pointers. */ static struct dn_sched fifo_desc = { - .type = DN_SCHED_FIFO, - .name = "FIFO", - - .sch_inst_len = sizeof(struct new_queue), + .type = DN_SCHED_FIFO, + .name = "FIFO", - .enqueue = fifo_enqueue, - .dequeue = fifo_dequeue, + .sch_inst_len = sizeof(struct new_queue), - .new_sched = fifo_new_sched, + .enqueue = fifo_enqueue, + .dequeue = fifo_dequeue, + .new_sched = fifo_new_sched, }; DECLARE_DNSCHED_MODULE(dn_fifo, &fifo_desc); Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c Fri Jan 15 23:02:46 2010 (r202423) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c Fri Jan 15 23:03:51 2010 (r202424) @@ -24,7 +24,7 @@ * SUCH DAMAGE. */ -/* XXX this is only a stub for wf2q+ */ +#ifdef _KERNEL #include #include #include @@ -35,69 +35,41 @@ #include #include /* ipfw_rule_ref */ #include /* flow_id */ +#else +#include "dn_test.h" +#endif #include #include #include #include /* - * This file implements a FIFO scheduler. - * A FIFO scheduler is a simple scheduler algorithm that can be use to - * scheduling internet packets. - * The scheduler receive a packet (by enqueue() function) and put in in the - * unique queue that manages. - * When the scheduler can transmit, the first packet in the queue is sent - * out (First In First Out) - * The complexity of this algorithm is O(1), all flows use the same queue. - * - * No parameters are required to configure a FIFO scheduler or a - * FIFO flowset. - * + * This file implements a FIFO scheduler for a single queue. + * The queue is allocated as part of the scheduler instance, + * and there is a single flowset is in the template which stores + * queue-related information. + * No parameters are used except queue sizes and management policy. + * Enqueue and dequeue use the default library functions. */ - static int fifo_enqueue(struct new_sch_inst *si, struct new_queue *q, struct mbuf *m) { - q = (struct new_queue *)(si+1); - if (dn_queue_packet(q, m, 0)) - return 1; - - /* Ok, the packet is now in the queue. - * The dequeue() function will be called when the scheduler - * instance has credit to transmit packets - */ - return 0; + return dn_enqueue((struct new_queue *)(si+1), m, 0); } static struct mbuf * -fifo_dequeue(struct new_sch_inst *_si) +fifo_dequeue(struct new_sch_inst *si) { - /* - * The dequeue() function is called by the system when the scheduler - * instance can transmit packets. The dequeue() is called until the - * instance has credit and packet to send. - * If the scheduler wants to dequeue a packet, it should call the - * dn_return_packet() function, that take a packet pkt and the relative - * queue and update. - * If the queue is empty, no packet can be send and the dequeue() must - * return NULL. - */ - - /* Access scheduler instance private data */ - struct new_queue *q = (struct new_queue *)(_si + 1); - - if (q->mq.head == NULL) - return NULL; - - return dn_return_packet(q); + return dn_dequeue((struct new_queue *)(si + 1)); } static int -wf2q_new_sched(struct new_sch_inst *si) +wf2qp_new_sched(struct new_sch_inst *si) { - /* This scheduler instance only has a queue pointer. */ + /* This scheduler instance contains the queue */ struct new_queue *q = (struct new_queue *)(si + 1); + set_oid(&q->ni.oid, DN_QUEUE, sizeof(*q)); q->si = si; q->fs = si->sched->fs; return 0; @@ -105,20 +77,18 @@ wf2q_new_sched(struct new_sch_inst *si) /* * FIFO scheduler descriptor - * contains the type of the scheduler, the name, the size of the various - * structures and function pointers. If a function is not implemented, - * the pointer is initialized to NULL + * contains the type of the scheduler, the name, the size of extra + * data structures, and function pointers. */ static struct dn_sched fifo_desc = { - .type = DN_SCHED_WF2QP, - .name = "WF2Q+", - - .sch_inst_len = sizeof(struct new_queue), + .type = DN_SCHED_WF2QP, + .name = "WF2QP", - .enqueue = fifo_enqueue, - .dequeue = fifo_dequeue, + .sch_inst_len = sizeof(struct new_queue), - .new_sched = wf2q_new_sched, + .enqueue = fifo_enqueue, + .dequeue = fifo_dequeue, + .new_sched = wf2qp_new_sched, }; DECLARE_DNSCHED_MODULE(dn_wf2qp, &fifo_desc); Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Fri Jan 15 23:02:46 2010 (r202423) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Fri Jan 15 23:03:51 2010 (r202424) @@ -215,7 +215,7 @@ mq_append(struct mq *q, struct mbuf *m) * Return 0 on success, 1 on drop. The packet is consumed anyways. */ int -dn_queue_packet(struct new_queue *q, struct mbuf* m, int drop) +dn_enqueue(struct new_queue *q, struct mbuf* m, int drop) { struct new_fs *f; struct new_inst *ni; /* stats for scheduler instance */ Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h Fri Jan 15 23:02:46 2010 (r202423) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_private.h Fri Jan 15 23:03:51 2010 (r202424) @@ -30,7 +30,6 @@ /* * internal dummynet APIs. */ -#define div64(a, b) ((int64_t)(a) / (int64_t)(b)) MALLOC_DECLARE(M_DUMMYNET); @@ -53,13 +52,15 @@ SLIST_HEAD(new_queue_head, new_queue); SLIST_HEAD(dn_sched_head, dn_sched); /* - * global configuration parameters. + * configuration and global data for a dummynet instance * * When a configuration is modified from userland, 'id' is incremented * so we can use the value to check for stale pointers. */ struct dn_parms { uint32_t id; /* configuration version */ + + /* defaults (sysctl-accessible) */ int red_lookup_depth; int red_avg_pkt_size; int red_max_pkt_size; @@ -68,6 +69,8 @@ struct dn_parms { long pipe_slot_limit; int io_fast; + + /* timekeeping */ struct timeval prev_t; /* last time dummynet_tick ran */ struct dn_heap evheap; /* scheduled events */ @@ -77,6 +80,10 @@ struct dn_parms { int fsk_count; int queue_count; + /* flowsets and schedulers are in hash tables, whose size + * is programmable. fshash is looked up at every packet arrival + * so better be generous if we expect many entries. + */ int buckets; /* for the hash tables below */ struct dn_ht *fshash; struct dn_ht *schedhash; @@ -86,11 +93,11 @@ struct dn_parms { }; static inline void -set_oid(struct dn_id *o, int type, int subtype, int len) +set_oid(struct dn_id *o, int type, int len) { o->type = type; - o->subtype = subtype; o->len = len; + o->subtype = 0; }; struct mq { /* a basic queue of packets*/ @@ -184,10 +191,7 @@ struct new_sch_inst { SLIST_ENTRY(new_sch_inst) si_next; /* next item in the bucket */ struct delay_line dline; struct new_schk *sched; /* the template */ - int kflags; /* DN_SCHED_ACTIVE */ - - /* queues attached to this scheduler instance */ - struct new_queue_head ql_list; + int kflags; /* DN_ACTIVE */ int64_t credit; /* bits I can transmit (more or less). */ dn_key sched_time ; /* time pipe was scheduled in ready_heap */ @@ -196,24 +200,17 @@ struct new_sch_inst { /* kernel-side flags */ enum { - DN_DELETE = 0x0004, /* destroy when refcnt=0 */ - DN_REENQUEUE = 0x0008, /* (k) */ - DN_ACTIVE = 0x0010, /* (k) */ - DN_FORCE = 0x0080 + DN_DELETE = 0x0004, /* destroy when refcnt=0 */ + DN_ACTIVE = 0x0010, /* object is in evheap */ + DN_F_DLINE = 0x0020, /* object is a delay line */ + DN_F_SCHI = 0x0030, /* object is a sched.instance */ }; extern struct dn_parms dn_cfg; -struct new_pipe *ipdn_locate_pipe(int); -struct new_fsk *ipdn_locate_flowset(int); int dummynet_io(struct mbuf **, int , struct ip_fw_args *); void dummynet_task(void *context, int pending); void dn_reschedule(void); -int dn_fs_config(struct new_fsk *); -struct new_queue * -dn_create_queue(struct new_sch_inst *si, struct new_fsk *f, - struct ipfw_flow_id *id); - struct new_sch_inst *ipdn_si_find(struct new_schk *s, struct ipfw_flow_id *id); Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Fri Jan 15 23:02:46 2010 (r202423) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Fri Jan 15 23:03:51 2010 (r202424) @@ -58,8 +58,6 @@ __FBSDID("$FreeBSD$"); #include #include -static int ip_dn_ctl(struct sockopt *sopt); - /* which objects to copy */ #define DN_C_PIPE 0x01 #define DN_C_SCH 0x02 @@ -104,7 +102,7 @@ find_sched_type(int type, char *name) * need to free extra state associated to a packet, this is a * central point to do it. */ -static __inline void dn_free_pkts(struct mbuf *mnext) +static void dn_free_pkts(struct mbuf *mnext) { struct mbuf *m; @@ -226,7 +224,7 @@ q_match(void *obj, uintptr_t key, int fl } /* - * create a new queue instance for the given 'key' + * create a new queue instance for the given 'key'. */ static void * q_new(uintptr_t key, int flags, void *arg) @@ -242,7 +240,7 @@ q_new(uintptr_t key, int flags, void *ar return NULL; } - set_oid(&q->ni.oid, DN_QUEUE, 0, size); + set_oid(&q->ni.oid, DN_QUEUE, size); q->ni.id = *id; q->fs = fs; q->si = template->si; @@ -298,8 +296,8 @@ si_new(uintptr_t key, int flags, void *a /* XXX note we set the length only for the initial part which * is passed up to userland. */ - set_oid(&si->ni.oid, DN_SCH_I, 0, sizeof(struct new_inst)); - set_oid(&(si->dline.oid), DN_DELAY_LINE, 0, sizeof(struct delay_line)); + set_oid(&si->ni.oid, DN_SCH_I, sizeof(struct new_inst)); + set_oid(&(si->dline.oid), DN_DELAY_LINE, sizeof(struct delay_line)); si->ni.oid.id = si->dline.oid.id = -1; /* mark outside scheduler */ si->sched = s; @@ -404,7 +402,7 @@ fsk_new(uintptr_t key, int flags, void * fs = malloc(sizeof(*fs), M_DUMMYNET, M_NOWAIT | M_ZERO); if (fs) { - set_oid(&fs->fs.oid, DN_FS, 0, sizeof(fs->fs)); + set_oid(&fs->fs.oid, DN_FS, sizeof(fs->fs)); dn_cfg.fsk_count++; SLIST_INSERT_HEAD(&dn_cfg.fsu, fs, sch_chain); } @@ -416,23 +414,24 @@ fsk_new(uintptr_t key, int flags, void * * Return 1 if freed, o otherwise. * Removal from the hashtable must be done outside this function. */ -static int -fsk_destroy(struct new_fsk *fs) +static void +fsk_destroy(struct new_fsk *fs, int do_free) { struct new_fsk_head *h; fs->kflags |= DN_DELETE; if (fs->refcnt != 0) - return 0; + return; /* find the container list */ h = fs->sched ? &fs->sched->fsk_list : &dn_cfg.fsu; SLIST_REMOVE(h, fs, new_fsk, sch_chain); dn_cfg.fsk_count--; fs->sched = NULL; - if (fs->qht) - dn_ht_free(fs->qht, 0); - free(fs, M_DUMMYNET); - return 1; /* can remove from the ht */ + if (do_free) { + if (fs->qht) + dn_ht_free(fs->qht, 0); + free(fs, M_DUMMYNET); + } } /*----- end of flowset hashtable support -------------*/ @@ -449,10 +448,6 @@ fsk_destroy_list(struct new_fsk_head *h, while ((fs = SLIST_FIRST(h))) { /* remember if the flowset is dying */ - int dying; - if (h == &dn_cfg.fsu) - fs->kflags |= DN_DELETE; - dying = fs->kflags & DN_DELETE; printf("%s unlink flowset %d\n", __FUNCTION__, fs->fs.fs_nr); SLIST_REMOVE_HEAD(h, sch_chain); @@ -462,17 +457,23 @@ fsk_destroy_list(struct new_fsk_head *h, */ free(fs, M_DUMMYNET); dn_cfg.fsk_count--; - } else if (fs->qht) - dn_ht_scan(fs->qht, dn_delete_queue, NULL); - - /* if not already gone, move to fsunlinked. - * The internal fs is marked DN_DELETE so it - * will go away. Also, we scan all flowsets - * so we are guaranteed that those marked DN_DELETE - * will be deleted. + continue; + } + /* drain queues, but pass NULL so the fs is not deleted. + * We cannot destroy it from the callback or it + * would kill the hashtable as well. After the pass, + * refcnt is surely 0. + * If the flowset was marked delete, destroy it. + * otherwise move it to fsunlinked. */ - if (!dying) { - fs->sched = NULL; + if (fs->qht) + dn_ht_scan(fs->qht, dn_delete_queue, NULL); + fs->sched = NULL; + if (fs->kflags & DN_DELETE) { + if (fs->qht) + dn_ht_free(fs->qht, 0); + free(fs, M_DUMMYNET); + } else { SLIST_INSERT_HEAD(&dn_cfg.fsu, fs, sch_chain); } } @@ -480,10 +481,9 @@ fsk_destroy_list(struct new_fsk_head *h, /* * Delete a queue (helper for the schedulers and callback) - * Call th */ int -dn_delete_queue(void *_q, void *foo) +dn_delete_queue(void *_q, void *do_free) { struct new_queue *q = _q; struct new_fsk *fs = q->fs; @@ -496,7 +496,7 @@ dn_delete_queue(void *_q, void *foo) dn_cfg.queue_count--; fs->refcnt--; if (fs->refcnt == 0 && fs->kflags & DN_DELETE) - fsk_destroy(fs); + fsk_destroy(fs, (int)do_free); return 0; } @@ -632,7 +632,19 @@ locate_scheduler(int i) static void update_fs(struct new_schk *s) { - printf("%s to be implemented\n", __FUNCTION__); + struct new_fsk *fs, *tmp; + printf("%s XXX chech be implemented\n", __FUNCTION__); + SLIST_FOREACH_SAFE(fs, &dn_cfg.fsu, sch_chain, tmp) { + if (s->sch.sched_nr != fs->fs.fs_nr) { + printf("fs %d still unlinked\n", fs->fs.fs_nr); + continue; + } + printf("remove fs %d from fsunlinked, link to sched %d\n", + fs->fs.fs_nr, s->sch.sched_nr); + SLIST_REMOVE(&dn_cfg.fsu, fs, new_fsk, sch_chain); + fs->sched = s; + SLIST_INSERT_HEAD(&s->fsk_list, fs, sch_chain); + } #if 0 // XXX to be completed scan the children of s and see if they still apply. scan fsunlinked and link all schedulers to s; @@ -827,7 +839,7 @@ again: /* run twice, for wfq and fifo */ struct new_fs fs; bzero(&fs, sizeof(fs)); - set_oid(&fs.oid, DN_FS, 0, sizeof(fs)); + set_oid(&fs.oid, DN_FS, sizeof(fs)); fs.fs_nr = i + DN_MAX_ID; fs.sched_nr = i; s->fs = config_fs(&fs, NULL, 1 /* locked */); @@ -917,12 +929,13 @@ del_fs(int i) struct new_fsk *fs = dn_ht_find(dn_cfg.fshash, i, DNHT_REMOVE, NULL); printf("%s fs %d found %p\n", __FUNCTION__, i, fs); - if (fs) { - fsk_destroy(fs); - return 0; - } else { + if (fs == NULL) return EINVAL; - } + // XXX not sure if we want to kill the queues now + if (0 && fs->qht) + dn_ht_scan(fs->qht, dn_delete_queue, NULL); + fsk_destroy(fs, 1 /* do free the object */); + return 0; } static int @@ -1207,8 +1220,8 @@ schk_match(void *obj, uintptr_t key, int /* * Create the entry and intialize with the sched hash if needed. - * XXX how do we tell between an old and a brand new thing ? - * perhaps do not initialize s->fp ? + * Leave s->fp unset so we can tell whether a dn_ht_find() returns + * a new object or a previously existing one. */ static void * schk_new(uintptr_t key, int flags, void *_fp) @@ -1222,7 +1235,7 @@ schk_new(uintptr_t key, int flags, void s = malloc(l, M_DUMMYNET, M_NOWAIT | M_ZERO); if (s == NULL) return NULL; - set_oid(&s->pipe.oid, DN_PIPE, 0, sizeof(s->pipe)); + set_oid(&s->pipe.oid, DN_PIPE, sizeof(s->pipe)); s->sch = *sch; // copy initial values s->pipe.pipe_nr = sch->sched_nr; SLIST_INIT(&s->fsk_list); @@ -1238,7 +1251,6 @@ schk_new(uintptr_t key, int flags, void return s; } - static void ip_dn_init(void) { @@ -1284,16 +1296,16 @@ ip_dn_init(void) static void ip_dn_destroy(void) { + DUMMYNET_LOCK(); ip_dn_ctl_ptr = NULL; ip_dn_io_ptr = NULL; - DUMMYNET_LOCK(); callout_stop(&dn_timeout); + dummynet_flush(); DUMMYNET_UNLOCK(); taskqueue_drain(dn_tq, &dn_task); taskqueue_free(dn_tq); - dummynet_flush(); dn_ht_free(dn_cfg.schedhash, 0); dn_ht_free(dn_cfg.fshash, 0); heap_free(&dn_cfg.evheap); @@ -1332,7 +1344,7 @@ dummynet_modevent(module_t mod, int type /* modevent helpers for the modules */ static int -load_descriptor(struct dn_sched *d) +load_dn_sched(struct dn_sched *d) { struct dn_sched *s; @@ -1362,7 +1374,7 @@ load_descriptor(struct dn_sched *d) } static int -unload_descriptor(struct dn_sched *s) +unload_dn_sched(struct dn_sched *s) { struct dn_sched *tmp, *r; int err = EINVAL; @@ -1390,9 +1402,9 @@ dn_sched_modevent(module_t mod, int cmd, struct dn_sched *sch = arg; if (cmd == MOD_LOAD) - return load_descriptor(sch); + return load_dn_sched(sch); else if (cmd == MOD_UNLOAD) - return unload_descriptor(sch); + return unload_dn_sched(sch); else return EINVAL; } From owner-svn-src-user@FreeBSD.ORG Sat Jan 16 08:12:22 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id BCDA7106566B; Sat, 16 Jan 2010 08:12:22 +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 ABD598FC1A; Sat, 16 Jan 2010 08:12:22 +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 o0G8CMbH036938; Sat, 16 Jan 2010 08:12:22 GMT (envelope-from luigi@svn.freebsd.org) Received: (from luigi@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0G8CMSC036936; Sat, 16 Jan 2010 08:12:22 GMT (envelope-from luigi@svn.freebsd.org) Message-Id: <201001160812.o0G8CMSC036936@svn.freebsd.org> From: Luigi Rizzo Date: Sat, 16 Jan 2010 08:12:22 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202432 - user/luigi/ipfw3-head/sbin/ipfw X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 16 Jan 2010 08:12:22 -0000 Author: luigi Date: Sat Jan 16 08:12:22 2010 New Revision: 202432 URL: http://svn.freebsd.org/changeset/base/202432 Log: small formatting fixes Modified: user/luigi/ipfw3-head/sbin/ipfw/dummynet.c Modified: user/luigi/ipfw3-head/sbin/ipfw/dummynet.c ============================================================================== --- user/luigi/ipfw3-head/sbin/ipfw/dummynet.c Sat Jan 16 07:55:46 2010 (r202431) +++ user/luigi/ipfw3-head/sbin/ipfw/dummynet.c Sat Jan 16 08:12:22 2010 (r202432) @@ -1232,16 +1232,19 @@ dummynet_list(int ac, char *av[], int sh case 2: oid.subtype = DN_FS; /* list queue */ break; + case 3: + oid.subtype = DN_SCH; /* list sched */ + break; } + /* XXX we could use oid.id for the filter */ ret = do_cmd(-IP_DUMMYNET3, &oid, (uintptr_t)&l); printf("%s returns %d need %d\n", __FUNCTION__, ret, oid.id); if (ret != 0 || oid.id <= sizeof(oid)) return; l = oid.id; x = malloc(l); - if (x == NULL) { - err(1, "no memory in %s", __FUNCTION__); - } + if (x == NULL) + err(1, "no memory in %s", __FUNCTION__); *x = oid; ret = do_cmd(-IP_DUMMYNET3, x, (uintptr_t)&l); printf("%s returns %d need %d\n", __FUNCTION__, ret, oid.id); From owner-svn-src-user@FreeBSD.ORG Sat Jan 16 08:23:09 2010 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 9B15A106566B; Sat, 16 Jan 2010 08:23:09 +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 88C638FC13; Sat, 16 Jan 2010 08:23:09 +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 o0G8N9tV039338; Sat, 16 Jan 2010 08:23:09 GMT (envelope-from luigi@svn.freebsd.org) Received: (from luigi@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0G8N9wn039334; Sat, 16 Jan 2010 08:23:09 GMT (envelope-from luigi@svn.freebsd.org) Message-Id: <201001160823.o0G8N9wn039334@svn.freebsd.org> From: Luigi Rizzo Date: Sat, 16 Jan 2010 08:23:09 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202433 - user/luigi/ipfw3-head/sys/netinet/ipfw X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 16 Jan 2010 08:23:09 -0000 Author: luigi Date: Sat Jan 16 08:23:09 2010 New Revision: 202433 URL: http://svn.freebsd.org/changeset/base/202433 Log: import initial wf2q+ code ported by Riccardo Panicucci. Code not working yet. Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c Sat Jan 16 08:12:22 2010 (r202432) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c Sat Jan 16 08:23:09 2010 (r202433) @@ -1,5 +1,6 @@ /* * Copyright (c) 2010 Riccardo Panicucci, Universita` di Pisa + * Copyright (c) 2000-2002 Luigi Rizzo, Universita` di Pisa * All rights reserved * * Redistribution and use in source and binary forms, with or without @@ -24,7 +25,6 @@ * SUCH DAMAGE. */ -#ifdef _KERNEL #include #include #include @@ -35,60 +35,354 @@ #include #include /* ipfw_rule_ref */ #include /* flow_id */ -#else -#include "dn_test.h" -#endif #include #include #include #include +#ifndef MAX64 +#define MAX64(x,y) (( (int64_t) ( (y)-(x) )) > 0 ) ? (y) : (x) +#endif + +#ifndef MY_M +#define MY_M 16 /* shift for fixed point arithmetic */ +#endif + +#ifndef isdigit +#define isdigit(x) ((x) >= '0' && (x) <= '9' ) +#endif + +/* + * Private information for the scheduler instance: + * sch_heap (key is Finish time) returns the next queue to serve + * ne_heap (key is Start time) stores not-eligible queues + * idle_heap (key=start/finish time) stores idle flows. It must + * support extract-from-middle. + * A flow is normally only in 1 of the three heaps. + * XXX todo: use a more efficient data structure, e.g. a tree sorted + * by F with min_subtree(S) in each node + */ +struct wf2qp_si { + struct dn_heap *sch_heap; /* top extract - key Finish time */ + struct dn_heap *ne_heap; /* top extract - key Start time */ + struct dn_heap *idle_heap; /* random extract - key Start=Finish time */ + dn_key V ; /* virtual time */ + int sum; +}; + +struct wf2qp_queue { + struct new_queue g; + + dn_key S,F; /* start time, finish time */ + + int heap_pos; /* position (index) of struct in heap */ +// struct wf2qp_queue *next; /* next queue in the bucket */ +}; + /* - * This file implements a FIFO scheduler for a single queue. - * The queue is allocated as part of the scheduler instance, - * and there is a single flowset is in the template which stores - * queue-related information. - * No parameters are used except queue sizes and management policy. - * Enqueue and dequeue use the default library functions. + * This file implements a WF2Q+ scheduler as it has been in dummynet + * since 2000. + * The scheduler supports per-flow queues and has O(log N) complexity. */ + static int -fifo_enqueue(struct new_sch_inst *si, struct new_queue *q, struct mbuf *m) +wf2qp_enqueue(struct new_sch_inst *_si, struct new_queue *q, struct mbuf *m) { - return dn_enqueue((struct new_queue *)(si+1), m, 0); + struct new_fsk *fs = q->fs; + struct wf2qp_si *si = (struct wf2qp_si *)(_si + 1); + struct wf2qp_queue *alg_fq; + uint64_t len = m->m_pkthdr.len; + + int q_was_idle = 0; + + if (q->mq.head == NULL) + q_was_idle = 1; + + if (dn_enqueue(q, m, 0)) /* packet was dropped */ + return 1; + + if(!q_was_idle) + return 0; + + /* If reach this point, queue q was idle */ + alg_fq = (struct wf2qp_queue *)q; + + if (DN_KEY_LT(alg_fq->F, alg_fq->S)) { + /* Fbrand new queue. */ + alg_fq->S = si->V; + si->sum += fs->fs.weight; /* Add weight of new queue. */ + } else { /* if it was idle then it was in the idle heap */ + heap_extract(si->idle_heap, q); + alg_fq->S = MAX64(alg_fq->F, si->V); + } + // XXX use div64 + alg_fq->F = alg_fq->S + (len << MY_M) / (uint64_t)fs->fs.weight; + + if (si->ne_heap->elements == 0 && si->sch_heap->elements == 0) + si->V = MAX64(alg_fq->S, si->V); + + /* + * Look at eligibility. A flow is not eligibile if S>V (when + * this happens, it means that there is some other flow already + * scheduled for the same pipe, so the sch_heap cannot be + * empty). If the flow is not eligible we just store it in the + * ne_heap. Otherwise, we store in the sch_heap. + * Note that for all flows in sch_heap (SCH), S_i <= V, + * and for all flows in ne_heap (NEH), S_i > V. + * So when we need to compute max(V, min(S_i)) forall i in + * SCH+NEH, we only need to look into NEH. + */ + if (DN_KEY_LT(si->V, alg_fq->S)) { + /* S>V means flow Not eligible. */ + if (si->sch_heap->elements == 0) + printf("dummynet: ++ ouch! not eligible but empty scheduler!\n"); + heap_insert(si->ne_heap, alg_fq->S, q); + } + else { + heap_insert(si->sch_heap, alg_fq->F, q); + /* Pipe *must* be idle. */ +#if 0 + if ((si->sch_heap.elements != 1) && (s->numbytes >= 0)) + printf("dummynet: OUCH! pipe should have been idle!\n"); + DPRINTF(("dummynet: waking up pipe %d at %d\n", + s->sched_nr, (int)(alg_fq->F >> MY_M))); +#endif + } + return 0; } static struct mbuf * -fifo_dequeue(struct new_sch_inst *si) +wf2qp_dequeue(struct new_sch_inst *_si) +{ + /* Access scheduler instance private data */ + struct wf2qp_si *si = (struct wf2qp_si *)(_si + 1); + + struct mbuf *pkt = NULL; + struct new_queue *qq, *q1, *q = NULL; + + struct dn_heap *sch = si->sch_heap; + struct dn_heap *neh = si->ne_heap; + + struct wf2qp_queue *alg_fq = NULL; + + uint64_t len; + + /* XXX: + * This block in the previous version were done in the dummynet_task() + * function. Check if this is the appropriate function to do it. + */ + if (si->idle_heap->elements > 0 && + DN_KEY_LT(HEAP_TOP(si->idle_heap)->key, si->V)) { + qq = HEAP_TOP(si->idle_heap)->object; + alg_fq = (struct wf2qp_queue *) qq; + + heap_extract(si->idle_heap, NULL); + /* Mark timestamp as invalid. */ + /* XXX why don't delete the queue now? */ + alg_fq->S = alg_fq->F + 1; + si->sum -= qq->fs->fs.weight; + } + + +#if 0 + if (p->if_name[0] == 0) { /* tx clock is simulated */ + s->numbytes += (curr_time - s->sched_time) * p->bandwidth; + } + else { + /* tx clock is for real, the ifq must be empty or this is a NOP. */ + if (p->ifp && p->ifp->if_snd.ifq_head != NULL) + return NULL; + else { + DPRINTF(("dummynet: pipe %d ready from %s --\n", + p->pipe_nr, p->if_name)); + } + } +#endif + /* + * While we have backlogged traffic AND credit, we need to do + * something on the queue. + * XXX cannot be a 'while -- + */ + while ( sch->elements > 0 || neh->elements > 0) { + if (sch->elements > 0) { + /* Have some eligible pkts to send out. */ + q = HEAP_TOP(sch)->object; + alg_fq = (struct wf2qp_queue *)q; + + pkt = q->mq.head; + + heap_extract(sch, NULL); /* Remove queue from heap. */ + + si->V += (pkt->m_pkthdr.len << MY_M) / si->sum; /* Update V. */ + alg_fq->S = alg_fq->F; /* Update start time. */ + + if (q->ni.length == 1) /* Flow not backlogged any more. */ + heap_insert(si->idle_heap, alg_fq->F, q); + else { + /* Still backlogged. */ + + /* + * Update F and position in backlogged queue, + * then put flow in ne_heap + * (we will fix this later). + */ + /* len = (q->head)->m_pkthdr.len; */ + len = ((q->mq.head)->m_nextpkt)->m_pkthdr.len; + alg_fq->F += (len << MY_M) / (uint64_t)q->fs->fs.weight; + if (DN_KEY_LEQ(alg_fq->S, si->V)) { + heap_insert(neh, alg_fq->S, q); + } + else { + heap_insert(sch, alg_fq->F, q); + } + } + } + /* + * Now compute V = max(V, min(S_i)). Remember that all elements + * in sch have by definition S_i <= V so if sch is not empty, + * V is surely the max and we must not update it. Conversely, + * if sch is empty we only need to look at neh. + */ + if (sch->elements == 0 && neh->elements > 0) + si->V = MAX64(si->V, HEAP_TOP(neh)->key); + /* Move from neh to sch any packets that have become eligible */ + while (neh->elements > 0 && DN_KEY_LEQ(HEAP_TOP(neh)->key, si->V)) { + qq = HEAP_TOP(neh)->object; + alg_fq = (struct wf2qp_queue *)qq; + heap_extract(neh, NULL); + heap_insert(sch, alg_fq->F, qq); + } +#if 0 + if (p->if_name[0] != '\0') { /* Tx clock is from a real thing */ + s->numbytes = -1; /* Mark not ready for I/O. */ /* WARNING*/ + debMes(" %s f\n", __FUNCTION__); + break; + } +#endif + if (pkt != NULL) + return dn_dequeue(q); + + } /* end of while */ + + if (sch->elements == 0 && neh->elements == 0 && + si->idle_heap->elements > 0) { + /* + * No traffic and no events scheduled. + * We can get rid of idle-heap. + */ + int i; + int elem = si->idle_heap->elements; + + for (i = 0; i < elem; i++) { + /* XXX NOTE: before the heap changed, this block extracted + * all elements + */ + q1 = HEAP_TOP(si->idle_heap)->object; + heap_extract(si->idle_heap, NULL); + alg_fq = (struct wf2qp_queue *)q1; + + alg_fq->F = 0; + alg_fq->S = alg_fq->F + 1; + /* XXX: why don't call delete queue? */ + } + si->sum = 0; + si->V = 0; +// si->idle_heap.elements = 0; + } + /* + * If we are getting clocks from dummynet (not a real interface) and + * If we are under credit, schedule the next ready event. + * Also fix the delivery time of the last packet. + */ + +#if 0 + if (p->if_name[0]==0 && s->numbytes < 0) + ... +#endif + return NULL; +} + +static int +wf2qp_new_sched(struct new_sch_inst *_si) +{ + struct wf2qp_si *si = (struct wf2qp_si *)(_si + 1); + int ofs = offsetof(struct wf2qp_queue, heap_pos); + + /* only idle-heap supports extract from middle */ + if (heap_init(si->idle_heap, 16, ofs) || + heap_init(si->sch_heap, 16, -1) || + heap_init(si->ne_heap, 16, -1)) { + heap_free(si->ne_heap); + heap_free(si->sch_heap); + heap_free(si->idle_heap); + return ENOMEM; + } + return 0; +} + +static int +wf2qp_free_sched(struct new_sch_inst *_si) +{ + struct wf2qp_si *si = (struct wf2qp_si *)(_si + 1); + + heap_free(si->sch_heap); + heap_free(si->ne_heap); + heap_free(si->idle_heap); + + return 0; +} + +static int +wf2qp_new_queue (struct new_queue *q) { - return dn_dequeue((struct new_queue *)(si + 1)); + struct wf2qp_queue *tmp = (struct wf2qp_queue *) q; + + q->ni.oid.subtype = DN_SCHED_WF2QP; + + tmp->S = tmp->F + 1; /* hack - mark timestamp as invalid. */ + + return 0; } static int -wf2qp_new_sched(struct new_sch_inst *si) +wf2qp_free_queue(struct new_queue *q) { - /* This scheduler instance contains the queue */ - struct new_queue *q = (struct new_queue *)(si + 1); + struct wf2qp_si *si = (struct wf2qp_si *)q->si + 1; + struct wf2qp_queue *alg_fq = (struct wf2qp_queue *)q; + + /* If the queue was valid, decrement the sum value + * else this was done by dequeue() + */ + if(alg_fq->S != alg_fq->F + 1) + si->sum -= q->fs->fs.weight; - set_oid(&q->ni.oid, DN_QUEUE, sizeof(*q)); - q->si = si; - q->fs = si->sched->fs; - return 0; + return 0; } /* - * FIFO scheduler descriptor - * contains the type of the scheduler, the name, the size of extra - * data structures, and function pointers. + * WF2Q+ scheduler descriptor + * contains the type of the scheduler, the name, the size of the various + * structures and function pointers. If a function is not implemented, + * the pointer is initialized to NULL */ -static struct dn_sched fifo_desc = { - .type = DN_SCHED_WF2QP, - .name = "WF2QP", - - .sch_inst_len = sizeof(struct new_queue), - - .enqueue = fifo_enqueue, - .dequeue = fifo_dequeue, - .new_sched = wf2qp_new_sched, +static struct dn_sched wf2qp_desc = { + .type = DN_SCHED_WF2QP, + .name = "WF2Q+", + .flags = DN_MULTIQUEUE, + + .sch_inst_len = sizeof(struct wf2qp_si), + .queue_len = sizeof(struct wf2qp_queue), + + .enqueue = wf2qp_enqueue, + .dequeue = wf2qp_dequeue, + + .new_sched = wf2qp_new_sched, + .free_sched = wf2qp_free_sched, + + .new_queue = wf2qp_new_queue, + .free_queue = wf2qp_free_queue, + }; -DECLARE_DNSCHED_MODULE(dn_wf2qp, &fifo_desc); + +DECLARE_DNSCHED_MODULE(dn_wf2qp, &wf2qp_desc); Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Sat Jan 16 08:12:22 2010 (r202432) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dn_io.c Sat Jan 16 08:23:09 2010 (r202433) @@ -1,6 +1,5 @@ /*- - * Copyright (c) 2010 Riccardo Panicucci, Universita` di Pisa - * Copyright (c) 2010 Luigi Rizzo, Universita` di Pisa + * Copyright (c) 2010 Luigi Rizzo, Riccardo Panicucci, Universita` di Pisa * All rights reserved * * Redistribution and use in source and binary forms, with or without @@ -305,9 +304,6 @@ extra_bits(struct mbuf *m, struct new_sc return bits; } - - - /* * Send traffic from a scheduler instance due by 'now'. * Return a pointer to the head of the queue. @@ -338,7 +334,7 @@ serve_sched(struct mq *q, struct new_sch while (si->credit >= 0 && (m = s->fp->dequeue(si)) != NULL) { uint64_t len_scaled; done++; - len_scaled = bw == 0 ? 0 : hz * + len_scaled = (bw == 0) ? 0 : hz * (m->m_pkthdr.len * 8 + extra_bits(m, s)); si->credit -= len_scaled; /* Move packet in the delay line */ @@ -355,7 +351,7 @@ serve_sched(struct mq *q, struct new_sch } else { dn_key t; KASSERT (bw > 0, ("bw=0 and credit<0 ?")); - t = (bw - 1 - si->credit) / bw; + t = div64(bw - 1 - si->credit, bw); if (m) dn_tag_get(m)->output_time += t; si->kflags |= DN_ACTIVE; @@ -617,17 +613,16 @@ dummynet_io(struct mbuf **m0, int dir, s } /* compute the initial allowance */ - { - struct new_pipe *pipe = &fs->sched->pipe; - si->credit = dn_cfg.io_fast ? pipe->bandwidth : 0; - if (pipe->burst) { - uint64_t burst = (now - si->idle_time) * - pipe->bandwidth; - if (burst > pipe->burst) - burst = pipe->burst; + { + struct new_pipe *p = &fs->sched->pipe; + si->credit = dn_cfg.io_fast ? p->bandwidth : 0; + if (p->burst) { + uint64_t burst = (now - si->idle_time) * p->bandwidth; + if (burst > p->burst) + burst = p->burst; si->credit += burst; - } - } + } + } /* pass through scheduler and delay line */ m = serve_sched(NULL, si, now); Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c ============================================================================== --- user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Sat Jan 16 08:12:22 2010 (r202432) +++ user/luigi/ipfw3-head/sys/netinet/ipfw/ip_dummynet.c Sat Jan 16 08:23:09 2010 (r202433) @@ -447,14 +447,9 @@ fsk_destroy_list(struct new_fsk_head *h, struct new_fsk *fs; while ((fs = SLIST_FIRST(h))) { - /* remember if the flowset is dying */ - printf("%s unlink flowset %d\n", - __FUNCTION__, fs->fs.fs_nr); SLIST_REMOVE_HEAD(h, sch_chain); if (fs == int_fs) { - /* free the internal flowset. - * XXX maybe do it same as others - */ + /* free the internal flowset. */ free(fs, M_DUMMYNET); dn_cfg.fsk_count--; continue; @@ -633,7 +628,6 @@ static void update_fs(struct new_schk *s) { struct new_fsk *fs, *tmp; - printf("%s XXX chech be implemented\n", __FUNCTION__); SLIST_FOREACH_SAFE(fs, &dn_cfg.fsu, sch_chain, tmp) { if (s->sch.sched_nr != fs->fs.fs_nr) { printf("fs %d still unlinked\n", fs->fs.fs_nr); @@ -645,10 +639,6 @@ update_fs(struct new_schk *s) fs->sched = s; SLIST_INSERT_HEAD(&s->fsk_list, fs, sch_chain); } -#if 0 // XXX to be completed - scan the children of s and see if they still apply. - scan fsunlinked and link all schedulers to s; -#endif } /* @@ -825,7 +815,10 @@ again: /* run twice, for wfq and fifo */ printf("sched %d type changed from %s to %s" " let it drain and reallocate\n", i, s->fp->name, fp->name); - /* XXX detach flowsets */ + /* mark delete so it won't be matched. + * XXX todo: make it die when its queues are done. + * XXX otherwise do a real delete. + */ s->kflags = DN_DELETE; notify_fs = 1; goto again; @@ -879,7 +872,6 @@ config_profile(struct new_profile *pf, s if (i <= 0 || i >= DN_MAX_ID) return EINVAL; /* XXX other sanity checks */ - DUMMYNET_LOCK(); s = locate_scheduler(i); @@ -1118,10 +1110,8 @@ dummynet_get(struct sockopt *sopt) a.flags = to_copy; a.type = DN_SCH; dn_ht_scan(dn_cfg.schedhash, copy_data_helper, &a); -#if 0 // XXX temporarily disable a.type = DN_FS; dn_ht_scan(dn_cfg.fshash, copy_data_helper, &a); -#endif } DUMMYNET_UNLOCK(); error = sooptcopyout(sopt, start, buf - start);