mikro - Multiprocessor Init in Kernel CPU init Percpu variables - - PowerPoint PPT Presentation

mikro multiprocessor init in kernel
SMART_READER_LITE
LIVE PREVIEW

mikro - Multiprocessor Init in Kernel CPU init Percpu variables - - PowerPoint PPT Presentation

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions mikro - Multiprocessor Init in Kernel CPU init Percpu variables Conclusion Julien Freche julien.freche@lse.epita.fr http://lse.epita.fr/ Outline I mikro -


slide-1
SLIDE 1

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions CPU init Percpu variables Conclusion

mikro - Multiprocessor Init in Kernel

Julien Freche

julien.freche@lse.epita.fr http://lse.epita.fr/

slide-2
SLIDE 2

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions CPU init Percpu variables Conclusion

Outline I

1

Introduction

2

Interruptions Old PIC IOAPIC LAPIC IPI

3

CPU init BootStrap Processor Application Processor INIT-SIPI-SIPI

4

Percpu variables Usage Implementation Using clang

5

Conclusion

slide-3
SLIDE 3

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions CPU init Percpu variables Conclusion

Introduction

Introduction

slide-4
SLIDE 4

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions CPU init Percpu variables Conclusion

Too many questions

I will talk about x86 system with multiple processors. How to handle interruptions ? How to boot all CPUs ? What is the state of the system at boot ? How to detect the number of CPU(s) ? Dealing with multiple processors requires to deal with

  • interruptions. Let’s see why.
slide-5
SLIDE 5

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions

Old PIC IOAPIC LAPIC IPI

CPU init Percpu variables Conclusion

Interruptions

Interruptions

slide-6
SLIDE 6

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions

Old PIC IOAPIC LAPIC IPI

CPU init Percpu variables Conclusion

I interrupt you

Interruption

Signal sent to a processor to report an event that requires immediate attention. Interrupts can be caused by: Hardware: event caused by some device Software: system call from userland, debugging purposes, ..

slide-7
SLIDE 7

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions

Old PIC IOAPIC LAPIC IPI

CPU init Percpu variables Conclusion

Old PIC

Old PIC

slide-8
SLIDE 8

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions

Old PIC IOAPIC LAPIC IPI

CPU init Percpu variables Conclusion

Vintage chip

PIC

It controls the CPU’s interrupt mechanism, by accepting several interrupt requests and feeding them to the processor in order. Limitations: Only 8 pin per PIC (16 IRQ on x86 with two PICs). No SMP support, can only send interrupts to one CPU. Programmed with IO ports The PIC is no replaced by the IOAPIC on modern systems.

slide-9
SLIDE 9

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions

Old PIC IOAPIC LAPIC IPI

CPU init Percpu variables Conclusion

IOAPIC

IOAPIC

slide-10
SLIDE 10

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions

Old PIC IOAPIC LAPIC IPI

CPU init Percpu variables Conclusion

Incoming chip

IOAPIC

It collects interrupts from all devices and provide a way to send it to a CPU or a group of CPU. Features: 24 pin per IOAPIC Memory mapped device You can have multiple IOAPICs Special bus to send interruptions: ICC bus Handle global interruptions (not specific to a CPU)

slide-11
SLIDE 11

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions

Old PIC IOAPIC LAPIC IPI

CPU init Percpu variables Conclusion

LAPIC

LAPIC

slide-12
SLIDE 12

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions

Old PIC IOAPIC LAPIC IPI

CPU init Percpu variables Conclusion

That chip is mine

Local APIC

It collects local interrupts and provide a way to a CPU to accept interrupts. Features: 2 pin per local APIC Memory mapped device Each CPU has a local APIC Timer, Performance monitoring, Thermal sensor Use ICC bus to speak with IOAPIC(s) Handle local interruptions Each Lapic has an unique ID

slide-13
SLIDE 13

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions

Old PIC IOAPIC LAPIC IPI

CPU init Percpu variables Conclusion

All together

slide-14
SLIDE 14

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions

Old PIC IOAPIC LAPIC IPI

CPU init Percpu variables Conclusion

IPI

IPI

slide-15
SLIDE 15

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions

Old PIC IOAPIC LAPIC IPI

CPU init Percpu variables Conclusion

Poke

InterProcessor Interrupts

IPIs are interrupts issued by one processor and sent to another. Issued by the Local Apic Destination

All including self All excluding self Self One processor

Delivery Mode

Low priority NMI INIT, STARTUP ...

slide-16
SLIDE 16

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions CPU init

BootStrap Processor Application Processor INIT-SIPI-SIPI

Percpu variables Conclusion

CPU init

CPU init

slide-17
SLIDE 17

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions CPU init

BootStrap Processor Application Processor INIT-SIPI-SIPI

Percpu variables Conclusion

(Gla)DOS: I am still alive

For backward compatibility all modern PCs starts in the following state: Only one CPU active Real mode (16 bits) PIC available to handle interruptions

slide-18
SLIDE 18

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions CPU init

BootStrap Processor Application Processor INIT-SIPI-SIPI

Percpu variables Conclusion

BootStrap Processor

BootStrap Processor

slide-19
SLIDE 19

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions CPU init

BootStrap Processor Application Processor INIT-SIPI-SIPI

Percpu variables Conclusion

Dibs on the kernel

Bootstrap Processor

This processor is chosen by the BIOS to start executing the bootloader code. It is the first to execute the kernel code and must wake up the other processors if needed. Duties on mikro: Create a GDT and an IDT Init the paging Move the kernel code to its final location Parse MP Tables and/or MADT table Init IOAPIC(s) and its own LAPIC Perform some per-cpu init Wake every processors Start scheduling tasks

slide-20
SLIDE 20

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions CPU init

BootStrap Processor Application Processor INIT-SIPI-SIPI

Percpu variables Conclusion

Vintage table

MultiProcessor Table

Created by Intel in 1997. Provides MP related informations to the OS. Informations: Processors list Buses list IOAPICs list Interrupts list Limitations: qemu: list only processors, not core nor threads. On some real hardware: list only cores, not threads. On other hardwares: not present

slide-21
SLIDE 21

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions CPU init

BootStrap Processor Application Processor INIT-SIPI-SIPI

Percpu variables Conclusion

Colona’s favorite toy

MADT: Multiple APIC Description Table

Part of the ACPI spec. Provides informations about an SMP system. Informations: Processors, cores, threads IOAPICs, x2APIC list Interrupt Source Override Kind of the easy part of the ACPI (no AML).

slide-22
SLIDE 22

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions CPU init

BootStrap Processor Application Processor INIT-SIPI-SIPI

Percpu variables Conclusion

Application Processor

Application Processor

slide-23
SLIDE 23

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions CPU init

BootStrap Processor Application Processor INIT-SIPI-SIPI

Percpu variables Conclusion

Dibs on the kernel

Application Processor

Processor in the halt state, waiting for a special IPI to start executing code. This processor is in real mode. Duties on mikro: Jump to protected mode Create its own GDT Load the existing IDT Perform some per-cpu init Init its LAPIC Start scheduling tasks

slide-24
SLIDE 24

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions CPU init

BootStrap Processor Application Processor INIT-SIPI-SIPI

Percpu variables Conclusion

INIT-SIPI-SIPI

INIT-SIPI-SIPI

slide-25
SLIDE 25

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions CPU init

BootStrap Processor Application Processor INIT-SIPI-SIPI

Percpu variables Conclusion

Wake up!

A processor will start executing code when receiving this sequence of IPIs. Copy some code in low memory Send an INIT IPI Send a StartUP IPI Send another StartUP IPI

slide-26
SLIDE 26

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions CPU init

BootStrap Processor Application Processor INIT-SIPI-SIPI

Percpu variables Conclusion

Some magic

I found this code on the internet.

. i n i t : ; s e t NMI ha n dle r mov dword [ 4 ∗ 2 ] , . b o o t xor eax , eax mov ebx , (11 b shl 18) + (0 shl 15) + (1 shl 14) + (0 shl 11) + (100 b shl 8) + 2 ; t r i g g e r i n t e r r u p t s in every p r o c e s s o r mov [ dword 0xFEE00300 + 16] , eax mov [ dword 0xFEE00300 + 00] , ebx ret a l i g n 16 . b o o t :

It works on qemu and some systems.

slide-27
SLIDE 27

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions CPU init

BootStrap Processor Application Processor INIT-SIPI-SIPI

Percpu variables Conclusion

Let me explain it

Steps: Register boot function as handler into the IDT Set eax to zero Set IPI parameters into ebx:

NMI Physical, Assert level, Edge trigger mode All excluding self

Send the IPI using the LAPIC Kind of the quickest hack to wake every processors !

slide-28
SLIDE 28

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions CPU init

BootStrap Processor Application Processor INIT-SIPI-SIPI

Percpu variables Conclusion

What is wrong?

Issues: Do not follow the spec.. Assume that LAPIC is at 0xfee00000 (default addr but can be changed) Wake every processor (even processor disabled by the BIOS) Kind of the quickest hack to wake every processors !

slide-29
SLIDE 29

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions CPU init Percpu variables

Usage Implementation Using clang

Conclusion

Percpu variables

Percpu variables

slide-30
SLIDE 30

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions CPU init Percpu variables

Usage Implementation Using clang

Conclusion

Usage

Usage

slide-31
SLIDE 31

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions CPU init Percpu variables

Usage Implementation Using clang

Conclusion

My precious variable

Per-cpu variable

A cpu local variable. Each cpu can has a different value stored in this variable. Considerations: Kind of TLS (Thread Local Storage) but for processors Accessed using macro on Linux Useful to change behavior of the code depending on the CPU

slide-32
SLIDE 32

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions CPU init Percpu variables

Usage Implementation Using clang

Conclusion

Implementation

Implementation

slide-33
SLIDE 33

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions CPU init Percpu variables

Usage Implementation Using clang

Conclusion

mikro

How to implement it ? Create a special section in binary file for these variables Allocate needed space by every processor for these variables Set a special entry in every GDT (at the same offset for every processor) but with a different values. Set FS to this special entry in the GDT Access variables relatively to FS

slide-34
SLIDE 34

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions CPU init Percpu variables

Usage Implementation Using clang

Conclusion

Using clang

Using clang

slide-35
SLIDE 35

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions CPU init Percpu variables

Usage Implementation Using clang

Conclusion

clang: 1, gcc: 0

With clang you can do the following:

# define FS_RELATIVE address_space (257) # define PCPU_S s e c t i o n ( " . cpuvar " ) # define __percpu _ _ a t t r i b u t e _ _ ( ( FS_RELATIVE , PCPU_S ) ) i n t __percpu myvar ; void do_something ( ) { myvar = 42; }

After per-cpu init, you can access your variable normally without macros. Pretty clean.

slide-36
SLIDE 36

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions CPU init Percpu variables Conclusion

Conclusion

Conclusion

slide-37
SLIDE 37

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions CPU init Percpu variables Conclusion

Almost done

To finish: To support SMP in kernel, think about it early Very interesting subject closely related to interruptions Think about a clever algorithm to dispatch interrupts All SMP systems has IOAPIC and LAPIC, try to play with it !

slide-38
SLIDE 38

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions CPU init Percpu variables Conclusion

Contacts

Julien Freche julien.freche@lse.epita.fr @JulienFreche

slide-39
SLIDE 39

mikro - Multiprocessor Init in Kernel Julien Freche Introduction Interruptions CPU init Percpu variables Conclusion

The end

Thank you for your attention