Subject: Re: UVM - Kernel & User access question
To: Stephan Uphoff <ups@stups.com>
From: Eric Circlaeys <eric.c@mac.com>
List: tech-kern
Date: 10/18/2003 00:23:14
> error = uvm_map(&p->p_vmspace->vm_map, &handler, segment_size,
>> 		  *object, 0, 0,
>> 		  UVM_MAPFLAG(prot, prot, UVM_INH_SHARE, UVM_ADV_RANDOM, 0));
>
> p->p_vmspace->vm_map is the user space map of the process p.
> Since you want kernel space you need to use kernel_map instead
> error = uvm_map(kernel_map,....

I though as I called this from a kernel process p->p_vmspace->vm_map 
was like kernel_map.

> I would also replace UVM_INH_SHARE with UVM_INH_NONE.
> ( Not that inheritance matters in the kernel ...  )

I try in a second with all of that!!

>> 	strncpy(pointeur, "toto\0", 5);
>
> strncpy(pointeur, "toto\0", 5); is a dangerous way to access the 
> memory.
> If the buffer is paged out and the swap is bad (disk error) you will 
> get
> a kernel panic.
> Using kcopy/uiomove you can try to copy the memory - and the functions 
> will
> just return an error on failure (no kernel panic).

You say that kcopy will avoid kernel panic if page is out,
how can I be sure that all the time I can read or write to my pageable 
kernel memory.
Because as I understand kcopy will return an error if the page is out 
but will not force the page to be up and wait for it to copy the data?

>> BUT questions:
>> Is that new allocated pointer available at any time physically?
>
> The memory is pageable and in kernel space.
> Since accessing it can cause a (major) page fault (sleep) the memory 
> can
> not be accessed  from interrupt context. (Unless wired before - making 
> it
> non pageable)
> It should only be accessed using special functions (unless temporarily 
> wired)
> to avoid kernel panics on swap space errors.

Is kcopy one of those functions?
What kind of other functions can I use to play with that memory and be 
sure it is wired at a time for usage?

>> Is this using virtual space, or physical?
>
> pageable virtual space - physical pages are allocated by page faults 
> and
> can change.
>
>> Is it similar to malloc used in kernel?
>
> malloc memory is not pageable.


Thank you a lot,
I am learning so much with you guys!!
Thanks for you time answering my poor questions!

Eric.


> 	Stephan
>
> Eric Circlaeys wrote:
>> Here the code I used:
>>
>> TEST is a test call used in a kthread.
>> And get a page fault...
>>
>> TEST
>> {
>> 	struct uvm_object	*o;
>>      char		*pointeur;
>>
>>      pointeur = (char *)nm_core_uvm_allocate(curproc, 6, &o);
>>
>> 	// tried
>> 	strncpy(pointeur, "toto\0", 5);
>> 	// or
>> 	copyout("toto\0", pointeur, 5);
>>
>>      printf("%s", pointeur);
>>
>>      nm_core_uvm_deallocate(p, 5, pointeur, o);
>> }
>>
>> void		*nm_core_uvm_allocate(struct proc *p, int size,
>> 				      struct uvm_object **object)
>> {
>>     size_t	segment_size;
>>    vaddr_t	handler;
>>    vm_prot_t	prot;
>>    int		error;
>>
>>    segment_size = (size + PGOFSET) & ~PGOFSET;
>>    *object = uao_create(segment_size, 0);
>>    prot = VM_PROT_READ | VM_PROT_WRITE;
>>    handler = round_page((vaddr_t)p->p_vmspace->vm_taddr + MAXTSIZ +
>> MAXDSIZ);
>>
>>    uao_reference(*object);
>>    error = uvm_map(&p->p_vmspace->vm_map, &handler, segment_size,
>> 		  *object, 0, 0,
>> 		  UVM_MAPFLAG(prot, prot, UVM_INH_SHARE, UVM_ADV_RANDOM, 0));
>>    if (error)
>>      {
>>        printf("uvm_map failed\n");
>>
>>        return (NULL);
>>      }
>>
>> return ((void *)handler);
>> }
>>
>> void		nm_core_uvm_deallocate(struct proc *p, int size, void *handler,
>> 				       struct uvm_object *object)
>> {
>>    size_t	segment_size;
>>
>>    segment_size = (size + PGOFSET) & ~PGOFSET;
>>    uao_detach(object);
>>    uvm_deallocate(&p->p_vmspace->vm_map, (vaddr_t)handler, 
>> segment_size);
>> }
>>
>>
>> I just tried the following with your help and it works:
>>
>> TEST
>> {
>> 	char *pointeur;
>>
>> 	pointeur = (char *)uvm_km_valloc_wait(kernel_map, 10);
>>
>> 	strcpy(pointeur, "toto\0");
>>
>> 	printf("%s\n", pointeur);
>> }
>>
>> BUT questions:
>> Is that new allocated pointer available at any time physically?
>> Is this using virtual space, or physical?
>> Is it similar to malloc used in kernel?
>>
>> What I would like is to allocate large amount of data without using
>> physical kernel memory but using the vm, all of this in a kernel
>> process.
>> This data should be able to access in the kernel process for read and
>> write...
>>
>> Thank you a lot for your help.
>> Eric.
>>
>> On 17 oct. 03, at 03:49, Stephan Uphoff wrote:
>>
>>>
>>>> der Mouse wrote:
>>>>> Eric Circlaeys wrote:
>>>>> I would like to use UVM to allocate large memory in kernel land.  I
>>>>> used uao_create, round_page, uvm_map to allocate virtual space.
>>>>
>>>> As I understand it, those allocate userland VM.
>>>
>>> Depends on the map passed to uvm_map().
>>> A kernel (sub) map will result in kernel virtual space.
>>>
>>> Do you need more than uvm_km_valloc_wait(kernel_map, 
>>> sizeOfYourBuffer)
>>> ?
>>>
>>>>
>>>>> But now I would like to write and read inside those pages still 
>>>>> being
>>>>> in kernel land.  When I tried with copyout to write buffer inside 
>>>>> it
>>>>> I got a page fault...
>>>
>>> copyin/copyin_proc from userspace to your buffer
>>> or kcopy from/to "normal" kernel space to/from your buffer.
>>> (or uiomove() as a parameter based wrapper around the functions 
>>> above)
>>>
>>> You can also temporary wire the memory to access it without special
>>> functions.
>>> ( The only way to access it from interrupt context)
>>>
>>> Without more information is is hard to guess your problem.
>>>
>>>
>>> Stephan
>>>
>
>