]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lwip.git/commitdiff
* pbuf.c: reclaim pbufs from TCP out-of-sequence segments if we run
authorjifl <jifl>
Wed, 28 Jan 2009 05:43:35 +0000 (05:43 +0000)
committerjifl <jifl>
Wed, 28 Jan 2009 05:43:35 +0000 (05:43 +0000)
  out of pool pbufs.

CHANGELOG
src/core/pbuf.c

index 13fd4bbff42143b9359bba2cabaa996f15f7e6be..61946841e1e5105558b63781885f47518ee7a31e 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -56,6 +56,10 @@ HISTORY
 
   ++ Bugfixes:
 
+  2009-01-28 Jonathan Larmour
+  * pbuf.c: reclaim pbufs from TCP out-of-sequence segments if we run
+    out of pool pbufs.
+
   2008-12-19 Simon Goldschmidt
   * many files: patch #6699: fixed some warnings on platform where sizeof(int) == 2 
 
index 030248879fed801dbb53d87ac8fbb865d0788c4e..e1c2854879ef48b5fe3352e610e77420d2c2ed93 100644 (file)
@@ -70,6 +70,9 @@
 #include "lwip/pbuf.h"
 #include "lwip/sys.h"
 #include "arch/perf.h"
+#if TCP_QUEUE_OOSEQ
+#include "lwip/tcp.h"
+#endif
 
 #include <string.h>
 
    aligned there. Therefore, PBUF_POOL_BUFSIZE_ALIGNED can be used here. */
 #define PBUF_POOL_BUFSIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE)
 
+#if TCP_QUEUE_OOSEQ
+#define ALLOC_POOL_PBUF(p) do { (p) = alloc_pool_pbuf(); } while (0)
+#else
+#define ALLOC_POOL_PBUF(p) do { (p) = memp_malloc(MEMP_PBUF_POOL); } while (0)
+#endif
+
+
+#if TCP_QUEUE_OOSEQ
+/**
+ * Attempt to reclaim some memory from queued out-of-sequence TCP segments
+ * if we run out of pool pbufs. It's better to give priority to new packets
+ * if we're running out.
+ *
+ * @return the allocated pbuf.
+ */
+static struct pbuf *
+alloc_pool_pbuf(void)
+{
+  struct tcp_pcb *pcb;
+  struct pbuf *p;
+
+retry:
+  p = memp_malloc(MEMP_PBUF_POOL);
+  if (NULL == p) {
+    for (pcb=tcp_active_pcbs; NULL != pcb; pcb = pcb->next) {
+      if (NULL != pcb->ooseq) {
+        tcp_segs_free(pcb->ooseq);
+        pcb->ooseq = NULL;
+        goto retry;
+      }
+    }
+  }
+  return p;
+}
+#endif /* TCP_QUEUE_OOSEQ */
+
 /**
  * Allocates a pbuf of the given type (possibly a chain for PBUF_POOL type).
  *
@@ -142,7 +181,7 @@ pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
   switch (type) {
   case PBUF_POOL:
     /* allocate head of pbuf chain into p */
-      p = memp_malloc(MEMP_PBUF_POOL);
+    ALLOC_POOL_PBUF(p);
     LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE | 3, ("pbuf_alloc: allocated pbuf %p\n", (void *)p));
     if (p == NULL) {
       return NULL;
@@ -172,7 +211,7 @@ pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
     rem_len = length - p->len;
     /* any remaining pbufs to be allocated? */
     while (rem_len > 0) {
-      q = memp_malloc(MEMP_PBUF_POOL);
+      ALLOC_POOL_PBUF(q);
       if (q == NULL) {
         /* free chain so far allocated */
         pbuf_free(p);