From owner-freebsd-ipfw@FreeBSD.ORG Mon Aug 23 21:55:05 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 37C9016A4CE; Mon, 23 Aug 2004 21:55:05 +0000 (GMT) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 2C15B43D31; Mon, 23 Aug 2004 21:55:05 +0000 (GMT) (envelope-from pjd@FreeBSD.org) Received: from freefall.freebsd.org (pjd@localhost [127.0.0.1]) i7NLt5nM052090; Mon, 23 Aug 2004 21:55:05 GMT (envelope-from pjd@freefall.freebsd.org) Received: (from pjd@localhost) by freefall.freebsd.org (8.12.11/8.12.11/Submit) id i7NLt4gF052086; Mon, 23 Aug 2004 21:55:04 GMT (envelope-from pjd) Date: Mon, 23 Aug 2004 21:55:04 GMT From: Pawel Jakub Dawidek Message-Id: <200408232155.i7NLt4gF052086@freefall.freebsd.org> To: pjd@FreeBSD.org, ipfw@FreeBSD.org, pjd@FreeBSD.org 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 List-Id: IPFW Technical Discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 23 Aug 2004 21:55:05 -0000 Synopsis: ipfw pipe show fails with lots of queues Responsible-Changed-From-To: ipfw->pjd Responsible-Changed-By: pjd Responsible-Changed-When: Mon Aug 23 21:53:44 GMT 2004 Responsible-Changed-Why: I'll take this one. Here is prosposed patch against HEAD: Index: ip_dummynet.c =================================================================== RCS file: /private/FreeBSD/src/sys/netinet/ip_dummynet.c,v retrieving revision 1.82 diff -u -p -r1.82 ip_dummynet.c --- ip_dummynet.c 15 Jul 2004 08:26:07 -0000 1.82 +++ ip_dummynet.c 23 Aug 2004 21:41:06 -0000 @@ -1895,17 +1895,14 @@ dn_copy_set(struct dn_flow_set *set, cha return (char *)qp ; } -static int -dummynet_get(struct sockopt *sopt) +static size_t +dn_calc_size(void) { - char *buf, *bp ; /* bp is the "copy-pointer" */ - size_t size ; struct dn_flow_set *set ; struct dn_pipe *p ; - int error=0 ; + size_t size ; - /* XXX lock held too long */ - DUMMYNET_LOCK(); + DUMMYNET_LOCK_ASSERT(); /* * compute size of data structures: list of pipes and flow_sets. */ @@ -1915,8 +1912,35 @@ dummynet_get(struct sockopt *sopt) 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) { + return size ; +} + +static int +dummynet_get(struct sockopt *sopt) +{ + char *buf, *bp ; /* bp is the "copy-pointer" */ + size_t size ; + struct dn_flow_set *set ; + struct dn_pipe *p ; + int error=0, 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); + DUMMYNET_LOCK(); + if (size == dn_calc_size()) + break; + free(buf, M_TEMP); + buf = NULL; + } + if (buf == NULL) { DUMMYNET_UNLOCK(); return ENOBUFS ; } http://www.freebsd.org/cgi/query-pr.cgi?pr=46557