思维导图备注

Understanding the Linux Kernel - Daniel P. Bovet
首页 收藏书籍 阅读记录
  • 书签 我的书签
  • 添加书签 添加书签 移除书签 移除书签

15. The Page Cache

浏览 10 扫码
  • 小字体
  • 中字体
  • 大字体
2022-02-24 02:57:32
请 登录 再阅读
上一篇:
下一篇:
  • 书签
  • 添加书签 移除书签
  • SPECIAL OFFER: Upgrade this ebook with O’Reilly
  • Preface
    • The Audience for This Book
    • Organization of the Material
    • Level of Description
    • Overview of the Book
    • Background Information
    • Conventions in This Book
    • How to Contact Us
    • Safari® Enabled
    • Acknowledgments
  • 1. Introduction
    • 1.1. Linux Versus Other Unix-Like Kernels
    • 1.2. Hardware Dependency
    • 1.3. Linux Versions
    • 1.4. Basic Operating System Concepts
      • 1.4.1. Multiuser Systems
      • 1.4.2. Users and Groups
      • 1.4.3. Processes
      • 1.4.4. Kernel Architecture
    • 1.5. An Overview of the Unix Filesystem
      • 1.5.1. Files
      • 1.5.2. Hard and Soft Links
      • 1.5.3. File Types
      • 1.5.4. File Descriptor and Inode
      • 1.5.5. Access Rights and File Mode
      • 1.5.6. File-Handling System Calls
    • 1.6. An Overview of Unix Kernels
      • 1.6.1. The Process/Kernel Model
      • 1.6.2. Process Implementation
      • 1.6.3. Reentrant Kernels
      • 1.6.4. Process Address Space
      • 1.6.5. Synchronization and Critical Regions
      • 1.6.6. Signals and Interprocess Communication
      • 1.6.7. Process Management
      • 1.6.8. Memory Management
      • 1.6.9. Device Drivers
  • 2. Memory Addressing
    • 2.1. Memory Addresses
    • 2.2. Segmentation in Hardware
      • 2.2.1. Segment Selectors and Segmentation Registers
      • 2.2.2. Segment Descriptors
      • 2.2.3. Fast Access to Segment Descriptors
      • 2.2.4. Segmentation Unit
    • 2.3. Segmentation in Linux
      • 2.3.1. The Linux GDT
      • 2.3.2. The Linux LDTs
    • 2.4. Paging in Hardware
      • 2.4.1. Regular Paging
      • 2.4.2. Extended Paging
      • 2.4.3. Hardware Protection Scheme
      • 2.4.4. An Example of Regular Paging
      • 2.4.5. The Physical Address Extension (PAE) Paging Mechanism
      • 2.4.6. Paging for 64-bit Architectures
      • 2.4.7. Hardware Cache
      • 2.4.8. Translation Lookaside Buffers (TLB)
    • 2.5. Paging in Linux
      • 2.5.1. The Linear Address Fields
      • 2.5.2. Page Table Handling
      • 2.5.3. Physical Memory Layout
      • 2.5.4. Process Page Tables
      • 2.5.5. Kernel Page Tables
      • 2.5.6. Fix-Mapped Linear Addresses
      • 2.5.7. Handling the Hardware Cache and the TLB
  • 3. Processes
    • 3.1. Processes, Lightweight Processes, and Threads
    • 3.2. Process Descriptor
      • 3.2.1. Process State
      • 3.2.2. Identifying a Process
      • 3.2.3. Relationships Among Processes
      • 3.2.4. How Processes Are Organized
      • 3.2.5. Process Resource Limits
    • 3.3. Process Switch
      • 3.3.1. Hardware Context
      • 3.3.2. Task State Segment
      • 3.3.3. Performing the Process Switch
      • 3.3.4. Saving and Loading the FPU, MMX, and XMM Registers
    • 3.4. Creating Processes
      • 3.4.1. The clone( ), fork( ), and vfork( ) System Calls
      • 3.4.2. Kernel Threads
    • 3.5. Destroying Processes
      • 3.5.1. Process Termination
      • 3.5.2. Process Removal
  • 4. Interrupts and Exceptions
    • 4.1. The Role of Interrupt Signals
    • 4.2. Interrupts and Exceptions
      • 4.2.1. IRQs and Interrupts
      • 4.2.2. Exceptions
      • 4.2.3. Interrupt Descriptor Table
      • 4.2.4. Hardware Handling of Interrupts and Exceptions
    • 4.3. Nested Execution of Exception and Interrupt Handlers
    • 4.4. Initializing the Interrupt Descriptor Table
      • 4.4.1. Interrupt, Trap, and System Gates
      • 4.4.2. Preliminary Initialization of the IDT
    • 4.5. Exception Handling
      • 4.5.1. Saving the Registers for the Exception Handler
      • 4.5.2. Entering and Leaving the Exception Handler
    • 4.6. Interrupt Handling
      • 4.6.1. I/O Interrupt Handling
      • 4.6.2. Interprocessor Interrupt Handling
    • 4.7. Softirqs and Tasklets
      • 4.7.1. Softirqs
      • 4.7.2. Tasklets
    • 4.8. Work Queues
      • 4.8.1.
    • 4.9. Returning from Interrupts and Exceptions
      • 4.9.1.
  • 5. Kernel Synchronization
    • 5.1. How the Kernel Services Requests
      • 5.1.1. Kernel Preemption
      • 5.1.2. When Synchronization Is Necessary
      • 5.1.3. When Synchronization Is Not Necessary
    • 5.2. Synchronization Primitives
      • 5.2.1. Per-CPU Variables
      • 5.2.2. Atomic Operations
      • 5.2.3. Optimization and Memory Barriers
      • 5.2.4. Spin Locks
      • 5.2.5. Read/Write Spin Locks
      • 5.2.6. Seqlocks
      • 5.2.7. Read-Copy Update (RCU)
      • 5.2.8. Semaphores
      • 5.2.9. Read/Write Semaphores
      • 5.2.10. Completions
      • 5.2.11. Local Interrupt Disabling
      • 5.2.12. Disabling and Enabling Deferrable Functions
    • 5.3. Synchronizing Accesses to Kernel Data Structures
      • 5.3.1. Choosing Among Spin Locks, Semaphores, and Interrupt Disabling
    • 5.4. Examples of Race Condition Prevention
      • 5.4.1. Reference Counters
      • 5.4.2. The Big Kernel Lock
      • 5.4.3. Memory Descriptor Read/Write Semaphore
      • 5.4.4. Slab Cache List Semaphore
      • 5.4.5. Inode Semaphore
  • 6. Timing Measurements
    • 6.1. Clock and Timer Circuits
      • 6.1.1. Real Time Clock (RTC)
      • 6.1.2. Time Stamp Counter (TSC)
      • 6.1.3. Programmable Interval Timer (PIT)
      • 6.1.4. CPU Local Timer
      • 6.1.5. High Precision Event Timer (HPET)
      • 6.1.6. ACPI Power Management Timer
    • 6.2. The Linux Timekeeping Architecture
      • 6.2.1. Data Structures of the Timekeeping Architecture
      • 6.2.2. Timekeeping Architecture in Uniprocessor Systems
      • 6.2.3. Timekeeping Architecture in Multiprocessor Systems
    • 6.3. Updating the Time and Date
    • 6.4. Updating System Statistics
      • 6.4.1. Updating Local CPU Statistics
      • 6.4.2. Keeping Track of System Load
      • 6.4.3. Profiling the Kernel Code
      • 6.4.4. Checking the NMI Watchdogs
    • 6.5. Software Timers and Delay Functions
      • 6.5.1. Dynamic Timers
      • 6.5.2. An Application of Dynamic Timers: the nanosleep( ) System Call
      • 6.5.3. Delay Functions
    • 6.6. System Calls Related to Timing Measurements
      • 6.6.1. The time( ) and gettimeofday( ) System Calls
      • 6.6.2. The adjtimex( ) System Call
      • 6.6.3. The setitimer( ) and alarm( ) System Calls
      • 6.6.4. System Calls for POSIX Timers
  • 7. Process Scheduling
    • 7.1. Scheduling Policy
      • 7.1.1. Process Preemption
      • 7.1.2. How Long Must a Quantum Last?
    • 7.2. The Scheduling Algorithm
      • 7.2.1. Scheduling of Conventional Processes
      • 7.2.2. Scheduling of Real-Time Processes
    • 7.3. Data Structures Used by the Scheduler
      • 7.3.1. The runqueue Data Structure
      • 7.3.2. Process Descriptor
    • 7.4. Functions Used by the Scheduler
      • 7.4.1. The scheduler_tick( ) Function
      • 7.4.2. The try_to_wake_up( ) Function
      • 7.4.3. The recalc_task_prio( ) Function
      • 7.4.4. The schedule( ) Function
    • 7.5. Runqueue Balancing in Multiprocessor Systems
      • 7.5.1. Scheduling Domains
      • 7.5.2. The rebalance_tick( ) Function
      • 7.5.3. The load_balance( ) Function
      • 7.5.4. The move_tasks( ) Function
    • 7.6. System Calls Related to Scheduling
      • 7.6.1. The nice( ) System Call
      • 7.6.2. The getpriority( ) and setpriority( ) System Calls
      • 7.6.3. The sched_getaffinity( ) and sched_setaffinity( ) System Calls
      • 7.6.4. System Calls Related to Real-Time Processes
  • 8. Memory Management
    • 8.1. Page Frame Management
      • 8.1.1. Page Descriptors
      • 8.1.2. Non-Uniform Memory Access (NUMA)
      • 8.1.3. Memory Zones
      • 8.1.4. The Pool of Reserved Page Frames
      • 8.1.5. The Zoned Page Frame Allocator
      • 8.1.6. Kernel Mappings of High-Memory Page Frames
      • 8.1.7. The Buddy System Algorithm
      • 8.1.8. The Per-CPU Page Frame Cache
      • 8.1.9. The Zone Allocator
    • 8.2. Memory Area Management
      • 8.2.1. The Slab Allocator
      • 8.2.2. Cache Descriptor
      • 8.2.3. Slab Descriptor
      • 8.2.4. General and Specific Caches
      • 8.2.5. Interfacing the Slab Allocator with the Zoned Page Frame Allocator
      • 8.2.6. Allocating a Slab to a Cache
      • 8.2.7. Releasing a Slab from a Cache
      • 8.2.8. Object Descriptor
      • 8.2.9. Aligning Objects in Memory
      • 8.2.10. Slab Coloring
      • 8.2.11. Local Caches of Free Slab Objects
      • 8.2.12. Allocating a Slab Object
      • 8.2.13. Freeing a Slab Object
      • 8.2.14. General Purpose Objects
      • 8.2.15. Memory Pools
    • 8.3. Noncontiguous Memory Area Management
      • 8.3.1. Linear Addresses of Noncontiguous Memory Areas
      • 8.3.2. Descriptors of Noncontiguous Memory Areas
      • 8.3.3. Allocating a Noncontiguous Memory Area
      • 8.3.4. Releasing a Noncontiguous Memory Area
  • 9. Process Address Space
    • 9.1. The Process's Address Space
    • 9.2. The Memory Descriptor
      • 9.2.1. Memory Descriptor of Kernel Threads
    • 9.3. Memory Regions
      • 9.3.1. Memory Region Data Structures
      • 9.3.2. Memory Region Access Rights
      • 9.3.3. Memory Region Handling
      • 9.3.4. Allocating a Linear Address Interval
      • 9.3.5. Releasing a Linear Address Interval
    • 9.4. Page Fault Exception Handler
      • 9.4.1. Handling a Faulty Address Outside the Address Space
      • 9.4.2. Handling a Faulty Address Inside the Address Space
      • 9.4.3. Demand Paging
      • 9.4.4. Copy On Write
      • 9.4.5. Handling Noncontiguous Memory Area Accesses
    • 9.5. Creating and Deleting a Process Address Space
      • 9.5.1. Creating a Process Address Space
      • 9.5.2. Deleting a Process Address Space
    • 9.6. Managing the Heap
  • 10. System Calls
    • 10.1. POSIX APIs and System Calls
    • 10.2. System Call Handler and Service Routines
    • 10.3. Entering and Exiting a System Call
      • 10.3.1. Issuing a System Call via the int $0x80 Instruction
      • 10.3.2. Issuing a System Call via the sysenter Instruction
    • 10.4. Parameter Passing
      • 10.4.1. Verifying the Parameters
      • 10.4.2. Accessing the Process Address Space
      • 10.4.3. Dynamic Address Checking: The Fix-up Code
      • 10.4.4. The Exception Tables
      • 10.4.5. Generating the Exception Tables and the Fixup Code
    • 10.5. Kernel Wrapper Routines
  • 11. Signals
    • 11.1. The Role of Signals
      • 11.1.1. Actions Performed upon Delivering a Signal
      • 11.1.2. POSIX Signals and Multithreaded Applications
      • 11.1.3. Data Structures Associated with Signals
      • 11.1.4. Operations on Signal Data Structures
    • 11.2. Generating a Signal
      • 11.2.1. The specific_send_sig_info( ) Function
      • 11.2.2. The send_signal( ) Function
      • 11.2.3. The group_send_sig_info( ) Function
    • 11.3. Delivering a Signal
      • 11.3.1. Executing the Default Action for the Signal
      • 11.3.2. Catching the Signal
      • 11.3.3. Reexecution of System Calls
    • 11.4. System Calls Related to Signal Handling
      • 11.4.1. The kill( ) System Call
      • 11.4.2. The tkill( ) and tgkill( ) System Calls
      • 11.4.3. Changing a Signal Action
      • 11.4.4. Examining the Pending Blocked Signals
      • 11.4.5. Modifying the Set of Blocked Signals
      • 11.4.6. Suspending the Process
      • 11.4.7. System Calls for Real-Time Signals
  • 12. The Virtual Filesystem
    • 12.1. The Role of the Virtual Filesystem (VFS)
      • 12.1.1. The Common File Model
      • 12.1.2. System Calls Handled by the VFS
    • 12.2. VFS Data Structures
      • 12.2.1. Superblock Objects
      • 12.2.2. Inode Objects
      • 12.2.3. File Objects
      • 12.2.4. dentry Objects
      • 12.2.5. The dentry Cache
      • 12.2.6. Files Associated with a Process
    • 12.3. Filesystem Types
      • 12.3.1. Special Filesystems
      • 12.3.2. Filesystem Type Registration
    • 12.4. Filesystem Handling
      • 12.4.1. Namespaces
      • 12.4.2. Filesystem Mounting
      • 12.4.3. Mounting a Generic Filesystem
      • 12.4.4. Mounting the Root Filesystem
      • 12.4.5. Unmounting a Filesystem
    • 12.5. Pathname Lookup
      • 12.5.1. Standard Pathname Lookup
      • 12.5.2. Parent Pathname Lookup
      • 12.5.3. Lookup of Symbolic Links
    • 12.6. Implementations of VFS System Calls
      • 12.6.1. The open( ) System Call
      • 12.6.2. The read( ) and write( ) System Calls
      • 12.6.3. The close( ) System Call
    • 12.7. File Locking
      • 12.7.1. Linux File Locking
      • 12.7.2. File-Locking Data Structures
      • 12.7.3. FL_FLOCK Locks
      • 12.7.4. FL_POSIX Locks
  • 13. I/O Architecture and Device Drivers
    • 13.1. I/O Architecture
      • 13.1.1. I/O Ports
      • 13.1.2. I/O Interfaces
      • 13.1.3. Device Controllers
    • 13.2. The Device Driver Model
      • 13.2.1. The sysfs Filesystem
      • 13.2.2. Kobjects
      • 13.2.3. Components of the Device Driver Model
    • 13.3. Device Files
      • 13.3.1. User Mode Handling of Device Files
      • 13.3.2. VFS Handling of Device Files
    • 13.4. Device Drivers
      • 13.4.1. Device Driver Registration
      • 13.4.2. Device Driver Initialization
      • 13.4.3. Monitoring I/O Operations
      • 13.4.4. Accessing the I/O Shared Memory
      • 13.4.5. Direct Memory Access (DMA)
      • 13.4.6. Levels of Kernel Support
    • 13.5. Character Device Drivers
      • 13.5.1. Assigning Device Numbers
      • 13.5.2. Accessing a Character Device Driver
      • 13.5.3. Buffering Strategies for Character Devices
  • 14. Block Device Drivers
    • 14.1. Block Devices Handling
      • 14.1.1. Sectors
      • 14.1.2. Blocks
      • 14.1.3. Segments
    • 14.2. The Generic Block Layer
      • 14.2.1. The Bio Structure
      • 14.2.2. Representing Disks and Disk Partitions
      • 14.2.3. Submitting a Request
    • 14.3. The I/O Scheduler
      • 14.3.1. Request Queue Descriptors
      • 14.3.2. Request Descriptors
      • 14.3.3. Activating the Block Device Driver
      • 14.3.4. I/O Scheduling Algorithms
      • 14.3.5. Issuing a Request to the I/O Scheduler
    • 14.4. Block Device Drivers
      • 14.4.1. Block Devices
      • 14.4.2. Device Driver Registration and Initialization
      • 14.4.3. The Strategy Routine
      • 14.4.4. The Interrupt Handler
    • 14.5. Opening a Block Device File
  • 15. The Page Cache
    • 15.1. The Page Cache
      • 15.1.1. The address_space Object
      • 15.1.2. The Radix Tree
      • 15.1.3. Page Cache Handling Functions
      • 15.1.4. The Tags of the Radix Tree
    • 15.2. Storing Blocks in the Page Cache
      • 15.2.1. Block Buffers and Buffer Heads
      • 15.2.2. Managing the Buffer Heads
      • 15.2.3. Buffer Pages
      • 15.2.4. Allocating Block Device Buffer Pages
      • 15.2.5. Releasing Block Device Buffer Pages
      • 15.2.6. Searching Blocks in the Page Cache
      • 15.2.7. Submitting Buffer Heads to the Generic Block Layer
    • 15.3. Writing Dirty Pages to Disk
      • 15.3.1. The pdflush Kernel Threads
      • 15.3.2. Looking for Dirty Pages To Be Flushed
      • 15.3.3. Retrieving Old Dirty Pages
    • 15.4. The sync( ), fsync( ), and fdatasync( ) System Calls
      • 15.4.1. The sync ( ) System Call
      • 15.4.2. The fsync ( ) and fdatasync ( ) System Calls
  • 16. Accessing Files
    • 16.1. Reading and Writing a File
      • 16.1.1. Reading from a File
      • 16.1.2. Read-Ahead of Files
      • 16.1.3. Writing to a File
      • 16.1.4. Writing Dirty Pages to Disk
    • 16.2. Memory Mapping
      • 16.2.1. Memory Mapping Data Structures
      • 16.2.2. Creating a Memory Mapping
      • 16.2.3. Destroying a Memory Mapping
      • 16.2.4. Demand Paging for Memory Mapping
      • 16.2.5. Flushing Dirty Memory Mapping Pages to Disk
      • 16.2.6. Non-Linear Memory Mappings
    • 16.3. Direct I/O Transfers
    • 16.4. Asynchronous I/O
      • 16.4.1. Asynchronous I/O in Linux 2.6
  • 17. Page Frame Reclaiming
    • 17.1. The Page Frame Reclaiming Algorithm
      • 17.1.1. Selecting a Target Page
      • 17.1.2. Design of the PFRA
    • 17.2. Reverse Mapping
      • 17.2.1. Reverse Mapping for Anonymous Pages
      • 17.2.2. Reverse Mapping for Mapped Pages
    • 17.3. Implementing the PFRA
      • 17.3.1. The Least Recently Used (LRU) Lists
      • 17.3.2. Low On Memory Reclaiming
      • 17.3.3. Reclaiming Pages of Shrinkable Disk Caches
      • 17.3.4. Periodic Reclaiming
      • 17.3.5. The Out of Memory Killer
      • 17.3.6. The Swap Token
    • 17.4. Swapping
      • 17.4.1. Swap Area
      • 17.4.2. Swap Area Descriptor
      • 17.4.3. Swapped-Out Page Identifier
      • 17.4.4. Activating and Deactivating a Swap Area
      • 17.4.5. Allocating and Releasing a Page Slot
      • 17.4.6. The Swap Cache
      • 17.4.7. Swapping Out Pages
      • 17.4.8. Swapping in Pages
  • 18. The Ext2 and Ext3 Filesystems
    • 18.1. General Characteristics of Ext2
    • 18.2. Ext2 Disk Data Structures
      • 18.2.1. Superblock
      • 18.2.2. Group Descriptor and Bitmap
      • 18.2.3. Inode Table
      • 18.2.4. Extended Attributes of an Inode
      • 18.2.5. Access Control Lists
      • 18.2.6. How Various File Types Use Disk Blocks
    • 18.3. Ext2 Memory Data Structures
      • 18.3.1. The Ext2 Superblock Object
      • 18.3.2. The Ext2 inode Object
    • 18.4. Creating the Ext2 Filesystem
    • 18.5. Ext2 Methods
      • 18.5.1. Ext2 Superblock Operations
      • 18.5.2. Ext2 inode Operations
      • 18.5.3. Ext2 File Operations
    • 18.6. Managing Ext2 Disk Space
      • 18.6.1. Creating inodes
      • 18.6.2. Deleting inodes
      • 18.6.3. Data Blocks Addressing
      • 18.6.4. File Holes
      • 18.6.5. Allocating a Data Block
      • 18.6.6. Releasing a Data Block
    • 18.7. The Ext3 Filesystem
      • 18.7.1. Journaling Filesystems
      • 18.7.2. The Ext3 Journaling Filesystem
      • 18.7.3. The Journaling Block Device Layer
      • 18.7.4. How Journaling Works
  • 19. Process Communication
    • 19.1. Pipes
      • 19.1.1. Using a Pipe
      • 19.1.2. Pipe Data Structures
      • 19.1.3. Creating and Destroying a Pipe
      • 19.1.4. Reading from a Pipe
      • 19.1.5. Writing into a Pipe
    • 19.2. FIFOs
      • 19.2.1. Creating and Opening a FIFO
    • 19.3. System V IPC
      • 19.3.1. Using an IPC Resource
      • 19.3.2. The ipc( ) System Call
      • 19.3.3. IPC Semaphores
      • 19.3.4. IPC Messages
      • 19.3.5. IPC Shared Memory
    • 19.4. POSIX Message Queues
  • 20. Program ExZecution
    • 20.1. Executable Files
      • 20.1.1. Process Credentials and Capabilities
      • 20.1.2. Command-Line Arguments and Shell Environment
      • 20.1.3. Libraries
      • 20.1.4. Program Segments and Process Memory Regions
      • 20.1.5. Execution Tracing
    • 20.2. Executable Formats
    • 20.3. Execution Domains
    • 20.4. The exec Functions
  • A. System Startup
    • A.1. Prehistoric Age: the BIOS
    • A.2. Ancient Age: the Boot Loader
      • A.2.1. Booting Linux from a Disk
    • A.3. Middle Ages: the setup( ) Function
    • A.4. Renaissance: the startup_32( ) Functions
    • A.5. Modern Age: the start_kernel( ) Function
  • B. Modules
    • B.1. To Be (a Module) or Not to Be?
      • B.1.1. Module Licenses
    • B.2. Module Implementation
      • B.2.1. Module Usage Counters
      • B.2.2. Exporting Symbols
      • B.2.3. Module Dependency
    • B.3. Linking and Unlinking Modules
    • B.4. Linking Modules on Demand
      • B.4.1. The modprobe Program
      • B.4.2. The request_module( ) Function
  • C. Bibliography
    • Books on Unix Kernels
    • Books on the Linux Kernel
    • Books on PC Architecture and Technical Manuals on Intel Microprocessors
    • Other Online Documentation Sources
    • Research Papers Related to Linux Development
  • SPECIAL OFFER: Upgrade this ebook with O’Reilly
暂无相关搜索结果!
    展开/收起文章目录

    二维码

    手机扫一扫,轻松掌上学

    《Understanding the Linux Kernel - Daniel P. Bovet》电子书下载

    请下载您需要的格式的电子书,随时随地,享受学习的乐趣!
    EPUB 电子书

    书签列表

      阅读记录

      阅读进度: 0.00% ( 0/0 ) 重置阅读进度