From 5f2796d7270de336fc0a35535dc4998bcd8ceacf Mon Sep 17 00:00:00 2001 From: Zsolt Varga Date: Thu, 14 Sep 2023 16:02:42 +0200 Subject: [PATCH] move commands related code from device_driver.c --- commands.c | 68 +++++++++++++++++++++++++++++++++++++++ commands.h | 20 ++++++++++++ device_driver.c | 85 ------------------------------------------------- 3 files changed, 88 insertions(+), 85 deletions(-) diff --git a/commands.c b/commands.c index 999dacfb..edfbca1b 100644 --- a/commands.c +++ b/commands.c @@ -7,10 +7,63 @@ * , at your option. This file may not be copied, * modified, or distributed except according to those terms. */ +#include +#include #include "commands.h" #include "json.h" +// create a function to add a command to the list (called from the VM), locked with a spinlock +command_answer *send_command(char *name, char *data, task_context *context) +{ + struct command *cmd = kmalloc(sizeof(struct command), GFP_KERNEL); + + uuid_gen(&cmd->uuid); + cmd->name = name; + cmd->data = data; + cmd->context = context; + init_waitqueue_head(&cmd->wait_queue); + + spin_lock_irqsave(&command_list_lock, command_list_lock_flags); + list_add_tail(&cmd->list, &command_list); + spin_unlock_irqrestore(&command_list_lock, command_list_lock_flags); + + DEFINE_WAIT(wait); + + // wait until the command is processed + printk("wasm: waiting for command to be processed"); + + // wait for the command to be processed + prepare_to_wait(&cmd->wait_queue, &wait, TASK_INTERRUPTIBLE); + // Sleep until the condition is true or the timeout expires + unsigned long timeout = msecs_to_jiffies(COMMAND_TIMEOUT_SECONDS * 1000); + schedule_timeout(timeout); + + finish_wait(&cmd->wait_queue, &wait); + + if (cmd->answer == NULL) + { + printk(KERN_ERR "wasm: command answer timeout"); + + cmd->answer = kmalloc(sizeof(struct command_answer), GFP_KERNEL); + cmd->answer->error = kmalloc(strlen("timeout") + 1, GFP_KERNEL); + strcpy(cmd->answer->error, "timeout"); + } + + spin_lock_irqsave(&command_list_lock, command_list_lock_flags); + list_del(&cmd->list); + spin_unlock_irqrestore(&command_list_lock, command_list_lock_flags); + + command_answer *cmd_answer = cmd->answer; + if (cmd->context) + { + free_task_context(cmd->context); + } + kfree(cmd); + + return cmd_answer; +} + command_answer *send_accept_command(u16 port) { JSON_Value *root_value = json_value_init_object(); @@ -34,3 +87,18 @@ command_answer *send_connect_command(u16 port) return answer; } + +void free_command_answer(struct command_answer *cmd_answer) +{ + if (cmd_answer->error) + { + kfree(cmd_answer->error); + } + + if (cmd_answer->answer) + { + kfree(cmd_answer->answer); + } + + kfree(cmd_answer); +} diff --git a/commands.h b/commands.h index 98fdf024..af32fb06 100644 --- a/commands.h +++ b/commands.h @@ -13,6 +13,8 @@ #include "task_context.h" +#define COMMAND_TIMEOUT_SECONDS 1 + typedef struct command_answer { char *error; @@ -26,4 +28,22 @@ command_answer *send_command(char *name, char *data, task_context *context); command_answer *send_accept_command(u16 port); command_answer *send_connect_command(u16 port); +// create a linked list for outgoing commands +typedef struct command +{ + struct list_head list; + char *name; + char *data; + task_context *context; + uuid_t uuid; + struct command_answer *answer; + wait_queue_head_t wait_queue; +}; + +// protect the command list with a mutex +static DEFINE_SPINLOCK(command_list_lock); +static unsigned long command_list_lock_flags; +static LIST_HEAD(command_list); +static LIST_HEAD(in_flight_command_list); + #endif diff --git a/device_driver.c b/device_driver.c index 3ca971ff..e4562e88 100644 --- a/device_driver.c +++ b/device_driver.c @@ -25,7 +25,6 @@ /* Global variables are declared as static, so are global within the file. */ #define DEFAULT_MODULE_ENTRYPOINT "main" -#define COMMAND_TIMEOUT_SECONDS 1 static int major; /* major number assigned to our device driver */ @@ -38,24 +37,6 @@ enum /* Is device open? Used to prevent multiple access to device */ static atomic_t already_open = ATOMIC_INIT(CDEV_NOT_USED); -// create a linked list for outgoing commands -typedef struct command -{ - struct list_head list; - char *name; - char *data; - task_context *context; - uuid_t uuid; - struct command_answer *answer; - wait_queue_head_t wait_queue; -}; - -// protect the command list with a mutex -static DEFINE_SPINLOCK(command_list_lock); -static unsigned long command_list_lock_flags; -static LIST_HEAD(command_list); -static LIST_HEAD(in_flight_command_list); - static struct command *lookup_in_flight_command(char *id) { spin_lock_irqsave(&command_list_lock, command_list_lock_flags); @@ -76,72 +57,6 @@ static struct command *lookup_in_flight_command(char *id) return cmd; } -void free_command_answer(struct command_answer *cmd_answer) -{ - if (cmd_answer->error) - { - kfree(cmd_answer->error); - } - - if (cmd_answer->answer) - { - kfree(cmd_answer->answer); - } - - kfree(cmd_answer); -} - -// create a function to add a command to the list (called from the VM), locked with a spinlock -command_answer *send_command(char *name, char *data, task_context *context) -{ - struct command *cmd = kmalloc(sizeof(struct command), GFP_KERNEL); - - uuid_gen(&cmd->uuid); - cmd->name = name; - cmd->data = data; - cmd->context = context; - init_waitqueue_head(&cmd->wait_queue); - - spin_lock_irqsave(&command_list_lock, command_list_lock_flags); - list_add_tail(&cmd->list, &command_list); - spin_unlock_irqrestore(&command_list_lock, command_list_lock_flags); - - DEFINE_WAIT(wait); - - // wait until the command is processed - printk("wasm: waiting for command to be processed"); - - // wait for the command to be processed - prepare_to_wait(&cmd->wait_queue, &wait, TASK_INTERRUPTIBLE); - // Sleep until the condition is true or the timeout expires - unsigned long timeout = msecs_to_jiffies(COMMAND_TIMEOUT_SECONDS * 1000); - schedule_timeout(timeout); - - finish_wait(&cmd->wait_queue, &wait); - - if (cmd->answer == NULL) - { - printk(KERN_ERR "wasm: command answer timeout"); - - cmd->answer = kmalloc(sizeof(struct command_answer), GFP_KERNEL); - cmd->answer->error = kmalloc(strlen("timeout") + 1, GFP_KERNEL); - strcpy(cmd->answer->error, "timeout"); - } - - spin_lock_irqsave(&command_list_lock, command_list_lock_flags); - list_del(&cmd->list); - spin_unlock_irqrestore(&command_list_lock, command_list_lock_flags); - - command_answer *cmd_answer = cmd->answer; - if (cmd->context) - { - free_task_context(cmd->context); - } - kfree(cmd); - - return cmd_answer; -} - // create a function to get a command from the list (called from the driver), locked with a mutex static struct command *get_command(void) {