From owner-svn-src-all@freebsd.org Sun Nov 8 18:49:24 2020 Return-Path: Delivered-To: svn-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 105D82D2624; Sun, 8 Nov 2020 18:49:24 +0000 (UTC) (envelope-from mhorne@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4CTjpW75PPz4kSQ; Sun, 8 Nov 2020 18:49:23 +0000 (UTC) (envelope-from mhorne@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id E678124714; Sun, 8 Nov 2020 18:49:23 +0000 (UTC) (envelope-from mhorne@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 0A8InNKH067650; Sun, 8 Nov 2020 18:49:23 GMT (envelope-from mhorne@FreeBSD.org) Received: (from mhorne@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 0A8InNCR067649; Sun, 8 Nov 2020 18:49:23 GMT (envelope-from mhorne@FreeBSD.org) Message-Id: <202011081849.0A8InNCR067649@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mhorne set sender to mhorne@FreeBSD.org using -f From: Mitchell Horne Date: Sun, 8 Nov 2020 18:49:23 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r367493 - head/sys/netinet X-SVN-Group: head X-SVN-Commit-Author: mhorne X-SVN-Commit-Paths: head/sys/netinet X-SVN-Commit-Revision: 367493 X-SVN-Commit-Repository: base 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.34 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: Sun, 08 Nov 2020 18:49:24 -0000 Author: mhorne Date: Sun Nov 8 18:49:23 2020 New Revision: 367493 URL: https://svnweb.freebsd.org/changeset/base/367493 Log: igmp: convert igmpstat to use PCPU counters Currently there is no locking done to protect this structure. It is likely okay due to the low-volume nature of IGMP, but allows for the possibility of underflow. This appears to be one of the only holdouts of the conversion to counter(9) which was done for most protocol stat structures around 2013. This also updates the visibility of this stats structure so that it can be consumed from elsewhere in the kernel, consistent with the vast majority of VNET_PCPUSTAT structures. Reviewed by: kp Sponsored by: NetApp, Inc. Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D27023 Modified: head/sys/netinet/igmp.c head/sys/netinet/igmp_var.h Modified: head/sys/netinet/igmp.c ============================================================================== --- head/sys/netinet/igmp.c Sun Nov 8 18:47:05 2020 (r367492) +++ head/sys/netinet/igmp.c Sun Nov 8 18:49:23 2020 (r367493) @@ -230,16 +230,15 @@ VNET_DEFINE_STATIC(int, current_state_timers_running); #define V_state_change_timers_running VNET(state_change_timers_running) #define V_current_state_timers_running VNET(current_state_timers_running) +VNET_PCPUSTAT_DEFINE(struct igmpstat, igmpstat); +VNET_PCPUSTAT_SYSINIT(igmpstat); +VNET_PCPUSTAT_SYSUNINIT(igmpstat); + VNET_DEFINE_STATIC(LIST_HEAD(, igmp_ifsoftc), igi_head) = LIST_HEAD_INITIALIZER(igi_head); -VNET_DEFINE_STATIC(struct igmpstat, igmpstat) = { - .igps_version = IGPS_VERSION_3, - .igps_len = sizeof(struct igmpstat), -}; VNET_DEFINE_STATIC(struct timeval, igmp_gsrdelay) = {10, 0}; #define V_igi_head VNET(igi_head) -#define V_igmpstat VNET(igmpstat) #define V_igmp_gsrdelay VNET(igmp_gsrdelay) VNET_DEFINE_STATIC(int, igmp_recvifkludge) = 1; @@ -263,7 +262,8 @@ VNET_DEFINE_STATIC(int, igmp_default_version) = IGMP_V */ SYSCTL_PROC(_net_inet_igmp, IGMPCTL_STATS, stats, CTLFLAG_VNET | CTLTYPE_STRUCT | CTLFLAG_RW | CTLFLAG_MPSAFE, - &VNET_NAME(igmpstat), 0, sysctl_igmp_stat, "S,igmpstat", ""); + &VNET_NAME(igmpstat), 0, sysctl_igmp_stat, "S,igmpstat", + "IGMP statistics (struct igmpstat, netinet/igmp_var.h)"); SYSCTL_INT(_net_inet_igmp, OID_AUTO, recvifkludge, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(igmp_recvifkludge), 0, "Rewrite IGMPv1/v2 reports from 0.0.0.0 to contain subnet address"); @@ -347,22 +347,31 @@ sysctl_igmp_stat(SYSCTL_HANDLER_ARGS) int error; char *p; - error = sysctl_wire_old_buffer(req, sizeof(V_igmpstat)); + error = sysctl_wire_old_buffer(req, sizeof(struct igmpstat)); if (error) return (error); if (req->oldptr != NULL) { - if (req->oldlen < sizeof(V_igmpstat)) + if (req->oldlen < sizeof(struct igmpstat)) error = ENOMEM; - else - error = SYSCTL_OUT(req, &V_igmpstat, - sizeof(V_igmpstat)); + else { + /* + * Copy the counters, and explicitly set the struct's + * version and length fields. + */ + COUNTER_ARRAY_COPY(VNET(igmpstat), &igps0, + sizeof(struct igmpstat) / sizeof(uint64_t)); + igps0.igps_version = IGPS_VERSION_3; + igps0.igps_len = IGPS_VERSION3_LEN; + error = SYSCTL_OUT(req, &igps0, + sizeof(struct igmpstat)); + } } else - req->validlen = sizeof(V_igmpstat); + req->validlen = sizeof(struct igmpstat); if (error) goto out; if (req->newptr != NULL) { - if (req->newlen < sizeof(V_igmpstat)) + if (req->newlen < sizeof(struct igmpstat)) error = ENOMEM; else error = SYSCTL_IN(req, &igps0, @@ -379,12 +388,8 @@ sysctl_igmp_stat(SYSCTL_HANDLER_ARGS) error = EINVAL; goto out; } - /* - * Avoid overwrite of the version and length field. - */ - igps0.igps_version = V_igmpstat.igps_version; - igps0.igps_len = V_igmpstat.igps_len; - bcopy(&igps0, &V_igmpstat, sizeof(V_igmpstat)); + COUNTER_ARRAY_ZERO(VNET(igmpstat), + sizeof(struct igmpstat) / sizeof(uint64_t)); } out: return (error); Modified: head/sys/netinet/igmp_var.h ============================================================================== --- head/sys/netinet/igmp_var.h Sun Nov 8 18:47:05 2020 (r367492) +++ head/sys/netinet/igmp_var.h Sun Nov 8 18:49:23 2020 (r367493) @@ -54,6 +54,7 @@ struct igmpstat { /* * Structure header (to insulate ABI changes). + * XXX: unset inside the kernel, exported via sysctl_igmp_stat(). */ uint32_t igps_version; /* version of this structure */ uint32_t igps_len; /* length of this structure */ @@ -184,8 +185,12 @@ struct igmp_ifinfo { }; #ifdef _KERNEL -#define IGMPSTAT_ADD(name, val) V_igmpstat.name += (val) -#define IGMPSTAT_INC(name) IGMPSTAT_ADD(name, 1) +#include + +VNET_PCPUSTAT_DECLARE(struct igmpstat, igmpstat); +#define IGMPSTAT_ADD(name, val) \ + VNET_PCPUSTAT_ADD(struct igmpstat, igmpstat, name, (val)) +#define IGMPSTAT_INC(name) IGMPSTAT_ADD(name, 1) /* * Subsystem lock macros.