From owner-freebsd-ipfw@FreeBSD.ORG Fri Aug 13 08:20:24 2004 Return-Path: Delivered-To: freebsd-ipfw@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 47EB416A4CE for ; Fri, 13 Aug 2004 08:20:24 +0000 (GMT) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 37BDE43D5C for ; Fri, 13 Aug 2004 08:20:24 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.12.11/8.12.11) with ESMTP id i7D8KOgh062945 for ; Fri, 13 Aug 2004 08:20:24 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.11/8.12.11/Submit) id i7D8KN21062944; Fri, 13 Aug 2004 08:20:23 GMT (envelope-from gnats) Date: Fri, 13 Aug 2004 08:20:23 GMT Message-Id: <200408130820.i7D8KN21062944@freefall.freebsd.org> To: ipfw@FreeBSD.org From: Pawel Malachowski Subject: Re: kern/46557: ipfw pipe show fails with lots of queues X-BeenThere: freebsd-ipfw@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list Reply-To: Pawel Malachowski List-Id: IPFW Technical Discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 13 Aug 2004 08:20:24 -0000 The following reply was made to PR kern/46557; it has been noted by GNATS. From: Pawel Malachowski To: Pawel Malachowski Cc: freebsd-gnats-submit@FreeBSD.org Subject: Re: kern/46557: ipfw pipe show fails with lots of queues Date: Fri, 13 Aug 2004 10:13:35 +0200 On Thu, Aug 12, 2004 at 07:30:25PM +0000, Pawel Malachowski wrote: > Here are more details what is going on. I hope someone will look at this and > explain why malloc() can fail here and what can be done to prevent this. Well, I will explain myself. First, a patch: *** ip_dummynet.c.orig Fri Aug 13 09:51:54 2004 --- ip_dummynet.c Fri Aug 13 09:52:23 2004 *************** *** 1833,1839 **** for (set = all_flow_sets ; set ; set = set->next ) size += sizeof ( *set ) + set->rq_elements * sizeof(struct dn_flow_queue); ! buf = malloc(size, M_TEMP, M_NOWAIT); if (buf == 0) { splx(s); return ENOBUFS ; --- 1833,1839 ---- for (set = all_flow_sets ; set ; set = set->next ) size += sizeof ( *set ) + set->rq_elements * sizeof(struct dn_flow_queue); ! buf = malloc(size, M_TEMP, M_WAITOK); if (buf == 0) { splx(s); return ENOBUFS ; Since buf can be very big (on my system, up to 3MB), malloc typically consumes only 128k-512k buckets (as checked in vmstat -m). On heavy loaded system with huge number of pipes, there is a risk that first-fit strategy won't find memory because of fragmentation. We will change M_NOWAIT to M_WAITOK flag so malloc() will always succeed; dummynet_get() is called only when superuser runs `ipfw pipe show', so WAITOK is not a problem for us. -- Paweł Małachowski