libnet: adding buffer debug facilities
authorReto Achermann <reto.achermann@inf.ethz.ch>
Wed, 5 Apr 2017 06:17:43 +0000 (08:17 +0200)
committerReto Achermann <reto.achermann@inf.ethz.ch>
Wed, 5 Apr 2017 06:17:43 +0000 (08:17 +0200)
Signed-off-by: Reto Achermann <reto.achermann@inf.ethz.ch>

lib/net/net.c
lib/net/netbufs.c
lib/net/netif.c
lib/net/networking_internal.h
lib/net/pbuf.c

index 069690b..8284fef 100644 (file)
@@ -28,7 +28,7 @@ struct net_state state = {0};
 
 #define NETWORKING_DEFAULT_QUEUE_ID 0
 #define NETWORKING_BUFFER_COUNT (4096 * 3)
-#define NETWORKING_BUFFER_RX_POPULATE (4096)
+#define NETWORKING_BUFFER_RX_POPULATE (4096 - 10)
 #define NETWORKING_BUFFER_SIZE  2048
 
 
index 6d74b14..6951f63 100644 (file)
@@ -100,7 +100,7 @@ errval_t net_buf_add(struct net_buf_pool *bp, struct capref frame, size_t buffer
 
 
     size_t numbuf = reg->frame.bytes / reg->buffer_size;
-
+    assert(numbuf * reg->buffer_size <= reg->frame.bytes);
 
     reg->netbufs = calloc(numbuf, sizeof(struct net_buf_p));
     if (reg->netbufs == NULL) {
@@ -134,8 +134,12 @@ errval_t net_buf_add(struct net_buf_pool *bp, struct capref frame, size_t buffer
         nb->vbase = reg->vbase + offset;
         nb->region = reg;
         nb->pbuf.custom_free_function = net_buf_free;
+#if NETBUF_DEBGUG
         nb->allocated = 0;
-
+        nb->enqueued = 0;
+        nb->flags = 0;
+        nb->magic = 0xdeadbeefcafebabe;
+#endif
         /* enqueue to freelist */
         nb->pbuf.pbuf.next =  bp->pbufs;
         bp->pbufs = &nb->pbuf.pbuf;
@@ -206,17 +210,27 @@ struct pbuf *net_buf_alloc(struct net_buf_pool *bp)
 #if BENCH_LWIP_STACK
         nb->timestamp = 0;
 #endif
+
+#if NETBUF_DEBGUG
+        assert(nb->magic == 0xdeadbeefcafebabe);
         assert(nb->allocated == 0);
+        assert(nb->enqueued == 0);
+        assert(nb->flags == 0);
 
+#endif
         bp->pbufs = bp->pbufs->next;
         bp->buffer_free--;
         struct pbuf* p;
         p = pbuf_alloced_custom(PBUF_RAW, 0, PBUF_REF, &nb->pbuf,
                                 nb->vbase, nb->region->buffer_size);
-
+#if NETBUF_DEBGUG
         nb->allocated = 1;
+        assert(p->next == NULL);
+#endif
         NETDEBUG("bp=%p, allocated pbuf=%p, free count %zu / %zu\n", bp, p,
                  bp->buffer_free, bp->buffer_count);
+     //   printf("alloc: %p\n", p);
+
         return p;
     }
 
@@ -229,14 +243,30 @@ struct pbuf *net_buf_alloc(struct net_buf_pool *bp)
 void net_buf_free(struct pbuf *p)
 {
     NETDEBUG("pbuf=%p\n", p);
+
+    if (p->next) {
+        debug_printf("!!!!!! p->NEXT was not NULL\n");
+    }
+
+   // printf("free: %p\n", p);
+
     // TODO sanity checks ?
     struct net_buf_p *nb = (struct net_buf_p *)p;
-    struct net_buf_pool *bp = nb->region->pool;
-    nb->pbuf.pbuf.next =  bp->pbufs;
-    bp->pbufs = &nb->pbuf.pbuf;
-    bp->buffer_free++;
+
+#if NETBUF_DEBGUG
+    assert(nb->magic == 0xdeadbeefcafebabe);
+    assert(p->ref == 0);
     assert(nb->allocated == 1);
+    assert(nb->enqueued == 0);
+    assert(nb->flags == 0);
     nb->allocated = 0;
+
+#endif
+
+    struct net_buf_pool *bp = nb->region->pool;
+    p->next =  bp->pbufs;
+    bp->pbufs = p;
+    bp->buffer_free++;
 }
 
 struct pbuf *net_buf_get_by_region(struct net_buf_pool *bp,
@@ -251,8 +281,13 @@ struct pbuf *net_buf_get_by_region(struct net_buf_pool *bp,
             if (reg->frame.bytes < offset) {
                 return NULL;
             }
-            assert(reg->netbufs[offset / reg->buffer_size].allocated);
-            return &reg->netbufs[offset / reg->buffer_size].pbuf.pbuf;
+
+            assert((offset & (reg->buffer_size - 1)) == 0);
+            assert(offset / reg->buffer_size < reg->pool->buffer_count);
+            struct net_buf_p *nb = reg->netbufs + (offset / reg->buffer_size);
+            assert(nb->offset == offset);
+
+            return (struct pbuf *)nb;
         }
         reg = reg->next;
     }
index 30fa668..8ae34fd 100644 (file)
@@ -193,6 +193,15 @@ errval_t net_if_add_rx_buf(struct netif *netif, struct pbuf *pbuf)
     NETDEBUG("netif=%p <- pbuf=%p   (reg=%u, offset=%" PRIxLPADDR ")\n", netif,
              pbuf, nb->region->regionid, nb->offset);
 
+#if NETBUF_DEBGUG
+    assert(nb->magic == 0xdeadbeefcafebabe);
+    assert(nb->allocated == 1);
+    assert(nb->enqueued == 0);
+    assert(nb->flags == 0);
+    nb->enqueued = 1;
+    nb->flags = NETIF_RXFLAG;
+#endif
+
 
 #if BENCH_DEVQ_ENQUEUE
     cycles_t tsc_start = rdtsc();
@@ -253,6 +262,17 @@ errval_t net_if_add_tx_buf(struct netif *netif, struct pbuf *pbuf)
         if (tmpp->next == NULL) {
             flags |= NETIF_TXFLAG_LAST;
         }
+
+#if NETBUF_DEBGUG
+        assert(nb->magic == 0xdeadbeefcafebabe);
+        assert(nb->allocated == 1);
+        assert(nb->enqueued == 0);
+        assert(nb->flags == 0);
+        nb->enqueued = 1;
+        nb->flags = flags;
+#endif
+
+
 #if BENCH_LWIP_STACK
         if (nb->timestamp) {
             if (bench_lwip_processing_count == BENCH_LWIP_STACK_MEASUREMENT) {
@@ -264,6 +284,10 @@ errval_t net_if_add_tx_buf(struct netif *netif, struct pbuf *pbuf)
             bench_lwip_processing_count++;
         }
 #endif
+
+        size_t valid_data = (uintptr_t)tmpp->payload - (uintptr_t)nb->vbase;
+        assert((valid_data + tmpp->len) < nb->region->buffer_size);
+        assert(((uintptr_t)tmpp->payload - valid_data) == (uintptr_t)nb->vbase);
         err = devq_enqueue(st->queue, nb->region->regionid, nb->offset,
                            nb->region->buffer_size,
                            ((uintptr_t)tmpp->payload - (uintptr_t)nb->vbase),
@@ -332,6 +356,19 @@ errval_t net_if_poll(struct netif *netif)
             continue;
         }
 
+
+#if NETBUF_DEBGUG
+        struct net_buf_p *nb = (struct net_buf_p *)p;
+
+        assert((buf.valid_data + buf.valid_length) < nb->region->buffer_size);
+
+        if (nb->magic != 0xdeadbeefcafebabe || nb->enqueued != 1 || nb->allocated != 1 || nb->flags != buf.flags) {
+            debug_printf("ERROR: pbuf=%p, rid=%u, offset=%lx magic=%lx, enq=%u, alloc=%u, flags=%lx (%lx)\n",
+                         p, nb->region->regionid, nb->offset, nb->magic, nb->enqueued, nb->allocated, nb->flags, buf.flags);
+        }
+#endif
+
+
 #if BENCH_LWIP_STACK
         ((struct net_buf_p *)p)->timestamp = rdtsc();
 #endif
@@ -339,17 +376,41 @@ errval_t net_if_poll(struct netif *netif)
             NETDEBUG("netif=%p, polling %u/%u. TX done of pbuf=%p (rid=%u, "
                       "offset=%"PRIxLPADDR ")\n", netif, i, NET_IF_POLL_MAX,
                       p, buf.rid, buf.offset);
-            net_buf_free(p);
-        }
 
-        if (buf.flags & NETIF_RXFLAG) {
+#if NETBUF_DEBGUG
+            assert(nb->magic == 0xdeadbeefcafebabe);
+            assert(nb->flags == buf.flags);
+            assert(nb->enqueued == 1);
+            assert(nb->allocated == 1);
+
+            nb->enqueued = 0;
+            nb->flags = 0;
+#endif
+
+            pbuf_free(p);
+
+            assert(!(buf.flags & NETIF_RXFLAG));
+
+        } else if (buf.flags & NETIF_RXFLAG) {
             NETDEBUG("netif=%p, polling %u/%u. RX done of pbuf=%p (rid=%u, "
-                     "offset=%"PRIxLPADDR ")\n", netif, i, NET_IF_POLL_MAX,
-                     p, buf.rid, buf.offset);
+                            "offset=%"PRIxLPADDR ")\n", netif, i, NET_IF_POLL_MAX,
+                            p, buf.rid, buf.offset);
+
+#if NETBUF_DEBGUG
+            assert(nb->magic == 0xdeadbeefcafebabe);
+            assert(nb->enqueued == 1);
+            assert(nb->allocated == 1);
+            assert(nb->flags == buf.flags);
+            nb->enqueued = 0;
+            nb->flags = 0;
+#endif
 
             p->len = buf.valid_length;
             p->tot_len = p->len;
             p->payload += buf.valid_data;
+
+            assert(!(buf.flags & NETIF_TXFLAG));
+
 #if 0
 #include <lwip/pbuf.h>
 #include <lwip/prot/ethernet.h>
@@ -380,15 +441,27 @@ errval_t net_if_poll(struct netif *netif)
             udphdr->len = PP_HTONS(64 + UDP_HLEN);
 
 #endif
-            netif_input(p, &st->netif);
-
-            /* XXX: do this at another time ? */
-            p = net_buf_alloc(st->pool);
-            if (p) {
+            if (netif_input(p, &st->netif) != ERR_OK) {
                 net_if_add_rx_buf(&st->netif, p);
             } else {
-                USER_PANIC("Could not allocate a receive buffer\n");
+                /* XXX: do this at another time ? */
+                p = net_buf_alloc(st->pool);
+#if NETBUF_DEBGUG
+        nb = (struct net_buf_p *)p;
+        assert(nb->magic == 0xdeadbeefcafebabe);
+        assert(nb->allocated == 1);
+        assert(nb->enqueued == 0);
+        assert(nb->flags == 0);
+
+#endif
+                if (p) {
+                    net_if_add_rx_buf(&st->netif, p);
+                } else {
+                    USER_PANIC("Could not allocate a receive buffer\n");
+                }
             }
+        } else {
+            debug_printf("WARNING: got buffer without a flag\n");
         }
     }
 
index b22e79b..c17f3ce 100644 (file)
@@ -35,6 +35,7 @@
 #define BENCH_LWIP_STACK 0
 #define BENCH_DEVQ_ENQUEUE 0
 
+#define NETBUF_DEBGUG 1
 
 /**
  * @brief encapsulates the state of the networking library
@@ -60,13 +61,21 @@ struct net_buf_pool;
 struct net_buf_p
 {
     struct pbuf_custom pbuf;
+#if NETBUF_DEBGUG
+    uint64_t flags;
+    bool allocated;
+    bool enqueued;
+#endif
     lpaddr_t offset;
     void *vbase;
     struct net_buf_region *region;
-    bool allocated;
 #if BENCH_LWIP_STACK
     cycles_t timestamp;
 #endif
+#if NETBUF_DEBGUG
+    uint64_t magic;
+#endif
+
 };
 
 struct net_buf_region
index 369a10a..d5c3619 100644 (file)
@@ -427,9 +427,10 @@ pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
   /* set reference count */
   p->ref = 1;
   p->type = PBUF_REF;
-
   /* set flags */
   LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F") == %p\n", length, (void *)p));
+
+  assert(p->next == NULL);
   return p;
 }