bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v5 2/2 gnumach] percpu area using gs segment


From: Samuel Thibault
Subject: Re: [PATCH v5 2/2 gnumach] percpu area using gs segment
Date: Sun, 24 Sep 2023 14:43:15 +0200
User-agent: NeoMutt/20170609 (1.8.3)

Applied, thanks!

Damien Zammit, le dim. 24 sept. 2023 10:35:10 +0000, a ecrit:
> This speeds up smp again, by storing the struct processor
> in a percpu area and avoiding an expensive cpu_number every call
> of current_processor(), as well as getting the cpu_number by
> an offset into the percpu area.  Untested on 64 bit
> and work remains to use other percpu arrays.
> 
> TESTED: (NCPUS=8) -smp 1 boots to login shell ~2x slower than uniprocessor
> TESTED: (NCPUS=8) -smp 2 boots to INIT but hangs there
> TESTED: (NCPUS=8) -smp 4 gets stuck seemingly within rumpdisk and hangs
> TESTED: (NCPUS=1) uniprocessor is a bit faster than normal
> 
> ---
>  i386/Makefrag.am        |  2 +
>  i386/i386/cpu_number.h  | 17 +++++++--
>  i386/i386/fpu.c         |  2 +-
>  i386/i386/gdt.c         | 21 +++++++++--
>  i386/i386/gdt.h         |  8 ++--
>  i386/i386/i386asm.sym   |  2 +
>  i386/i386/locore.S      | 20 ++++++----
>  i386/i386/mp_desc.c     |  3 +-
>  i386/i386/percpu.c      | 31 +++++++++++++++
>  i386/i386/percpu.h      | 83 +++++++++++++++++++++++++++++++++++++++++
>  i386/i386/pit.c         |  2 +-
>  i386/i386/spl.S         | 16 ++++----
>  i386/i386at/model_dep.c |  1 +
>  kern/cpu_number.h       |  3 +-
>  kern/processor.c        |  7 +---
>  kern/processor.h        | 17 +++------
>  kern/startup.c          |  3 +-
>  x86_64/Makefrag.am      |  2 +
>  x86_64/locore.S         |  7 ++--
>  19 files changed, 194 insertions(+), 53 deletions(-)
>  create mode 100644 i386/i386/percpu.c
>  create mode 100644 i386/i386/percpu.h
> 
> diff --git a/i386/Makefrag.am b/i386/Makefrag.am
> index 274e8695..c1724cea 100644
> --- a/i386/Makefrag.am
> +++ b/i386/Makefrag.am
> @@ -108,6 +108,8 @@ libkernel_a_SOURCES += \
>       i386/i386/irq.c \
>       i386/i386/irq.h \
>       i386/i386/msr.h \
> +     i386/i386/percpu.c \
> +     i386/i386/percpu.h \
>       i386/i386/pit.c \
>       i386/i386/pit.h
>  
> diff --git a/i386/i386/cpu_number.h b/i386/i386/cpu_number.h
> index 8357be84..6ba46e4b 100644
> --- a/i386/i386/cpu_number.h
> +++ b/i386/i386/cpu_number.h
> @@ -30,6 +30,8 @@
>  #ifndef      _I386_CPU_NUMBER_H_
>  #define      _I386_CPU_NUMBER_H_
>  
> +#define MY(stm)              %gs:PERCPU_##stm
> +
>  #if  NCPUS > 1
>  
>  #ifdef __i386__
> @@ -45,8 +47,8 @@
>       shrl    $24, reg                ;\
>       movl    %cs:CX(cpu_id_lut, reg), reg    ;\
>  
> -/* Never call CPU_NUMBER(%esi) */
> -#define CPU_NUMBER(reg)              \
> +/* Never call CPU_NUMBER_NO_GS(%esi) */
> +#define CPU_NUMBER_NO_GS(reg)                \
>       pushl   %esi            ;\
>       pushl   %eax            ;\
>       pushl   %ebx            ;\
> @@ -63,20 +65,29 @@
>       movl    %esi, reg       ;\
>       popl    %esi            ;\
>  
> +#define CPU_NUMBER(reg)      \
> +     movl    MY(CPU_ID), reg;
> +
>  #ifndef __ASSEMBLER__
>  #include <kern/cpu_number.h>
>  #include <i386/apic.h>
> +#include <i386/percpu.h>
>  
> -static inline int cpu_number(void)
> +static inline int cpu_number_slow(void)
>  {
>       return cpu_id_lut[apic_get_current_cpu()];
>  }
>  
> +static inline int cpu_number(void)
> +{
> +     return percpu_get(int, cpu_id);
> +}
>  #endif
>  
>  #else        /* NCPUS == 1 */
>  
>  #define      CPU_NUMBER_NO_STACK(reg)
> +#define      CPU_NUMBER_NO_GS(reg)
>  #define      CPU_NUMBER(reg)
>  #define      CX(addr,reg)    addr
>  
> diff --git a/i386/i386/fpu.c b/i386/i386/fpu.c
> index fefe5e49..e1818683 100644
> --- a/i386/i386/fpu.c
> +++ b/i386/i386/fpu.c
> @@ -119,7 +119,7 @@ init_fpu(void)
>  #else        /* MACH_RING1 */
>       unsigned int native = 0;
>  
> -     if (machine_slot[cpu_number()].cpu_type >= CPU_TYPE_I486)
> +     if (machine_slot[cpu_number_slow()].cpu_type >= CPU_TYPE_I486)
>               native = CR0_NE;
>  
>       /*
> diff --git a/i386/i386/gdt.c b/i386/i386/gdt.c
> index ddda603b..4edd3ec5 100644
> --- a/i386/i386/gdt.c
> +++ b/i386/i386/gdt.c
> @@ -35,6 +35,8 @@
>  
>  #include <kern/assert.h>
>  #include <intel/pmap.h>
> +#include <kern/cpu_number.h>
> +#include <machine/percpu.h>
>  
>  #include "vm_param.h"
>  #include "seg.h"
> @@ -48,7 +50,7 @@ extern
>  struct real_descriptor gdt[GDTSZ];
>  
>  static void
> -gdt_fill(struct real_descriptor *mygdt)
> +gdt_fill(int cpu, struct real_descriptor *mygdt)
>  {
>       /* Initialize the kernel code and data segment descriptors.  */
>  #ifdef __x86_64__
> @@ -73,6 +75,16 @@ gdt_fill(struct real_descriptor *mygdt)
>                           0xffffffff,
>                           ACC_PL_K|ACC_DATA_W, SZ_32);
>  #endif       /* MACH_PV_DESCRIPTORS */
> +     vm_offset_t thiscpu = kvtolin(&percpu_array[cpu]);
> +     _fill_gdt_descriptor(mygdt, PERCPU_DS,
> +                         thiscpu,
> +                         thiscpu + sizeof(struct percpu) - 1,
> +#ifdef __x86_64__
> +                         ACC_PL_K|ACC_DATA_W, SZ_64
> +#else
> +                         ACC_PL_K|ACC_DATA_W, SZ_32
> +#endif
> +     );
>  #endif
>  
>  #ifdef       MACH_PV_DESCRIPTORS
> @@ -119,15 +131,16 @@ reload_segs(void)
>                    
>                    "movw      %w1,%%ds\n"
>                    "movw      %w1,%%es\n"
> +                  "movw      %w3,%%gs\n"
>                    "movw      %w1,%%ss\n"
> -                  : : "i" (KERNEL_CS), "r" (KERNEL_DS), "r" (0));
> +                  : : "i" (KERNEL_CS), "r" (KERNEL_DS), "r" (0), "r" 
> (PERCPU_DS));
>  #endif
>  }
>  
>  void
>  gdt_init(void)
>  {
> -     gdt_fill(gdt);
> +     gdt_fill(0, gdt);
>  
>       reload_segs();
>  
> @@ -146,7 +159,7 @@ gdt_init(void)
>  void
>  ap_gdt_init(int cpu)
>  {
> -     gdt_fill(mp_gdt[cpu]);
> +     gdt_fill(cpu, mp_gdt[cpu]);
>  
>       reload_segs();
>  }
> diff --git a/i386/i386/gdt.h b/i386/i386/gdt.h
> index 80ca8ada..c7da012a 100644
> --- a/i386/i386/gdt.h
> +++ b/i386/i386/gdt.h
> @@ -77,11 +77,9 @@
>  
>  /*                   0x58               used by user TSS in 64bit mode */
>  
> -#ifdef __x86_64__
> -#define      GDTSZ           sel_idx(0x60)
> -#else
> -#define      GDTSZ           sel_idx(0x58)
> -#endif
> +#define PERCPU_DS    0x68            /* per-cpu data mapping */
> +
> +#define      GDTSZ           sel_idx(0x70)
>  
>  #ifndef __ASSEMBLER__
>  
> diff --git a/i386/i386/i386asm.sym b/i386/i386/i386asm.sym
> index 5d546c08..d96b8be8 100644
> --- a/i386/i386/i386asm.sym
> +++ b/i386/i386/i386asm.sym
> @@ -53,6 +53,8 @@ expr        CALL_PMAP_UPDATE
>  
>  offset       ApicLocalUnit           lu      apic_id         APIC_ID
>  
> +offset       percpu                  pc      cpu_id          PERCPU_CPU_ID
> +
>  offset       pcb                     pcb     iss
>  
>  offset       thread                  th      pcb
> diff --git a/i386/i386/locore.S b/i386/i386/locore.S
> index 0cac8df4..870db785 100644
> --- a/i386/i386/locore.S
> +++ b/i386/i386/locore.S
> @@ -244,7 +244,7 @@ timer_normalize:
>   * Switch to a new timer.
>   */
>  ENTRY(timer_switch)
> -     CPU_NUMBER(%edx)                        /* get this CPU  */
> +     CPU_NUMBER_NO_GS(%edx)                  /* get this CPU  */
>       movl    VA_ETC,%ecx                     /* get timer */
>       movl    CX(EXT(current_tstamp),%edx),%eax       /* get old time stamp  
> */
>       movl    %ecx,CX(EXT(current_tstamp),%edx)       /* set new time stamp */
> @@ -262,7 +262,7 @@ ENTRY(timer_switch)
>   * Initialize the first timer for a CPU.
>   */
>  ENTRY(start_timer)
> -     CPU_NUMBER(%edx)                        /* get this CPU */
> +     CPU_NUMBER_NO_GS(%edx)                  /* get this CPU */
>       movl    VA_ETC,%ecx                     /* get timer */
>       movl    %ecx,CX(EXT(current_tstamp),%edx)       /* set initial time 
> stamp */
>       movl    S_ARG0,%ecx                     /* get timer */
> @@ -469,7 +469,8 @@ trap_push_segs:
>       mov     %ax,%ds                 /* (same as kernel stack segment) */
>       mov     %ax,%es
>       mov     %ax,%fs
> -     mov     %ax,%gs
> +     mov     $(PERCPU_DS),%ax
> +     movw    %ax,%gs
>  
>  trap_set_segs:
>       cld                             /* clear direction flag */
> @@ -673,7 +674,7 @@ ENTRY(all_intrs)
>       pushl   %edx
>       cld                             /* clear direction flag */
>  
> -     CPU_NUMBER(%ecx)
> +     CPU_NUMBER_NO_GS(%ecx)
>       movl    %esp,%edx               /* on an interrupt stack? */
>       and     $(~(INTSTACK_SIZE-1)),%edx
>       cmpl    %ss:CX(EXT(int_stack_base),%ecx),%edx
> @@ -687,7 +688,8 @@ ENTRY(all_intrs)
>       mov     %dx,%ds
>       mov     %dx,%es
>       mov     %dx,%fs
> -     mov     %dx,%gs
> +     mov     $(PERCPU_DS),%dx
> +     movw    %dx,%gs
>  
>       CPU_NUMBER(%edx)
>  
> @@ -745,7 +747,7 @@ LEXT(return_to_iret)                      /* to find the 
> return from calling interrupt) */
>       iret                            /* return to caller */
>  
>  int_from_intstack:
> -     CPU_NUMBER(%edx)
> +     CPU_NUMBER_NO_GS(%edx)
>       cmpl    CX(EXT(int_stack_base),%edx),%esp /* seemingly looping? */
>       jb      stack_overflowed        /* if not: */
>       call    EXT(interrupt)          /* call interrupt routine */
> @@ -793,7 +795,8 @@ ast_from_interrupt:
>       mov     %dx,%ds
>       mov     %dx,%es
>       mov     %dx,%fs
> -     mov     %dx,%gs
> +     mov     $(PERCPU_DS),%dx
> +     movw    %dx,%gs
>  
>       CPU_NUMBER(%edx)
>       TIME_TRAP_UENTRY
> @@ -1052,7 +1055,8 @@ syscall_entry_2:
>       mov     %dx,%ds
>       mov     %dx,%es
>       mov     %dx,%fs
> -     mov     %dx,%gs
> +     mov     $(PERCPU_DS),%dx
> +     movw    %dx,%gs
>  
>  /*
>   * Shuffle eflags,eip,cs into proper places
> diff --git a/i386/i386/mp_desc.c b/i386/i386/mp_desc.c
> index f1a1f989..f4ccc381 100644
> --- a/i386/i386/mp_desc.c
> +++ b/i386/i386/mp_desc.c
> @@ -238,6 +238,7 @@ cpu_setup(int cpu)
>      flush_instr_queue();
>      printf("AP=(%u) paging done\n", cpu);
>  
> +    init_percpu(cpu);
>      mp_desc_init(cpu);
>      printf("AP=(%u) mpdesc done\n", cpu);
>  
> @@ -275,7 +276,7 @@ cpu_setup(int cpu)
>  void
>  cpu_ap_main()
>  {
> -    int cpu = cpu_number();
> +    int cpu = cpu_number_slow();
>  
>      do {
>       cpu_pause();
> diff --git a/i386/i386/percpu.c b/i386/i386/percpu.c
> new file mode 100644
> index 00000000..a4db7b68
> --- /dev/null
> +++ b/i386/i386/percpu.c
> @@ -0,0 +1,31 @@
> +/*
> + * Copyright (c) 2023 Free Software Foundation, Inc.
> + *
> + * This program is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +#include <i386/smp.h>
> +#include <i386/apic.h>
> +#include <kern/cpu_number.h>
> +#include <i386/percpu.h>
> +
> +struct percpu percpu_array[NCPUS] = {0};
> +
> +void init_percpu(int cpu)
> +{
> +    int apic_id = apic_get_current_cpu();
> +
> +    percpu_array[cpu].self = &percpu_array[cpu];
> +    percpu_array[cpu].apic_id = apic_id;
> +    percpu_array[cpu].cpu_id = cpu;
> +}
> diff --git a/i386/i386/percpu.h b/i386/i386/percpu.h
> new file mode 100644
> index 00000000..202504da
> --- /dev/null
> +++ b/i386/i386/percpu.h
> @@ -0,0 +1,83 @@
> +/*
> + * Copyright (c) 2023 Free Software Foundation, Inc.
> + *
> + * This program is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation, either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#ifndef _PERCPU_H_
> +#define _PERCPU_H_
> +
> +struct percpu;
> +
> +#define percpu_assign(stm, val)     \
> +    asm("mov %[src], %%gs:%c[offs]" \
> +         : /* No outputs */         \
> +         : [src] "r" (val), [offs] "e" (__builtin_offsetof(struct percpu, 
> stm)) \
> +         : );
> +
> +#define percpu_get(typ, stm)        \
> +MACRO_BEGIN                         \
> +    typ val_;                       \
> +                                    \
> +    asm("mov %%gs:%c[offs], %[dst]" \
> +         : [dst] "=r" (val_)        \
> +         : [offs] "e" (__builtin_offsetof(struct percpu, stm)) \
> +         : );                       \
> +                                    \
> +    val_;                           \
> +MACRO_END
> +
> +#define percpu_ptr(typ, stm)        \
> +MACRO_BEGIN                         \
> +    typ *ptr_ = (typ *)__builtin_offsetof(struct percpu, stm); \
> +                                    \
> +    asm("add %%gs:0, %[pointer]"    \
> +         : [pointer] "+r" (ptr_)    \
> +         : /* No inputs */          \
> +         : );                       \
> +                                    \
> +    ptr_;                           \
> +MACRO_END
> +
> +#include <kern/processor.h>
> +#include <kern/thread.h>
> +
> +struct percpu {
> +    struct percpu    *self;
> +    int                      apic_id;
> +    int                      cpu_id;
> +    struct processor processor;
> +/*
> +    struct machine_slot      machine_slot;
> +    struct mp_desc_table mp_desc_table;
> +    thread_t         active_thread;
> +    vm_offset_t              active_stack;
> +    vm_offset_t              int_stack_top;
> +    vm_offset_t              int_stack_base;
> +    ast_t            need_ast;
> +    ipc_kmsg_t               ipc_kmsg_cache;
> +    pmap_update_list cpu_update_list;
> +    spl_t            saved_ipl;
> +    spl_t            curr_ipl;
> +    timer_data_t     kernel_timer;
> +    timer_t          current_timer;
> +    unsigned long    in_interrupt;
> +*/
> +};
> +
> +extern struct percpu percpu_array[NCPUS];
> +
> +void init_percpu(int cpu);
> +
> +#endif /* _PERCPU_H_ */
> diff --git a/i386/i386/pit.c b/i386/i386/pit.c
> index 6c006a98..9e527fca 100644
> --- a/i386/i386/pit.c
> +++ b/i386/i386/pit.c
> @@ -118,7 +118,7 @@ pit_mdelay(int msec)
>  void
>  clkstart(void)
>  {
> -     if (cpu_number() != 0)
> +     if (cpu_number_slow() != 0)
>               /* Only one PIT initialization is needed */
>               return;
>       unsigned char   byte;
> diff --git a/i386/i386/spl.S b/i386/i386/spl.S
> index 2f2c8e3a..9ce780f4 100644
> --- a/i386/i386/spl.S
> +++ b/i386/i386/spl.S
> @@ -48,7 +48,7 @@ lock        orl     $1,hyp_shared_info+CPU_PENDING_SEL; /* 
> Yes, activate it */ \
>  
>  ENTRY(spl0)
>       mb;
> -     CPU_NUMBER(%edx)
> +     CPU_NUMBER_NO_GS(%edx)
>       movl    CX(EXT(curr_ipl),%edx),%eax     /* save current ipl */
>       pushl   %eax
>       cli                             /* disable interrupts */
> @@ -77,7 +77,7 @@ ENTRY(spl0)
>  #endif
>       cli                             /* disable interrupts */
>  1:
> -     CPU_NUMBER(%edx)
> +     CPU_NUMBER_NO_GS(%edx)
>       cmpl    $(SPL0),CX(EXT(curr_ipl),%edx)  /* are we at spl0? */
>       je      1f                              /* yes, all done */
>       movl    $(SPL0),CX(EXT(curr_ipl),%edx)  /* set ipl */
> @@ -123,14 +123,14 @@ ENTRY(spl7)
>       mb;
>       /* just clear IF */
>       cli
> -     CPU_NUMBER(%edx)
> +     CPU_NUMBER_NO_GS(%edx)
>       movl    $SPL7,%eax
>       xchgl   CX(EXT(curr_ipl),%edx),%eax
>       ret
>  
>  ENTRY(splx)
>       movl    S_ARG0,%edx             /* get ipl */
> -     CPU_NUMBER(%eax)
> +     CPU_NUMBER_NO_GS(%eax)
>  #if (MACH_KDB || MACH_TTD) && !defined(MACH_XEN)
>       /* First make sure that if we're exitting from ipl7, IF is still 
> cleared */
>       cmpl    $SPL7,CX(EXT(curr_ipl),%eax)    /* from ipl7? */
> @@ -145,7 +145,7 @@ ENTRY(splx)
>  #endif       /* (MACH_KDB || MACH_TTD) && !MACH_XEN */
>       testl   %edx,%edx               /* spl0? */
>       jz      EXT(spl0)               /* yes, handle specially */
> -     CPU_NUMBER(%eax)
> +     CPU_NUMBER_NO_GS(%eax)
>       cmpl    CX(EXT(curr_ipl),%eax),%edx     /* same ipl as current? */
>       jne     spl                     /* no */
>       cmpl    $SPL7,%edx              /* spl7? */
> @@ -194,7 +194,7 @@ splx_cli:
>  1:
>       xorl    %edx,%edx               /* edx = ipl 0 */
>  2:
> -     CPU_NUMBER(%eax)
> +     CPU_NUMBER_NO_GS(%eax)
>       cmpl    CX(EXT(curr_ipl),%eax),%edx     /* same ipl as current? */
>       je      1f                              /* yes, all done */
>       movl    %edx,CX(EXT(curr_ipl),%eax)     /* set ipl */
> @@ -213,7 +213,7 @@ splx_cli:
>       .align  TEXT_ALIGN
>       .globl  spl
>  spl:
> -     CPU_NUMBER(%eax)
> +     CPU_NUMBER_NO_GS(%eax)
>  #if (MACH_KDB || MACH_TTD) && !defined(MACH_XEN)
>       /* First make sure that if we're exitting from ipl7, IF is still 
> cleared */
>       cmpl    $SPL7,CX(EXT(curr_ipl),%eax)    /* from ipl7? */
> @@ -233,7 +233,7 @@ spl:
>                                       /* get int mask */
>  #endif
>       cli                             /* disable interrupts */
> -     CPU_NUMBER(%eax)
> +     CPU_NUMBER_NO_GS(%eax)
>       xchgl   CX(EXT(curr_ipl),%eax),%edx     /* set ipl */
>  #ifdef MACH_XEN
>       XEN_SETMASK()                   /* program PICs with new mask */
> diff --git a/i386/i386at/model_dep.c b/i386/i386at/model_dep.c
> index f83214b1..97acfdd6 100644
> --- a/i386/i386at/model_dep.c
> +++ b/i386/i386at/model_dep.c
> @@ -462,6 +462,7 @@ i386at_init(void)
>       ldt_init();
>       ktss_init();
>  
> +     init_percpu(0);
>  #if NCPUS > 1
>       /* Initialize SMP structures in the master processor */
>       mp_desc_init(0);
> diff --git a/kern/cpu_number.h b/kern/cpu_number.h
> index 0be2d338..1abe3dbb 100644
> --- a/kern/cpu_number.h
> +++ b/kern/cpu_number.h
> @@ -37,7 +37,8 @@ extern int  master_cpu;     /* 'master' processor - keeps 
> time */
>  
>  #if  (NCPUS == 1)
>       /* cpu number is always 0 on a single processor system */
> -#define      cpu_number()    (0)
> +#define      cpu_number()            (0)
> +#define      cpu_number_slow()       (0)
>  
>  #endif       /* NCPUS == 1 */
>  
> diff --git a/kern/processor.c b/kern/processor.c
> index 2cd6d46c..76735381 100644
> --- a/kern/processor.c
> +++ b/kern/processor.c
> @@ -60,14 +60,12 @@ struct kmem_cache pset_cache;
>  int  master_cpu;
>  
>  struct processor_set default_pset;
> -struct processor processor_array[NCPUS];
>  
>  queue_head_t         all_psets;
>  int                  all_psets_count;
>  def_simple_lock_data(, all_psets_lock);
>  
>  processor_t  master_processor;
> -processor_t  processor_ptr[NCPUS];
>  
>  /*
>   *   Bootstrap the processor/pset system so the scheduler can run.
> @@ -81,10 +79,9 @@ void pset_sys_bootstrap(void)
>       for (i = 0; i < NCPUS; i++) {
>               /*
>                *      Initialize processor data structures.
> -              *      Note that cpu_to_processor(i) is processor_ptr[i].
> +              *      Note that cpu_to_processor is processor_ptr.
>                */
> -             processor_ptr[i] = &processor_array[i];
> -             processor_init(processor_ptr[i], i);
> +             processor_init(processor_ptr(i), i);
>       }
>       master_processor = cpu_to_processor(master_cpu);
>       queue_init(&all_psets);
> diff --git a/kern/processor.h b/kern/processor.h
> index 79386627..fc204ffa 100644
> --- a/kern/processor.h
> +++ b/kern/processor.h
> @@ -112,6 +112,7 @@ typedef struct processor Processor;
>  extern struct processor      processor_array[NCPUS];
>  
>  #include <kern/cpu_number.h>
> +#include <machine/percpu.h>
>  
>  /*
>   *   Chain of all processor sets.
> @@ -196,23 +197,15 @@ extern processor_t      master_processor;
>  #define      PROCESSOR_ASSIGN        4       /* Assignment is changing */
>  #define PROCESSOR_SHUTDOWN   5       /* Being shutdown */
>  
> -/*
> - *   Use processor ptr array to find current processor's data structure.
> - *   This replaces a multiplication (index into processor_array) with
> - *   an array lookup and a memory reference.  It also allows us to save
> - *   space if processor numbering gets too sparse.
> - */
> -
> -extern processor_t   processor_ptr[NCPUS];
> -
> -#define cpu_to_processor(i)  (processor_ptr[i])
> +#define processor_ptr(i)     (&percpu_array[i].processor)
> +#define cpu_to_processor     processor_ptr
>  
> -#define current_processor()  (processor_ptr[cpu_number()])
> +#define current_processor()  (percpu_ptr(struct processor, processor))
>  #define current_processor_set()      (current_processor()->processor_set)
>  
>  /* Compatibility -- will go away */
>  
> -#define cpu_state(slot_num)  (processor_ptr[slot_num]->state)
> +#define cpu_state(slot_num)  (processor_ptr(slot_num)->state)
>  #define cpu_idle(slot_num)   (cpu_state(slot_num) == PROCESSOR_IDLE)
>  
>  /* Useful lock macros */
> diff --git a/kern/startup.c b/kern/startup.c
> index 2eb3a739..88608c7d 100644
> --- a/kern/startup.c
> +++ b/kern/startup.c
> @@ -74,6 +74,7 @@ boolean_t reboot_on_panic = TRUE;
>  
>  #if  NCPUS > 1
>  #include <machine/mp_desc.h>
> +#include <kern/smp.h>
>  #include <kern/machine.h>
>  #endif       /* NCPUS > 1 */
>  
> @@ -281,7 +282,7 @@ void cpu_launch_first_thread(thread_t th)
>  {
>       int     mycpu;
>  
> -     mycpu = cpu_number();
> +     mycpu = cpu_number_slow();
>  
>       cpu_up(mycpu);
>  
> diff --git a/x86_64/Makefrag.am b/x86_64/Makefrag.am
> index 008ac58f..0c67517c 100644
> --- a/x86_64/Makefrag.am
> +++ b/x86_64/Makefrag.am
> @@ -103,6 +103,8 @@ libkernel_a_SOURCES += \
>       i386/i386/irq.c \
>       i386/i386/irq.h \
>       i386/i386/msr.h \
> +     i386/i386/percpu.h \
> +     i386/i386/percpu.c \
>       i386/i386/pit.c \
>       i386/i386/pit.h
>  
> diff --git a/x86_64/locore.S b/x86_64/locore.S
> index fabbf2e7..d640ef73 100644
> --- a/x86_64/locore.S
> +++ b/x86_64/locore.S
> @@ -140,6 +140,7 @@
>       mov     %dx,%ds                 ;\
>       mov     %dx,%es                 ;\
>       mov     %dx,%fs                 ;\
> +     mov     $(PERCPU_DS),%dx        ;\
>       mov     %dx,%gs
>  #else
>  #define SET_KERNEL_SEGMENTS
> @@ -350,7 +351,7 @@ timer_normalize:
>   * Switch to a new timer.
>   */
>  ENTRY(timer_switch)
> -     CPU_NUMBER(%edx)                        /* get this CPU  */
> +     CPU_NUMBER_NO_GS(%edx)                  /* get this CPU  */
>       movl    VA_ETC,%ecx                     /* get timer */
>       movl    CX(EXT(current_tstamp),%rdx),%eax       /* get old time stamp  
> */
>       movl    %ecx,CX(EXT(current_tstamp),%rdx)       /* set new time stamp */
> @@ -368,7 +369,7 @@ ENTRY(timer_switch)
>   * Initialize the first timer for a CPU.
>   */
>  ENTRY(start_timer)
> -     CPU_NUMBER(%edx)                        /* get this CPU */
> +     CPU_NUMBER_NO_GS(%edx)                  /* get this CPU */
>       movl    VA_ETC,%ecx                     /* get timer */
>       movl    %ecx,CX(EXT(current_tstamp),%rdx)       /* set initial time 
> stamp */
>       movl    S_ARG0,%ecx                     /* get timer */
> @@ -1445,7 +1446,7 @@ _syscall64_call:
>  
>  _syscall64_check_for_ast:
>       /* Check for ast. */
> -     CPU_NUMBER(%r11)
> +     CPU_NUMBER_NO_GS(%r11)
>       cmpl    $0,CX(EXT(need_ast),%r11)
>       jz      _syscall64_restore_state
>  
> -- 
> 2.40.1
> 
> 
> 

-- 
Samuel
---
Pour une évaluation indépendante, transparente et rigoureuse !
Je soutiens la Commission d'Évaluation de l'Inria.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]