f-stack/adapter/ff_so_zone.c

209 lines
5.6 KiB
C
Raw Normal View History

2023-04-06 07:02:39 +00:00
#include <stdio.h>
#include <string.h>
#include <rte_eal.h>
#include <rte_memzone.h>
#include "ff_config.h"
#include "ff_socket_ops.h"
#define SOCKET_OPS_ZONE_NAME "ff_socket_ops_zone_%d"
2023-04-06 10:23:35 +00:00
/* Must be power of 2 */
#define SOCKET_OPS_CONTEXT_MAX_NUM (2 << 5)
2023-04-06 07:02:39 +00:00
#define SOCKET_OPS_CONTEXT_NAME_SIZE 32
#define SOCKET_OPS_CONTEXT_NAME "ff_so_context_"
static uint16_t ff_max_so_context = SOCKET_OPS_CONTEXT_MAX_NUM;
2023-04-06 11:09:55 +00:00
__FF_THREAD struct ff_socket_ops_zone *ff_so_zone;
2023-04-06 07:02:39 +00:00
2023-04-06 10:23:35 +00:00
static inline int
is_power_of_2(uint64_t n)
{
return (n != 0 && ((n & (n - 1)) == 0));
}
2023-04-06 07:02:39 +00:00
int
ff_set_max_so_context(uint16_t count)
{
if (ff_so_zone) {
ERR_LOG("Can not set: memzone has inited\n");
return -1;
}
/*if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
ERR_LOG("Can not set: process is not primary\n");
return 1;
}*/
2023-04-06 10:23:35 +00:00
if (!is_power_of_2(count)) {
ERR_LOG("Can not set: count:%d is not power of 2, use default:%d\n",
count, ff_max_so_context);
return -1;
}
2023-04-06 07:02:39 +00:00
ff_max_so_context = count;
return 0;
}
int
ff_create_so_memzone()
{
if (ff_so_zone) {
ERR_LOG("Can not create memzone: memzone has inited\n");
return -1;
}
if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
uint16_t i, proc_id;
for (proc_id = 0; proc_id < ff_global_cfg.dpdk.nb_procs; proc_id++) {
struct ff_socket_ops_zone *so_zone_tmp;
const struct rte_memzone *mz;
char zn[64];
size_t zone_size = sizeof(struct ff_socket_ops_zone) +
sizeof(struct ff_so_context) * ff_max_so_context;
snprintf(zn, sizeof(zn), SOCKET_OPS_ZONE_NAME, proc_id);
ERR_LOG("To create memzone:%s\n", zn);
mz = rte_memzone_reserve(zn, zone_size, rte_socket_id(), 0);
if (mz == NULL) {
ERR_LOG("Cannot reserve memory zone:%s\n", zn);
return -1;
}
memset(mz->addr, 0, zone_size);
so_zone_tmp = mz->addr;
rte_spinlock_init(&so_zone_tmp->lock);
so_zone_tmp->count = ff_max_so_context;
2023-04-06 10:23:35 +00:00
so_zone_tmp->mask = so_zone_tmp->count - 1;
2023-04-06 07:02:39 +00:00
so_zone_tmp->free = so_zone_tmp->count;
2023-04-06 10:23:35 +00:00
so_zone_tmp->idx = 0;
2023-04-06 07:02:39 +00:00
so_zone_tmp->sc = (struct ff_so_context *)(so_zone_tmp + 1);
for (i = 0; i < ff_max_so_context; i++) {
struct ff_so_context *sc = &so_zone_tmp->sc[i];
rte_spinlock_init(&sc->lock);
sc->status = FF_SC_IDLE;
sc->idx = i;
2023-04-06 07:02:39 +00:00
sc->inuse = 0;
if (sem_init(&sc->wait_sem, 1, 0) == -1) {
ERR_LOG("Initialize semaphore failed:%d\n", errno);
return -1;
}
}
if (proc_id == 0) {
ff_so_zone = so_zone_tmp;
}
}
}else {
const struct rte_memzone *mz;
char zn[64];
snprintf(zn, sizeof(zn), SOCKET_OPS_ZONE_NAME, ff_global_cfg.dpdk.proc_id);
ERR_LOG("To lookup memzone:%s\n", zn);
mz = rte_memzone_lookup(zn);
if (mz == NULL) {
ERR_LOG("Lookup memory zone:%s failed\n", zn);
return -1;
}
ff_so_zone = mz->addr;
}
return 0;
}
struct ff_so_context *
ff_attach_so_context(int proc_id)
{
struct ff_so_context *sc = NULL;
uint16_t i;
2023-04-06 11:09:55 +00:00
DEBUG_LOG("proc_id:%d, ff_so_zone:%p\n", proc_id, ff_so_zone);
2023-04-06 07:02:39 +00:00
if (ff_so_zone == NULL) {
const struct rte_memzone *mz;
char zn[64];
snprintf(zn, sizeof(zn), SOCKET_OPS_ZONE_NAME, proc_id);
ERR_LOG("To lookup memzone:%s\n", zn);
mz = rte_memzone_lookup(zn);
if (mz == NULL) {
ERR_LOG("Lookup memory zone:%s failed\n", zn);
return NULL;
}
ff_so_zone = mz->addr;
}
rte_spinlock_lock(&ff_so_zone->lock);
if (ff_so_zone->free == 0) {
ERR_LOG("Attach memzone failed: no free context\n");
rte_spinlock_unlock(&ff_so_zone->lock);
return NULL;
}
for (i = 0; i < ff_so_zone->count; i++) {
2023-04-06 10:23:35 +00:00
uint16_t idx = (ff_so_zone->idx + i) & ff_so_zone->mask;
sc = &ff_so_zone->sc[idx];
2023-04-06 07:02:39 +00:00
if (sc->inuse == 0) {
sc->inuse = 1;
rte_spinlock_init(&sc->lock);
sc->status = FF_SC_IDLE;
ff_so_zone->free--;
2023-04-06 11:09:55 +00:00
ff_so_zone->idx = idx + 1;
2023-04-06 07:02:39 +00:00
break;
}
}
2023-04-06 10:23:35 +00:00
if (unlikely(i == ff_so_zone->count)) {
ERR_LOG("Attach memzone failed: instance %d no free context,"
" fetel error of so status, all sc inuse, count:%d, free:%d\n",
proc_id, ff_so_zone->count, ff_so_zone->free);
sc = NULL;
}
DEBUG_LOG("attach sc:%p, so count:%d, free:%d, idx:%d, i:%d\n",
sc, ff_so_zone->count, ff_so_zone->free, ff_so_zone->idx, i);
2023-04-06 07:02:39 +00:00
rte_spinlock_unlock(&ff_so_zone->lock);
return sc;
}
void
ff_detach_so_context(struct ff_so_context *sc)
{
DEBUG_LOG("ff_so_zone:%p, sc:%p\n", ff_so_zone, sc);
2023-04-06 07:02:39 +00:00
if (ff_so_zone == NULL || sc == NULL) {
return;
}
DEBUG_LOG("detach sc:%p, ops:%d, status:%d, idx:%d, inuse:%d, so free:%u, idx:%u\n",
sc, sc->ops, sc->status, sc->idx, sc->inuse, ff_so_zone->free, ff_so_zone->idx);
2023-04-06 07:02:39 +00:00
rte_spinlock_lock(&ff_so_zone->lock);
if (sc->inuse == 1) {
sc->inuse = 0;
ff_so_zone->free++;
ff_so_zone->idx = sc->idx;
}
2023-04-06 07:02:39 +00:00
DEBUG_LOG("detach sc:%p, ops:%d, status:%d, idx:%d, inuse:%d, so free:%u, idx:%u\n",
sc, sc->ops, sc->status, sc->idx, sc->inuse, ff_so_zone->free, ff_so_zone->idx);
2023-04-06 07:02:39 +00:00
rte_spinlock_unlock(&ff_so_zone->lock);
}