preempt rt对pagefault的处理

在项目中我们发现了实时系统的pagefault开销比非实时要高,所以本文对pagefault做一下分析和对比。

1,pagefault调用栈(以arm64为例,内核版本为4.19.90)

el1_da (arch/arm64/kernel/entry.S) -- arm64发生data abort的异常处理入口

     do_mem_abort

          inf = esr_to_fault_info (fault_info, 异常向量表,见arch/arm64/mm/fault.c +661)

           inf->fn(也就是 do_page_fault)

                     __do_page_fault

                          find_vma //如果找不到相应的vma,说明地址不合法

                          handle_mm_fault

                                __handle_mm_fault

                                     pgd = pgd_offset(mm, address);

                                     p4d = p4d_alloc(mm, pgd, address);//获取该进程的pgd(p4d一样)

                                    vmf.pud = pud_alloc(mm, p4d, address); //获取pud,没有分配

                                    vmf.pmd = pmd_alloc(mm, vmf.pud, address);//获取pmd,没有分配

                                    handle_pte_fault(不知为什么,该函数没有出现在function_graph中)      

                                          do_anonymous_page//分配一个物理页,并把页表信息写到pte中

                                               (本例是堆栈中的pagefault,进入函数do_anonymous_page,还有可能进入  swap等函数的major pagefault)

                                                 pte_alloc(vma->vm_mm, vmf->pmd...//获取或分配pte

                                                 vmf->pte = pte_offset_map_lock(vma->vm_mm,//得到pte索引

                                                 page = alloc_zeroed_user_highpage_movable//分配一页物理内存

                                                 alloc_page_vma

                                                 entry = mk_pte(page, vma->vm_page_prot);//设置页表属性

                                                 set_pte_at(...vmf->pte, entry); //将该页表项放到pte的索引位置上

异常处理结束,然后返回用户空间,用户进程继续访问该地址,这次已经映射好,可以正常使用。

2,测试程序

这个很简单,应用程序中,申请几页内存,然后循环写入,通常在第二页就发生pagefault。

3,测试方法

trace-cmd start -e all;./mem_test

trace-cmd start -e all -p function -l "do_page_fault";./mem_test

trace-cmd start -p function_graph -g do_page_fault;./mem_test

4,通过function_graph来对比pagefault在实时和标准内核的区别

1)实时系统

mem_test-2096    2....0    83.211342: funcgraph_entry:                   |  do_page_fault() {
mem_test-2096    2....0    83.211342: funcgraph_entry:                   |    down_read_trylock() {
mem_test-2096    2....0    83.211343: funcgraph_entry:                   |      __down_read_trylock() {
mem_test-2096    2....0    83.211343: funcgraph_exit:         0.542 us   |      }
mem_test-2096    2....0    83.211344: funcgraph_exit:         1.646 us   |    }
mem_test-2096    2....0    83.211344: funcgraph_entry:                   |    find_vma() {
mem_test-2096    2....0    83.211345: funcgraph_entry:                   |      vmacache_find() {
mem_test-2096    2....0    83.211346: funcgraph_exit:         0.667 us   |      }
mem_test-2096    2....0    83.211346: funcgraph_exit:         1.792 us   |    }
mem_test-2096    2....0    83.211347: funcgraph_entry:                   |    handle_mm_fault() {
mem_test-2096    2....0    83.211347: funcgraph_entry:                   |      preempt_count_add() {
mem_test-2096    2...10    83.211348: funcgraph_exit:         0.562 us   |      }
mem_test-2096    2...10    83.211348: funcgraph_entry:                   |      preempt_count_sub() {
mem_test-2096    2....0    83.211349: funcgraph_exit:         0.521 us   |      }
mem_test-2096    2....0    83.211350: funcgraph_entry:                   |      __rcu_read_lock() {
mem_test-2096    2....0    83.211350: funcgraph_exit:         0.542 us   |      }
mem_test-2096    2....0    83.211351: funcgraph_entry:                   |      mem_cgroup_from_task() {
mem_test-2096    2....0    83.211351: funcgraph_exit:         0.542 us   |      }
mem_test-2096    2....0    83.211352: funcgraph_entry:                   |      __rcu_read_unlock() {
mem_test-2096    2....0    83.211352: funcgraph_exit:         0.521 us   |      }
mem_test-2096    2....0    83.211353: funcgraph_entry:                   |      __handle_mm_fault() {
mem_test-2096    2....0    83.211354: funcgraph_entry:                   |        do_anonymous_page() {
mem_test-2096    2....0    83.211354: funcgraph_entry:                   |          alloc_pages_vma() {
mem_test-2096    2....0    83.211355: funcgraph_entry:                   |            __get_vma_policy() {
mem_test-2096    2....0    83.211356: funcgraph_exit:         0.542 us   |            }
mem_test-2096    2....0    83.211356: funcgraph_entry:                   |            get_vma_policy.part.0() {
mem_test-2096    2....0    83.211357: funcgraph_entry:                   |              get_task_policy.part.0() {
mem_test-2096    2....0    83.211357: funcgraph_exit:         0.542 us   |              }
mem_test-2096    2....0    83.211358: funcgraph_exit:         1.646 us   |            }
mem_test-2096    2....0    83.211358: funcgraph_entry:                   |            policy_nodemask() {
mem_test-2096    2....0    83.211359: funcgraph_exit:         0.521 us   |            }
mem_test-2096    2....0    83.211359: funcgraph_entry:                   |            policy_node() {
mem_test-2096    2....0    83.211360: funcgraph_exit:         0.541 us   |            }
mem_test-2096    2....0    83.211360: funcgraph_entry:                   |            __alloc_pages_nodemask() {
mem_test-2096    2....0    83.211361: funcgraph_entry:                   |              get_page_from_freelist() {
mem_test-2096    2....0    83.211362: funcgraph_entry:                   |                rmqueue_pcplist.isra.0() {
mem_test-2096    2....0    83.211362: funcgraph_entry:                   |                  migrate_disable() {
mem_test-2096    2....0    83.211363: funcgraph_entry:                   |                    preempt_count_add() {
mem_test-2096    2...10    83.211363: funcgraph_exit:         0.541 us   |                    }
mem_test-2096    2...10    83.211364: funcgraph_entry:                   |                    pin_current_cpu() {
mem_test-2096    2...10    83.211364: funcgraph_entry:                   |                      __read_rt_trylock() {
mem_test-2096    2...10    83.211365: funcgraph_exit:         0.541 us   |                      }
mem_test-2096    2...10    83.211366: funcgraph_exit:         1.625 us   |                    }
mem_test-2096    2...10    83.211366: funcgraph_entry:                   |                    task_rq_lock() {
mem_test-2096    2...10    83.211367: funcgraph_entry:                   |                      _raw_spin_lock_irqsave() {
mem_test-2096    2d..10    83.211367: funcgraph_entry:                   |                        preempt_count_add() {
mem_test-2096    2d..20    83.211368: funcgraph_exit:         0.500 us   |                        }
mem_test-2096    2d..20    83.211368: funcgraph_exit:         1.584 us   |                      }
mem_test-2096    2d..20    83.211369: funcgraph_entry:                   |                      _raw_spin_lock() {
mem_test-2096    2d..20    83.211369: funcgraph_entry:                   |                        preempt_count_add() {
mem_test-2096    2d..30    83.211370: funcgraph_exit:         0.500 us   |                        }
mem_test-2096    2d..30    83.211370: funcgraph_exit:         1.541 us   |                      }
mem_test-2096    2d..30    83.211371: funcgraph_exit:         4.666 us   |                    }
mem_test-2096    2d..30    83.211371: funcgraph_entry:                   |                    preempt_count_sub() {
mem_test-2096    2d..20    83.211372: funcgraph_exit:         0.542 us   |                    }
mem_test-2096    2d..20    83.211372: funcgraph_entry:                   |                    _raw_spin_unlock_irqrestore() {
mem_test-2096    2...20    83.211373: funcgraph_entry:                   |                      preempt_count_sub() {
mem_test-2096    2...10    83.211373: funcgraph_exit:         0.521 us   |                      }
mem_test-2096    2...10    83.211374: funcgraph_exit:         1.541 us   |                    }
mem_test-2096    2...11    83.211374: funcgraph_entry:                   |                    preempt_count_sub() {
mem_test-2096    2....1    83.211375: funcgraph_exit:         0.542 us   |                    }
mem_test-2096    2....1    83.211375: funcgraph_exit:       + 13.250 us  |                  }
mem_test-2096    2....1    83.211376: funcgraph_entry:                   |                  rt_spin_lock() {
mem_test-2096    2....1    83.211377: funcgraph_entry:                   |                    migrate_disable() {
mem_test-2096    2....2    83.211377: funcgraph_exit:         0.542 us   |                    }
mem_test-2096    2....2    83.211378: funcgraph_exit:         1.646 us   |                  }
mem_test-2096    2....2    83.211378: funcgraph_entry:                   |                  preempt_count_add() {
mem_test-2096    2...12    83.211379: funcgraph_exit:         0.563 us   |                  }
mem_test-2096    2...12    83.211379: funcgraph_entry:                   |                  preempt_count_sub() {
mem_test-2096    2....2    83.211380: funcgraph_exit:         0.520 us   |                  }
mem_test-2096    2....2    83.211381: funcgraph_entry:                   |                  __inc_numa_state() {
mem_test-2096    2....2    83.211381: funcgraph_exit:         0.583 us   |                  }
mem_test-2096    2....2    83.211382: funcgraph_entry:                   |                  __inc_numa_state() {
mem_test-2096    2....2    83.211382: funcgraph_exit:         0.562 us   |                  }
mem_test-2096    2....2    83.211383: funcgraph_entry:                   |                  rt_spin_unlock() {
mem_test-2096    2....2    83.211383: funcgraph_entry:                   |                    migrate_enable() {
mem_test-2096    2....1    83.211384: funcgraph_exit:         0.562 us   |                    }
mem_test-2096    2....1    83.211384: funcgraph_exit:         1.666 us   |                  }
mem_test-2096    2....1    83.211385: funcgraph_entry:                   |                  migrate_enable() {
mem_test-2096    2....1    83.211386: funcgraph_entry:                   |                    preempt_count_add() {
mem_test-2096    2...11    83.211386: funcgraph_exit:         0.625 us   |                    }
mem_test-2096    2...10    83.211387: funcgraph_entry:                   |                    task_rq_lock() {
mem_test-2096    2...10    83.211387: funcgraph_entry:                   |                      _raw_spin_lock_irqsave() {
mem_test-2096    2d..10    83.211388: funcgraph_entry:                   |                        preempt_count_add() {
mem_test-2096    2d..20    83.211388: funcgraph_exit:         0.500 us   |                        }
mem_test-2096    2d..20    83.211389: funcgraph_exit:         1.562 us   |                      }
mem_test-2096    2d..20    83.211389: funcgraph_entry:                   |                      _raw_spin_lock() {
mem_test-2096    2d..20    83.211390: funcgraph_entry:                   |                        preempt_count_add() {
mem_test-2096    2d..30    83.211390: funcgraph_exit:         0.500 us   |                        }
mem_test-2096    2d..30    83.211391: funcgraph_exit:         1.542 us   |                      }
mem_test-2096    2d..30    83.211391: funcgraph_exit:         4.646 us   |                    }
mem_test-2096    2d..30    83.211392: funcgraph_entry:                   |                    preempt_count_sub() {
mem_test-2096    2d..20    83.211393: funcgraph_exit:         0.500 us   |                    }
mem_test-2096    2d..20    83.211393: funcgraph_entry:                   |                    _raw_spin_unlock_irqrestore() {
mem_test-2096    2...20    83.211394: funcgraph_entry:                   |                      preempt_count_sub() {
mem_test-2096    2...10    83.211394: funcgraph_exit:         0.500 us   |                      }
mem_test-2096    2...10    83.211395: funcgraph_exit:         1.562 us   |                    }
mem_test-2096    2...10    83.211395: funcgraph_entry:                   |                    unpin_current_cpu() {
mem_test-2096    2...10    83.211396: funcgraph_entry:                   |                      __read_rt_unlock() {
mem_test-2096    2...10    83.211396: funcgraph_exit:         0.521 us   |                      }
mem_test-2096    2...10    83.211397: funcgraph_exit:         1.604 us   |                    }
mem_test-2096    2...10    83.211397: funcgraph_entry:                   |                    preempt_count_sub() {
mem_test-2096    2....0    83.211398: funcgraph_exit:         0.500 us   |                    }
mem_test-2096    2....0    83.211398: funcgraph_exit:       + 13.312 us  |                  }
mem_test-2096    2....0    83.211399: funcgraph_exit:       + 37.229 us  |                }
mem_test-2096    2....0    83.211399: funcgraph_exit:       + 38.333 us  |              }
mem_test-2096    2....0    83.211400: mm_page_alloc:        page=0xffa09b71 pfn=2139273 order=0 migratetype=1 gfp_flags=GFP_HIGHUSER_MOVABLE
mem_test-2096    2....0    83.211400: funcgraph_exit:       + 39.979 us  |            }
mem_test-2096    2....0    83.211401: funcgraph_exit:       + 46.584 us  |          }
mem_test-2096    2....0    83.211402: funcgraph_entry:                   |          migrate_disable() {
mem_test-2096    2....0    83.211402: funcgraph_entry:                   |            preempt_count_add() {
mem_test-2096    2...10    83.211403: funcgraph_exit:         0.521 us   |            }
mem_test-2096    2...10    83.211403: funcgraph_entry:                   |            pin_current_cpu() {
mem_test-2096    2...10    83.211404: funcgraph_entry:                   |              __read_rt_trylock() {
mem_test-2096    2...10    83.211404: funcgraph_exit:         0.562 us   |              }
mem_test-2096    2...10    83.211405: funcgraph_exit:         1.625 us   |            }
mem_test-2096    2...10    83.211405: funcgraph_entry:                   |            task_rq_lock() {
mem_test-2096    2...10    83.211406: funcgraph_entry:                   |              _raw_spin_lock_irqsave() {
mem_test-2096    2d..10    83.211406: funcgraph_entry:                   |                preempt_count_add() {
mem_test-2096    2d..20    83.211407: funcgraph_exit:         0.479 us   |                }
mem_test-2096    2d..20    83.211407: funcgraph_exit:         1.563 us   |              }
mem_test-2096    2d..20    83.211408: funcgraph_entry:                   |              _raw_spin_lock() {
mem_test-2096    2d..20    83.211409: funcgraph_entry:                   |                preempt_count_add() {
mem_test-2096    2d..30    83.211409: funcgraph_exit:         0.521 us   |                }
mem_test-2096    2d..30    83.211409: funcgraph_exit:         1.541 us   |              }
mem_test-2096    2d..30    83.211410: funcgraph_exit:         4.666 us   |            }
mem_test-2096    2d..30    83.211410: funcgraph_entry:                   |            preempt_count_sub() {
mem_test-2096    2d..20    83.211411: funcgraph_exit:         0.500 us   |            }
mem_test-2096    2d..20    83.211412: funcgraph_entry:                   |            _raw_spin_unlock_irqrestore() {
mem_test-2096    2...20    83.211412: funcgraph_entry:                   |              preempt_count_sub() {
mem_test-2096    2...10    83.211413: funcgraph_exit:         0.521 us   |              }
mem_test-2096    2...10    83.211413: funcgraph_exit:         1.563 us   |            }
mem_test-2096    2...11    83.211414: funcgraph_entry:                   |            preempt_count_sub() {
mem_test-2096    2....1    83.211414: funcgraph_exit:         0.521 us   |            }
mem_test-2096    2....1    83.211415: funcgraph_exit:       + 13.146 us  |          }
mem_test-2096    2....1    83.211415: funcgraph_entry:                   |          __cpu_clear_user_page() {
mem_test-2096    2....1    83.211420: funcgraph_exit:         4.270 us   |          }
mem_test-2096    2....1    83.211420: funcgraph_entry:                   |          migrate_enable() {
mem_test-2096    2....1    83.211421: funcgraph_entry:                   |            preempt_count_add() {
mem_test-2096    2...11    83.211421: funcgraph_exit:         0.521 us   |            }
mem_test-2096    2...10    83.211422: funcgraph_entry:                   |            task_rq_lock() {
mem_test-2096    2...10    83.211422: funcgraph_entry:                   |              _raw_spin_lock_irqsave() {
mem_test-2096    2d..10    83.211423: funcgraph_entry:                   |                preempt_count_add() {
mem_test-2096    2d..20    83.211423: funcgraph_exit:         0.500 us   |                }
mem_test-2096    2d..20    83.211424: funcgraph_exit:         1.583 us   |              }
mem_test-2096    2d..20    83.211424: funcgraph_entry:                   |              _raw_spin_lock() {
mem_test-2096    2d..20    83.211425: funcgraph_entry:                   |                preempt_count_add() {
mem_test-2096    2d..30    83.211425: funcgraph_exit:         0.500 us   |                }
mem_test-2096    2d..30    83.211426: funcgraph_exit:         1.563 us   |              }
mem_test-2096    2d..30    83.211426: funcgraph_exit:         4.687 us   |            }
mem_test-2096    2d..30    83.211427: funcgraph_entry:                   |            preempt_count_sub() {
mem_test-2096    2d..20    83.211427: funcgraph_exit:         0.500 us   |            }
mem_test-2096    2d..20    83.211428: funcgraph_entry:                   |            _raw_spin_unlock_irqrestore() {
mem_test-2096    2...20    83.211429: funcgraph_entry:                   |              preempt_count_sub() {
mem_test-2096    2...10    83.211429: funcgraph_exit:         0.542 us   |              }
mem_test-2096    2...10    83.211430: funcgraph_exit:         1.563 us   |            }
mem_test-2096    2...10    83.211430: funcgraph_entry:                   |            unpin_current_cpu() {
mem_test-2096    2...10    83.211431: funcgraph_entry:                   |              __read_rt_unlock() {
mem_test-2096    2...10    83.211431: funcgraph_exit:         0.542 us   |              }
mem_test-2096    2...10    83.211432: funcgraph_exit:         1.605 us   |            }
mem_test-2096    2...10    83.211432: funcgraph_entry:                   |            preempt_count_sub() {
mem_test-2096    2....0    83.211433: funcgraph_exit:         0.521 us   |            }
mem_test-2096    2....0    83.211433: funcgraph_exit:       + 13.187 us  |          }
mem_test-2096    2....0    83.211434: funcgraph_entry:                   |          mem_cgroup_try_charge_delay() {
mem_test-2096    2....0    83.211434: funcgraph_entry:                   |            mem_cgroup_try_charge() {
mem_test-2096    2....0    83.211435: funcgraph_entry:                   |              get_mem_cgroup_from_mm() {
mem_test-2096    2....0    83.211436: funcgraph_entry:                   |                __rcu_read_lock() {
mem_test-2096    2....0    83.211436: funcgraph_exit:         0.521 us   |                }
mem_test-2096    2....0    83.211437: funcgraph_entry:                   |                __rcu_read_unlock() {
mem_test-2096    2....0    83.211437: funcgraph_exit:         0.521 us   |                }
mem_test-2096    2....0    83.211438: funcgraph_exit:         2.708 us   |              }
mem_test-2096    2....0    83.211438: funcgraph_entry:                   |              try_charge() {
mem_test-2096    2....0    83.211439: funcgraph_exit:         0.521 us   |              }
mem_test-2096    2....0    83.211439: funcgraph_exit:         4.834 us   |            }
mem_test-2096    2....0    83.211440: funcgraph_entry:                   |            mem_cgroup_throttle_swaprate() {
mem_test-2096    2....0    83.211440: funcgraph_entry:                   |              __rcu_read_lock() {
mem_test-2096    2....0    83.211441: funcgraph_exit:         0.520 us   |              }
mem_test-2096    2....0    83.211441: funcgraph_entry:                   |              kthread_blkcg() {
mem_test-2096    2....0    83.211442: funcgraph_exit:         0.542 us   |              }
mem_test-2096    2....0    83.211443: funcgraph_entry:                   |              __rcu_read_unlock() {
mem_test-2096    2....0    83.211443: funcgraph_exit:         0.542 us   |              }
mem_test-2096    2....0    83.211444: funcgraph_exit:         3.813 us   |            }
mem_test-2096    2....0    83.211444: funcgraph_exit:       + 10.229 us  |          }
mem_test-2096    2....0    83.211445: funcgraph_entry:                   |          rt_spin_lock() {
mem_test-2096    2....0    83.211445: funcgraph_entry:                   |            migrate_disable() {
mem_test-2096    2....0    83.211446: funcgraph_entry:                   |              preempt_count_add() {
mem_test-2096    2...10    83.211446: funcgraph_exit:         0.542 us   |              }
mem_test-2096    2...10    83.211447: funcgraph_entry:                   |              pin_current_cpu() {
mem_test-2096    2...10    83.211447: funcgraph_entry:                   |                __read_rt_trylock() {
mem_test-2096    2...10    83.211448: funcgraph_exit:         0.521 us   |                }
mem_test-2096    2...10    83.211448: funcgraph_exit:         1.605 us   |              }
mem_test-2096    2...10    83.211449: funcgraph_entry:                   |              task_rq_lock() {
mem_test-2096    2...10    83.211450: funcgraph_entry:                   |                _raw_spin_lock_irqsave() {
mem_test-2096    2d..10    83.211450: funcgraph_entry:                   |                  preempt_count_add() {
mem_test-2096    2d..20    83.211451: funcgraph_exit:         0.500 us   |                  }
mem_test-2096    2d..20    83.211451: funcgraph_exit:         1.583 us   |                }
mem_test-2096    2d..20    83.211452: funcgraph_entry:                   |                _raw_spin_lock() {
mem_test-2096    2d..20    83.211452: funcgraph_entry:                   |                  preempt_count_add() {
mem_test-2096    2d..30    83.211453: funcgraph_exit:         0.500 us   |                  }
mem_test-2096    2d..30    83.211453: funcgraph_exit:         1.542 us   |                }
mem_test-2096    2d..30    83.211454: funcgraph_exit:         4.688 us   |              }
mem_test-2096    2d..30    83.211454: funcgraph_entry:                   |              preempt_count_sub() {
mem_test-2096    2d..20    83.211455: funcgraph_exit:         0.500 us   |              }
mem_test-2096    2d..20    83.211455: funcgraph_entry:                   |              _raw_spin_unlock_irqrestore() {
mem_test-2096    2...20    83.211456: funcgraph_entry:                   |                preempt_count_sub() {
mem_test-2096    2...10    83.211456: funcgraph_exit:         0.521 us   |                }
mem_test-2096    2...10    83.211457: funcgraph_exit:         1.584 us   |              }
mem_test-2096    2...11    83.211457: funcgraph_entry:                   |              preempt_count_sub() {
mem_test-2096    2....1    83.211458: funcgraph_exit:         0.520 us   |              }
mem_test-2096    2....1    83.211458: funcgraph_exit:       + 13.187 us  |            }
mem_test-2096    2....1    83.211459: funcgraph_exit:       + 14.271 us  |          }
mem_test-2096    2....1    83.211459: funcgraph_entry:                   |          page_add_new_anon_rmap() {
mem_test-2096    2....1    83.211460: funcgraph_entry:                   |            __mod_node_page_state() {
mem_test-2096    2....1    83.211461: funcgraph_entry:                   |              preempt_count_add() {
mem_test-2096    2...11    83.211461: funcgraph_exit:         0.563 us   |              }
mem_test-2096    2...11    83.211462: funcgraph_entry:                   |              preempt_count_sub() {
mem_test-2096    2....1    83.211462: funcgraph_exit:         0.521 us   |              }
mem_test-2096    2....1    83.211463: funcgraph_exit:         2.792 us   |            }
mem_test-2096    2....1    83.211463: funcgraph_entry:                   |            __page_set_anon_rmap() {
mem_test-2096    2....1    83.211464: funcgraph_exit:         0.542 us   |            }
mem_test-2096    2....1    83.211464: funcgraph_exit:         4.958 us   |          }
mem_test-2096    2....1    83.211465: funcgraph_entry:                   |          mem_cgroup_commit_charge() {
mem_test-2096    2....1    83.211466: funcgraph_entry:                   |            migrate_disable() {
mem_test-2096    2....2    83.211466: funcgraph_exit:         0.563 us   |            }
mem_test-2096    2....2    83.211467: funcgraph_entry:                   |            rt_spin_lock() {
mem_test-2096    2....2    83.211467: funcgraph_entry:                   |              migrate_disable() {
mem_test-2096    2....3    83.211468: funcgraph_exit:         0.542 us   |              }
mem_test-2096    2....3    83.211468: funcgraph_exit:         1.646 us   |            }
mem_test-2096    2....3    83.211469: funcgraph_entry:                   |            mem_cgroup_charge_statistics() {
mem_test-2096    2....3    83.211470: funcgraph_exit:         0.688 us   |            }
mem_test-2096    2....3    83.211470: funcgraph_entry:                   |            memcg_check_events() {
mem_test-2096    2....3    83.211471: funcgraph_entry:                   |              mem_cgroup_event_ratelimit.isra.0() {
mem_test-2096    2....3    83.211471: funcgraph_exit:         0.605 us   |              }
mem_test-2096    2....3    83.211472: funcgraph_exit:         1.729 us   |            }
mem_test-2096    2....3    83.211472: funcgraph_entry:                   |            rt_spin_unlock() {
mem_test-2096    2....3    83.211473: funcgraph_entry:                   |              migrate_enable() {
mem_test-2096    2....2    83.211474: funcgraph_exit:         0.542 us   |              }
mem_test-2096    2....2    83.211474: funcgraph_exit:         1.646 us   |            }
mem_test-2096    2....2    83.211475: funcgraph_entry:                   |            migrate_enable() {
mem_test-2096    2....1    83.211475: funcgraph_exit:         0.563 us   |            }
mem_test-2096    2....1    83.211476: funcgraph_exit:       + 10.708 us  |          }
mem_test-2096    2....1    83.211476: funcgraph_entry:                   |          lru_cache_add_active_or_unevictable() {
mem_test-2096    2....1    83.211477: funcgraph_entry:                   |            __lru_cache_add() {
mem_test-2096    2....1    83.211477: funcgraph_entry:                   |              migrate_disable() {
mem_test-2096    2....2    83.211478: funcgraph_exit:         0.542 us   |              }
mem_test-2096    2....2    83.211479: funcgraph_entry:                   |              rt_spin_lock() {
mem_test-2096    2....2    83.211479: funcgraph_entry:                   |                migrate_disable() {
mem_test-2096    2....3    83.211480: funcgraph_exit:         0.500 us   |                }
mem_test-2096    2....3    83.211480: funcgraph_exit:         1.625 us   |              }
mem_test-2096    2....3    83.211481: funcgraph_entry:                   |              rt_spin_unlock() {
mem_test-2096    2....3    83.211481: funcgraph_entry:                   |                migrate_enable() {
mem_test-2096    2....2    83.211482: funcgraph_exit:         0.541 us   |                }
mem_test-2096    2....2    83.211482: funcgraph_exit:         1.667 us   |              }
mem_test-2096    2....2    83.211483: funcgraph_entry:                   |              migrate_enable() {
mem_test-2096    2....1    83.211483: funcgraph_exit:         0.562 us   |              }
mem_test-2096    2....1    83.211484: funcgraph_exit:         7.229 us   |            }
mem_test-2096    2....1    83.211484: funcgraph_exit:         8.291 us   |          }
mem_test-2096    2....1    83.211485: funcgraph_entry:                   |          rt_spin_unlock() {
mem_test-2096    2....1    83.211486: funcgraph_entry:                   |            migrate_enable() {
mem_test-2096    2....1    83.211486: funcgraph_entry:                   |              preempt_count_add() {
mem_test-2096    2...11    83.211487: funcgraph_exit:         0.541 us   |              }
mem_test-2096    2...10    83.211487: funcgraph_entry:                   |              task_rq_lock() {
mem_test-2096    2...10    83.211488: funcgraph_entry:                   |                _raw_spin_lock_irqsave() {
mem_test-2096    2d..10    83.211488: funcgraph_entry:                   |                  preempt_count_add() {
mem_test-2096    2d..20    83.211489: funcgraph_exit:         0.479 us   |                  }
mem_test-2096    2d..20    83.211490: funcgraph_exit:         2.042 us   |                }
mem_test-2096    2d..20    83.211490: funcgraph_entry:                   |                _raw_spin_lock() {
mem_test-2096    2d..20    83.211491: funcgraph_entry:                   |                  preempt_count_add() {
mem_test-2096    2d..30    83.211492: funcgraph_exit:         0.500 us   |                  }
mem_test-2096    2d..30    83.211492: funcgraph_exit:         1.708 us   |                }
mem_test-2096    2d..30    83.211493: funcgraph_exit:         5.333 us   |              }
mem_test-2096    2d..30    83.211493: funcgraph_entry:                   |              preempt_count_sub() {
mem_test-2096    2d..20    83.211494: funcgraph_exit:         0.500 us   |              }
mem_test-2096    2d..20    83.211494: funcgraph_entry:                   |              _raw_spin_unlock_irqrestore() {
mem_test-2096    2...20    83.211495: funcgraph_entry:                   |                preempt_count_sub() {
mem_test-2096    2...10    83.211495: funcgraph_exit:         0.521 us   |                }
mem_test-2096    2...10    83.211496: funcgraph_exit:         1.583 us   |              }
mem_test-2096    2...10    83.211496: funcgraph_entry:                   |              unpin_current_cpu() {
mem_test-2096    2...10    83.211497: funcgraph_entry:                   |                __read_rt_unlock() {
mem_test-2096    2...10    83.211497: funcgraph_exit:         0.521 us   |                }
mem_test-2096    2...10    83.211498: funcgraph_exit:         1.583 us   |              }
mem_test-2096    2...10    83.211498: funcgraph_entry:                   |              preempt_count_sub() {
mem_test-2096    2....0    83.211499: funcgraph_exit:         0.520 us   |              }
mem_test-2096    2....0    83.211500: funcgraph_exit:       + 13.896 us  |            }
mem_test-2096    2....0    83.211500: funcgraph_exit:       + 14.979 us  |          }
mem_test-2096    2....0    83.211501: funcgraph_exit:       ! 146.792 us |        }
mem_test-2096    2....0    83.211501: funcgraph_exit:       ! 148.188 us |      }
mem_test-2096    2....0    83.211502: funcgraph_exit:       ! 154.813 us |    }
mem_test-2096    2....0    83.211502: funcgraph_entry:                   |    up_read() {
mem_test-2096    2....0    83.211503: funcgraph_entry:                   |      __up_read() {
mem_test-2096    2....0    83.211503: funcgraph_exit:         0.562 us   |      }
mem_test-2096    2....0    83.211504: funcgraph_exit:         1.646 us   |    }
mem_test-2096    2....0    83.211504: funcgraph_exit:       ! 162.729 us |  }

2)标准内核

mem_test-2234    3....   438.228220: funcgraph_entry:                   |  do_page_fault() {
mem_test-2234    3....   438.228220: funcgraph_entry:                   |    down_read_trylock() {
mem_test-2234    3....   438.228221: funcgraph_exit:         0.355 us   |    }
mem_test-2234    3....   438.228221: funcgraph_entry:                   |    find_vma() {
mem_test-2234    3....   438.228222: funcgraph_entry:                   |      vmacache_find() {
mem_test-2234    3....   438.228222: funcgraph_exit:         0.333 us   |      }
mem_test-2234    3....   438.228222: funcgraph_exit:         1.041 us   |    }
mem_test-2234    3....   438.228223: funcgraph_entry:                   |    handle_mm_fault() {
mem_test-2234    3....   438.228223: funcgraph_entry:                   |      mem_cgroup_from_task() {
mem_test-2234    3....   438.228223: funcgraph_exit:         0.334 us   |      }
mem_test-2234    3....   438.228224: funcgraph_entry:                   |      __handle_mm_fault() {
mem_test-2234    3....   438.228224: funcgraph_entry:                   |        pmd_devmap_trans_unstable() {
mem_test-2234    3....   438.228224: funcgraph_exit:         0.334 us   |        }
mem_test-2234    3....   438.228225: funcgraph_entry:                   |        do_anonymous_page() {
mem_test-2234    3....   438.228225: funcgraph_entry:                   |          alloc_pages_vma() {
mem_test-2234    3....   438.228226: funcgraph_entry:                   |            __get_vma_policy() {
mem_test-2234    3....   438.228226: funcgraph_exit:         0.333 us   |            }
mem_test-2234    3....   438.228226: funcgraph_entry:                   |            get_vma_policy.part.10() {
mem_test-2234    3....   438.228227: funcgraph_entry:                   |              get_task_policy.part.7() {
mem_test-2234    3....   438.228227: funcgraph_exit:         0.354 us   |              }
mem_test-2234    3....   438.228227: funcgraph_exit:         1.021 us   |            }
mem_test-2234    3....   438.228228: funcgraph_entry:                   |            policy_nodemask() {
mem_test-2234    3....   438.228228: funcgraph_exit:         0.354 us   |            }
mem_test-2234    3....   438.228228: funcgraph_entry:                   |            policy_node() {
mem_test-2234    3....   438.228229: funcgraph_exit:         0.334 us   |            }
mem_test-2234    3....   438.228229: funcgraph_entry:                   |            __alloc_pages_nodemask() {
mem_test-2234    3....   438.228229: funcgraph_entry:                   |              get_page_from_freelist() {
mem_test-2234    3d...   438.228230: funcgraph_entry:                   |                __inc_numa_state() {
mem_test-2234    3d...   438.228230: funcgraph_exit:         0.313 us   |                }
mem_test-2234    3d...   438.228231: funcgraph_entry:                   |                __inc_numa_state() {
mem_test-2234    3d...   438.228231: funcgraph_exit:         0.334 us   |                }
mem_test-2234    3....   438.228231: funcgraph_exit:         1.833 us   |              }
mem_test-2234    3....   438.228232: mm_page_alloc:        page=0xffa0b329 pfn=2145349 order=0 migratetype=1 gfp_flags=GFP_HIGHUSER_MOVABLE
mem_test-2234    3....   438.228232: funcgraph_exit:         2.750 us   |            }
mem_test-2234    3....   438.228232: funcgraph_exit:         6.917 us   |          }
mem_test-2234    3....   438.228232: funcgraph_entry:                   |          __cpu_clear_user_page() {
mem_test-2234    3....   438.228237: funcgraph_exit:         4.000 us   |          }
mem_test-2234    3....   438.228237: funcgraph_entry:                   |          mem_cgroup_try_charge_delay() {
mem_test-2234    3....   438.228237: funcgraph_entry:                   |            mem_cgroup_try_charge() {
mem_test-2234    3....   438.228238: funcgraph_entry:                   |              get_mem_cgroup_from_mm() {
mem_test-2234    3....   438.228238: funcgraph_exit:         0.334 us   |              }
mem_test-2234    3....   438.228238: funcgraph_entry:                   |              try_charge() {
mem_test-2234    3....   438.228239: funcgraph_exit:         0.333 us   |              }
mem_test-2234    3....   438.228239: funcgraph_exit:         1.730 us   |            }
mem_test-2234    3....   438.228239: funcgraph_entry:                   |            mem_cgroup_throttle_swaprate() {
mem_test-2234    3....   438.228240: funcgraph_entry:                   |              kthread_blkcg() {
mem_test-2234    3....   438.228240: funcgraph_exit:         0.354 us   |              }
mem_test-2234    3....   438.228240: funcgraph_exit:         1.021 us   |            }
mem_test-2234    3....   438.228241: funcgraph_exit:         3.792 us   |          }
mem_test-2234    3....   438.228241: funcgraph_entry:                   |          page_add_new_anon_rmap() {
mem_test-2234    3....   438.228242: funcgraph_entry:                   |            __mod_node_page_state() {
mem_test-2234    3....   438.228242: funcgraph_exit:         0.333 us   |            }
mem_test-2234    3....   438.228242: funcgraph_entry:                   |            __page_set_anon_rmap() {
mem_test-2234    3....   438.228243: funcgraph_exit:         0.333 us   |            }
mem_test-2234    3....   438.228243: funcgraph_exit:         1.729 us   |          }
mem_test-2234    3....   438.228243: funcgraph_entry:                   |          mem_cgroup_commit_charge() {
mem_test-2234    3d...   438.228244: funcgraph_entry:                   |            mem_cgroup_charge_statistics() {
mem_test-2234    3d...   438.228244: funcgraph_exit:         0.333 us   |            }
mem_test-2234    3d...   438.228244: funcgraph_entry:                   |            memcg_check_events() {
mem_test-2234    3d...   438.228245: funcgraph_entry:                   |              mem_cgroup_event_ratelimit.isra.2() {
mem_test-2234    3d...   438.228245: funcgraph_exit:         0.333 us   |              }
mem_test-2234    3d...   438.228245: funcgraph_exit:         1.000 us   |            }
mem_test-2234    3....   438.228246: funcgraph_exit:         2.354 us   |          }
mem_test-2234    3....   438.228246: funcgraph_entry:                   |          lru_cache_add_active_or_unevictable() {
mem_test-2234    3....   438.228246: funcgraph_entry:                   |            __lru_cache_add() {
mem_test-2234    3....   438.228247: funcgraph_exit:         0.354 us   |            }
mem_test-2234    3....   438.228247: funcgraph_exit:         1.042 us   |          }
mem_test-2234    3....   438.228247: funcgraph_exit:       + 22.541 us  |        }
mem_test-2234    3....   438.228248: funcgraph_exit:       + 23.980 us  |      }
mem_test-2234    3....   438.228248: funcgraph_exit:       + 25.437 us  |    }
mem_test-2234    3....   438.228248: funcgraph_entry:                   |    up_read() {
mem_test-2234    3....   438.228249: funcgraph_exit:         0.333 us   |    }
mem_test-2234    3....   438.228249: funcgraph_exit:       + 29.021 us  |  }

5,分析

从上述log的对比来看,实时内核的do_page_fault比非实时内核耗时多100+us,但主要是由于function_graph的开销引起的,实测没有多那么多,大约多5us左右。

实时内核调用了get_page_from_freelist--rmqueue_pcplist--rmqueue--local_lock_irqsave--rt_spin_lock--migrate_disable,migrate_disable里包含了很多preempt的操作,同时还有其成对出现的migrate_enable,也有同样的操作,所以导致了额外的开销以及耗时。

在申请大量内存并使用的情况下,系统会发生多次这种minor pagefault,累计起来,会有一定的性能损失。同时,migrate disable/enable也会使用_raw_spin_lock,task_rq_lock,如果申请的资源没有空闲的话,还有额外的等待时间。

6,参考

本文参考了链接“(十四)Linux内存管理之page fault处理【转】 - sky-heaven - 博客园”对pagefault的分析,结合代码来看,分析的很准确。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值