From owner-dev-commits-src-main@freebsd.org Fri Apr 16 07:24:43 2021 Return-Path: Delivered-To: dev-commits-src-main@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 8DF2D5E77B9; Fri, 16 Apr 2021 07:24:43 +0000 (UTC) (envelope-from git@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 "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4FM7573Zkqz3NYy; Fri, 16 Apr 2021 07:24:43 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (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 did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 6DBAE20ACA; Fri, 16 Apr 2021 07:24:43 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 13G7OhbN005576; Fri, 16 Apr 2021 07:24:43 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 13G7Oh8v005575; Fri, 16 Apr 2021 07:24:43 GMT (envelope-from git) Date: Fri, 16 Apr 2021 07:24:43 GMT Message-Id: <202104160724.13G7Oh8v005575@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: "Andrey V. Elsukov" Subject: git: 9bacbf1ae243 - main - ipfw: do not use sleepable malloc in callout context. MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: ae X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 9bacbf1ae243de43d642c3ac0b7318ae0e5c5235 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-main@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for the main branch of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 16 Apr 2021 07:24:43 -0000 The branch main has been updated by ae: URL: https://cgit.FreeBSD.org/src/commit/?id=9bacbf1ae243de43d642c3ac0b7318ae0e5c5235 commit 9bacbf1ae243de43d642c3ac0b7318ae0e5c5235 Author: Andrey V. Elsukov AuthorDate: 2021-04-16 07:22:44 +0000 Commit: Andrey V. Elsukov CommitDate: 2021-04-16 07:22:44 +0000 ipfw: do not use sleepable malloc in callout context. Use M_NOWAIT flag when hash growing is called from callout. PR: 255041 Reviewed by: kevans MFC after: 10 days Differential Revision: https://reviews.freebsd.org/D29772 --- sys/netpfil/ipfw/ip_fw_dynamic.c | 68 ++++++++++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 17 deletions(-) diff --git a/sys/netpfil/ipfw/ip_fw_dynamic.c b/sys/netpfil/ipfw/ip_fw_dynamic.c index 7b5a7f60e495..a76e8b1ac667 100644 --- a/sys/netpfil/ipfw/ip_fw_dynamic.c +++ b/sys/netpfil/ipfw/ip_fw_dynamic.c @@ -2582,7 +2582,7 @@ dyn_send_keepalive_ipv6(struct ip_fw_chain *chain) #endif /* INET6 */ static void -dyn_grow_hashtable(struct ip_fw_chain *chain, uint32_t new) +dyn_grow_hashtable(struct ip_fw_chain *chain, uint32_t new, int flags) { #ifdef INET6 struct dyn_ipv6ck_slist *ipv6, *ipv6_parent; @@ -2600,31 +2600,64 @@ dyn_grow_hashtable(struct ip_fw_chain *chain, uint32_t new) DYN_DEBUG("grow hash size %u -> %u", V_curr_dyn_buckets, new); /* * Allocate and initialize new lists. - * XXXAE: on memory pressure this can disable callout timer. */ bucket_lock = malloc(new * sizeof(struct mtx), M_IPFW, - M_WAITOK | M_ZERO); + flags | M_ZERO); + if (bucket_lock == NULL) + return; + + ipv4 = ipv4_parent = NULL; + ipv4_add = ipv4_del = ipv4_parent_add = ipv4_parent_del = NULL; +#ifdef INET6 + ipv6 = ipv6_parent = NULL; + ipv6_add = ipv6_del = ipv6_parent_add = ipv6_parent_del = NULL; +#endif + ipv4 = malloc(new * sizeof(struct dyn_ipv4ck_slist), M_IPFW, - M_WAITOK | M_ZERO); + flags | M_ZERO); + if (ipv4 == NULL) + goto bad; ipv4_parent = malloc(new * sizeof(struct dyn_ipv4ck_slist), M_IPFW, - M_WAITOK | M_ZERO); - ipv4_add = malloc(new * sizeof(uint32_t), M_IPFW, M_WAITOK | M_ZERO); - ipv4_del = malloc(new * sizeof(uint32_t), M_IPFW, M_WAITOK | M_ZERO); + flags | M_ZERO); + if (ipv4_parent == NULL) + goto bad; + ipv4_add = malloc(new * sizeof(uint32_t), M_IPFW, flags | M_ZERO); + if (ipv4_add == NULL) + goto bad; + ipv4_del = malloc(new * sizeof(uint32_t), M_IPFW, flags | M_ZERO); + if (ipv4_del == NULL) + goto bad; ipv4_parent_add = malloc(new * sizeof(uint32_t), M_IPFW, - M_WAITOK | M_ZERO); + flags | M_ZERO); + if (ipv4_parent_add == NULL) + goto bad; ipv4_parent_del = malloc(new * sizeof(uint32_t), M_IPFW, - M_WAITOK | M_ZERO); + flags | M_ZERO); + if (ipv4_parent_del == NULL) + goto bad; #ifdef INET6 ipv6 = malloc(new * sizeof(struct dyn_ipv6ck_slist), M_IPFW, - M_WAITOK | M_ZERO); + flags | M_ZERO); + if (ipv6 == NULL) + goto bad; ipv6_parent = malloc(new * sizeof(struct dyn_ipv6ck_slist), M_IPFW, - M_WAITOK | M_ZERO); - ipv6_add = malloc(new * sizeof(uint32_t), M_IPFW, M_WAITOK | M_ZERO); - ipv6_del = malloc(new * sizeof(uint32_t), M_IPFW, M_WAITOK | M_ZERO); + flags | M_ZERO); + if (ipv6_parent == NULL) + goto bad; + ipv6_add = malloc(new * sizeof(uint32_t), M_IPFW, flags | M_ZERO); + if (ipv6_add == NULL) + goto bad; + ipv6_del = malloc(new * sizeof(uint32_t), M_IPFW, flags | M_ZERO); + if (ipv6_del == NULL) + goto bad; ipv6_parent_add = malloc(new * sizeof(uint32_t), M_IPFW, - M_WAITOK | M_ZERO); + flags | M_ZERO); + if (ipv6_parent_add == NULL) + goto bad; ipv6_parent_del = malloc(new * sizeof(uint32_t), M_IPFW, - M_WAITOK | M_ZERO); + flags | M_ZERO); + if (ipv6_parent_del == NULL) + goto bad; #endif for (bucket = 0; bucket < new; bucket++) { DYN_BUCKET_LOCK_INIT(bucket_lock, bucket); @@ -2695,6 +2728,7 @@ dyn_grow_hashtable(struct ip_fw_chain *chain, uint32_t new) /* Release old resources */ while (bucket-- != 0) DYN_BUCKET_LOCK_DESTROY(bucket_lock, bucket); +bad: free(bucket_lock, M_IPFW); free(ipv4, M_IPFW); free(ipv4_parent, M_IPFW); @@ -2762,7 +2796,7 @@ dyn_tick(void *vnetx) buckets = 1 << fls(V_dyn_count); if (buckets > V_dyn_buckets_max) buckets = V_dyn_buckets_max; - dyn_grow_hashtable(&V_layer3_chain, buckets); + dyn_grow_hashtable(&V_layer3_chain, buckets, M_NOWAIT); } callout_reset_on(&V_dyn_timeout, hz, dyn_tick, vnetx, 0); @@ -3187,7 +3221,7 @@ ipfw_dyn_init(struct ip_fw_chain *chain) /* Initialize buckets. */ V_curr_dyn_buckets = 0; V_dyn_bucket_lock = NULL; - dyn_grow_hashtable(chain, 256); + dyn_grow_hashtable(chain, 256, M_WAITOK); if (IS_DEFAULT_VNET(curvnet)) dyn_hp_cache = malloc(mp_ncpus * sizeof(void *), M_IPFW,