1717
1818// #define DEBUG
1919// #undef NO_DEBUG
20- #include < debug>
21- #include < cassert>
2220#if !defined(__MACH__)
2321#include < malloc.h>
2422#else
@@ -27,16 +25,23 @@ extern void *memalign(size_t, size_t);
2725#include < net/buffer_store.hpp>
2826#include < kernel/syscalls.hpp>
2927#include < common>
28+ #include < debug>
29+ #include < info>
30+ #include < cassert>
3031#include < smp>
3132#define PAGE_SIZE 0x1000
3233
34+ #define ENABLE_BUFFERSTORE_CHAIN
35+ #define BS_CHAIN_ALLOC_PACKETS 2048
36+
3337namespace net {
3438
3539 bool BufferStore::smp_enabled_ = false ;
3640
3741 BufferStore::BufferStore (size_t num, size_t bufsize) :
3842 poolsize_ {num * bufsize},
39- bufsize_ {bufsize}
43+ bufsize_ {bufsize},
44+ next_ (nullptr )
4045 {
4146 assert (num != 0 );
4247 assert (bufsize != 0 );
@@ -64,6 +69,29 @@ namespace net {
6469 free (this ->pool_ );
6570 }
6671
72+ BufferStore* BufferStore::get_next_bufstore ()
73+ {
74+ #ifdef ENABLE_BUFFERSTORE_CHAIN
75+ BufferStore* parent = this ;
76+ while (parent->next_ != nullptr ) {
77+ parent = parent->next_ ;
78+ if (parent->available () != 0 ) return parent;
79+ }
80+ INFO (" BufferStore" , " Allocating %u new packets" , BS_CHAIN_ALLOC_PACKETS);
81+ parent->next_ = new BufferStore (BS_CHAIN_ALLOC_PACKETS, bufsize ());
82+ return parent->next_ ;
83+ #else
84+ return nullptr ;
85+ #endif
86+ }
87+
88+ BufferStore::buffer_t BufferStore::get_buffer_directly () noexcept
89+ {
90+ auto addr = available_.back ();
91+ available_.pop_back ();
92+ return addr;
93+ }
94+
6795 BufferStore::buffer_t BufferStore::get_buffer ()
6896 {
6997#ifndef INCLUDEOS_SINGLE_THREADED
@@ -78,7 +106,11 @@ namespace net {
78106#ifndef INCLUDEOS_SINGLE_THREADED
79107 if (is_locked) unlock (plock);
80108#endif
81- panic (" <BufferStore> Storage pool full! Don't know how to increase pool size yet.\n " );
109+ #ifdef ENABLE_BUFFERSTORE_CHAIN
110+ return get_next_bufstore ()->get_buffer_directly ();
111+ #else
112+ panic (" <BufferStore> Buffer pool empty! Not configured to increase pool size.\n " );
113+ #endif
82114 }
83115
84116 auto addr = available_.back ();
@@ -111,6 +143,18 @@ namespace net {
111143 debug (" released\n " );
112144 return ;
113145 }
146+ #ifdef ENABLE_BUFFERSTORE_CHAIN
147+ // try to release buffer on linked bufferstore
148+ BufferStore* ptr = next_;
149+ while (ptr != nullptr ) {
150+ if (ptr->is_from_pool (buff)) {
151+ debug (" released on other bufferstore\n " );
152+ ptr->release_directly (buff);
153+ return ;
154+ }
155+ ptr = ptr->next_ ;
156+ }
157+ #endif
114158 // buffer not owned by bufferstore, so just delete it?
115159 debug (" deleted\n " );
116160 delete[] buff;
@@ -119,6 +163,11 @@ namespace net {
119163#endif
120164 }
121165
166+ void BufferStore::release_directly (buffer_t buffer)
167+ {
168+ available_.push_back (buffer);
169+ }
170+
122171 void BufferStore::move_to_this_cpu () noexcept
123172 {
124173 this ->cpu = SMP::cpu_id ();
0 commit comments