How to pass data to kthread_run - c

I'm try to make simple kernel module with multithreading.
So I'm using linux/kthread.h, kernel v. 5.2.11
Problem: I can't passing the char array into thread: Segmentation fault.
That's what I'm doing:
typedef struct {
int num;
char origin[MAXSTR]; //part of input for current thread
struct completion wait_for_thread; //completion struct
} kthread_arg;
Then:
struct task_struct *task;
static kthread_arg kta_first_thread;
kta_first_thread.num = 1;
strncpy(kta_first_thread.origin, dat1, MAXSTR );
//Here I have normal char array 'origin'
init_completion(&kta_first_thread.wait_for_thread);
task = kthread_run(&thread_function, (void*)&kta_first_thread, "one");
And after that I have the error. Moreover, if you remove the array from struct, then everything works.
I'm sure doing something wrong?

The args passed to kernel_run must be kmalloced, your args is in stack. I have met the same problem, your code should like this:
struct your_struct* test=NULL;
struct task_struct* t=NULL;
test=(struct your_struct*)kmalloc(sizeof(struct your_struct),GFP_KERNEL);
t=kthread_run(your_function,(void*)test,name);

Related

Attempting to lock a spinlock in the down function results in freezing

I am attempting to implement my own version of a semaphore into a linux vm and am running into a crash when I attempt to lock a spinlock inside the down function. Using GDB I found that the down is called immediately after the create function so the problem is definitely there.
Here is the create function:
asmlinkage long sys_create(int value, char name[32], char key[32]){
struct sem *new_sem = (struct sem*) kmalloc(sizeof(struct sem), GFP_ATOMIC);
struct sem_node *new_sem_node = (struct sem_node*) kmalloc(sizeof(struct sem_node), GFP_ATOMIC);
struct sem_node *curr_sem = sem_list_head;
new_sem_node->sem = new_sem;
spin_lock(&sem_lock);
new_sem->sem_id = IDcntr++;
spin_lock_init(&(new_sem->lock));
strncpy(new_sem->key, key, 32);
strncpy(new_sem->name, name, 32);
if(curr_sem == NULL)
{
sem_list_head = new_sem_node;
}
else
{
while(curr_sem->next != NULL)
{
curr_sem = curr_sem->next;
}
curr_sem->next = new_sem_node;
}
spin_unlock(&sem_lock);
return new_sem->sem_id;
}
Functions spin_lock, spin_unlock, and spin_lock_init are working as intended. The down function calls:
spin_lock(&(sem_list_head->sem->lock));
right at the beginning and freezes. To be more specific, in the gdb terminal, I try and get to the next line and it stops and in the actual machine it's completely stopped. No other functions are called between the create and down function. Below is the header file that defines the sem_node, process_node, and sem objects used in the create and down functions:
int IDcntr = 1;
DEFINE_SPINLOCK(sem_lock);
struct sem_node
{
struct sem* sem;
struct sem_node* next;
};
struct process_node
{
struct process_node* next;
struct task_struct* task;
};
struct sem
{
int value;
long sem_id;
spinlock_t lock;
char key[32];
char name[32];
struct process_node* head;
struct process_node* tail;
};
struct sem_node* sem_list_head = NULL;
Through independent testing the function DEFINE_SPINLOCK and object spinlock_t are working as intended. After thorough debugging the problem is in the create function. I freely admit that I am still learning how semaphores work so chances are I didn't set variables correctly or define things correctly. Any help in pointing me the right way would be greatly appreciated.

C - Reuse struct as argument for multiple PThreads

I have a while loop, and for each iteration of the loop, I am creating and populating a struct, and creating a thread while passing in that struct as an argument to the threaded function.
This is causing some issues - My while loop updates the data in the struct before my threaded function has a chance to make local copies of the struct data.
Does anyone know a good way to go about reusing a struct for multiple threads? I thought about using some kind of flag to make the main thread wait until the threaded function grabs its own copy, but this seems like it would introduce unnecessary waiting.
Here is an example of what I am trying to accomplish:
struct parameters {
int val1;
int val2;
int val3;
};
int main() {
...
while (readLine(file)) {
...
struct parameters *myParameters = malloc(sizeof(struct parameters));
myParameters.val1 = line.val1;
myParameters.val2 = line.val2;
myParameters.val3 = line.val3;
pthread_t myThread;
pthread_create(&myThread, NULL, &print, myParameters);
free(myParameters);
}
}
void *print(void *param) {
struct parameters *localParameters = param;
int threadVal1 = localParameters->val1;
int threadVal2 = localParameters->val2;
int threadVal3 = localParameters->val3;
}

Arguments on strcpy

So, I'm working on Binary Trees and I need to move information from one node to another one (structs). The thing is that I have this function that uses strcpy to copy the names and surnames from one node to other node (both sent as pointers) and when I try to run that part of the code in the program, it crashes.
Here is the function that copies the info (It has to copy the info from nodo2 to nodo1):
void MoverDatos(Tarbol *nodo1, Tarbol *nodo2)
{
strcpy((*nodo1)->appat, (*nodo2)->appat);
strcpy((*nodo1)->apmat, (*nodo2)->apmat);
strcpy((*nodo1)->nombre, (*nodo2)->nombre);
(*nodo1)->matr=(*nodo2)->matr;
}
As it wasn't working that way, I tried to use this one instead:
void MoverDatos(Tarbol *nodo1, Tarbol *nodo2)
{
char cad1[20];
char cad2[20];
char cad3[20];
strcpy(cad1, (*nodo2)->appat);
strcpy(cad2, (*nodo2)->apmat);
strcpy(cad3, (*nodo2)->nombre);
strcpy((*nodo1)->appat, cad1);
strcpy((*nodo1)->apmat, cad2);
strcpy((*nodo1)->nombre, cad3);
(*nodo1)->matr=(*nodo2)->matr;
}
But it didn't work either. I don't know if I'm not setting the arguments the right way or if I need to use another function, so any help or sugestion would be great. Thanks in advance.
It does compile with those arguments. I'm not getting any error message, it just crash and says that "program.exe has stopped working".
This is the struct that I'm using:
typedef struct _tdato
{
long matr;
char nombre[20];
char appat[20];
char apmat[20];
struct _tdato *sig;
struct _tdato *ant;
struct _tdato *padre=NULL;
}Tdato;
typedef Tdato *Tarbol;
The crash comes when I trie to copy a char[ ] to nodo1.

Static allocation of struct members within another static struct?

I am trying to implement a low-level thread lock without the use of dynamic memory allocation; this code will basically be used on a completely bare-bones kernel.
However, I am running into the problem of receiving a seg fault when I am trying to dereference a member inside this global static struct. My code is as such
My wrapper struct
/** LOCKING STRUCT & FUNCTIONS **/
struct lock {
int free;
struct thread_list* wait_list;
struct thread* current_holder;
};
The nested struct(intended as a linked list sort of deal)
struct thread_list {
struct thread *head;
};
And the member inside this list
struct thread {
void *top; // top of the stack for this thread
void *sp; // current stack pointer for this thread (context)
void (*start_func)(void *);
void *arg;
int state;
int exit_value;
struct thread *join_thread;
struct thread *next_thread;
int id;
};
The method I'm trying to implement is as such
void lock_init (struct lock *lk) {
lk->free = 1; //Set lock as free
struct thread_list waiting = lk->wait_list; //Get waitlist, works fine
waiting->head = NULL; //Set waitlist's head to null, SEGFAULTS HERE
}
I am not super proficient at C, but I can't seem to figure out the correct methodology/syntax to make my code work like this.
struct thread_list waiting = lk->wait_list; //Get waitlist, works fine
waiting->head = NULL; //Set waitlist's head to null, SEGFAULTS HERE
waiting is not a struct pointer but a struct variable . To access member using it you need to use . operator -
waiting.head = NULL;
Or to use -> operator declare it as a struct pointer .

Struct pointers behaving differently in two different functions, not sure why

I'm running into an issue where my "TEST INSIDE BUILD" works but not "TEST OUTSIDE." A fragment of the code is here
command_t build_op_command(unsigned code, command_t comone, command_t comtwo)
{
commad_t s;
s=malloc(sizeof(*s));
switch(code)
{
case 5:
s->type=SEQUENCE_COMMAND;
...
}
s->status=-1;
s->input=NULL;
s->output=NULL;
s->u.command[0]=comone;
s->u.command[1]=comtwo;
printf("TEST INSIDE BUILD: %d and %s",s->u.command[0]->type, s->u.command[0]->u.word[0]);
s->u.word=NULL;
s->u.subshell_command=NULL; //not yet implemented
return s;
}
and
...
command_t op_command;
op_command=build_op_command(op_pop(op_s),comone,comtwo);
printf("TEST OUTSIDE: %d and %s",op_command->u.command[0]->type,op_command->u.command[0]->u.word[0]);
...
command_t is a pointer for struct command. I'm not quite sure why it would correctly inside the build function, but not work correctly outside of it. Any input would be greatly appreciated. I run into a segmentation fault, I've tried allocating space for s->u.word, but that didn't seem to help anything.
struct command
{
enum command_type type;
int status;
char *input;
char *output;
union
{
struct command *command[2];
char **word;
struct command *subshell_command;
} u;
};
typeder struct command *command_t;
You do not give enough information, post the definition of command_t.
u is probably a union:
s->u.command[0]=comone;
s->u.command[1]=comtwo;
printf("TEST INSIDE BUILD: %d and %s",s->u.command[0]->type, s->u.command[0]->u.word[0]);
After the first printf, you initialize other members of this union and override the command:
s->u.word=NULL;
s->u.subshell_command=NULL; //not yet implemented
The next printf report different contents.
All members of a union share the same location in memory, you cannot use more than one member at a time.

Resources