Skip to content

Commit

Permalink
fix(core/remio): allow bind_key to accept any value
Browse files Browse the repository at this point in the history
This commit removes the previous restriction on the `bind_key`
field, which required 0 < bind_key < REMIO_MAX_DEVICES.

Signed-off-by: João Peixoto <[email protected]>
  • Loading branch information
joaopeixoto13 committed Oct 31, 2024
1 parent 99fe2a9 commit 29988f8
Showing 1 changed file with 49 additions and 44 deletions.
93 changes: 49 additions & 44 deletions src/core/remio.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,8 @@
#include <config.h>
#include <spinlock.h>

#define REMIO_MAX_DEVICES 32
#define REMIO_DEVICE_UNINITIALIZED -1
#define REMIO_VCPU_NUM PLAT_CPU_NUM
#define REMIO_NUM_DEV_TYPES (REMIO_DEV_BACKEND - REMIO_DEV_FRONTEND + 1)
#define REMIO_VCPU_NUM PLAT_CPU_NUM
#define REMIO_NUM_DEV_TYPES (REMIO_DEV_BACKEND - REMIO_DEV_FRONTEND + 1)

/**
* @enum REMIO_HYP_EVENT
Expand Down Expand Up @@ -101,14 +99,18 @@ struct remio_request_event {
*/
struct remio_device_config {
struct {
cpuid_t cpu_id; /**< Backend VM CPU ID */
vmid_t vm_id; /**< Backend VM ID */
irqid_t interrupt; /**< Backend interrupt ID */
remio_bind_key_t bind_key; /**< Backend bind key */
cpuid_t cpu_id; /**< Backend VM CPU ID */
vmid_t vm_id; /**< Backend VM ID */
irqid_t interrupt; /**< Backend interrupt ID */
struct remio_shmem shmem; /**< Backend shared memory region */
} backend;
struct {
cpuid_t cpu_id; /**< Frontend VM CPU ID */
vmid_t vm_id; /**< Frontend VM ID */
irqid_t interrupt; /**< Frontend interrupt ID */
remio_bind_key_t bind_key; /**< Frontend bind key */
cpuid_t cpu_id; /**< Frontend VM CPU ID */
vmid_t vm_id; /**< Frontend VM ID */
irqid_t interrupt; /**< Frontend interrupt ID */
struct remio_shmem shmem; /**< Frontend shared memory region */
} frontend;
};

Expand Down Expand Up @@ -385,9 +387,7 @@ static void remio_cpu_send_msg(enum REMIO_CPU_MSG_EVENT event, unsigned long tar

void remio_init(void)
{
size_t frontend_cnt = 0, backend_cnt = 0;
int devices[REMIO_MAX_DEVICES][REMIO_NUM_DEV_TYPES];
struct remio_shmem shmem[REMIO_MAX_DEVICES][REMIO_NUM_DEV_TYPES];
size_t counter[REMIO_NUM_DEV_TYPES] = { 0 };

/** Only execute the Remote I/O initialization routine on the master CPU */
if (!cpu_is_master()) {
Expand All @@ -398,60 +398,65 @@ void remio_init(void)
objpool_init(&remio_request_event_pool);
list_init(&remio_device_list);

for (size_t i = 0; i < REMIO_MAX_DEVICES; i++) {
devices[i][REMIO_DEV_FRONTEND] = REMIO_DEVICE_UNINITIALIZED;
devices[i][REMIO_DEV_BACKEND] = REMIO_DEVICE_UNINITIALIZED;
shmem[i][REMIO_DEV_FRONTEND] = (struct remio_shmem){ 0 };
shmem[i][REMIO_DEV_BACKEND] = (struct remio_shmem){ 0 };
}

/** Create the Remote I/O devices based on the VM configuration */
for (size_t vm_id = 0; vm_id < config.vmlist_size; vm_id++) {
struct vm_config* vm_config = &config.vmlist[vm_id];
for (size_t i = 0; i < vm_config->platform.remio_dev_num; i++) {
struct remio_dev* dev = &vm_config->platform.remio_devs[i];
if (devices[dev->bind_key][dev->type] != REMIO_DEVICE_UNINITIALIZED) {
ERROR("Failed to link backend to the frontend, more than one %s was "
"atributed to the Remote I/O device %d",
dev->type == REMIO_DEV_BACKEND ? "backend" : "frontend", dev->bind_key);
struct remio_device* device = NULL;
list_foreach (remio_device_list, struct remio_device, remio_device) {
if ((dev->bind_key == remio_device->config.backend.bind_key &&
dev->type == REMIO_DEV_BACKEND) ||
(dev->bind_key == remio_device->config.frontend.bind_key &&
dev->type == REMIO_DEV_FRONTEND)) {
ERROR("Failed to link backend to the frontend, more than one %s was "
"atributed to the Remote I/O device %d",
dev->type == REMIO_DEV_BACKEND ? "backend" : "frontend", dev->bind_key);
} else if ((dev->type == REMIO_DEV_BACKEND &&
dev->bind_key == remio_device->config.frontend.bind_key) ||
(dev->type == REMIO_DEV_FRONTEND &&
dev->bind_key == remio_device->config.backend.bind_key)) {
device = remio_device;
break;
}
}
if (dev->type == REMIO_DEV_BACKEND) {
struct remio_device* device = objpool_alloc(&remio_device_pool);
if (device == NULL) {
device = objpool_alloc(&remio_device_pool);
if (device == NULL) {
ERROR("Failed allocating Remote I/O device node");
ERROR("Failed creating Remote I/O device %d", dev->bind_key);
}
device->bind_key = dev->bind_key;
device->config.backend.bind_key = (remio_bind_key_t)-1;
device->config.frontend.bind_key = (remio_bind_key_t)-1;
list_init(&device->request_event_list);
list_push(&remio_device_list, (node_t*)device);
backend_cnt++;
devices[dev->bind_key][REMIO_DEV_BACKEND] = (int)vm_id;
shmem[dev->bind_key][REMIO_DEV_BACKEND] = dev->shmem;
}
if (dev->type == REMIO_DEV_BACKEND) {
device->config.backend.bind_key = dev->bind_key;
device->config.backend.shmem = dev->shmem;
} else if (dev->type == REMIO_DEV_FRONTEND) {
frontend_cnt++;
devices[dev->bind_key][REMIO_DEV_FRONTEND] = (int)vm_id;
shmem[dev->bind_key][REMIO_DEV_FRONTEND] = dev->shmem;
device->config.frontend.bind_key = dev->bind_key;
device->config.frontend.shmem = dev->shmem;
} else {
ERROR("Unknown Remote I/O device type");
}
counter[dev->type]++;
}
}

/** Check if there is a 1-to-1 mapping between a Remote I/O backend and Remote I/O frontend */
if (backend_cnt != frontend_cnt) {
if (counter[REMIO_DEV_FRONTEND] != counter[REMIO_DEV_BACKEND]) {
ERROR("There is no 1-to-1 mapping between a Remote I/O backend and Remote I/O frontend");
}

/** Check if the shared memory regions are correctly configured */
for (size_t i = 0; i < REMIO_MAX_DEVICES; i++) {
if (devices[i][REMIO_DEV_FRONTEND] != REMIO_DEVICE_UNINITIALIZED &&
devices[i][REMIO_DEV_BACKEND] != REMIO_DEVICE_UNINITIALIZED) {
if (shmem[i][REMIO_DEV_FRONTEND].base != shmem[i][REMIO_DEV_BACKEND].base ||
shmem[i][REMIO_DEV_FRONTEND].size != shmem[i][REMIO_DEV_BACKEND].size ||
shmem[i][REMIO_DEV_FRONTEND].shmem_id != shmem[i][REMIO_DEV_BACKEND].shmem_id) {
ERROR("Invalid shared memory region configuration for Remote I/O device %d.\n"
"The frontend and backend shared memory regions must be the aligned.",
i);
}
list_foreach (remio_device_list, struct remio_device, dev) {
if (dev->config.backend.shmem.base != dev->config.frontend.shmem.base ||
dev->config.backend.shmem.size != dev->config.frontend.shmem.size ||
dev->config.backend.shmem.shmem_id != dev->config.frontend.shmem.shmem_id) {
ERROR("Invalid shared memory region configuration for Remote I/O device %d.\n"
"The frontend and backend shared memory regions must be the aligned.",
dev->bind_key);
}
}

Expand Down

0 comments on commit 29988f8

Please sign in to comment.