Is there any reason why process limits (struct rlimit rlim[RLIM_NLIMITS]) are located within signal_struct structure of process descriptor (struct task_struct) in Linux Kernel?
Related
#include<stdio.h>
int giCtr0;
int main(void){
int iPid;
iPid = fork();
if (iPid == 0){
giCtr0++;
printf("In Child\n");
printf("Addr\t%x Value\t%d\n",&giCtr0,giCtr0);
}
else{
giCtr0+=2;
printf("In Parent\n");
printf("Addr\t%x Value\t%d\n",&giCtr0,giCtr0);
}
return 0;
}
The output from Ubuntu is as follows:
In Parent
Addr 601054 Value 2
In Child
Addr 601054 Value 1
The Value is proper and as expected.
How does address of the variable remain same in child and parent process?
Is there anything wrong in this code? Please suggest.
Memory addresses in a Unix-like VM system are per-process. The address you obtain with the C & operator is an OS-level construct, not the addressing scheme that maps directly to bits in RAM chips (or swapped-out VM pages). Thus, it's possible for the same address in two different processes to refer to two different locations in "real" memory.
fork spawns a clone of the parent process. For both processes to continue operating as they had before the fork, the entire memory image of the parent process is copied to create that of the child process... so, from each process' perspective, the memory addresses of all variables still point to the same things they did before. (But since the processes are now separate, changes in one affect a different underlying storage than is used by the other.)
How does address of the variable remain same in child and parent process?
To add to the comment from mkimball
Linux implements virtual memory. That means it sets up the hardware so each process sees a 'virtual' memory map instead of the 'real'/physical memory map.
Because of this the memory address 0x601054 of one process does not necessarily correspond to the same real memory 'cell' as the same address 0x601054 inside another process.
Kernel thread does not have memory descriptor it use mm_struct of last used process
how and what part of mm_struct use by kernel thread?
is it clear all detail of previous process?
kernel threads runs only in kernel address space. They don't have access to user space virtual memory and they only use kernel space memory address after PAGE_OFFSET. So (struct task_struct *)->mm field in the process descriptor is NULL. You would require to dynamically allocate memory within your kernel thread if required.
I have the pointer to the task struct for each tasks inside the Linux kernel, now how do I derive the CPU registers value (eax, or rax) for each tasks, assuming that the tasks is now not running?
task_pt_regs(task) provides a pointer to the block of saved registers. They are always located at the top of the task's kernel stack area. The kernel stack area is essentially "empty" while the task is executing. When a system call is executed (or the kernel is entered for other reasons), the "system entry" code is executed (for x86 this is in arch/x86/kernel/entry_{32,64}.S). The pt_regs structure is constructed to match the order of register saves done in the entry code.
In task_struct structure there is field called thread_struct. You can use that to get CPU specific state.
/* CPU-specific state of this task */
struct thread_struct thread;
Is there any way to get address and size of code segment of linux kernel thread (like task_struct->mm->mmap->vm_start and vm_end for active task with task_struct->mm != 0)?
I would recommend you go through the taskstats interface from the Linux kernel which can provide info on all the Linux threads, including VM stats.
Have a look on the doc, as well as on the header for the interface.
There is no easy way to hack into the kernel to enumerate all the task_struct available.
I am developing a kernel application which involves kthreads. I create an array of structure and allocate memory using malloc in user-space. Then I call a system call (which I implemented) and pass the address of array to kernel-space. In the handler of system-call I create I create 2 kthreads which will monitor the array. kthread can change some value and user-space threads can also change some values. The idea is to use the array as a shared memory. But some when I access the memory in kernel space (using copy_from_user) the data are somehow changed. I can verify that the address are same when it was assigned and in kernel. But when using copy_from_user it is giving various values like garbage values.
Also is the following statement ok?
int kthread_run_function(void* data){
struct entry tmp;
copy_from_user(&tmp, data, sizeof(struct entry));
}
This is not OK because copy_from_user() copies from the current user process (which should be obvious, since there's no way to tell it which user process to copy from).
In a syscall invoked by your userspace process this is OK, because the current process is your userspace process. However, within the kernel thread the current process could be any other process on the system - so you're copying from a random process's memory, which is why you get garbage.
If you want to share memory between the kernel and a userspace process, the right way to do this is to have the kernel allocate it, then allow the userspace process to map it into its address space with mmap(). The kernel thread and the userspace process will use different pointers to refer to the memory region - the kernel thread will use a pointer to the memory allocated within the kernel address space, and the userspace process will use a pointer to the memory region returned by mmap().
No, generally it's not OK since data is kernel virtual address, not a user virtual address.
However, IFF you called kthread_create with the data argument equal to an __user pointer, this should be ok.