Re: Using emap for i386/amd64 early during boot

2010-06-22 Thread Mindaugas Rasiukevicius
Jean-Yves Migeon jeanyves.mig...@free.fr wrote:
  Agree with David's point, but it should not be done at function level.
  Rather higher level interface abstraction.  In uvmplock branch, I have
  already split some x86 pmap bits into pmap_tlb.c and xen_pmap.c modules.
  More interfaces can be abstracted in respect to e.g. Xen.

 ... 
 
 Is pmap.c expected to be split in two files too (pmap.c and x86_pmap.c?) 
 I noticed that in your pmap.c, some functions (already found in 
 xen_pmap.c) are #ifndef XEN out, to avoid conflict I suppose.

Not into pmap.c and x86_pmap.c - it is already x86. :) But yes, some helper
routines which tend to differ between i386 and amd64 might be abstracted into
separate {i386,amd64}_pmap.c modules.  However, I am thinking of higher level
abstractions first, for example - splitting page table management code into
pmap_pt.c and making it a clearer interface.

-- 
Mindaugas


Re: Using emap for i386/amd64 early during boot

2010-06-20 Thread Mindaugas Rasiukevicius
Jean-Yves Migeon jeanyves.mig...@free.fr wrote:
 As I have yet to understand the inner workings of emap, I'd like to know 
 if it is possible to wrap i386_cpu_switch_pmap() around uvm_emap 
 functions, like this:
 
 [...]
 u_int gen = uvm_emap_gen_return();
 i386_cpu_switch_pmap(pmap);
 uvm_emap_update(gen);
 [...]

Sure.  Both calls just get/update the generation numbers (see uvm_emap.c).

However, there are some thoughts to revisit current UVM emap, so I would
suggest you to not spend much time on this (i.e. you can just skip these
calls around TLB flushes for now).

-- 
Mindaugas


Re: Using emap for i386/amd64 early during boot

2010-06-20 Thread David Young
On Sun, Jun 20, 2010 at 07:45:32PM +0200, Jean-Yves Migeon wrote:
 For convenience, here's i386_cpu_switch_pmap:

I know that a lot of legacy code uses the preprocessor the way that you
have in i386_cpu_switch_pmap(), but I don't think that the preprocessor
should be used in that way any longer.  In my experience, code that uses
the preprocessor heavily is harder to read and to change and to test.
Why don't you let config(1) and ld(1) do the work that the preprocessor
does?  For example:

file switch_pmap_pae_xen.c  pae  xen

/*
 * Switches pmap for the current CPU. Hides the implementation
 * differences between the PAE and non-PAE cases.
 */
void
i386_cpu_switch_pmap(struct pmap *pmap)
{
int i;
int s = splvm(); /* just to be safe */
struct cpu_info *ci = curcpu();
paddr_t l3_pd = xpmap_ptom_masked(ci-ci_l3_pdirpa);
/* don't update the kernel L3 slot */
for (i = 0 ; i  PDP_SIZE - 1; i++) {
xpq_queue_pte_update(l3_pd + i * sizeof(pd_entry_t),
xpmap_ptom(pmap-pm_pdirpa[i]) | PG_V);
}
splx(s);

u_int gen = uvm_emap_gen_return();
tlbflush();
uvm_emap_update(gen);
}

file switch_pmap_pae.c  pae  !xen
/*
 * Switches pmap for the current CPU. Hides the implementation
 * differences between the PAE and non-PAE cases.
 */
void
i386_cpu_switch_pmap(struct pmap *pmap)
{
int i;
int s = splvm(); /* just to be safe */
struct cpu_info *ci = curcpu();
pd_entry_t *l3_pd = ci-ci_l3_pdir;
for (i = 0 ; i  PDP_SIZE; i++) {
l3_pd[i] = pmap-pm_pdirpa[i] | PG_V;
}
splx(s);

u_int gen = uvm_emap_gen_return();
tlbflush();
uvm_emap_update(gen);
}

file switch_pmap.c  !pae

/*
 * Switches pmap for the current CPU. Hides the implementation
 * differences between the PAE and non-PAE cases.
 */
void
i386_cpu_switch_pmap(struct pmap *pmap)
{
u_int gen = uvm_emap_gen_return();
lcr3(pmap_pdirpa(pmap, 0));
uvm_emap_update(gen);
}

-- 
David Young OJC Technologies
dyo...@ojctech.com  Urbana, IL * (217) 278-3933


Re: Using emap for i386/amd64 early during boot

2010-06-20 Thread Jean-Yves Migeon

On 20.06.2010 22:19, David Young wrote:

On Sun, Jun 20, 2010 at 07:45:32PM +0200, Jean-Yves Migeon wrote:

For convenience, here's i386_cpu_switch_pmap:


I know that a lot of legacy code uses the preprocessor the way that you
have in i386_cpu_switch_pmap(), but I don't think that the preprocessor
should be used in that way any longer.  In my experience, code that uses
the preprocessor heavily is harder to read and to change and to test.
Why don't you let config(1) and ld(1) do the work that the preprocessor
does?  For example:

[snip]

I like that. Will do. Thanks!

--
Jean-Yves Migeon
jeanyves.mig...@free.fr


Re: Using emap for i386/amd64 early during boot

2010-06-20 Thread Jean-Yves Migeon

On 20.06.2010 20:00, Mindaugas Rasiukevicius wrote:

Jean-Yves Migeonjeanyves.mig...@free.fr  wrote:

As I have yet to understand the inner workings of emap, I'd like to know
if it is possible to wrap i386_cpu_switch_pmap() around uvm_emap
functions, like this:

[...]
u_int gen = uvm_emap_gen_return();
i386_cpu_switch_pmap(pmap);
uvm_emap_update(gen);
[...]


Sure.  Both calls just get/update the generation numbers (see uvm_emap.c).

However, there are some thoughts to revisit current UVM emap, so I would
suggest you to not spend much time on this (i.e. you can just skip these
calls around TLB flushes for now).


Alright; then I'll go directly to benchmarking/regression testing, patch 
is in final state for me.


Cheers,

--
Jean-Yves Migeon
jeanyves.mig...@free.fr


Re: Using emap for i386/amd64 early during boot

2010-06-20 Thread Mindaugas Rasiukevicius
Jean-Yves Migeon jeanyves.mig...@free.fr wrote:
 
  I know that a lot of legacy code uses the preprocessor the way that you
  have in i386_cpu_switch_pmap(), but I don't think that the preprocessor
  should be used in that way any longer.  In my experience, code that uses
  the preprocessor heavily is harder to read and to change and to test.
  Why don't you let config(1) and ld(1) do the work that the preprocessor
  does?  For example:
  [snip]
 
 I like that. Will do. Thanks!

Agree with David's point, but it should not be done at function level.
Rather higher level interface abstraction.  In uvmplock branch, I have
already split some x86 pmap bits into pmap_tlb.c and xen_pmap.c modules.
More interfaces can be abstracted in respect to e.g. Xen.

-- 
Mindaugas


Re: Using emap for i386/amd64 early during boot

2010-06-20 Thread Jean-Yves Migeon

On 21.06.2010 00:39, Mindaugas Rasiukevicius wrote:

Jean-Yves Migeonjeanyves.mig...@free.fr  wrote:


I know that a lot of legacy code uses the preprocessor the way that you
have in i386_cpu_switch_pmap(), but I don't think that the preprocessor
should be used in that way any longer.  In my experience, code that uses
the preprocessor heavily is harder to read and to change and to test.
Why don't you let config(1) and ld(1) do the work that the preprocessor
does?  For example:

  [snip]

I like that. Will do. Thanks!


Agree with David's point, but it should not be done at function level.
Rather higher level interface abstraction.  In uvmplock branch, I have
already split some x86 pmap bits into pmap_tlb.c and xen_pmap.c modules.
More interfaces can be abstracted in respect to e.g. Xen.


I just took a look: to avoid ugly #ifdef's, we have to handle 4 
different scenarios for pmap switching:


- i386 native, amd64 native, and i386 Xen (no-PAE) case, which all share 
the same piece of code (use of lcr3)


- i386 PAE, not Xen: iterate through L3 entries, without Xen address 
physical = machine address translation


- i386 PAE, Xen: same as above, but use P2M translations

- amd64 Xen, where pmap code has some quirks to circumvent amd64 
limitations regarding paravirtualization.


I can split Xen and non-Xen case, but we will still have to distinguish 
i386 and amd64 case, as well as PAE/!PAE (within i386). Either we deal 
with it at function level and let config(1) handle that, or cpp(1). 
Choice is limited here :/


For your branch:
* xen/x86/xen_pmap.c will contain the code for i386 (PAE  !PAE), amd64, 
only for Xen


* x86/x86/pmap.c will contain native i386 (PAE  !PAE), and amd64.

Is pmap.c expected to be split in two files too (pmap.c and x86_pmap.c?) 
I noticed that in your pmap.c, some functions (already found in 
xen_pmap.c) are #ifndef XEN out, to avoid conflict I suppose.


--
Jean-Yves Migeon
jeanyves.mig...@free.fr