Commit graph

627 commits

Author SHA1 Message Date
Tomas Hruby
f42b90806a BSP apic id
- BSP apic id used uninitialized causes problems
2010-10-19 17:07:19 +00:00
Tomas Hruby
e6b1a30a26 panic in dummy apic handlers
- as panic can do the same as printf now, let's rather panic when a
  dummy apic interrupt vector handler is hit
2010-10-19 17:07:17 +00:00
Tomas Hruby
2419ab589d Fixed BKL statistics 2010-10-19 17:07:11 +00:00
Tomas Hruby
8145b458d6 A klib.S include fix
- by Antoine Leca
2010-10-15 22:21:01 +00:00
Ben Gras
c521f2a138 kernel: fix idle time accounting. 2010-10-04 19:12:55 +00:00
Tomas Hruby
1786291e32 Watchdog and kernel profiling for AMD
- a different set of MSRs and performance counters is used on AMD

- when initializing NMI watchdog the test for Intel architecture
  performance counters feature only applies to Intel now

- NMI is enabled if the CPU belongs to a family which has the
  performance counters that we use
2010-09-23 14:42:30 +00:00
Tomas Hruby
8eece1c00c CPU type detection
- sometimes the system needs to know precisely on what type of cpu is
  running. The cpu type id detected during arch specific
  initialization and kept in the machine structure for later use.

- as a side-effect the information is exported to userland
2010-09-23 14:42:19 +00:00
Tomas Hruby
ef92583c3a Busy idle loop when profiling
- the Intel architecture cycle counter (performance counter) does not
  count when the CPU is idle therefore we use busy loop instead of
  halting the cpu when there is nothing to schedule

- the downside is that handling interrupts may be accounted as idle
  time if a sample is taken before we get out of the nested trap and
  pick a new process
2010-09-23 10:49:52 +00:00
Tomas Hruby
d2b56f60da sprofile exports kernel sample entries
- in case of kernel hit while proc_ptr is IDLE, account for idle time
  instead of taking kernel sample
2010-09-23 10:49:50 +00:00
Tomas Hruby
87c576584d Internal 64M buffer for profiling
- when profiling is compiled in kernel includes a 64M buffer for
  sample

- 64M is the default used by profile tool as its buffer

- when using nmi profiling it is not possible to always copy sample
  stright to userland as the nmi may (and does) happen in bad moments

- reduces sampling overhead as samples are copied out only when
  profiling stops
2010-09-23 10:49:48 +00:00
Tomas Hruby
e63b85a50b NMI sampling
- if profile --nmi kernel uses NMI watchdog based sampling based on
  Intel architecture performance counters

- using NMI makes kernel profiling possible

- watchdog kernel lockup detection is disabled while sampling as we
  may get unpredictable interrupts in kernel and thus possibly many
  false positives

- if watchdog is not enabled at boot time, profiling enables it and
  turns it of again when done
2010-09-23 10:49:45 +00:00
Tomas Hruby
db12229ce3 New profile protocol
- when kernel profiles a process for the first time it saves an entry
  describing the process [endpoint|name]

- every profile sample is only [endpoint|pc]

- profile utility creates a table of endpoint <-> name relations and
  translates endpoints of samples into names and writing out the
  results to comply with the processing tools

- "task" endpoints like KERNEL are negative thus we must cast it to
  unsigned when hashing
2010-09-23 10:49:39 +00:00
Tomas Hruby
123a968be3 32bit process flags
- we are running out of space in 16bit flags
2010-09-23 10:49:36 +00:00
Ben Gras
82d576c9ca enable_fpu_exception() - only write cr0 if bit isn't already on.
(NMI profiling results indicate this both is relatively expensive and
happens a lot unnecessarily if the fpu is in use.)
2010-09-22 14:31:06 +00:00
Tomas Hruby
2d1c8849d8 Remove unnecessary TLB flushes
- this should be only for SMP
2010-09-22 08:01:36 +00:00
Tomas Hruby
08bf4dec4f Fixed comments in watchdog 2010-09-19 23:23:44 +00:00
Tomas Hruby
e9ecba9fc7 fix - forgotten debug print 2010-09-19 15:54:31 +00:00
Tomas Hruby
a665ae3de1 Userspace scheduling - exporting stats
- contributed by Bjorn Swift

- adds process accounting, for example counting the number of messages
  sent, how often the process was preemted and how much time it spent
  in the run queue. These statistics, along with the current cpu load,
  are sent back to the user-space scheduler in the Out Of Quantum
  message.

- the user-space scheduler may choose to make use of these statistics
  when making scheduling decisions. For isntance the cpu load becomes
  especially useful when scheduling on multiple cores.
2010-09-19 15:52:12 +00:00
Tomas Hruby
13bda81ee0 Fixed FPU for single cpu 2010-09-16 09:51:45 +00:00
Tomas Hruby
72cc01ff48 apic_timer_x
- set the apic_timer_x factor variable to slowdown apic timer in
  virtual machines
2010-09-16 07:18:47 +00:00
Tomas Hruby
4ee139b0be SMP - all process have pagetables
- all processes have private pagetables if CONFIG_SMP is set

- this make possible to safely schedule PM, RS, VFS anywhere
2010-09-15 14:11:30 +00:00
Tomas Hruby
5b8b623765 SMP - lazy FPU
- when a process is migrated to a different CPU it may have an active
  FPU context in the processor registers. We must save it and migrate
  it together with the process.
2010-09-15 14:11:25 +00:00
Tomas Hruby
1f89845bb2 SMP - can boot even if some cpus fail to boot
- EBADCPU is returned is scheduler tries to run a process on a CPU
  that either does not exist or isn't booted

- this change was originally meant to deal with stupid cpuid
  instruction which provides totally useless information about
  hyper-threading and MPS which does not deal with ht at all. ACPI
  provides correct information. If ht is turned off it looks like some
  CPUs failed to boot.  Nevertheless this patch may be handy for
  testing/benchmarking in the future.
2010-09-15 14:11:21 +00:00
Tomas Hruby
421f324baa SMP - Make sure that VM does not change pt of a process while kernel copies 2010-09-15 14:11:19 +00:00
Tomas Hruby
e4283176ae SMP - Force TLB flush before scheduling a process
- this makes sure that each process always run with updated TLB

- this is the simplest way how to achieve the consistency. As it means
  significant performace degradation when not require, this is nto the
  final solution and will be refined
2010-09-15 14:11:17 +00:00
Tomas Hruby
6513d20744 SMP - Process is stopped when VM modifies the page tables
- RTS_VMINHIBIT flag is used to stop process while VM is fiddling with
  its pagetables

- more generic way of sending synchronous scheduling events among cpus

- do the x-cpu smp sched calls only if the target process is runnable.
  If it is not, it cannot be running and it cannot become runnable
  this CPU holds the BKL
2010-09-15 14:11:12 +00:00
Tomas Hruby
906a81a1c7 SMP - runctl() can stop across cpus
- if stopping a process that runs on a different CPU we tell the
  remote cpu to do that
2010-09-15 14:11:09 +00:00
Tomas Hruby
e2701da5a9 SMP - Single shot local timer
- APIC timer always reprogrammed if expired

- timer tick never happens when in kernel => never immediate return
  from userspace to kernel because of a buffered interrupt

- renamed argument to lapic_set_timer_one_shot()

- removed arch_ prefix from timer functions
2010-09-15 14:11:06 +00:00
Tomas Hruby
e87d29171f SMP - Compiles for both single and multi processor again
- this patch adds various fixes as some of the previous patches break
  compilations without CONFIG_SMP being set
2010-09-15 14:11:03 +00:00
Tomas Hruby
454589debd SMP - Print cpu of the process
- adds '4' to print processes assigned to each cpu without printing
  the process it is blocked on (a lightweight '1')
2010-09-15 14:11:01 +00:00
Tomas Hruby
0ac9b6d4cf SMP - trully idle APs
- any cpu can use smp_schedule() to tell another cpu to reschedule

- if an AP is idle, it turns off timer as there is nothing to
  preempt, no need to wakeup just to go back to sleep again

- if a cpu makes a process runnable on an idle cpu, it must wake it up
  to reschedule
2010-09-15 14:10:57 +00:00
Tomas Hruby
387e1835d1 SMP - BSP halts APs before shutting down 2010-09-15 14:10:54 +00:00
Tomas Hruby
311f145bc7 SMP - Balancing run queues for SMP
- it preempts running processes though :( this is not the final
  solution
2010-09-15 14:10:51 +00:00
Tomas Hruby
06b6e5624a SMP - Changed prototype of sys_schedule()
- sys_schedule can change only selected values, -1 means that the
  current value should be kept unchanged. For instance we mostly want
  to change the scheduling quantum and priority but we want to keep
  the process at the current cpu

- RS can hand off its processes to scheduler

- service can read the destination cpu from system.conf

- RS can pass the information farther
2010-09-15 14:10:42 +00:00
Tomas Hruby
c554aef0e1 SMP - BKL statistics
- pressing 'B' on the serial cnsole prints statistics for BKL per cpu.

- 'b' resets the counters

- it presents number of cycles each CPU spends in kernel, how many
  cycyles it spends spinning while waiting for the BKL

- it shows optimistic estimation in how many cases we get the lock
  immediately without spinning. As the test is not atomic the lock may
  be already held by some other cpu before we actually try to acquire
  it.
2010-09-15 14:10:37 +00:00
Tomas Hruby
93b9873a56 SMP - Free PDE slots are split among CPU
- cross-address space copies use these slots to map user memory for
  kernel. This avoid any collisions between CPUs

- well, we only have a single CPU running at a time, this is just to
  be safe for the future
2010-09-15 14:10:36 +00:00
Tomas Hruby
1e273f640e SMP - Scheduler can assign process to a cpu
- machine information contains the number of cpus and the bsp id

- a dummy SMP scheduler which keeps all system processes on BSP and
  all other process on APs. The scheduler remembers how many processes
  are assigned to each CPU and always picks the one with the least
  processes for a new process.
2010-09-15 14:10:33 +00:00
Tomas Hruby
9e12630d75 SMP - APs are fully enabled
- apic_send_ipi() to send inter-processor interrupts (IPIs)

- APIC IPI schedule and halt handlers to signal x-cpu that a cpu shold
  reschedule or halt

- various little changes to let APs run

- no processes are scheduled at the APs and therefore they are idle
  except being interrupted by a timer time to time
2010-09-15 14:10:30 +00:00
Tomas Hruby
d37b7ebc0b SMP - CPU local cycles accounting
- tsc_ctr_switch is made cpu local

- although an x86 specific variable it must be declared globaly as the
  cpulocal implementation does not allow otherwise
2010-09-15 14:10:27 +00:00
Tomas Hruby
67f039540c SMP - proc_ptr and bill_ptr initialization
- they should point somewhere
2010-09-15 14:10:24 +00:00
Tomas Hruby
865e21b884 SMP - CPU local idle stub
- each CPU has its own pseudo idle process and its structure

- idle cycles accounting is agregated when exporting to userspace
2010-09-15 14:10:21 +00:00
Tomas Hruby
fac5fbfdbf SMP - CPU local run queues
- each CPU has its own runqueues

- processes on BSP are put on the runqueues later after a switch to
  the final stack when cpuid works to avoid special cases

- enqueue() and dequeue() use the run queues of the cpu the process is
  assigned to

- pick_proc() uses the local run queues

- printing of per-CPU run queues ('2') on serial console
2010-09-15 14:10:18 +00:00
Tomas Hruby
ad73a4f50c SMP - CPU and CPU mask for processes
- each process has associated information about the cpu it is currently
  scheduled on and the mask of cpus it is allowed to use.
2010-09-15 14:10:16 +00:00
Tomas Hruby
9b6d66c787 SMP - BSP waits until the APs finish their booting
- APs configure local timers

- while configuring local APIC timer the CPUs fiddle with the interrupt
  handlers. As the interrupt table is shared the BSP must not run
2010-09-15 14:10:12 +00:00
Tomas Hruby
b7aed08e65 SMP - Only a single APIC timer handler
- bsp_timer_int_handler() and ap_timer_int_handler() unified into
  timer_int_handler()

- global realtime updated only on BSP
2010-09-15 14:10:09 +00:00
Tomas Hruby
85cca7096f SMP - The slave CPUs turn paging on
- APs wait until BSP turns paging on, it is not possible to safely
  execute any code on APs until we can turn paging on as well as it
  must be done synchronously everywhere

- APs turn paging on but do not continue and wait
2010-09-15 14:10:07 +00:00
Tomas Hruby
6aa26565e6 SMP - Big kernel lock (BKL)
- to isolate execution inside kernel we use a big kernel lock
  implemented as a spinlock

- the lock is acquired asap after entering kernel mode and released as
  late as possible. Only one CPU as a time can execute the core kernel
  code

- measurement son real hw show that the overhead of this lock is close
  to 0% of kernel time for the currnet system

- the overhead of this lock may be as high as 45% of kernel time in
  virtual machines depending on the ratio between physical CPUs
  available and emulated CPUs. The performance degradation is
  significant
2010-09-15 14:10:03 +00:00
Tomas Hruby
a42ab504a0 SMP - Kernel is loaded above 1M by default
- the 16-bit trampoline must be within the first megabyte of physical
  memory thus the smp trampoline is copied explicitly below 1M
2010-09-15 14:10:00 +00:00
Tomas Hruby
62c666566e SMP - We boot APs
- kernel detects CPUs by searching ACPI tables for local apic nodes

- each CPU has its own TSS that points to its own stack. All cpus boot
  on the same boot stack (in sequence) but switch to its private stack
  as soon as they can.

- final booting code in main() placed in bsp_finish_booting() which is
  executed only after the BSP switches to its final stack

- apic functions to send startup interrupts

- assembler functions to handle CPU features not needed for single cpu
  mode like memory barries, HT detection etc.

- new files kernel/smp.[ch], kernel/arch/i386/arch_smp.c and
  kernel/arch/i386/include/arch_smp.h

- 16-bit trampoline code for the APs. It is executed by each AP after
  receiving startup IPIs it brings up the CPUs to 32bit mode and let
  them spin in an infinite loop so they don't do any damage.

- implementation of kernel spinlock

- CONFIG_SMP and CONFIG_MAX_CPUS set by the build system
2010-09-15 14:09:52 +00:00
Tomas Hruby
13a0d5fa5e SMP - Cpu local variables
- most global variables carry information which is specific to the
  local CPU and each CPU must have its own copy

- cpu local variable must be declared in cpulocal.h between
  DECLARE_CPULOCAL_START and DECLARE_CPULOCAL_END markers using
  DECLARE_CPULOCAL macro

- to access the cpu local data the provided macros must be used

	get_cpu_var(cpu, name)
	get_cpu_var_ptr(cpu, name)

	get_cpulocal_var(name)
	get_cpulocal_var_ptr(name)

- using this macros makes future changes in the implementation
  possible

- switching to ELF will make the declaration of cpu local data much
  simpler, e.g.

  CPULOCAL int blah;

  anywhere in the kernel source code
2010-09-15 14:09:46 +00:00