Skip to content
This repository has been archived by the owner on Sep 19, 2024. It is now read-only.

Commit

Permalink
move commands related code from device_driver.c
Browse files Browse the repository at this point in the history
  • Loading branch information
waynz0r committed Sep 14, 2023
1 parent 7b925b1 commit 5f2796d
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 85 deletions.
68 changes: 68 additions & 0 deletions commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,63 @@
* <LICENSE.GPL or https://opensource.org/license/gpl-2-0>, at your option. This file may not be copied,
* modified, or distributed except according to those terms.
*/
#include <linux/slab.h>
#include <linux/uuid.h>

#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();
Expand All @@ -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);
}
20 changes: 20 additions & 0 deletions commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

#include "task_context.h"

#define COMMAND_TIMEOUT_SECONDS 1

typedef struct command_answer
{
char *error;
Expand All @@ -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
85 changes: 0 additions & 85 deletions device_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */

Expand All @@ -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);
Expand All @@ -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)
{
Expand Down

0 comments on commit 5f2796d

Please sign in to comment.