summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorDimitri Staessens <dimitri@ouroboros.rocks>2026-01-20 22:25:41 +0100
committerSander Vrijders <sander@ouroboros.rocks>2026-01-26 07:50:33 +0100
commit0ca48453a067c7862f0bb6b85f152da826f59af7 (patch)
tree5daf26d84777ec6ad1c266601b66e59f9dcc88ca /include
parent1775201647a10923b9f73addf2304c3124350836 (diff)
downloadouroboros-0ca48453a067c7862f0bb6b85f152da826f59af7.tar.gz
ouroboros-0ca48453a067c7862f0bb6b85f152da826f59af7.zip
lib: Replace rdrbuff with a proper slab allocatorbe
This is a first step towards the Secure Shared Memory (SSM) infrastructure for Ouroboros, which will allow proper resource separation for non-privileged processes. This replaces the rdrbuff (random-deletion ring buffer) PoC allocator with a sharded slab allocator for the packet buffer pool to avoid the head-of-line blocking behaviour of the rdrb and reduce lock contention in multi-process scenarios. Each size class contains multiple independent shards, allowing parallel allocations without blocking. - Configurable shard count per size class (default: 4, set via SSM_POOL_SHARDS in CMake). The configured number of blocks are spread over the number of shards. As an example: SSM_POOL_512_BLOCKS = 768 blocks total These 768 blocks are shared among 4 shards (not 768 × 4 = 3072 blocks) - Lazy block distribution: all blocks initially reside in shard 0 and naturally migrate to process-local shards upon first allocation and subsequent free operations - Fallback with work stealing: processes attempt allocation from their local shard (pid % SSM_POOL_SHARDS) first, then steal from other shards if local is exhausted, eliminating fragmentation while maintaining low contention - Round-robin condvar signaling: blocking allocations cycle through all shard condition variables to ensure fairness - Blocks freed to allocator's shard: uses allocator_pid to determine target shard, enabling natural load balancing as process allocation patterns stabilize over time Maintains existing robust mutex semantics including EOWNERDEAD handling for dead process recovery. Internal structures exposed in ssm.h for testing purposes. Adds some tests (pool_test, pool_sharding_test.c. etc) verifying lazy distribution, migration, fallback stealing, and multiprocess behavior. Updates the ring buffer (rbuff) to use relaxed/acquire/release ordering on atomic indices. The ring buffer requires the (robust) mutex to ensure cross-structure synchronization between pool buffer writes and ring buffer index publication. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
Diffstat (limited to 'include')
-rw-r--r--include/ouroboros/crypt.h2
-rw-r--r--include/ouroboros/ipcp-dev.h14
-rw-r--r--include/ouroboros/shm_rdrbuff.h69
-rw-r--r--include/ouroboros/ssm_flow_set.h (renamed from include/ouroboros/shm_flow_set.h)28
-rw-r--r--include/ouroboros/ssm_pk_buff.h (renamed from include/ouroboros/shm_du_buff.h)30
-rw-r--r--include/ouroboros/ssm_pool.h72
-rw-r--r--include/ouroboros/ssm_rbuff.h (renamed from include/ouroboros/shm_rbuff.h)34
7 files changed, 126 insertions, 123 deletions
diff --git a/include/ouroboros/crypt.h b/include/ouroboros/crypt.h
index e1ad3199..6587a277 100644
--- a/include/ouroboros/crypt.h
+++ b/include/ouroboros/crypt.h
@@ -23,7 +23,7 @@
#ifndef OUROBOROS_LIB_CRYPT_H
#define OUROBOROS_LIB_CRYPT_H
-#include <ouroboros/shm_du_buff.h>
+#include <ouroboros/ssm_pk_buff.h>
#include <ouroboros/utils.h>
#include <assert.h>
diff --git a/include/ouroboros/ipcp-dev.h b/include/ouroboros/ipcp-dev.h
index 35e07414..118f1101 100644
--- a/include/ouroboros/ipcp-dev.h
+++ b/include/ouroboros/ipcp-dev.h
@@ -25,7 +25,7 @@
#include <ouroboros/ipcp.h>
#include <ouroboros/qoscube.h>
-#include <ouroboros/shm_rdrbuff.h>
+#include <ouroboros/ssm_pool.h>
#include <ouroboros/utils.h>
int ipcp_create_r(const struct ipcp_info * info);
@@ -41,16 +41,16 @@ int ipcp_flow_alloc_reply(int fd,
const buffer_t * data);
int ipcp_flow_read(int fd,
- struct shm_du_buff ** sdb);
+ struct ssm_pk_buff ** spb);
int ipcp_flow_write(int fd,
- struct shm_du_buff * sdb);
+ struct ssm_pk_buff * spb);
int np1_flow_read(int fd,
- struct shm_du_buff ** sdb);
+ struct ssm_pk_buff ** spb);
int np1_flow_write(int fd,
- struct shm_du_buff * sdb);
+ struct ssm_pk_buff * spb);
int ipcp_flow_dealloc(int fd);
@@ -61,9 +61,9 @@ int ipcp_flow_get_qoscube(int fd,
size_t ipcp_flow_queued(int fd);
-int ipcp_sdb_reserve(struct shm_du_buff ** sdb,
+int ipcp_spb_reserve(struct ssm_pk_buff ** spb,
size_t len);
-void ipcp_sdb_release(struct shm_du_buff * sdb);
+void ipcp_spb_release(struct ssm_pk_buff * spb);
#endif /* OUROBOROS_LIB_IPCP_DEV_H */
diff --git a/include/ouroboros/shm_rdrbuff.h b/include/ouroboros/shm_rdrbuff.h
deleted file mode 100644
index 30dc3ff7..00000000
--- a/include/ouroboros/shm_rdrbuff.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Ouroboros - Copyright (C) 2016 - 2024
- *
- * Random Deletion Ring Buffer for Data Units
- *
- * Dimitri Staessens <dimitri@ouroboros.rocks>
- * Sander Vrijders <sander@ouroboros.rocks>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * version 2.1 as published by the Free Software Foundation.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., http://www.fsf.org/about/contact/.
- */
-
-#ifndef OUROBOROS_LIB_SHM_RDRBUFF_H
-#define OUROBOROS_LIB_SHM_RDRBUFF_H
-
-#include <ouroboros/shm_du_buff.h>
-#include <ouroboros/time.h>
-
-#include <pthread.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-struct shm_rdrbuff;
-
-struct shm_rdrbuff * shm_rdrbuff_create(void);
-
-struct shm_rdrbuff * shm_rdrbuff_open(void);
-
-void shm_rdrbuff_close(struct shm_rdrbuff * rdrb);
-
-void shm_rdrbuff_destroy(struct shm_rdrbuff * rdrb);
-
-void shm_rdrbuff_purge(void);
-
-int shm_rdrbuff_mlock(struct shm_rdrbuff * rdrb);
-
-/* Returns block index, a ptr and du_buff. */
-ssize_t shm_rdrbuff_alloc(struct shm_rdrbuff * rdrb,
- size_t count,
- uint8_t ** ptr,
- struct shm_du_buff ** sdb);
-
-ssize_t shm_rdrbuff_alloc_b(struct shm_rdrbuff * rdrb,
- size_t count,
- uint8_t ** ptr,
- struct shm_du_buff ** sdb,
- const struct timespec * abstime);
-
-ssize_t shm_rdrbuff_read(uint8_t ** dst,
- struct shm_rdrbuff * rdrb,
- size_t idx);
-
-struct shm_du_buff * shm_rdrbuff_get(struct shm_rdrbuff * rdrb,
- size_t idx);
-
-int shm_rdrbuff_remove(struct shm_rdrbuff * rdrb,
- size_t idx);
-
-#endif /* OUROBOROS_LIB_SHM_RDRBUFF_H */
diff --git a/include/ouroboros/shm_flow_set.h b/include/ouroboros/ssm_flow_set.h
index 09e37649..02a5cb71 100644
--- a/include/ouroboros/shm_flow_set.h
+++ b/include/ouroboros/ssm_flow_set.h
@@ -20,8 +20,8 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#ifndef OUROBOROS_LIB_SHM_FLOW_SET_H
-#define OUROBOROS_LIB_SHM_FLOW_SET_H
+#ifndef OUROBOROS_LIB_SSM_FLOW_SET_H
+#define OUROBOROS_LIB_SSM_FLOW_SET_H
#include <ouroboros/fqueue.h>
@@ -32,38 +32,38 @@ struct flowevent {
int event;
};
-struct shm_flow_set;
+struct ssm_flow_set;
-struct shm_flow_set * shm_flow_set_create(pid_t pid);
+struct ssm_flow_set * ssm_flow_set_create(pid_t pid);
-void shm_flow_set_destroy(struct shm_flow_set * set);
+void ssm_flow_set_destroy(struct ssm_flow_set * set);
-struct shm_flow_set * shm_flow_set_open(pid_t pid);
+struct ssm_flow_set * ssm_flow_set_open(pid_t pid);
-void shm_flow_set_close(struct shm_flow_set * set);
+void ssm_flow_set_close(struct ssm_flow_set * set);
-void shm_flow_set_zero(struct shm_flow_set * shm_set,
+void ssm_flow_set_zero(struct ssm_flow_set * set,
size_t idx);
-int shm_flow_set_add(struct shm_flow_set * shm_set,
+int ssm_flow_set_add(struct ssm_flow_set * set,
size_t idx,
int flow_id);
-int shm_flow_set_has(struct shm_flow_set * shm_set,
+int ssm_flow_set_has(struct ssm_flow_set * set,
size_t idx,
int flow_id);
-void shm_flow_set_del(struct shm_flow_set * shm_set,
+void ssm_flow_set_del(struct ssm_flow_set * set,
size_t idx,
int flow_id);
-void shm_flow_set_notify(struct shm_flow_set * set,
+void ssm_flow_set_notify(struct ssm_flow_set * set,
int flow_id,
int event);
-ssize_t shm_flow_set_wait(const struct shm_flow_set * shm_set,
+ssize_t ssm_flow_set_wait(const struct ssm_flow_set * set,
size_t idx,
struct flowevent * fqueue,
const struct timespec * abstime);
-#endif /* OUROBOROS_LIB_SHM_FLOW_SET_H */
+#endif /* OUROBOROS_LIB_SSM_FLOW_SET_H */
diff --git a/include/ouroboros/shm_du_buff.h b/include/ouroboros/ssm_pk_buff.h
index c25d4b95..9b82ede3 100644
--- a/include/ouroboros/shm_du_buff.h
+++ b/include/ouroboros/ssm_pk_buff.h
@@ -20,39 +20,39 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#ifndef OUROBOROS_LIB_SHM_DU_BUFF_H
-#define OUROBOROS_LIB_SHM_DU_BUFF_H
+#ifndef OUROBOROS_LIB_SSM_PK_BUFF_H
+#define OUROBOROS_LIB_SSM_PK_BUFF_H
#include <sys/types.h>
#include <stdint.h>
-struct shm_du_buff;
+struct ssm_pk_buff;
-size_t shm_du_buff_get_idx(struct shm_du_buff * sdb);
+size_t ssm_pk_buff_get_idx(struct ssm_pk_buff * spb);
-uint8_t * shm_du_buff_head(struct shm_du_buff * sdb);
+uint8_t * ssm_pk_buff_head(struct ssm_pk_buff * spb);
-uint8_t * shm_du_buff_tail(struct shm_du_buff * sdb);
+uint8_t * ssm_pk_buff_tail(struct ssm_pk_buff * spb);
-size_t shm_du_buff_len(struct shm_du_buff * sdb);
+size_t ssm_pk_buff_len(struct ssm_pk_buff * spb);
-uint8_t * shm_du_buff_head_alloc(struct shm_du_buff * sdb,
+uint8_t * ssm_pk_buff_head_alloc(struct ssm_pk_buff * spb,
size_t size);
-uint8_t * shm_du_buff_tail_alloc(struct shm_du_buff * sdb,
+uint8_t * ssm_pk_buff_tail_alloc(struct ssm_pk_buff * spb,
size_t size);
-uint8_t * shm_du_buff_head_release(struct shm_du_buff * sdb,
+uint8_t * ssm_pk_buff_head_release(struct ssm_pk_buff * spb,
size_t size);
-uint8_t * shm_du_buff_tail_release(struct shm_du_buff * sdb,
+uint8_t * ssm_pk_buff_tail_release(struct ssm_pk_buff * spb,
size_t size);
-void shm_du_buff_truncate(struct shm_du_buff * sdb,
+void ssm_pk_buff_truncate(struct ssm_pk_buff * spb,
size_t len);
-int shm_du_buff_wait_ack(struct shm_du_buff * sdb);
+int ssm_pk_buff_wait_ack(struct ssm_pk_buff * spb);
-int shm_du_buff_ack(struct shm_du_buff * sdb);
+int ssm_pk_buff_ack(struct ssm_pk_buff * spb);
-#endif /* OUROBOROS_LIB_SHM_DU_BUFF_H */
+#endif /* OUROBOROS_LIB_SSM_PK_BUFF_H */
diff --git a/include/ouroboros/ssm_pool.h b/include/ouroboros/ssm_pool.h
new file mode 100644
index 00000000..80b22489
--- /dev/null
+++ b/include/ouroboros/ssm_pool.h
@@ -0,0 +1,72 @@
+/*
+ * Ouroboros - Copyright (C) 2016 - 2024
+ *
+ * Secure Shared Memory infrastructure (SSM) Packet Buffer
+ *
+ * Dimitri Staessens <dimitri@ouroboros.rocks>
+ * Sander Vrijders <sander@ouroboros.rocks>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., http://www.fsf.org/about/contact/.
+ */
+
+#ifndef OUROBOROS_LIB_SSM_POOL_H
+#define OUROBOROS_LIB_SSM_POOL_H
+
+#include <ouroboros/ssm_pk_buff.h>
+#include <ouroboros/time.h>
+
+#include <pthread.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+struct ssm_pool;
+
+struct ssm_pool * ssm_pool_create(void);
+
+struct ssm_pool * ssm_pool_open(void);
+
+void ssm_pool_close(struct ssm_pool * pool);
+
+void ssm_pool_destroy(struct ssm_pool * pool);
+
+void ssm_pool_purge(void);
+
+int ssm_pool_mlock(struct ssm_pool * pool);
+
+/* Alloc count bytes, returns block index, a ptr and pk_buff. */
+ssize_t ssm_pool_alloc(struct ssm_pool * pool,
+ size_t count,
+ uint8_t ** ptr,
+ struct ssm_pk_buff ** spb);
+
+ssize_t ssm_pool_alloc_b(struct ssm_pool * pool,
+ size_t count,
+ uint8_t ** ptr,
+ struct ssm_pk_buff ** spb,
+ const struct timespec * abstime);
+
+ssize_t ssm_pool_read(uint8_t ** dst,
+ struct ssm_pool * pool,
+ size_t idx);
+
+struct ssm_pk_buff * ssm_pool_get(struct ssm_pool * pool,
+ size_t idx);
+
+int ssm_pool_remove(struct ssm_pool * pool,
+ size_t idx);
+
+void ssm_pool_reclaim_orphans(struct ssm_pool * pool,
+ pid_t pid);
+
+#endif /* OUROBOROS_LIB_SSM_POOL_H */
diff --git a/include/ouroboros/shm_rbuff.h b/include/ouroboros/ssm_rbuff.h
index a1d2816a..791befa2 100644
--- a/include/ouroboros/shm_rbuff.h
+++ b/include/ouroboros/ssm_rbuff.h
@@ -20,8 +20,8 @@
* Foundation, Inc., http://www.fsf.org/about/contact/.
*/
-#ifndef OUROBOROS_LIB_SHM_RBUFF_H
-#define OUROBOROS_LIB_SHM_RBUFF_H
+#ifndef OUROBOROS_LIB_SSM_RBUFF_H
+#define OUROBOROS_LIB_SSM_RBUFF_H
#include <sys/types.h>
#include <sys/time.h>
@@ -33,39 +33,39 @@
#define ACL_FLOWDOWN 0002
#define ACL_FLOWPEER 0004
-struct shm_rbuff;
+struct ssm_rbuff;
-struct shm_rbuff * shm_rbuff_create(pid_t pid,
+struct ssm_rbuff * ssm_rbuff_create(pid_t pid,
int flow_id);
-void shm_rbuff_destroy(struct shm_rbuff * rb);
+void ssm_rbuff_destroy(struct ssm_rbuff * rb);
-struct shm_rbuff * shm_rbuff_open(pid_t pid,
+struct ssm_rbuff * ssm_rbuff_open(pid_t pid,
int flow_id);
-void shm_rbuff_close(struct shm_rbuff * rb);
+void ssm_rbuff_close(struct ssm_rbuff * rb);
-void shm_rbuff_set_acl(struct shm_rbuff * rb,
+void ssm_rbuff_set_acl(struct ssm_rbuff * rb,
uint32_t flags);
-uint32_t shm_rbuff_get_acl(struct shm_rbuff * rb);
+uint32_t ssm_rbuff_get_acl(struct ssm_rbuff * rb);
-void shm_rbuff_fini(struct shm_rbuff * rb);
+void ssm_rbuff_fini(struct ssm_rbuff * rb);
-int shm_rbuff_mlock(struct shm_rbuff * rb);
+int ssm_rbuff_mlock(struct ssm_rbuff * rb);
-int shm_rbuff_write(struct shm_rbuff * rb,
+int ssm_rbuff_write(struct ssm_rbuff * rb,
size_t idx);
-int shm_rbuff_write_b(struct shm_rbuff * rb,
+int ssm_rbuff_write_b(struct ssm_rbuff * rb,
size_t idx,
const struct timespec * abstime);
-ssize_t shm_rbuff_read(struct shm_rbuff * rb);
+ssize_t ssm_rbuff_read(struct ssm_rbuff * rb);
-ssize_t shm_rbuff_read_b(struct shm_rbuff * rb,
+ssize_t ssm_rbuff_read_b(struct ssm_rbuff * rb,
const struct timespec * abstime);
-size_t shm_rbuff_queued(struct shm_rbuff * rb);
+size_t ssm_rbuff_queued(struct ssm_rbuff * rb);
-#endif /* OUROBOROS_LIB_SHM_RBUFF_H */
+#endif /* OUROBOROS_LIB_SSM_RBUFF_H */