bug-hurd
[Top][All Lists]
Advanced

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

Re: [PATCH v2 gnumach] percpu area using gs segment


From: Samuel Thibault
Subject: Re: [PATCH v2 gnumach] percpu area using gs segment
Date: Mon, 18 Sep 2023 01:32:30 +0200
User-agent: NeoMutt/20170609 (1.8.3)

Hello,

Thanks for this! Just a few comments.

Damien Zammit, le dim. 17 sept. 2023 01:15:14 +0000, a ecrit:
> +#define SMP_COMPLETE (-1)
> +#define MY(stm)              %gs:PERCPU_##stm
> +
>  #if  NCPUS > 1
>  
>  #ifdef __i386__
> @@ -63,14 +66,27 @@
>       movl    %esi, reg       ;\
>       popl    %esi            ;\
>  
> +/* Never call CPU_NUMBER_GS(%esi) */
> +#define CPU_NUMBER_GS(reg)   \
> +     movl    %cs:bspdone, reg        ;\
> +     cmpl    $SMP_COMPLETE, reg      ;\
> +     je      8f              ;\
> +     CPU_NUMBER(reg)         ;\
> +     jmp     9f              ;\

Is the CPU_NUMBER assembly macro really possibly used before we set up
segments in gdt_init?

> diff --git a/i386/i386/cpuboot.S b/i386/i386/cpuboot.S
> index 4a5823be..7d1e815c 100644
> --- a/i386/i386/cpuboot.S
> +++ b/i386/i386/cpuboot.S
> @@ -119,7 +119,7 @@ _apboot:
>       wrmsr
>  
>       /* Load int_stack_top[cpu] -> esp */
> -     CPU_NUMBER(%edx)
> +     CPU_NUMBER_NO_STACK(%edx)
>       movl    CX(EXT(int_stack_top), %edx), %esp
>  
>       /* Ensure stack alignment */

This deserves a separate commit.

> diff --git a/i386/i386/gdt.c b/i386/i386/gdt.c
> index ddda603b..e335de50 100644
> --- a/i386/i386/gdt.c
> +++ b/i386/i386/gdt.c
> @@ -73,6 +74,11 @@ 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_number_slow()]);

Rather just get the cpu number through an additional parameter
for gdt_fill, we do have it at hand in gdt_init (it's 0), and in
ap_gdt_init.

> diff --git a/i386/i386/i386asm.sym b/i386/i386/i386asm.sym
> index 436e296a..620e8f37 100644
> --- a/i386/i386/i386asm.sym
> +++ b/i386/i386/i386asm.sym
> @@ -154,17 +156,10 @@ expr    NPTES                                           
> PTES_PER_PAGE
>  expr INTEL_PTE_VALID|INTEL_PTE_WRITE                 INTEL_PTE_KERNEL
>  
>  expr IDTSZ
> -expr GDTSZ
> -expr LDTSZ
>  
>  expr KERNEL_RING
> -
>  expr KERNEL_CS
>  expr KERNEL_DS
> -expr KERNEL_TSS
> -#ifndef      MACH_PV_DESCRIPTORS
> -expr KERNEL_LDT
> -#endif       /* MACH_PV_DESCRIPTORS */

> diff --git a/i386/i386/locore.S b/i386/i386/locore.S
> index 55aa9d60..ff59615b 100644
> --- a/i386/i386/locore.S
> +++ b/i386/i386/locore.S
> @@ -33,6 +33,7 @@
>  #include <i386/proc_reg.h>
>  #include <i386/trap.h>
>  #include <i386/seg.h>
> +#include <i386/gdt.h>

Rather make these a separate commit.

> @@ -479,7 +481,7 @@ trap_set_segs:
>       jz      trap_from_kernel        /* kernel trap if not */
>  trap_from_user:
>  
> -     CPU_NUMBER(%edx)
> +     CPU_NUMBER_GS(%edx)

Can't we make almost all CPU_NUMBER calls use gs? Having gs set up is
the normal situation, so better make CPU_NUMBER use gs, and have a
CPU_NUMBER_NOGS for the few situations where gs is not set up.

> diff --git a/i386/i386/percpu.c b/i386/i386/percpu.c
> new file mode 100644
> index 00000000..b2b8afa7
> --- /dev/null
> +++ b/i386/i386/percpu.c
> +#include <i386/smp.h>
> +#include <i386/apic.h>
> +#include <i386/percpu.h>
> +
> +struct percpu percpu_array[NCPUS] __aligned(0x8000) = {0};

Why aligning?

> +#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_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

Also introduce a percpu_get() that reads through %%gs:%c[offs], that
can be used in cpu_number, which will be more efficient than reading
%%gs:0 first. So that percpu_ptr will only be called when we really need
a pointer.

BTW, the cpu_number() functions really deserve being rather made
inlines.

Samuel



reply via email to

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