Rev 82 | Rev 84 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 82 | Rev 83 | ||
---|---|---|---|
Line 265... | Line 265... | ||
265 | </para> |
265 | </para> |
266 | 266 | ||
267 | <section> |
267 | <section> |
268 | <title>Implementation</title> |
268 | <title>Implementation</title> |
269 | 269 | ||
270 | <para>The slab allocator is closely modelled after OpenSolaris slab |
270 | <para>The slab allocator is closely modelled after <xref |
271 | allocator by Jeff Bonwick and Jonathan Adams <xref |
- | |
272 | linkend="Bonwick01" /> with the following exceptions:<itemizedlist> |
271 | linkend="Bonwick01" /> with the following exceptions:<itemizedlist> |
273 | <listitem> |
272 | <listitem> |
274 | <para>empty slabs are immediately deallocated and</para> |
273 | <para>empty slabs are immediately deallocated and</para> |
275 | </listitem> |
274 | </listitem> |
276 | 275 | ||
Line 487... | Line 486... | ||
487 | key for the hash table. One of the major differences between the |
486 | key for the hash table. One of the major differences between the |
488 | global page hash table and hierarchical 4-level page tables is that |
487 | global page hash table and hierarchical 4-level page tables is that |
489 | there is only a single global page hash table in the system while |
488 | there is only a single global page hash table in the system while |
490 | hierarchical page tables exist per address space. Thus, the global |
489 | hierarchical page tables exist per address space. Thus, the global |
491 | page hash table contains information about mappings of all address |
490 | page hash table contains information about mappings of all address |
492 | spaces in the system. </para> |
491 | spaces in the system.</para> |
493 | 492 | ||
494 | <para>The global page hash table mechanism uses the generic hash table |
493 | <para>The global page hash table mechanism uses the generic hash table |
495 | type as described in the chapter about <link linkend="hashtables">data |
494 | type as described in the chapter dedicated to <link |
496 | structures</link> earlier in this book.</para> |
495 | linkend="hashtables">data structures</link> earlier in this |
- | 496 | book.</para> |
|
497 | </section> |
497 | </section> |
498 | </section> |
498 | </section> |
499 | </section> |
499 | </section> |
500 | 500 | ||
501 | <section id="tlb"> |
501 | <section id="tlb"> |
Line 503... | Line 503... | ||
503 | <primary>TLB</primary> |
503 | <primary>TLB</primary> |
504 | </indexterm> |
504 | </indexterm> |
505 | 505 | ||
506 | <title>Translation Lookaside buffer</title> |
506 | <title>Translation Lookaside buffer</title> |
507 | 507 | ||
508 | <para>Due to the extensive overhead during the page mapping lookup in the |
508 | <para>Due to the extensive overhead of several extra memory accesses |
- | 509 | during page table lookup that are necessary on every instruction, modern |
|
509 | page tables, all architectures has fast assotiative cache memory built-in |
510 | architectures deploy fast assotiative cache of recelntly used page |
510 | CPU. This memory called TLB stores recently used page table |
511 | mappings. This cache is called TLB - Translation Lookaside Buffer - and is |
- | 512 | present on every processor in the system. As it has been already pointed |
|
- | 513 | out, TLB is the only page translation mechanism for some |
|
511 | entries.</para> |
514 | architectures.</para> |
512 | 515 | ||
513 | <section id="tlb_shootdown"> |
516 | <section id="tlb_shootdown"> |
514 | <indexterm> |
517 | <indexterm> |
515 | <primary>TLB</primary> |
518 | <primary>TLB</primary> |
516 | 519 | ||
517 | <secondary>- TLB shootdown</secondary> |
520 | <secondary>- TLB shootdown</secondary> |
518 | </indexterm> |
521 | </indexterm> |
519 | 522 | ||
520 | <title>TLB consistency. TLB shootdown algorithm.</title> |
523 | <title>TLB consistency</title> |
521 | 524 | ||
522 | <para>Operating system is responsible for keeping TLB consistent by |
525 | <para>The operating system is responsible for keeping TLB consistent |
523 | invalidating the contents of TLB, whenever there is some change in page |
526 | with the page tables. Whenever mappings are modified or purged from the |
524 | tables. Those changes may occur when page or group of pages were |
527 | page tables, or when an address space identifier is reused, the kernel |
525 | unmapped, mapping is changed or system switching active address space to |
- | |
526 | schedule a new system task. Moreover, this invalidation operation must |
- | |
527 | be done an all system CPUs because each CPU has its own independent TLB |
528 | needs to invalidate the respective contents of TLB. Some TLB types |
528 | cache. Thus maintaining TLB consistency on SMP configuration as not as |
- | |
529 | trivial task as it looks on the first glance. Naive solution would |
529 | support partial invalidation of their content (e.g. ranges of pages or |
530 | assume that is the CPU which wants to invalidate TLB will invalidate TLB |
530 | address spaces) while other types can be invalidated only entirely. The |
531 | caches on other CPUs. It is not possible on the most of the |
531 | invalidation must be done on all processors for there is one TLB per |
532 | architectures, because of the simple fact - flushing TLB is allowed only |
- | |
533 | on the local CPU and there is no possibility to access other CPUs' TLB |
532 | processor. Maintaining TLB consistency on multiprocessor configurations |
534 | caches, thus invalidate TLB remotely.</para> |
533 | is not as trivial as it might look from the first glance.</para> |
535 | 534 | ||
536 | <para>Technique of remote invalidation of TLB entries is called "TLB |
535 | <para>The remote TLB invalidation is called TLB shootdown. HelenOS uses |
537 | shootdown". HelenOS uses a variation of the algorithm described by D. |
536 | a simplified variant of the algorithm described in <xref |
538 | Black et al., "Translation Lookaside Buffer Consistency: A Software |
- | |
539 | Approach," Proc. Third Int'l Conf. Architectural Support for Programming |
- | |
540 | Languages and Operating Systems, 1989, pp. 113-122. <xref |
- | |
541 | linkend="Black89" /></para> |
537 | linkend="Black89" />. </para> |
542 | - | ||
543 | <para>As the situation demands, you will want partitial invalidation of |
- | |
544 | TLB caches. In case of simple memory mapping change it is necessary to |
- | |
545 | invalidate only one or more adjacent pages. In case if the architecture |
- | |
546 | is aware of ASIDs, when kernel needs to dump some ASID to use by another |
- | |
547 | task, it invalidates only entries from this particular address space. |
- | |
548 | Final option of the TLB invalidation is the complete TLB cache |
- | |
549 | invalidation, which is the operation that flushes all entries in |
- | |
550 | TLB.</para> |
- | |
551 | 538 | ||
552 | <para>TLB shootdown is performed in two phases.</para> |
539 | <para>TLB shootdown is performed in three phases.</para> |
553 | 540 | ||
554 | <formalpara> |
541 | <formalpara> |
555 | <title>Phase 1.</title> |
542 | <title>Phase 1.</title> |
556 | 543 | ||
557 | <para>First, initiator locks a global TLB spinlock, then request is |
544 | <para>The initiator clears its TLB flag and locks the global TLB |
558 | being put to the local request cache of every other CPU in the system |
545 | spinlock. The request is then enqueued into all other processors' TLB |
559 | protected by its spinlock. In case the cache is full, all requests in |
546 | shootdown message queues. When the TLB shootdown message queue is full |
560 | the cache are replaced by one request, indicating global TLB flush. |
547 | on any processor, the queue is purged and a single request to |
561 | Then the initiator thread sends an IPI message indicating the TLB |
548 | invalidate the entire TLB is stored there. Once all the TLB shootdown |
562 | shootdown request to the rest of the CPUs and waits actively until all |
549 | messages were dispatched, the initiator sends all other processors an |
563 | CPUs confirm TLB invalidating action execution by setting up a special |
550 | interrupt to notify them about the incoming TLB shootdown message. It |
564 | flag. After setting this flag this thread is blocked on the TLB |
551 | then spins until all processors accept the interrupt and clear their |
565 | spinlock, held by the initiator.</para> |
552 | TLB flags.</para> |
566 | </formalpara> |
553 | </formalpara> |
567 | 554 | ||
568 | <formalpara> |
555 | <formalpara> |
569 | <title>Phase 2.</title> |
556 | <title>Phase 2.</title> |
570 | 557 | ||
571 | <para>All CPUs are waiting on the TLB spinlock to execute TLB |
558 | <para>Except for the initiator, all other processors are spining on |
- | 559 | the TLB spinlock. The initiator is now free to modify the page tables |
|
572 | invalidation action and have indicated their intention to the |
560 | and purge its own TLB. The initiator then unlocks the global TLB |
- | 561 | spinlock and sets its TLB flag.</para> |
|
- | 562 | </formalpara> |
|
- | 563 | ||
- | 564 | <formalpara> |
|
- | 565 | <title>Phase 3.</title> |
|
- | 566 | ||
- | 567 | <para>When the spinlock is unlocked by the initiator, other processors |
|
573 | initiator. Initiator continues, cleaning up its TLB and releasing the |
568 | are sequentially granted the spinlock. However, once they manage to |
574 | global TLB spinlock. After this all other CPUs gain and immidiately |
569 | lock it, they immediately release it. Each processor invalidates its |
- | 570 | TLB according to messages found in its TLB shootdown message queue. In |
|
575 | release TLB spinlock and perform TLB invalidation actions.</para> |
571 | the end, each processor sets its TLB flag and resumes its previous |
- | 572 | operation.</para> |
|
576 | </formalpara> |
573 | </formalpara> |
577 | </section> |
574 | </section> |
578 | 575 | ||
579 | <section> |
576 | <section> |
580 | <title>Address spaces</title> |
577 | <title>Address spaces</title> |