kern/46557: ipfw pipe show fails with lots of queues
Pawel Jakub Dawidek
pjd at FreeBSD.org
Mon Aug 23 14:55:05 PDT 2004
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
More information about the freebsd-ipfw
mailing list