色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

內核mmap_sem鎖的危害和相關優化

Linux閱碼場 ? 來源:Linux閱碼場 ? 2023-02-07 16:01 ? 次閱讀

mmap_sem鎖簡介

mmap_sem鎖是進程為了保護自身虛擬地址空間不受多線程并發訪問影響而設計的。

多線程環境下,如果想訪問進程的虛擬地址空間(比如find_vma等),是要先持有該mmap_sem鎖才能訪問的,這樣可以避免多線程并發修改進程vma區域造成的沖突。

mmap_sem鎖的一些問題總結

內核mmap_sem鎖設計目前存在一些問題,簡單總結如下:

1:保護的東西太多,范圍太廣了。

mmap_sem目前保護:

1)Rbtree of VMA,比如做find_vma()時

arm64系統上,由于虛擬地址空間增大,進程的vma數量會特別多,每個vma操作幾乎都要首先獲取一把這樣的mmap_sem大鎖。

這樣會造成鎖的粒度太大,鎖整個進程的vma地址空間的。

2)VMA list,會Lock the whole address space for even touching one byte

3) VMA flags, 會Need hold write lock to update vm_flags

4)Most of the fields of the mm_struct are protected using the mm.mmap_sem

fields can be arg_start, arg_end, env_start, env_end等。

2: 內核會頻繁做page fault, 這樣會頻繁獲取mmap_sem鎖。

soft page fault的描述:

Page faults can be quite expensive, especially those which must be resolved by reading data from disk. On a typical system, though, there are a lot of page faults which do not require I/O. A page fault happens because a specific process does not have a valid page table entry for the needed page, but that page might already be in the page cache, in which case handling the fault is just a matter of fixing the page table entry and increasing the page's reference count; this happens often with shared pages or those brought in via the readahead mechanism. Faults for new anonymous pages (application data and stack space, mostly), instead, can be handled through the allocation of a zero-filled page. In either case, the fault is quickly taken care of with no recourse to backing store required.

In many workloads, this kind of "soft" fault happens much more often than hard faults requiring actual I/O. So it's important that they be executed quickly. Various developers had concluded that the kernel was, in fact, not handling this kind of fault quickly enough, and they identified the use of the mmap_sem reader/writer semaphore as the core of the problem.

Contention wasn't the issue in this case - only a reader lock is required for page fault handling - but the cache line bouncing caused by continual acquisition of the lock was killing performance. As the number of cores in systems increases, this kind of problem can get worse.

內核里面這樣的soft page fault會發生很多,勢必造成mmap_sem獲取很頻繁,引起多核cache顛簸,對多核程序性能也不好。

所以Linux kernel很多地方架構設計不怎么匹配如今的多核cpu架構。

3: 一旦有個寫請求在排隊了,該mmap_sem就會變成互斥意義上的鎖了。

mmap_sem這種讀寫鎖是有好處,可以實現一些并發的多線程讀訪問。

但是它的這種并發讀訪問是有條件的:

如果一個讀寫信號量當前沒有被寫者擁有并且也沒有寫者等待讀者釋放信號量,那么任何讀者都可以成功獲得該讀寫信號量,否則,讀者必須被掛起直到寫者釋放該信號量。

如果一個讀寫信號量當前沒有被讀者或寫者擁有并且也沒有寫者等待該信號量,那么一個寫者可以成功獲得該讀寫信號量,否則寫者將被掛起,直到沒有任何訪問者。

簡單來看個問題場景:

線程1以讀者身份持mmap_sem,然后該線程由于某種原因sleep了。

下來線程2以寫者身份請求持該mmap_sem鎖,因為該鎖已經被線程1持有,所以失敗就開始排隊。

再下來該鎖就變成互斥鎖了,再來的read請求(對應線程2,3...)就都得排隊了,不能發揮讀寫鎖并發讀的優勢了。

結論:

所以綜合上面3個問題特點,在多核,多線程并發環境下(比如安卓系統),勢必造成mmap_sem鎖競爭激烈,程序性能不好。

mmap_sem鎖在產品開發中的優化總結

優化方向1:方便快捷地找到持鎖線程。

目前很多方法是通過在出現問題時,人為地讓內核崩潰,然后再用crash工具分析內核內存dump鏡像,從而在一大堆等鎖和持鎖線程中,找到

導致問題出現的持鎖線程信息。一旦找到持鎖線程,就明白問題出現的root casue, 就會有優化方案了。

但這種crash工具分析方法還是有點笨重,當然由于mmap_sem鎖競爭導致的內核崩潰用這種方法是最好最對口的。

但是很多時候出問題是內核并未崩潰,只是android上層發生watchdog超時重啟,或者只是某進程工作timeout。

如果是mmap_sem競爭導致的這些問題發生可以嘗試用些簡單快捷的方法找到持鎖線程。

1) 可以在安卓fwk層發生watchdog超時時,打印下system server進程中每個線程的內核棧回溯信息。

這樣如果對內核代碼熟悉的話,會知道哪些地方會長時間持有mmap_sem鎖,這樣看下棧回溯信息,大概能猜出來哪些線程在持鎖或者等鎖。

如果信息還不夠,還可以通過sysrq,打印出系統此時所有處于D狀態和sleep狀態的線程內核棧回溯信息。

因為有持鎖等鎖導致的內核性能問題,基本上都出現在D和sleep狀態的線程里面,通過對這些信息分析,也可以大概猜出來可能的持鎖者。

2) 如果問題可以復現,可以用一些bcc工具找到mmap_sem的持鎖owner信息。

1>輸出持鎖的owner信息

sudo ./trace 'rwsem_down_read_slowpath(struct rw_semaphore *sem, int state) "count=0x%lx owner=%s", sem->count.counter, ((struct task_struct *)((sem->owner.counter)&~0x7))->comm'
/virtual/main.c:44:66: warning: comparison of array '((struct task_struct *)((sem->owner.counter) & ~7))->comm' not equal to a null pointer is
always true [-Wtautological-pointer-compare]
if (((struct task_struct *)((sem->owner.counter)&~0x7))->comm != 0) {
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~ ~
1 warning generated.
PID TID COMM FUNC -
10127 10127 sync rwsem_down_read_slowpath count=0x103 owner=modprobe //是modprobe進程持有該rwsem鎖。

2> 輸出持鎖owner的其他信息

sudo ./trace 'rwsem_down_read_slowpath(struct rw_semaphore *sem, int state) "count=0x%lx fs name=%s", sem->count.counter, (((struct super_block*)((void *)sem-(void*)(&(((struct super_block*)0)->s_umount))))->s_id)'
PID TID COMM FUNC -
10144 10144 sync rwsem_down_read_slowpath count=0x103 fs name=nfsd

從上面可以找到持鎖owner:modprobe進程此時正在掛載 nfsd 模塊。

優化方向2:核心路徑中避免對/proc目錄下每進程子目錄做遍歷訪問,規避mmap_sem導致的問題。

之前碰到一個問題是由于system_server進程發生watchdog超時導致安卓fwk層重啟。

watchdog超時原因是:

system_server進程一個核心路徑上代碼做了遍歷/proc/每進程/cmdline工作,正常情況下做該工作不會出現問題。

但是由于做該工作,需要down_read獲取每進程的mmap_sem鎖,只要有一個進程的該鎖已經被寫者身份持有了,那么再獲取該鎖時,就得等待了。

所以異常就發生在這個地方,所以該異常會導致該核心路徑中遍歷每進程cmdline工作耗時了,核心路徑一旦性能受影響,就會導致問題出現。

優化方法:

避免在核心路徑上做這種潛在的耗時工作:遍歷每進程狀態。改用其他方法去達到目的。

優化方向3:同步社區一些patch,避免出現因mmap_sem競爭導致的cgroup優先級反轉問題。

cgroup v2中容易出現這種優先級反轉問題:

一個高優先級group里面某個進程A正在做遍歷訪問/proc/每進程下面狀態信息的工作,所以需要獲取系統中每進程的mmap_sem鎖。

另外一個低優先級group里面,某進程B中有些線程在做耗時長的io操作(進入內核filemap_fault函數里面做的),操作前提前以寫身份獲取了mmap_sem鎖。

所以寫身份先獲取了這把鎖,那么進程A如果想通過訪問獲取進程B的狀態信息時,就會阻塞在等待進程B的mmap_sem這個地方。

這樣因為進程B是在低優先級group里面,io訪問也比高優先級group慢,但是此時卻阻塞住了高優先級group里面的進程。

優化方法:

同步社區該patch

[RFC][PATCH 0/9][V2] drop the mmap_sem when doing IO in the fault path

優化方向4: 其他的一些優化持鎖線程的工作負載方法。

前面提了,解決因mmap_sem競爭導致的問題,關鍵是找到持鎖線程信息。找到后,還需要優化該持鎖線程在持鎖后的工作負載。

只有保證持鎖過程中,工作時間越短,就越能降低性能問題出現的概率。

1: 比如之前還碰到過一個問題:

某業務進程包含若干個工作線程和一個數據加載線程。數據加載線程需要將工作線程不再使用的上一份數據釋放掉,具體需要做munmap 大塊內存 (20G+)工作 ,

結果在釋放數據過程中,工作線程的性能受到了影響。

2: 這類問題原因也是:

釋放數據時,需要做munmap工作,進一步需要以寫著身份拿工作線程的mmap_sem鎖。這樣會導致工作線程獲取自身mmap_sem的等待時間變長。

通過問題進一步分析,發現munmap中最耗時的是free_pgtables,做這個也需要寫者拿mmap_sem鎖。

網絡上一些好的建議是:實現分段munmap,或者Drop mmap_sem during unmapping large map。

3: 其實還有個好的優化方法:

不考慮mmap_sem的影響,munmap工作本身就會比較耗時,所以后來有了madvise MADV_FREE和MADV_DONTNEED的優化。

所以這個地方可以嘗試用madvise來代替munmap,會縮短釋放數據的時間的。

優化方向5: Speculative page faults

前面那些優化方向都是正面回避該mmap_sem自身的一些特性問題(詳見上面第二大節的總結),從側面,從程序自身業務著手去優化解決問題。

這個投機性缺頁異常則是嘗試從正面優化該mmap_sem問題。

審核編輯:湯梓紅
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 內核
    +關注

    關注

    3

    文章

    1377

    瀏覽量

    40326
  • Linux
    +關注

    關注

    87

    文章

    11322

    瀏覽量

    209865
  • 優化
    +關注

    關注

    0

    文章

    220

    瀏覽量

    23928
  • 線程
    +關注

    關注

    0

    文章

    505

    瀏覽量

    19709

原文標題:內核mmap_sem鎖的危害和相關優化

文章出處:【微信號:LinuxDev,微信公眾號:Linux閱碼場】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    拆解mmap內存映射的本質!

    mmap 內存映射里所謂的內存其實指的是虛擬內存,在調用 mmap 進行匿名映射的時候(比如進行堆內存的分配),是將進程虛擬內存空間中的某一段虛擬內存區域與物理內存中的匿名內存頁進行映射,當調用
    的頭像 發表于 01-24 14:30 ?1813次閱讀
    拆解<b class='flag-5'>mmap</b>內存映射的本質!

    參加搜索引擎營銷SEM培訓的好處?

    1. 可以快速學習搜索引擎營銷(SEM)投放策略、方法和技術,避免在自己摸索中浪費時間;2. 可以快速學習到搜索引擎營銷(SEM)最新優化技術,在頂尖SEM
    發表于 04-11 14:21

    第11章 臨界段,任務和中斷

    轉rtx操作系統 本章教程為大家講解幾個重要的概念,臨界段,任務和中斷。本章教程配套的例子含Cortex-M3內核的STM32F103和Cortex-M4內核的STM32F407。
    發表于 10-04 19:58

    Linux的mmap文件內存映射機制

    Linux的mmap文件內存映射機制在講述文件映射的概念時, 不可避免的要牽涉到虛存(SVR 4的VM). 實際上, 文件映射是虛存的中心概念, 文件映射一方面給用戶提供了一組措施, 好似用戶將文件
    發表于 03-08 09:54

    芯靈思SinlinxA33開發板的Linux內核信號量學習

    用戶進程。我們可以從頭文件/usr/src/linux/include/linux/sem.h 中看到內核用來維護信號量狀態的各個結構的定義。信號量是一個數據集合,用戶可以單獨使用這一集合的每個元素。要
    發表于 02-20 15:50

    芯靈思SinlinxA64開發板 Linux內核信號量學習

    等待此信號量,則喚醒此進程。     維護信號量狀態的是Linux內核操作系統而不是用戶進程。我們可以從頭文件/usr/src/linux/include/linux/sem.h 中看到內核用來維護
    發表于 03-15 16:10

    Linux內核同步機制的自旋原理是什么?

    自旋是專為防止多處理器并發而引入的一種,它在內核中大量應用于中斷處理等部分(對于單處理器來說,防止中斷處理中的并發可簡單采用關閉中斷的方式,即在標志寄存器中關閉/打開中斷標志位,不需要自旋
    發表于 03-31 08:06

    感性負載的危害

    感性負載的危害 先看看車和控制車的大致結構:我們一般用兩個電機
    發表于 11-21 14:28 ?6650次閱讀

    Linux內核同步機制的自旋原理

    一、自旋 自旋是專為防止多處理器并發而引入的一種,它在內核中大量應用于中斷處理等部分(對于單處理器來說,防止中斷處理中的并發可簡單采用關閉中
    發表于 06-08 14:50 ?1311次閱讀

    linux_mmap_access_performance

    linux 內存訪問提升性能的一片論文,需要理解kernel的mmap方式,比較適合優化驅動
    發表于 02-23 15:48 ?14次下載

    優化簡單的OpenCL內核:調整內核優化

    Robert Ioffe描述了一系列一致的優化,可以提高英特爾?上的OpenCL內核性能Iris?圖形或英特爾?Iris?Pro圖形,使用英特爾?SDKfor OpenCL?應用程序2013。
    的頭像 發表于 11-07 06:17 ?3321次閱讀

    mmap系統調用和vmalloc獲取地址空間

    mmap()系統調用是在用戶進程與內核之間共享內存區域的常用方法。我們最近有個程序,需要應用進程能夠讀取內核驅動獲取的數據,經過簡單的調研,決定采用mmap方式。
    的頭像 發表于 02-02 16:13 ?4369次閱讀

    linux drivers中的mmap實現

    將設備驅動內核空間的內存映射到用戶空間里,可以通過用戶空間中的mmap系統調用代替系統調用write和read。目的是提高讀寫效率。
    發表于 05-15 10:31 ?1609次閱讀

    信號量和自旋

    。??? Linux 使用的同步機制可以說從2.0到2.6以來不斷發展完善。從最初的原子操作,到后來的信號量,從大內核到今天的自旋。這些同步機制的發展伴隨 Linux從單處理器到對稱多處理器的過度
    發表于 04-02 14:43 ?812次閱讀

    什么是掃描電鏡(SEM)?

    掃描電子顯微鏡(SEM)掃描電子顯微鏡(SEM)是現代科學探索微觀世界的一把關鍵鑰匙。它通過高分辨率的電子成像技術,使我們能夠洞察物質的微觀構造,從而在科學研究和工業應用中發揮著不可替代的作用。金鑒
    的頭像 發表于 11-20 23:55 ?400次閱讀
    什么是掃描電鏡(<b class='flag-5'>SEM</b>)?
    主站蜘蛛池模板: 甜性涩爱下载| 女人张开腿让男人桶爽免| 美女内射少妇一区二区四区| 少妇内射视频播放舔大片| 99久久免热在线观看6| 久久99AV无色码人妻蜜柚| 亚洲刺激视频| 国产精品麻豆a啊在线观看| 日本人奶水中文影片| 被爽到叫呻呤视频免费视频| 狂野欧美性猛XXXX乱大交| 亚洲乱妇88网| 国产在线精品亚洲观看不卡欧美| 少妇两个奶头喷出奶水了怎么办| YY8090福利午夜理论片| 女性露出奶头流出精子| 97人人碰免费视频公开| 免费看成人毛片| 中文字幕久久久| 久久伊人影院| 97国产视频| 美女厕所撒尿ass| 99精品中文字幕在线观看| 欧美free嫩交hd| 扒开老师粉嫩的泬10P| 琪琪的色原网站| 大肥女ass樱桃| 午夜久久影院| 精品国产90后在线观看| 在线天天看片免费视频观看| 麻豆精品无码久久久久久久久| 91精品欧美一区二区三区| 暖暖 免费 高清 日本在线| 超碰人人草在线视频| 视频一区亚洲视频无码| 国产在线AV一区二区香蕉| 瑜伽牲交AV| 日本高清无卡码一区二区久久| 风车动漫(p)_在线观看官网| 羞羞影院午夜男女爽爽影院网站 | 小sao货水好多真紧h的视频|