Linuxの備忘録とか・・・(目次へ)Linuxの備忘録とか・・・(目次へ)kunmapkmap()のZONE_HIGHMEMは、pkmap_count[]=0のエントリーに割り当てるわけですが、pkmap_count[]=0が無い時、pkmap_count[]=1を0にして、そこに割り当てています。今までこの意味が疑問でずっと悩んでいたのですが、なるほど。言う思いで先のkmapの記事をアップしました。力が入ったのが、後で読み返すと、このあたりの解説がぼやけてしまいました。このあたりの説明にはkunmap()を見るのが一番。思いこの記事をアップしました。map_new_virtual()でページに仮想アドレスが割り当てられます。flush_all_zero_pkmaps()はpkmap_count[]=0のエントリーが無い場合、pkmap_count[]=1のエントリーを0にするために呼ばれる関数です。1とし、set_page_address()で、そのページをリストした後、kmap()に復帰し、pkmap_count[last_pkmap_nr]++とし、kmap()を呼び出したプロセスに復帰しています。なると、pkmap_count[]=1となるケースは、set_page_address()でのリスト処理、その後、再度pkmap_count[]=0を検索し、ページテーブルに所定の値をセットする処理の間に、他のプロセスによりkmap()を実行した時でのパスであるわけです。kmap()の処理では、ロックを取得して実行しています。そのような形でpkmap_count[]=1になることはありません。vaddr;}kunmap()はkmap()でページに割り当てた仮想アドレスを開放します。ZONE_HIGHMEMでないなら、カーネル自身の使用しているページで開放できません。ZONE_HIGHMEMの時のみ開放します。その処理はkunmap_high()で行います。kunmap_high(page);}kunmap_high()では、ページを管理しているpage_address_htable[]を走査して、そのページの仮想アドレスを取得し、この仮想アドレスに対応するインデックスので管理している参照カウンターpkmap_count[]をデクリメントしてチェックします。それが0ならバグです。kmap()でプロセスに復帰した時点で、最低でも2となっているからです。1なら他にそのページを参照しているプロセスはいません。処理の流れからいうと、本来ここで仮想アドレスを開放(ページテーブルをクリア)してページを回収ということですが、実装ではwaitqueue_active()でpkmap_map_waitリストでウエイトしているプロセスがいるかどうかチェックし、いるならwake_up()でそのプロセスを起床させているだけです。wake_up(&pkmap_map_wait);}kunmap_high()してもそのページに割り当てられた仮想アドレスは開放しません。その開放はkmap()で割り当てpkmap_count[]が無くなった時点で開放しています。することで、再度同じページに仮想アドレスを割り当てる必要がないからです。仮想アドレス割り当てはTBLをフラッシュします。これはパフォーマンス的によくありません。ノースAdsense広告情報が設定されていません。