Skip to content

Commit 2b9e924

Browse files
committed
net: Add chained bufferstores to dynamically create extra packets
1 parent 46dc223 commit 2b9e924

3 files changed

Lines changed: 66 additions & 16 deletions

File tree

api/net/buffer_store.hpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,21 +45,21 @@ namespace net
4545
void release(void*);
4646

4747
/** Get size of a buffer **/
48-
inline size_t bufsize() const noexcept
48+
size_t bufsize() const noexcept
4949
{ return bufsize_; }
5050

51-
inline size_t poolsize() const noexcept
51+
size_t poolsize() const noexcept
5252
{ return poolsize_; }
5353

5454
/** Check if a buffer belongs here */
55-
inline bool is_from_pool(buffer_t addr) const noexcept
55+
bool is_from_pool(buffer_t addr) const noexcept
5656
{ return addr >= pool_begin() and addr < pool_end(); }
5757

5858
/** Check if an address is the start of a buffer */
59-
inline bool is_buffer(buffer_t addr) const noexcept
59+
bool is_buffer(buffer_t addr) const noexcept
6060
{ return (addr - pool_) % bufsize_ == 0; }
6161

62-
inline size_t available() const noexcept
62+
size_t available() const noexcept
6363
{ return available_.size(); }
6464

6565
/** move this bufferstore to the current CPU **/
@@ -76,10 +76,15 @@ namespace net
7676
return (addr - pool_) / bufsize_;
7777
}
7878

79+
BufferStore* get_next_bufstore();
80+
inline buffer_t get_buffer_directly() noexcept;
81+
inline void release_directly(buffer_t);
82+
7983
size_t poolsize_;
8084
size_t bufsize_;
8185
buffer_t pool_;
8286
std::vector<buffer_t> available_;
87+
BufferStore* next_;
8388
int cpu;
8489
static bool smp_enabled_;
8590
#ifndef INCLUDEOS_SINGLE_THREADED

src/net/buffer_store.cpp

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@
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+
3337
namespace 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();

test/net/integration/bufstore/service.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,28 +61,24 @@ void Service::start(const std::string&)
6161
packet = nullptr;
6262
CHECKSERT(bufstore_.available() == BUFFER_CNT, "Bufcount is now %i", BUFFER_CNT);
6363

64-
INFO("Test 2","Create and chain packets, release one-by-one");
64+
INFO("Test 2", "Create and chain %u packets, release one-by-one", BUFFER_CNT*10);
6565

6666
// Reinitialize the first packet
6767
packet = create_packet(bufstore_);
6868
CHECKSERT(bufstore_.available() == BUFFER_CNT - 1, "Bufcount is now %i", BUFFER_CNT - 1);
6969

7070
// Chain
71-
for (int i = 0; i < chain_size - 1; i++){
71+
for (int i = 0; i < 10*BUFFER_CNT - 1; i++){
7272
auto chained_packet = create_packet(bufstore_);
7373
packet->chain(std::move(chained_packet));
74-
CHECKSERT(bufstore_.available() == BUFFER_CNT - i - 2, "Bufcount is now %i", BUFFER_CNT - i - 2);
7574
}
7675

7776
INFO("Test 2","Releasing packet-chain one-by-one");
7877

7978
// Release one-by-one
8079
auto tail = std::move(packet);
8180
size_t i = 0;
82-
while(tail && i < BUFFER_CNT - 1) {
83-
CHECKSERT(bufstore_.available() == i,
84-
"Bufcount is now %i == %i", i,
85-
bufstore_.available());
81+
while(tail && i < 10*BUFFER_CNT - 1) {
8682
tail = tail->detach_tail();
8783
i++;
8884
}

0 commit comments

Comments
 (0)