A message for Linux.com registered users: We are in the process of making changes to the Linux forums. Starting Monday, 8/13/18 at 6:00 PM PT, you will be unable to access the forums. They will re-launch as soon as possible on Wednesday, 8/15/18 with new features and improved functionality. Thank you for your patience and stay tuned for the new improved forums.

March 26, 2010

change user mode value from kernel control path

Hi,

for a special purpose I need to read values in lxrt user mode which are changed in the kernel control path. To avoid expensive system calls I register the address of a user mode variable (int) with a new pointer in the task control path:

typedef struct rt_task_struct {
…
volatile int *tp_status;
…
}

To register the variable I introduced a new function in the api.c file:

RTAI_SYSCALL_MODE int rt_register_v(int variable, void *address, int size)
{
RT_TASK *rt_current;

if (!access_ok(VERIFY_WRITE, address, size)) {
return -EINVAL;
}

rt_current = RT_CURRENT;
switch(variable) {
case RT_VAR_TP_STATUS:
rt_current->tp_status = (int *)address;
break;
…
}

In my user space program I use the following code to register the variable:

int anytime_assign_tp_status(const int *tp_status) {
if (tp_status == NULL) {
return EANYTIME_INVAL;
}

if (mlock((const void *)tp_status, sizeof(const int )) < 0) {
return EANYTIME_MLOCK;
}
if (rt_register_v(RT_VAR_TP_STATUS, (void *)tp_status, sizeof(int)) < 0) {
return EANYTIME_INVAL;
}
return 0;
}

…..

I call the function with the following command:

volatile int tp_status = 1;
…
anytime_assign_tp_status(&tp_status);
…

The registration works fine. In rt_schedule() I am able to access the user mode value with *(rt_current->tp_status). To chance the value from kernel control path I use the following line of code:

if (rt_current->tp_status != NULL) put_user(3, rt_current->tp_status);

This also works fine. But after a lxrt_context_switch(prev, new_task->lnxtsk, cpuid); call in the rt_time_handler function the pointer new_task->tp_status points to the same user mode address but every access to user mode variable like *(new_task->tp_status) freeze the whole system? Furthermore sometimes it is possible to read the value of *(new_task->tp_status) and the content isn’t longer 1 or 3 - its 260348 for example. Does anybody knows the problem? I avoided swapping with the mlock call so why it is not longer possible to access the value after a context switch?

Best regards,

Nekoto

Click Here!