Subject: Re: UVM - Kernel & User access question
To: None <tech-kern@NetBSD.org>
From: Eric Circlaeys <eric.c@mac.com>
List: tech-kern
Date: 10/25/2003 11:16:20
--Apple-Mail-5-719351052
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
charset=US-ASCII;
format=flowed
Thanks a lot!
I am closed to the success, the module runs well!
BUT a last bug appeared and seems to be in relation to UVM...
I used the following code as we built together:
void *nm_core_uvm_allocate(struct proc *p, int size,
struct uvm_object **object)
{
vsize_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(kernel_map, &handler, segment_size,
*object, 0, 0,
UVM_MAPFLAG(prot, prot, UVM_INH_NONE, 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(kernel_map, (vaddr_t)handler, segment_size);
}
Using this API in my kernel module I can now allocate and deallocate
pageable kernel memory.
I use right now kcopy for all my needs.
BUT BUT BUT after deallocating such memory,
sometimes, my NetBSD 1.6.1, or other applications running raised an
uvm_page_fault, or other uvm_* errors and cause a kernel panic.
Did I forget something to do when deallocating memory or usage of
virtual / physical pages???
Thank you very much in advanced.
Best regards,
Eric.
On 20 oct. 03, at 16:21, Stephan Uphoff wrote:
>
>>> 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?
>
> Both normal memory access and kcopy will try to page in the memory
> if it is paged out - this is not the problem.
>
> However if paging in fails (disk error,...) kcopy will return an error
> while strncpy or access through a pointer would cause a kernel panic.
>
> ( for i386 take a look at pcb_onfault (PCB_ONFAULT) - an architecture
> specific exception mechanisms used for recovering from page faults
> that encountered errors in kcopy/copyin,...)
>
>
>> What kind of other functions can I use to play with that memory and be
>> sure it is wired at a time for usage?
>
> uvm_fault_wire can be used to wire the pages and you can then use
> anything
> to access the memory and even use it in a an interrupt context.
> (uvm_fault_unwire removes the wiring)
> Once the page is wired you no longer have to worry about page faults.
> However wiring/unwiring is a relative expensive function.
>
> kcopy/copyin/copyout can be used without first wiring the pages because
> of their internal exception handling.
> ( However these functions can not be used from interrupt context)
>
>
> Stephan
>
--Apple-Mail-5-719351052
Content-Transfer-Encoding: 7bit
Content-Type: text/enriched;
charset=US-ASCII
Thanks a lot!
I am closed to the success, the module runs well!
BUT a last bug appeared and seems to be in relation to UVM...
I used the following code as we built together:
<fixed><bigger>
<color><param>7675,0F0E,504F</param>void</color> *nm_core_uvm_allocate(<color><param>7675,0F0E,504F</param>struct</color>
proc *p, <color><param>7675,0F0E,504F</param>int</color> size,
<color><param>7675,0F0E,504F</param>struct</color>
uvm_object **object)
{
vsize_t segment_size;
vaddr_t handler;
vm_prot_t prot;
<color><param>7675,0F0E,504F</param>int</color> error;
segment_size = (size + PGOFSET) & ~PGOFSET;
*object = uao_create(segment_size,
<color><param>0000,0000,FFFE</param>0</color>);
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(kernel_map, &handler, segment_size,
*object, <color><param>0000,0000,FFFE</param>0</color>,
<color><param>0000,0000,FFFE</param>0</color>,
UVM_MAPFLAG(prot, prot, UVM_INH_NONE, UVM_ADV_RANDOM,
<color><param>0000,0000,FFFE</param>0</color>));
<color><param>7675,0F0E,504F</param>if</color> (error)
{
printf(<color><param>8988,1312,1514</param>"uvm_map
failed\n"</color>);
<color><param>7675,0F0E,504F</param>return</color>
(<color><param>7675,0F0E,504F</param>NULL</color>);
}
<color><param>7675,0F0E,504F</param>return</color>
((<color><param>7675,0F0E,504F</param>void</color> *)handler);
}
<color><param>7675,0F0E,504F</param>void</color> nm_core_uvm_deallocate(<color><param>7675,0F0E,504F</param>struct</color>
proc *p, <color><param>7675,0F0E,504F</param>int</color> size,
<color><param>7675,0F0E,504F</param>void</color> *handler,
<color><param>7675,0F0E,504F</param>struct</color>
uvm_object *object)
{
size_t segment_size;
segment_size = (size + PGOFSET) & ~PGOFSET;
uao_detach(object);
uvm_deallocate(kernel_map, (vaddr_t)handler, segment_size);
}
Using this API in my kernel module I can now allocate and deallocate
pageable kernel memory.
I use right now kcopy for all my needs.
BUT BUT BUT after deallocating such memory,
sometimes, my NetBSD 1.6.1, or other applications running raised an
uvm_page_fault, or other uvm_* errors and cause a kernel panic.
Did I forget something to do when deallocating memory or usage of
virtual / physical pages???
Thank you very much in advanced.
Best regards,
Eric.
</bigger></fixed>
On 20 oct. 03, at 16:21, Stephan Uphoff wrote:
<excerpt>
<excerpt><excerpt>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).
</excerpt>
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?
</excerpt>
Both normal memory access and kcopy will try to page in the memory
if it is paged out - this is not the problem.
However if paging in fails (disk error,...) kcopy will return an error
while strncpy or access through a pointer would cause a kernel panic.
( for i386 take a look at pcb_onfault (PCB_ONFAULT) - an architecture
specific exception mechanisms used for recovering from page faults
that encountered errors in kcopy/copyin,...)
<excerpt>What kind of other functions can I use to play with that
memory and be
sure it is wired at a time for usage?
</excerpt>
uvm_fault_wire can be used to wire the pages and you can then use
anything
to access the memory and even use it in a an interrupt context.
(uvm_fault_unwire removes the wiring)
Once the page is wired you no longer have to worry about page faults.
However wiring/unwiring is a relative expensive function.
kcopy/copyin/copyout can be used without first wiring the pages because
of their internal exception handling.
( However these functions can not be used from interrupt context)
Stephan
</excerpt>
--Apple-Mail-5-719351052--