From owner-svn-src-all@FreeBSD.ORG Thu May 21 06:34:07 2015 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 4F0D621B; Thu, 21 May 2015 06:34:07 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 3CA6616CC; Thu, 21 May 2015 06:34:07 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t4L6Y7KL088502; Thu, 21 May 2015 06:34:07 GMT (envelope-from hselasky@FreeBSD.org) Received: (from hselasky@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t4L6Y7Yq088501; Thu, 21 May 2015 06:34:07 GMT (envelope-from hselasky@FreeBSD.org) Message-Id: <201505210634.t4L6Y7Yq088501@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: hselasky set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky Date: Thu, 21 May 2015 06:34:07 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r283172 - stable/9/sys/kern X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 21 May 2015 06:34:07 -0000 Author: hselasky Date: Thu May 21 06:34:06 2015 New Revision: 283172 URL: https://svnweb.freebsd.org/changeset/base/283172 Log: MFC r280495: Implement a simple OID number garbage collector. Given the increasing number of dynamically created and destroyed SYSCTLs during runtime it is very likely that the current new OID number limit of 0x7fffffff can be reached. Especially if dynamic OID creation and destruction results from automatic tests. Additional changes: - Optimize the typical use case by decrementing the next automatic OID sequence number instead of incrementing it. This saves searching time when inserting new OIDs into a fresh parent OID node. - Add simple check for duplicate non-automatic OID numbers. Modified: stable/9/sys/kern/kern_sysctl.c Directory Properties: stable/9/sys/ (props changed) Modified: stable/9/sys/kern/kern_sysctl.c ============================================================================== --- stable/9/sys/kern/kern_sysctl.c Thu May 21 06:30:44 2015 (r283171) +++ stable/9/sys/kern/kern_sysctl.c Thu May 21 06:34:06 2015 (r283172) @@ -142,6 +142,8 @@ sysctl_register_oid(struct sysctl_oid *o struct sysctl_oid_list *parent = oidp->oid_parent; struct sysctl_oid *p; struct sysctl_oid *q; + int oid_number; + int timeout = 2; /* * First check if another oid with the same name already @@ -158,37 +160,66 @@ sysctl_register_oid(struct sysctl_oid *o return; } } + /* get current OID number */ + oid_number = oidp->oid_number; + +#if (OID_AUTO >= 0) +#error "OID_AUTO is expected to be a negative value" +#endif /* - * If this oid has a number OID_AUTO, give it a number which - * is greater than any current oid. + * Any negative OID number qualifies as OID_AUTO. Valid OID + * numbers should always be positive. + * * NOTE: DO NOT change the starting value here, change it in * , and make sure it is at least 256 to * accomodate e.g. net.inet.raw as a static sysctl node. */ - if (oidp->oid_number == OID_AUTO) { - static int newoid = CTL_AUTO_START; + if (oid_number < 0) { + static int newoid; + + /* + * By decrementing the next OID number we spend less + * time inserting the OIDs into a sorted list. + */ + if (--newoid < CTL_AUTO_START) + newoid = 0x7fffffff; - oidp->oid_number = newoid++; - if (newoid == 0x7fffffff) - panic("out of oids"); - } -#if 0 - else if (oidp->oid_number >= CTL_AUTO_START) { - /* do not panic; this happens when unregistering sysctl sets */ - printf("static sysctl oid too high: %d", oidp->oid_number); + oid_number = newoid; } -#endif /* - * Insert the oid into the parent's list in order. + * Insert the OID into the parent's list sorted by OID number. */ +retry: q = NULL; SLIST_FOREACH(p, parent, oid_link) { - if (oidp->oid_number < p->oid_number) + /* check if the current OID number is in use */ + if (oid_number == p->oid_number) { + /* get the next valid OID number */ + if (oid_number < CTL_AUTO_START || + oid_number == 0x7fffffff) { + /* wraparound - restart */ + oid_number = CTL_AUTO_START; + /* don't loop forever */ + if (!timeout--) + panic("sysctl: Out of OID numbers\n"); + goto retry; + } else { + oid_number++; + } + } else if (oid_number < p->oid_number) break; q = p; } - if (q) + /* check for non-auto OID number collision */ + if (oidp->oid_number >= 0 && oidp->oid_number < CTL_AUTO_START && + oid_number >= CTL_AUTO_START) { + printf("sysctl: OID number(%d) is already in use for '%s'\n", + oidp->oid_number, oidp->oid_name); + } + /* update the OID number, if any */ + oidp->oid_number = oid_number; + if (q != NULL) SLIST_INSERT_AFTER(q, oidp, oid_link); else SLIST_INSERT_HEAD(parent, oidp, oid_link);