描述 linux 系统中,当 cpu 上没有要执行的任务时,往往会运行 swapper 进程,即 idle 状态,这时我们可以说 cpu 处于空闲状态。...为什么在 cpu 处于无任务时要运行 swapper 而不是直接停止呢或者运行其他任务呢?...link:Why do we need a swapper task in linux?
*************[1273732.110173] [ffff889be8fbcd00][dev_gro_receive ][cpu:40 ][ens5 ][pid:0 ][swapper...seq: 56464[1273732.110185] [ffff889be8fbcd00][__netif_receive_skb_core][cpu:40 ][ens5 ][pid:0 ][swapper...request, seq: 56464[1273732.110189] [ffff889be8fbcd00][ip_rcv ][cpu:40 ][ens5 ][pid:0 ][swapper...request, seq: 56464[1273732.110192] [ffff889be8fbcd00][ip_rcv_core ][cpu:40 ][ens5 ][pid:0 ][swapper...seq: 56464[1273732.110252] [ffff889be8fbcc00][ip_local_deliver_finish][cpu:40 ][ens5 ][pid:0 ][swapper
************ [1273732.110173] [ffff889be8fbcd00][dev_gro_receive ][cpu:40 ][ens5 ][pid:0 ][swapper..., seq: 56464 [1273732.110189] [ffff889be8fbcd00][ip_rcv ][cpu:40 ][ens5 ][pid:0 ][swapper..., seq: 56464 [1273732.110192] [ffff889be8fbcd00][ip_rcv_core ][cpu:40 ][ens5 ][pid:0 ][swapper..., seq: 56464 [1273732.110196] [ffff889be8fbcd00][skb_clone ][cpu:40 ][ens5 ][pid:0 ][swapper..., seq: 56464 [1273732.110204] [ffff889be8fbcc00][nf_hook_slow ][cpu:40 ][ens5 ][pid:0 ][swapper
. # 19.14% 0.00% swapper [kernel.kallsyms] [k] cpu_startup_entry...--0.95%--select_task_rq_fair ... 19.14% 0.00% swapper.............. ............................ .......................................... # 14.55% swapper
在内存系统初始化过程中,有如下代码: 1: static void __init pagetable_init(void) 2: { 3: pgd_t *pgd_base = swapper_pg_dir...; 4: 5: permanent_kmaps_init(pgd_base); 6: } 这里,我们看到了神秘的swapper_pg_dir,全局搜索一下,发现了 1...In any case, 13: * paravirt_pagetable_setup_start() will set up swapper_pg_dir 14: * appropriately...在BSS段,一共保留了4个页面的空间,分别用initial_page_table, initial_pg_fixmap, empty_zero_page和swapper_pg_dir来标志其地址。...); 10: paging_init(); 11: x86_init.paging.pagetable_setup_done(swapper_pg_dir); 12: 13: ...
, pgd, PGD_SIZE);//将新建立的页表内容替换swapper_pg_dir页表内容 cpu_replace_ttbr1(lm_alias(swapper_pg_dir)); pgd_clear_fixmap...(); memblock_free(pgd_phys, PAGE_SIZE); /* * We only reuse the PGD from the swapper_pg_dir, not...the pud + pmd * allocated with it. */ memblock_free(__pa_symbol(swapper_pg_dir) + PAGE_SIZE,...SWAPPER_DIR_SIZE - PAGE_SIZE); } early_pgtable_alloc:分配一页大小的物理内存放进pgd map_kernel(pgd):将内核的各个段进行映射(.text...cpu_replace_ttbr1(__va(pgd_phys)):切换页表 memcpy(swapper_pg_dir, pgd, PGD_SIZE):将新建立的页表内容替换swapper_pg_dir
5.create_mapping函数 通过init_mm数据结构的pgd成员来获取, swapper_pg_dir全局变量指向PGD页表基地址。.... += IDMAP_DIR_SIZE; swapper_pg_dir = .; . += SWAPPER_DIR_SIZE; [arch/arm64/include/asm/page.h] #define...SWAPPER_PGTABLE_LEVELS (CONFIG_ARM64_PGTABLE_LEVELS - 1) #define SWAPPER DIR SIZE (SWAPPER PGTABLE...LEVELS * PAGE SIZE) 假设CONFIG_ARM64_PGTABLE_LEVELS定义为4,那么SWAPPER_DIR_SIZE大小就等于3个PAGE_SIZE的大小。...swapper_pg_dir的起始地址由vmlinux.lds.S链接文件计算得来。
after_hwframe+0x65 ([kernel.kallsyms]) 7f86e5fc47c7 mmap64+0x47 (/usr/lib64/ld-2.28.so) swapper...kernel.kallsyms]) ffffffff87c00107 secondary_startup_64_no_verify+0xc2 ([kernel.kallsyms]) swapper...kernel.kallsyms]) ffffffff87c00107 secondary_startup_64_no_verify+0xc2 ([kernel.kallsyms]) swapper...从前后对比来看,我们可以看出这个进程的名字是swapper,其调用顺序分别是secondary_startup_64_no_verify、start_kernel一直到native_safe_halt,...例如从上图中我们可以看出从swapper到native_safe_halt的调用栈。
r5:ffffffff-(2)[1:swapper/0] r4:00000000-(2)[1:swapper/0] r3:00000000-(2)[1:swapper/0] [ 3.056426...:00000000-(2)[1:swapper/0] r4:00000001-(2)[1:swapper/0] [ 3.056585] -(2)[1:swapper/0][swapper/0] r7:e7f001f2-(2)[1:swapper/0] r6:df04a000-(2)[1:swapper/0] r5:c04289dc...[ 3.056642] -(2)[1:swapper/0] r4:00000004-(2)[1:swapper/0] [ 3.056658] -(2)[1:swapper/0]...] r8:e7100000-(2)[1:swapper/0] r7:00000000-(2)[1:swapper/0] r6:c010cd98-(2)[1:swapper/0] r5:00000000-
/0] > 0 0 1 ffffffc07d190d80 RU 0.0 0 0 [swapper/1] 0 0 2...ffffffc07d191b00 RU 0.0 0 0 [swapper/2] > 0 0 3 ffffffc07d192880 RU 0.0...0 0 [swapper/3] > 0 0 4 ffffffc07d193600 RU 0.0 0 0 [swapper.../4] > 0 0 5 ffffffc07d194380 RU 0.0 0 0 [swapper/5] 0 0 6...0 0 [swapper/7] 1 0 4 ffffffc07d148000 UN 0.0 0 0 [swapper
] 67144.378145: irq:irq_handler_exit: irq=18 ret=unhandled swapper 0 [000] 67144.378146...swapper 0 [000] 67144.378692: irq:irq_handler_entry: irq=18 name=ioc0 swapper 0 [000...] 67144.378710: irq:irq_handler_exit: irq=18 ret=handled swapper 0 [001] 67144.512867:...: irq=26 ret=handled swapper 0 [001] 67144.512873: irq:softirq_entry: vec=3 [action=...swapper 0 [001] 67144.514144: irq:irq_handler_exit: irq=27 ret=handled swapper
int i = 10,j=20; ::cout<<"i, j ="<<i<<" , "<<j<<endl; coutswapper...template void Swap(int &t1,int &t2); int main() { coutswapper...int i = 10,j=20; cout<<"i, j ="<<i<<" , "<<j<<endl; coutswapper
/1:0 [120] R ==> [120] -0 [005] 857.011293: sched_switch: swapper/5:0...:7 [120] rcu_sched-7 [001] 857.014150: sched_switch: rcu_sched:7 [120] S ==> swapper...:7 [120] rcu_sched-7 [001] 857.017267: sched_switch: rcu_sched:7 [120] S ==> swapper...:7 [120] rcu_sched-7 [001] 857.020336: sched_switch: rcu_sched:7 [120] S ==> swapper.../0:0 [120] R ==> kw1342 [120] -0 1] 1891.403968: sched_switch: swapper/1:0
-(2)[1:swapper/0] r4:00000000-(2)[1:swapper/0] r3:00000000-(2)[1:swapper/0] [ 3.056426] -(2)[1:swapper...-(2)[1:swapper/0] r9:df060000-(2)[1:swapper/0] r8:df04a020-(2)[1:swapper/0] r7:c0caaaf0-(2)[1:swapper.../0] r6:c10f0c88-(2)[1:swapper/0] r5:00000001 [ 3.056539] -(2)[1:swapper/0] r4:df04bb74-(2)[1:swapper...+0x44/0x4c) [ 3.056560] -(2)[1:swapper/0] r6:df04bce8-(2)[1:swapper/0] r5:00000000-(2)[1:swapper/0.../0] r8:e7100000-(2)[1:swapper/0] r7:00000000-(2)[1:swapper/0] r6:c010cd98-(2)[1:swapper/0] r5:00000000
. += IDMAP_DIR_SIZE;swapper_pg_dir = .;. += SWAPPER_DIR_SIZE; 从链接脚本中可以看到预留6个页面存储页表项。紧跟在bss段后面。...index orr \phys, \flags, \phys, lsl #SWAPPER_BLOCK_SHIFT // table entry lsr \end, \end, #SWAPPER_BLOCK_SHIFT...#define SWAPPER_BLOCK_SHIFT PMD_SHIFT#define SWAPPER_BLOCK_SIZE (1 SWAPPER_BLOCK_SHIFT);/* 3 */ \ end >>= SWAPPER_BLOCK_SHIFT;...位进行清零,和第三步骤的phys SWAPPER_BLOCK_SHIFT收尾呼应。
do this we need to go via a temporary pgd. */ cpu_replace_ttbr1(__va(pgd_phys)); memcpy(swapper_pg_dir..., pgd, PAGE_SIZE); cpu_replace_ttbr1(swapper_pg_dir); pgd_clear_fixmap(); memblock_free(...pgd_phys, PAGE_SIZE); /* * We only reuse the PGD from the swapper_pg_dir, not the pud + pmd...* allocated with it. */ memblock_free(__pa(swapper_pg_dir) + PAGE_SIZE,...SWAPPER_DIR_SIZE - PAGE_SIZE); }
swapper_pg_dir是一级页表PGD的地址。 创建页表的过程主要涉及到3个宏,下面分别介绍。...== 3 create_table_entry \tbl, \virt, SWAPPER_TABLE_SHIFT, PTRS_PER_PTE, \tmp1, \tmp2 #endif...lsr \start, \start, #SWAPPER_BLOCK_SHIFT and \start, \start, #PTRS_PER_PTE - 1 // table index...orr \phys, \flags, \phys, lsl #SWAPPER_BLOCK_SHIFT // table entry lsr \end, \end, #SWAPPER_BLOCK_SHIFT...操作系统的PGD分为两个部分,一部分是内核PGD,保存在swapper_pg_dir中(TTBR1),用户PGD则独立存放。
/debug/tracing/trace_pipe -0 [006] d... 2741443.520814: sched_switch: prev_comm=swapper...2741443.522103: sched_switch: prev_comm=systemd prev_pid=1 prev_prio=120 prev_state=S ==> next_comm=swapper...next_pid=0 next_prio=120 -0 [006] d... 2741443.522141: sched_switch: prev_comm=swapper...2741443.522816: sched_switch: prev_comm=systemd prev_pid=1 prev_prio=120 prev_state=S ==> next_comm=swapper...next_pid=0 next_prio=120 -0 [006] d... 2741443.525867: sched_switch: prev_comm=swapper
0 [004] 5398.722328: sched:sched_stat_wait: comm=perf pid=7806 delay=0 [ns] swapper...0 [004] 5398.722333: sched:sched_switch: prev_comm=swapper/4 prev_pid=0 prev_prio=120 prev_state=R =...0 [002] 5398.722596: sched:sched_switch: prev_comm=swapper/2 prev_pid=0 prev_prio=120 prev_state=R =...0 [003] 5398.723508: sched:sched_switch: prev_comm=swapper/3 prev_pid=0 prev_prio=120 prev_state=R =...A0 5398.722365 secs . => swapper:0 .
领取专属 10元无门槛券
手把手带您无忧上云