<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Korant-个人技术分享]]></title><description><![CDATA[Thoughts, stories and ideas.]]></description><link>http://www.korantli.com.cn/</link><image><url>http://www.korantli.com.cn/favicon.png</url><title>Korant-个人技术分享</title><link>http://www.korantli.com.cn/</link></image><generator>Ghost 5.75</generator><lastBuildDate>Wed, 06 May 2026 11:40:22 GMT</lastBuildDate><atom:link href="http://www.korantli.com.cn/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[cgroup限制读写速率]]></title><description><![CDATA[<h2 id="0-%E5%89%8D%E8%A8%80">0-&#x524D;&#x8A00;</h2>
<p>&#x7ECF;&#x5E38;&#x5B58;&#x5728;&#x9700;&#x8981;&#x6A21;&#x62DF;&#x7528;&#x6237;&#x573A;&#x666F;&#x4E0B;&#x7684;&#x6027;&#x80FD;&#x6D4B;&#x8BD5;&#xFF0C;&#x6A21;&#x62DF;&#x7684;&#x4E00;&#x4E2A;&#x65B9;&#x5F0F;&#x5C31;&#x662F;&#x6784;&#x9020;&#x7279;&#x5B9A;&#x5E26;&#x5BBD;&#x7684;io&#xFF0C;&#x800C;fio&#x3001;dd&#x7B49;&#x7B49;io&#x6D4B;&#x8BD5;&#x5DE5;</p>]]></description><link>http://www.korantli.com.cn/cgroupxian-zhi-du-xie-su-lu/</link><guid isPermaLink="false">669735742bc2afda5bd2ed36</guid><category><![CDATA[linux内核特性]]></category><dc:creator><![CDATA[李星辉]]></dc:creator><pubDate>Wed, 17 Jul 2024 03:08:07 GMT</pubDate><content:encoded><![CDATA[<h2 id="0-%E5%89%8D%E8%A8%80">0-&#x524D;&#x8A00;</h2>
<p>&#x7ECF;&#x5E38;&#x5B58;&#x5728;&#x9700;&#x8981;&#x6A21;&#x62DF;&#x7528;&#x6237;&#x573A;&#x666F;&#x4E0B;&#x7684;&#x6027;&#x80FD;&#x6D4B;&#x8BD5;&#xFF0C;&#x6A21;&#x62DF;&#x7684;&#x4E00;&#x4E2A;&#x65B9;&#x5F0F;&#x5C31;&#x662F;&#x6784;&#x9020;&#x7279;&#x5B9A;&#x5E26;&#x5BBD;&#x7684;io&#xFF0C;&#x800C;fio&#x3001;dd&#x7B49;&#x7B49;io&#x6D4B;&#x8BD5;&#x5DE5;&#x5177;&#x662F;&#x4E0D;&#x5177;&#x5907;&#x9650;&#x5236;&#x8BFB;&#x5199;&#x901F;&#x5EA6;&#x7684;&#x529F;&#x80FD;&#x7684;&#xFF0C;&#x6240;&#x4EE5;&#x8FD9;&#x91CC;&#x5C31;&#x8981;&#x7528;&#x5230;cgroup&#x7684;&#x80FD;&#x529B;&#xFF0C;&#x8FD9;&#x91CC;&#x8BB0;&#x5F55;&#x4E00;&#x4E0B;&#x5982;&#x4F55;&#x9650;&#x5236;&#x7279;&#x5B9A;&#x8FDB;&#x7A0B;&#x3001;&#x76D8;&#x7B26;&#x7684;&#x8BFB;&#x5199;&#x80FD;&#x529B;&#x3002;</p>
<h2 id="1-%E5%AE%89%E8%A3%85%E5%B7%A5%E5%85%B7%E5%88%9B%E5%BB%BA%E7%BB%84">1-&#x5B89;&#x88C5;&#x5DE5;&#x5177;&amp;&#x521B;&#x5EFA;&#x7EC4;</h2>
<p>&#x9996;&#x5148;&#x8981;&#x5B89;&#x88C5;group&#x5DE5;&#x5177;</p>
<pre><code class="language-bash">yum install libcgroup-tools
</code></pre>
<p>&#x7136;&#x540E;&#x7528;<code>cgroup</code>&#x5DE5;&#x5177;&#x521B;&#x5EFA;&#x4E00;&#x4E2A;<code>io</code>cgroup&#x7EC4;</p>
<pre><code class="language-bash">cgcreate -g blkio:/iotest
</code></pre>
<p>&#x5982;&#x679C;&#x521B;&#x5EFA;&#x6210;&#x529F;&#x540E;&#xFF0C;&#x4F1A;&#x5B58;&#x5728;&#x4E0B;&#x5217;&#x7684;&#x76EE;&#x5F55;</p>
<pre><code class="language-bash"># tree /sys/fs/cgroup/blkio/iotest/
/sys/fs/cgroup/blkio/iotest/
&#x251C;&#x2500;&#x2500; blkio.bfq.ioprio_class
&#x251C;&#x2500;&#x2500; blkio.bfq.io_service_bytes
&#x251C;&#x2500;&#x2500; blkio.bfq.io_service_bytes_recursive
&#x251C;&#x2500;&#x2500; blkio.bfq.io_serviced
&#x251C;&#x2500;&#x2500; blkio.bfq.io_serviced_recursive
&#x251C;&#x2500;&#x2500; blkio.bfq.weight
&#x251C;&#x2500;&#x2500; blkio.bfq.weight_device
&#x251C;&#x2500;&#x2500; blkio.cost.stat
&#x251C;&#x2500;&#x2500; blkio.cost.weight
&#x251C;&#x2500;&#x2500; blkio.diskstats
&#x251C;&#x2500;&#x2500; blkio.diskstats_recursive
&#x251C;&#x2500;&#x2500; blkio.latency
&#x251C;&#x2500;&#x2500; blkio.reset_stats
&#x251C;&#x2500;&#x2500; blkio.throttle.buffered_write_bps
&#x251C;&#x2500;&#x2500; blkio.throttle.io_service_bytes
&#x251C;&#x2500;&#x2500; blkio.throttle.io_service_bytes_recursive
&#x251C;&#x2500;&#x2500; blkio.throttle.io_serviced
&#x251C;&#x2500;&#x2500; blkio.throttle.io_serviced_recursive
&#x251C;&#x2500;&#x2500; blkio.throttle.read_bps_device
&#x251C;&#x2500;&#x2500; blkio.throttle.read_iops_device
&#x251C;&#x2500;&#x2500; blkio.throttle.readwrite_bps_device
&#x251C;&#x2500;&#x2500; blkio.throttle.readwrite_dynamic_ratio
&#x251C;&#x2500;&#x2500; blkio.throttle.readwrite_iops_device
&#x251C;&#x2500;&#x2500; blkio.throttle.stat
&#x251C;&#x2500;&#x2500; blkio.throttle.write_bps_device
&#x251C;&#x2500;&#x2500; blkio.throttle.write_iops_device
&#x251C;&#x2500;&#x2500; cgroup.clone_children
&#x251C;&#x2500;&#x2500; cgroup.id
&#x251C;&#x2500;&#x2500; cgroup.priority
&#x251C;&#x2500;&#x2500; cgroup.procs
&#x251C;&#x2500;&#x2500; cgroup.role
&#x251C;&#x2500;&#x2500; io.pressure
&#x251C;&#x2500;&#x2500; notify_on_release
&#x2514;&#x2500;&#x2500; tasks
</code></pre>
<h2 id="2-%E9%85%8D%E7%BD%AE%E9%99%90%E5%88%B6%E7%9A%84%E8%AE%BE%E5%A4%87">2-&#x914D;&#x7F6E;&#x9650;&#x5236;&#x7684;&#x8BBE;&#x5907;</h2>
<p>&#x901A;&#x8FC7;lsblk&#x53EF;&#x4EE5;&#x67E5;&#x770B;&#x5757;&#x8BBE;&#x5907;&#x7684;&#x8BBE;&#x5907;&#x53F7;</p>
<pre><code class="language-bash"># lsblk
NAME     MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda        8:0    0 447.1G  0 disk 
&#x251C;&#x2500;sda1     8:1    0    20G  0 part /
&#x251C;&#x2500;sda2     8:2    0   512M  0 part /boot/efi
&#x251C;&#x2500;sda3     8:3    0    20G  0 part /usr/local
&#x2514;&#x2500;sda4     8:4    0 406.6G  0 part /data
nvme2n1  259:0    0   3.5T  0 disk 
nvme0n1  259:1    0   3.5T  0 disk 
nvme1n1  259:2    0   3.5T  0 disk 
nvme4n1  259:3    0   3.5T  0 disk /home
nvme7n1  259:4    0   3.5T  0 disk 
nvme6n1  259:5    0   3.5T  0 disk 
nvme3n1  259:6    0   3.5T  0 disk 
nvme8n1  259:7    0   3.5T  0 disk 
nvme9n1  259:8    0   3.5T  0 disk 
nvme5n1  259:9    0   3.5T  0 disk 
nvme11n1 259:10   0   3.5T  0 disk 
nvme10n1 259:11   0   3.5T  0 disk /test
</code></pre>
<p>&#x6BD4;&#x5982;&#x6211;&#x4EEC;&#x8FD9;&#x6B21;&#x6D4B;&#x8BD5;&#x7684;&#x8BBE;&#x5907;&#x662F;<code>nvme11n1</code>&#x88F8;&#x76D8;&#xFF0C;&#x5E76;&#x4E14;&#x9650;&#x5236;&#x5176;&#x8BFB;&#x5199;&#x7684;&#x5E26;&#x5BBD;&#x4E0A;&#x9650;&#x4E3A;<code>200MB/s</code>&#x90A3;&#x4E48;&#x5C31;</p>
<pre><code class="language-bash">echo &quot;259:10 209600000&quot; &gt; /sys/fs/cgroup/blkio/iotest/blkio.throttle.write_bps_device
echo &quot;259:10 209600000&quot; &gt; /sys/fs/cgroup/blkio/iotest/blkio.throttle.read_bps_device
</code></pre>
<h2 id="3-%E5%90%AF%E5%8A%A8%E5%BA%94%E7%94%A8">3-&#x542F;&#x52A8;&#x5E94;&#x7528;</h2>
<p>&#x542F;&#x52A8;&#x5E94;&#x7528;&#xFF0C;&#x5E76;&#x52A0;&#x5165;&#x521A;&#x521A;&#x521B;&#x5EFA;&#x7684;io cgroup&#xFF0C;&#x8FD9;&#x91CC;&#x4EE5;<code>fio</code>&#x8FDB;&#x884C;&#x88F8;&#x76D8;&#x8BFB;&#x8FDB;&#x884C;&#x6D4B;&#x8BD5;</p>
<pre><code class="language-bash">cgexec -g blkio:/iotest fio --name=mytest --ioengine=libaio --rw=read --bs=300k --numjobs=1 --size=1G --runtime=60s --time_based --iodepth=32 --filename=/dev/nvme11n1
</code></pre>
<p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#x6D4B;&#x8BD5;&#x7684;&#x7ED3;&#x679C;&#xFF0C;&#x8BFB;&#x76D8;&#x901F;&#x5EA6;&#x662F;&#x88AB;&#x4E25;&#x683C;&#x9650;&#x5236;&#x5728;200mb/s&#x7684;</p>
<pre><code class="language-bash">mytest: (g=0): rw=read, bs=(R) 300KiB-300KiB, (W) 300KiB-300KiB, (T) 300KiB-300KiB, ioengine=libaio, iodepth=32
fio-3.19
Starting 1 process
Jobs: 1 (f=1): [R(1)][100.0%][r=200MiB/s][r=681 IOPS][eta 00m:00s]
mytest: (groupid=0, jobs=1): err= 0: pid=59309: Tue Jul 16 14:24:26 2024
  read: IOPS=681, BW=200MiB/s (209MB/s)(11.7GiB/60008msec)
    slat (usec): min=63, max=97669, avg=1443.12, stdev=11037.07
    clat (usec): min=2, max=183638, avg=45455.52, stdev=46404.80
     lat (msec): min=3, max=183, avg=46.90, stdev=46.53
    clat percentiles (msec):
     |  1.00th=[    4],  5.00th=[    4], 10.00th=[    4], 20.00th=[    4],
     | 30.00th=[    4], 40.00th=[    4], 50.00th=[    4], 60.00th=[   92],
     | 70.00th=[   92], 80.00th=[  101], 90.00th=[  101], 95.00th=[  101],
     | 99.00th=[  101], 99.50th=[  102], 99.90th=[  176], 99.95th=[  184],
     | 99.99th=[  184]
   bw (  KiB/s): min=174600, max=234600, per=100.00%, avg=204873.28, stdev=6825.91, samples=119
   iops        : min=  582, max=  782, avg=682.91, stdev=22.75, samples=119
  lat (usec)   : 4=0.01%
  lat (msec)   : 4=53.92%, 10=0.49%, 20=0.35%, 100=43.77%, 250=1.47%
  cpu          : usr=0.06%, sys=6.89%, ctx=25101, majf=0, minf=2413
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=99.9%, &gt;=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, &gt;=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.1%, 64=0.0%, &gt;=64=0.0%
     issued rwts: total=40922,0,0,0 short=0,0,0,0 dropped=0,0,0,0
     latency   : target=0, window=0, percentile=100.00%, depth=32

Run status group 0 (all jobs):
   READ: bw=200MiB/s (209MB/s), 200MiB/s-200MiB/s (209MB/s-209MB/s), io=11.7GiB (12.6GB), run=60008-60008msec

Disk stats (read/write):
  nvme11n1: ios=47158/0, merge=598/0, ticks=5569/0, in_queue=0, util=8.04%
</code></pre>
]]></content:encoded></item><item><title><![CDATA[CPU虚拟化]]></title><description><![CDATA[<h2 id="1%E3%80%81cpu%E8%99%9A%E6%8B%9F%E5%8C%96%E6%A6%82%E8%BF%B0">1&#x3001;CPU&#x865A;&#x62DF;&#x5316;&#x6982;&#x8FF0;</h2><p>CPU&#x865A;&#x62DF;&#x5316;&#x662F;&#x4E00;&#x79CD;&#x6280;&#x672F;&#xFF0C;&#x5B83;&#x5141;&#x8BB8;&#x5355;&#x4E2A;&#x7269;&#x7406;CPU&#x6A21;&#x62DF;&#x591A;&#x4E2A;&#x865A;&#x62DF;CPU&#xFF08;VCPU&#xFF09;&#x3002;&#x8FD9;&#x4F7F;&#x5F97;&#x591A;&#x4E2A;&#x64CD;&#x4F5C;&#x7CFB;&#x7EDF;&#xFF08;OS&#xFF09;&#x5B9E;</p>]]></description><link>http://www.korantli.com.cn/linux/cpuxu-ni-hua/</link><guid isPermaLink="false">655c8b1cb936e6d99568cc87</guid><category><![CDATA[linux虚拟化]]></category><category><![CDATA[linux技术总结]]></category><dc:creator><![CDATA[李星辉]]></dc:creator><pubDate>Tue, 21 Nov 2023 10:51:34 GMT</pubDate><media:content url="http://www.korantli.com.cn/content/images/2023/11/WechatIMG3.jpeg" medium="image"/><content:encoded><![CDATA[<h2 id="1%E3%80%81cpu%E8%99%9A%E6%8B%9F%E5%8C%96%E6%A6%82%E8%BF%B0">1&#x3001;CPU&#x865A;&#x62DF;&#x5316;&#x6982;&#x8FF0;</h2><img src="http://www.korantli.com.cn/content/images/2023/11/WechatIMG3.jpeg" alt="CPU&#x865A;&#x62DF;&#x5316;"><p>CPU&#x865A;&#x62DF;&#x5316;&#x662F;&#x4E00;&#x79CD;&#x6280;&#x672F;&#xFF0C;&#x5B83;&#x5141;&#x8BB8;&#x5355;&#x4E2A;&#x7269;&#x7406;CPU&#x6A21;&#x62DF;&#x591A;&#x4E2A;&#x865A;&#x62DF;CPU&#xFF08;VCPU&#xFF09;&#x3002;&#x8FD9;&#x4F7F;&#x5F97;&#x591A;&#x4E2A;&#x64CD;&#x4F5C;&#x7CFB;&#x7EDF;&#xFF08;OS&#xFF09;&#x5B9E;&#x4F8B;&#x80FD;&#x591F;&#x5728;&#x540C;&#x4E00;&#x4E2A;&#x7269;&#x7406;&#x670D;&#x52A1;&#x5668;&#x4E0A;&#x5E76;&#x884C;&#x8FD0;&#x884C;&#xFF0C;&#x6BCF;&#x4E2A;&#x5B9E;&#x4F8B;&#x90FD;&#x5728;&#x81EA;&#x5DF1;&#x7684;&#x9694;&#x79BB;&#x73AF;&#x5883;&#x4E2D;&#x6267;&#x884C;&#x3002;&#x5728;&#x865A;&#x62DF;&#x5316;&#x73AF;&#x5883;&#x4E2D;&#xFF0C;&#x64CD;&#x4F5C;&#x7CFB;&#x7EDF;&#x901A;&#x5E38;&#x8FD0;&#x884C;&#x5728;&#x88AB;&#x79F0;&#x4E3A;<code>&#x865A;&#x62DF;&#x673A;</code>&#xFF08;VM&#xFF09;&#x7684;&#x5C01;&#x88C5;&#x73AF;&#x5883;&#x4E2D;&#x3002;&#x6BCF;&#x4E2A;VM&#x90FD;&#x50CF;&#x62E5;&#x6709;&#x72EC;&#x7ACB;&#x7684;&#x7269;&#x7406;&#x786C;&#x4EF6;&#x4E00;&#x6837;&#x8FD0;&#x884C;&#xFF0C;&#x5C3D;&#x7BA1;&#x5B9E;&#x9645;&#x4E0A;&#x5B83;&#x4EEC;&#x5171;&#x4EAB;&#x7740;&#x540C;&#x4E00;&#x53F0;&#x7269;&#x7406;&#x673A;&#x7684;&#x8D44;&#x6E90;&#x3002;</p><h3 id="11-%E8%99%9A%E6%8B%9F%E5%8C%96%E6%8A%80%E6%9C%AF%E7%9A%84%E5%85%B3%E9%94%AE%E6%8C%91%E6%88%98">1.1-&#x865A;&#x62DF;&#x5316;&#x6280;&#x672F;&#x7684;&#x5173;&#x952E;&#x6311;&#x6218;</h3><ol><li><strong>&#x7279;&#x6743;&#x6307;&#x4EE4;&#x548C;&#x654F;&#x611F;&#x64CD;&#x4F5C;</strong>&#xFF1A;&#x5728;&#x6CA1;&#x6709;&#x786C;&#x4EF6;&#x652F;&#x6301;&#x7684;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;CPU&#x865A;&#x62DF;&#x5316;&#x7684;&#x4E3B;&#x8981;&#x6311;&#x6218;&#x4E4B;&#x4E00;&#x662F;&#x5904;&#x7406;&#x7279;&#x6743;&#x6307;&#x4EE4;&#x3002;&#x8FD9;&#x4E9B;&#x6307;&#x4EE4;&#x901A;&#x5E38;&#x53EA;&#x80FD;&#x7531;&#x7269;&#x7406;CPU&#x4E0A;&#x7684;&#x6700;&#x9AD8;&#x6743;&#x9650;&#x7EA7;&#x522B;&#x6267;&#x884C;&#xFF0C;&#x4F8B;&#x5982;&#xFF0C;&#x76F4;&#x63A5;&#x8BBF;&#x95EE;&#x786C;&#x4EF6;&#x8D44;&#x6E90;&#x3002;&#x5728;&#x865A;&#x62DF;&#x73AF;&#x5883;&#x4E2D;&#xFF0C;&#x5F53;&#x865A;&#x62DF;&#x673A;&#x8BD5;&#x56FE;&#x6267;&#x884C;&#x8FD9;&#x4E9B;&#x6307;&#x4EE4;&#x65F6;&#xFF0C;&#x5FC5;&#x987B;&#x6709;&#x4E00;&#x79CD;&#x673A;&#x5236;&#x6765;&#x9002;&#x5F53;&#x5730;&#x5904;&#x7406;&#x5B83;&#x4EEC;&#xFF0C;&#x4EE5;&#x907F;&#x514D;&#x5BF9;&#x7CFB;&#x7EDF;&#x7684;&#x5B89;&#x5168;&#x548C;&#x7A33;&#x5B9A;&#x6027;&#x9020;&#x6210;&#x5F71;&#x54CD;&#x3002;&#x73B0;&#x4EE3;CPU&#x901A;&#x5E38;&#x5B58;&#x5728;<code>ring0</code>~<code>ring3</code>4&#x4E2A;&#x7EA7;&#x522B;&#xFF0C;&#x800C;&#x5728;linux&#x4E0E;windows&#x5219;&#x53EA;&#x4F7F;&#x7528;<code>ring0</code>&#x4E0E;<code>ring3</code>&#x4E24;&#x4E2A;&#x7EA7;&#x522B;&#xFF0C;&#x901A;&#x5E38;&#x6765;&#x8BF4;&#xFF0C;&#x7528;&#x6237;&#x6001;&#x7684;&#x4EE3;&#x7801;&#x8FD0;&#x884C;&#x5728;<code>ring3</code>&#x4E2D;&#xFF0C;&#x800C;&#x5185;&#x6838;&#x6001;&#x7684;&#x4EE3;&#x7801;&#x8FD0;&#x884C;&#x5728;<code>ring0</code>&#x4E2D;&#xFF0C;&#x4EFB;&#x4F55;&#x76F4;&#x63A5;&#x4E0E;&#x786C;&#x4EF6;&#x4EA4;&#x4E92;&#x3001;&#x7BA1;&#x7406;&#x7CFB;&#x7EDF;&#x8D44;&#x6E90;&#x7684;&#x64CD;&#x4F5C;&#x90FD;&#x662F;&#x5728;<code>ring0</code>&#x4E0B;&#x6267;&#x884C;&#x7684;&#x3002;&#x901A;&#x5E38;&#xFF0C;&#x5F53;CPU&#x5728;<code>ring3</code>&#x4E2D;&#x5C1D;&#x8BD5;&#x6267;&#x884C;<code>ring0</code>&#x7EA7;&#x522B;&#x64CD;&#x4F5C;&#x65F6;&#xFF0C;&#x4F1A;&#x629B;&#x51FA;&#x4E00;&#x4E2A;CPU&#x5F02;&#x5E38;&#xFF0C;&#x800C;&#x6B64;&#x65F6;VMM&#x5219;&#x4F1A;&#x6355;&#x83B7;&#x8FD9;&#x4E2A;&#x5F02;&#x5E38;&#xFF0C;&#x4EE3;&#x66FF;&#x7528;&#x6237;&#x6001;&#x7684;&#x865A;&#x62DF;&#x673A;&#x6267;&#x884C;&#x8BE5;&#x547D;&#x4EE4;&#x3002;&#x7136;&#x800C;&#x5728;<code>x86</code>&#x5E73;&#x53F0;&#x4E0A;&#x4E0D;&#x662F;&#x6240;&#x6709;&#x7684;&#x547D;&#x4EE4;&#x90FD;&#x4F1A;&#x629B;&#x51FA;&#x5F02;&#x5E38;&#xFF0C;&#x6709;&#x4E00;&#x4E9B;<code>&#x654F;&#x611F;&#x6307;&#x4EE4;</code>&#x5E76;&#x4E0D;&#x662F;<code>&#x7279;&#x6743;&#x6307;&#x4EE4;</code>&#xFF0C;&#x6BD4;&#x5982;&#x5728;&#x7528;&#x6237;&#x6001;&#x4FEE;&#x6539;<code>&#x4E2D;&#x65AD;&#x72B6;&#x6001;&#xFF08;IF&#xFF09;&#x5BC4;&#x5B58;&#x5668;</code>&#xFF0C;&#x5982;&#x679C;&#x5728;&#x7528;&#x6237;&#x6001;&#x6267;&#x884C;&#x8BE5;&#x547D;&#x4EE4;&#xFF0C;CPU&#x5219;&#x53EA;&#x4F1A;&#x5FFD;&#x7565;&#x8BE5;&#x547D;&#x4EE4;&#x3002;<ul><li><strong>&#x7279;&#x6743;&#x6307;&#x4EE4;&#xFF08;Privileged Instructions&#xFF09;</strong>&#xFF1A;<ul><li>&#x7279;&#x6743;&#x6307;&#x4EE4;&#x662F;&#x90A3;&#x4E9B;&#x53EA;&#x80FD;&#x5728;&#x5904;&#x7406;&#x5668;&#x7684;&#x6700;&#x9AD8;&#x7279;&#x6743;&#x7EA7;&#x522B;&#xFF08;&#x901A;&#x5E38;&#x662F;Ring 0&#xFF0C;&#x5728;x86&#x4F53;&#x7CFB;&#x7ED3;&#x6784;&#x4E2D;&#x88AB;&#x79F0;&#x4E3A;&#x5185;&#x6838;&#x6A21;&#x5F0F;&#xFF09;&#x4E0B;&#x8FD0;&#x884C;&#x7684;&#x6307;&#x4EE4;&#x3002;</li><li>&#x8FD9;&#x4E9B;&#x6307;&#x4EE4;&#x901A;&#x5E38;&#x7528;&#x4E8E;&#x6267;&#x884C;&#x7CFB;&#x7EDF;&#x7EA7;&#x7684;&#x64CD;&#x4F5C;&#xFF0C;&#x5982;&#x7BA1;&#x7406;&#x786C;&#x4EF6;&#x8BBE;&#x5907;&#x3001;&#x6539;&#x53D8;&#x5185;&#x5B58;&#x8BBF;&#x95EE;&#x6743;&#x9650;&#x3001;&#x63A7;&#x5236;CPU&#x7684;&#x72B6;&#x6001;&#x7B49;&#x3002;</li><li>&#x7279;&#x6743;&#x6307;&#x4EE4;&#x7684;&#x6267;&#x884C;&#x901A;&#x5E38;&#x662F;&#x53D7;&#x64CD;&#x4F5C;&#x7CFB;&#x7EDF;&#x5185;&#x6838;&#x63A7;&#x5236;&#x7684;&#x3002;&#x5F53;&#x7528;&#x6237;&#x7A7A;&#x95F4;&#x7684;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x9700;&#x8981;&#x6267;&#x884C;&#x8FD9;&#x4E9B;&#x64CD;&#x4F5C;&#x65F6;&#xFF0C;&#x5B83;&#x4EEC;&#x4F1A;&#x901A;&#x8FC7;&#x7CFB;&#x7EDF;&#x8C03;&#x7528;&#x7684;&#x5F62;&#x5F0F;&#x59D4;&#x6258;&#x7ED9;&#x5185;&#x6838;&#x6267;&#x884C;&#x3002;</li></ul></li><li><strong>&#x654F;&#x611F;&#x6307;&#x4EE4;&#xFF08;Sensitive Instructions&#xFF09;</strong>&#xFF1A;<ul><li>&#x654F;&#x611F;&#x6307;&#x4EE4;&#x662F;&#x90A3;&#x4E9B;&#x5BF9;&#x7CFB;&#x7EDF;&#x7684;&#x5168;&#x5C40;&#x72B6;&#x6001;&#x6216;&#x8D44;&#x6E90;&#x6709;&#x5F71;&#x54CD;&#x7684;&#x6307;&#x4EE4;&#xFF0C;&#x8FD9;&#x5305;&#x62EC;&#x7279;&#x6743;&#x6307;&#x4EE4;&#x548C;&#x975E;&#x7279;&#x6743;&#x6307;&#x4EE4;&#x3002;</li><li>&#x654F;&#x611F;&#x6307;&#x4EE4;&#x7684;&#x8303;&#x56F4;&#x66F4;&#x5E7F;&#xFF0C;&#x4E0D;&#x4EC5;&#x5305;&#x62EC;&#x6539;&#x53D8;&#x6216;&#x67E5;&#x8BE2;&#x5904;&#x7406;&#x5668;&#x6A21;&#x5F0F;&#x3001;&#x786C;&#x4EF6;&#x914D;&#x7F6E;&#x6216;&#x5176;&#x4ED6;&#x7CFB;&#x7EDF;&#x8D44;&#x6E90;&#x7684;&#x6307;&#x4EE4;&#xFF0C;&#x4E5F;&#x5305;&#x62EC;&#x90A3;&#x4E9B;&#x53EF;&#x80FD;&#x6539;&#x53D8;&#x7CFB;&#x7EDF;&#x7684;&#x63A7;&#x5236;&#x6D41;&#x3001;&#x4E2D;&#x65AD;&#x5904;&#x7406;&#x6216;&#x6570;&#x636E;&#x6D41;&#x7684;&#x6307;&#x4EE4;&#x3002;</li></ul></li></ul></li><li><strong>&#x8D44;&#x6E90;&#x5171;&#x4EAB;&#x548C;&#x9694;&#x79BB;</strong>&#xFF1A;&#x865A;&#x62DF;&#x5316;&#x73AF;&#x5883;&#x5FC5;&#x987B;&#x786E;&#x4FDD;&#x6240;&#x6709;&#x865A;&#x62DF;&#x673A;&#x53EF;&#x4EE5;&#x9AD8;&#x6548;&#x3001;&#x516C;&#x5E73;&#x5730;&#x5171;&#x4EAB;CPU&#x8D44;&#x6E90;&#xFF0C;&#x540C;&#x65F6;&#x4FDD;&#x6301;&#x5F7C;&#x6B64;&#x7684;&#x9694;&#x79BB;&#xFF0C;&#x4EE5;&#x907F;&#x514D;&#x4E00;&#x4E2A;&#x865A;&#x62DF;&#x673A;&#x7684;&#x64CD;&#x4F5C;&#x5F71;&#x54CD;&#x5230;&#x5176;&#x4ED6;&#x865A;&#x62DF;&#x673A;&#x3002;</li></ol><h3 id="12-%E8%99%9A%E6%8B%9F%E5%8C%96%E6%8A%80%E6%9C%AF%E7%9A%84%E5%8F%91%E5%B1%95">1.2-&#x865A;&#x62DF;&#x5316;&#x6280;&#x672F;&#x7684;&#x53D1;&#x5C55;</h3><ol><li><strong>&#x8F6F;&#x4EF6;&#x6A21;&#x62DF;</strong>&#xFF1A;&#x65E9;&#x671F;&#x7684;CPU&#x865A;&#x62DF;&#x5316;&#x6280;&#x672F;&#xFF0C;&#x5982;Bochs&#x548C;QEMU&#xFF0C;&#x4F7F;&#x7528;&#x7EAF;&#x7CB9;&#x7684;&#x8F6F;&#x4EF6;&#x6A21;&#x62DF;&#x6765;&#x5904;&#x7406;&#x7279;&#x6743;&#x6307;&#x4EE4;&#xFF0C;&#x8FD9;&#x79CD;&#x65B9;&#x6CD5;&#x7684;&#x7F3A;&#x70B9;&#x662F;&#x6027;&#x80FD;&#x5F00;&#x9500;&#x8F83;&#x5927;&#x3002;&#x53E6;&#x5916;&#x901A;&#x5E38;&#x5728;&#x5728;<code>A</code>&#x67B6;&#x6784;&#x4E0A;&#x6267;&#x884C;<code>B</code>&#x67B6;&#x6784;&#x865A;&#x62DF;&#x673A;&#x539F;&#x7406;&#x4E5F;&#x662F;&#x6A21;&#x62DF;&#x3002;</li><li><strong>&#x52A8;&#x6001;&#x4E8C;&#x8FDB;&#x5236;&#x7FFB;&#x8BD1;</strong>&#xFF1A;VMware&#x4F7F;&#x7528;&#x4E86;&#x4E00;&#x79CD;&#x79F0;&#x4E3A;&#x52A8;&#x6001;&#x4E8C;&#x8FDB;&#x5236;&#x7FFB;&#x8BD1;&#xFF08;DBT&#xFF09;&#x7684;&#x6280;&#x672F;&#xFF0C;&#x5B83;&#x5728;&#x8FD0;&#x884C;&#x65F6;&#x5C06;&#x7279;&#x6743;&#x6307;&#x4EE4;&#x8F6C;&#x6362;&#x4E3A;&#x4E0D;&#x540C;&#x7684;&#x6307;&#x4EE4;&#x5E8F;&#x5217;&#xFF0C;&#x4EE5;&#x5728;&#x865A;&#x62DF;&#x5316;&#x73AF;&#x5883;&#x4E2D;&#x6B63;&#x786E;&#x6267;&#x884C;&#x3002;&#x6211;&#x4EEC;&#x4E0A;&#x95EE;&#x9898;&#x6240;&#x63D0;&#x5230;&#x7684;&#x4E00;&#x79CD;&#x89E3;&#x51B3;<code>x86</code>&#x5E73;&#x53F0;&#x7279;&#x6743;&#x6307;&#x4EE4;&#x7684;&#x65B9;&#x6848;&#x5C31;&#x662F;&#x52A8;&#x6001;&#x7FFB;&#x8BD1;&#x3002;</li><li><strong>&#x786C;&#x4EF6;&#x8F85;&#x52A9;&#x865A;&#x62DF;&#x5316;</strong>&#xFF1A;&#x968F;&#x540E;&#xFF0C;&#x5904;&#x7406;&#x5668;&#x5236;&#x9020;&#x5546;&#x5982;Intel&#x548C;AMD&#x5728;&#x5176;CPU&#x4E2D;&#x5F15;&#x5165;&#x4E86;&#x786C;&#x4EF6;&#x8F85;&#x52A9;&#x865A;&#x62DF;&#x5316;&#x6280;&#x672F;&#xFF08;&#x4F8B;&#x5982;Intel&#x7684;VT-x&#x548C;AMD&#x7684;AMD-V&#xFF09;&#x3002;&#x8FD9;&#x4E9B;&#x6280;&#x672F;&#x901A;&#x8FC7;&#x5728;&#x786C;&#x4EF6;&#x5C42;&#x9762;&#x63D0;&#x4F9B;&#x5BF9;&#x865A;&#x62DF;&#x5316;&#x7684;&#x652F;&#x6301;&#xFF0C;&#x5141;&#x8BB8;&#x865A;&#x62DF;&#x673A;&#x53EF;&#x4EE5;&#x76F4;&#x63A5;&#x6267;&#x884C;ring0&#x7684;&#x4EE3;&#x7801;&#xFF0C;&#x8FD9;&#x79CD;&#x65B9;&#x6848;&#x65E0;&#x987B;&#x5BF9;&#x547D;&#x4EE4;&#x8FDB;&#x884C;&#x8F6C;&#x8BD1;&#x800C;&#x76F4;&#x63A5;&#x6267;&#x884C;&#x547D;&#x4EE4;&#xFF0C;&#x6545;&#x800C;&#x663E;&#x8457;&#x63D0;&#x9AD8;&#x4E86;&#x6027;&#x80FD;&#x548C;&#x6548;&#x7387;&#x3002;</li></ol><h3 id="13-%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%9B%91%E6%8E%A7%E5%99%A8%EF%BC%88vmm%EF%BC%89">1.3-&#x865A;&#x62DF;&#x673A;&#x76D1;&#x63A7;&#x5668;&#xFF08;VMM&#xFF09;</h3><ol><li><strong>&#x5B9A;&#x4E49;&#x548C;&#x4F5C;&#x7528;</strong>&#xFF1A;&#x865A;&#x62DF;&#x673A;&#x76D1;&#x63A7;&#x5668;&#xFF08;VMM&#xFF09;&#x662F;&#x865A;&#x62DF;&#x5316;&#x6280;&#x672F;&#x4E2D;&#x7684;&#x6838;&#x5FC3;&#x7EC4;&#x4EF6;&#x3002;&#x5B83;&#x8D1F;&#x8D23;&#x7BA1;&#x7406;&#x865A;&#x62DF;&#x673A;&#x7684;&#x8D44;&#x6E90;&#x5206;&#x914D;&#x3001;&#x8C03;&#x5EA6;&#x548C;&#x6267;&#x884C;&#x3002;&#x5728;&#x786C;&#x4EF6;&#x8F85;&#x52A9;&#x7684;&#x865A;&#x62DF;&#x5316;&#x73AF;&#x5883;&#x4E2D;&#xFF0C;VMM&#x901A;&#x5E38;&#x8FD0;&#x884C;&#x5728;&#x66F4;&#x9AD8;&#x7684;&#x6743;&#x9650;&#x7EA7;&#x522B;&#xFF0C;&#x4EE5;&#x4FBF;&#x63A7;&#x5236;&#x5BF9;&#x786C;&#x4EF6;&#x7684;&#x8BBF;&#x95EE;&#x548C;&#x7BA1;&#x7406;&#x865A;&#x62DF;&#x673A;&#x7684;&#x6267;&#x884C;&#x3002;</li><li><strong>VMM&#x7684;&#x7C7B;&#x578B;</strong>&#xFF1A;VMM&#x53EF;&#x4EE5;&#x662F;&#x7C7B;&#x578B;&#x4E00;&#xFF08;&#x8FD0;&#x884C;&#x5728;&#x88F8;&#x673A;&#x4E0A;&#xFF09;&#x6216;&#x7C7B;&#x578B;&#x4E8C;&#xFF08;&#x8FD0;&#x884C;&#x5728;&#x5BBF;&#x4E3B;&#x64CD;&#x4F5C;&#x7CFB;&#x7EDF;&#x4E4B;&#x4E0A;&#xFF09;&#x3002;KVM&#xFF08;Kernel-based Virtual Machine&#xFF09;&#x662F;&#x4E00;&#x79CD;&#x7C7B;&#x578B;&#x4E00;VMM&#xFF0C;&#x800C;QEMU&#x901A;&#x5E38;&#x4F5C;&#x4E3A;&#x7C7B;&#x578B;&#x4E8C;VMM&#x4F7F;&#x7528;&#x3002;</li></ol><h2 id="2%E3%80%81%E7%A1%AC%E4%BB%B6%E8%BE%85%E5%8A%A9%E8%99%9A%E6%8B%9F%E5%8C%96">2&#x3001;&#x786C;&#x4EF6;&#x8F85;&#x52A9;&#x865A;&#x62DF;&#x5316;</h2><h3 id="21-%E7%A1%AC%E4%BB%B6%E8%BE%85%E5%8A%A9%E8%99%9A%E6%8B%9F%E5%8C%96%E7%9A%84%E5%AE%9E%E7%8E%B0">2.1-&#x786C;&#x4EF6;&#x8F85;&#x52A9;&#x865A;&#x62DF;&#x5316;&#x7684;&#x5B9E;&#x73B0;</h3><p>&#x5982;&#x679C;&#x60F3;&#x8981;&#x5B9E;&#x73B0;CPU&#x7684;&#x786C;&#x4EF6;&#x865A;&#x62DF;&#x5316;&#xFF0C;&#x6211;&#x4EEC;&#x5219;&#x9700;&#x8981;CPU&#x5177;&#x5907;&#x4E00;&#x4E0B;&#x80FD;&#x529B;&#xFF1A;</p><ol><li><strong>CPU&#x6307;&#x4EE4;&#x96C6;&#x652F;&#x6301;</strong>&#xFF1A;&#x786C;&#x4EF6;&#x8F85;&#x52A9;&#x865A;&#x62DF;&#x5316;&#x9700;&#x8981;CPU&#x652F;&#x6301;&#x4E00;&#x7EC4;&#x7279;&#x6B8A;&#x7684;&#x6307;&#x4EE4;&#x96C6;&#x3002;&#x8FD9;&#x4E9B;&#x6307;&#x4EE4;&#x7528;&#x4E8E;&#x7BA1;&#x7406;&#x865A;&#x62DF;&#x673A;&#x7684;&#x521B;&#x5EFA;&#x3001;&#x6267;&#x884C;&#x3001;&#x6682;&#x505C;&#x548C;&#x9500;&#x6BC1;&#x3002;</li><li><strong>&#x4E0A;&#x4E0B;&#x6587;&#x5207;&#x6362;</strong>&#xFF1A;&#x786C;&#x4EF6;&#x8F85;&#x52A9;&#x865A;&#x62DF;&#x5316;&#x6280;&#x672F;&#x5141;&#x8BB8;&#x5FEB;&#x901F;&#x6709;&#x6548;&#x5730;&#x5728;&#x865A;&#x62DF;&#x673A;&#x548C;&#x5BBF;&#x4E3B;&#x673A;&#x73AF;&#x5883;&#x4E4B;&#x95F4;&#x8FDB;&#x884C;&#x4E0A;&#x4E0B;&#x6587;&#x5207;&#x6362;&#x3002;&#x8FD9;&#x4F7F;&#x5F97;&#x865A;&#x62DF;&#x673A;&#x53EF;&#x4EE5;&#x5728;&#x63A5;&#x8FD1;&#x539F;&#x751F;&#x6027;&#x80FD;&#x7684;&#x60C5;&#x51B5;&#x4E0B;&#x8FD0;&#x884C;&#x3002;</li></ol><h3 id="22-vmx">2.2-VMX</h3><p><code>Intel</code>&#x5F00;&#x53D1;&#x4E86;&#x4E00;&#x79CD;<code>VT</code>&#x6280;&#x672F;&#x4EE5;&#x652F;&#x6301;&#x865A;&#x62DF;&#x5316;&#xFF0C;&#x4E3A;CPU&#x865A;&#x62DF;&#x5316;&#x589E;&#x52A0;&#x4E86;&#x4E00;&#x4E2A;&#x53EB;&#x505A;<code>Virtual-Machine Extensions&#xFF08;VMX&#xFF09;</code>&#x7684;&#x529F;&#x80FD;&#x3002;</p><p>VT&#x4E2D;&#x7684;VMX root&#x6A21;&#x5F0F;&#x548C;non-root&#x6A21;&#x5F0F;&#x5206;&#x522B;&#x7528;&#x4E8E;&#x865A;&#x62DF;&#x673A;&#x76D1;&#x63A7;&#x5668;&#xFF08;VMM&#xFF09;&#x548C;&#x865A;&#x62DF;&#x673A;&#xFF08;VM&#xFF09;&#x3002;&#x8FD9;&#x79CD;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x4F7F;&#x865A;&#x62DF;&#x673A;&#x7684;&#x5185;&#x6838;&#x76F4;&#x63A5;&#x8FD0;&#x884C;&#x5728;CPU&#x7684;<code>ring0</code>&#xFF0C;&#x4E5F;&#x5C31;&#x907F;&#x514D;&#x7684;&#x7279;&#x6743;&#x3001;&#x654F;&#x611F;&#x6307;&#x4EE4;&#x7684;&#x76F8;&#x5173;&#x95EE;&#x9898;&#xFF0C;&#x800C;&#x865A;&#x62DF;&#x673A;&#x7684;&#x7528;&#x6237;&#x6001;&#x5219;&#x7EE7;&#x7EED;&#x7EF4;&#x6301;&#x5728;<code>ring3</code>&#x72B6;&#x6001;&#x4E0B;&#xFF0C;&#x4FDD;&#x8BC1;&#x4E86;&#x7CFB;&#x7EDF;&#x7684;&#x5B89;&#x5168;&#x3002;</p><figure class="kg-card kg-image-card"><img src="http://www.korantli.com.cn/content/images/2023/11/image-20231111142733554.png" class="kg-image" alt="CPU&#x865A;&#x62DF;&#x5316;" loading="lazy" width="1242" height="680" srcset="http://www.korantli.com.cn/content/images/size/w600/2023/11/image-20231111142733554.png 600w, http://www.korantli.com.cn/content/images/size/w1000/2023/11/image-20231111142733554.png 1000w, http://www.korantli.com.cn/content/images/2023/11/image-20231111142733554.png 1242w" sizes="(min-width: 720px) 720px"></figure><h4 id="221-%E8%BF%9B%E5%85%A5%E8%99%9A%E6%8B%9F%E6%9C%BA">2.2.1-&#x8FDB;&#x5165;&#x865A;&#x62DF;&#x673A;</h4><p>&#x8FD0;&#x884C;&#x5728;<code>ROOT Mode</code>&#x4E2D;&#x7684;VMM&#x7B2C;&#x4E00;&#x6B21;&#x5C06;&#x901A;&#x8FC7;<code>VMLaunch</code>&#x547D;&#x4EE4;&#x5C06;CPU&#x72B6;&#x6001;&#x5207;&#x6362;&#x5230;<code>non-Root Mode</code>&#xFF0C;&#x6267;&#x884C;&#x8FDB;&#x5165;Guest&#x7684;<code>VM entry</code>&#x64CD;&#x4F5C;&#x3002;&#x800C;&#x540E;&#x7EED;VMM&#x5219;&#x4F1A;&#x901A;&#x8FC7;<code>VMResume</code>&#x547D;&#x4EE4;&#x91CD;&#x65B0;&#x8FDB;&#x5165;&#x5230;<code>non-Root Mode</code>&#x3002;&#x901A;&#x8FC7;<code>kvm_arch_vcpu_ioctl_run</code>&#x7684;ioctl&#x5B9E;&#x73B0;&#x7528;&#x6237;&#x6001;&#x7684;&#x8C03;&#x7528;&#x3002;</p><pre><code class="language-cpp">static fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu)
{
	......
	/* &#x68C0;&#x67E5;&#x662F;&#x5426;&#x53EF;&#x4EE5;&#x8FDB;&#x5165;&#x865A;&#x62DF;&#x673A;&#xFF0C;&#x5982;&#x679C;&#x4E0D;&#x9700;&#x8981;&#x7684;&#x8BDD;&#x5219;&#x76F4;&#x63A5;&#x9000;&#x51FA; */
	if (unlikely(vmx-&gt;emulation_required)) {
		vmx-&gt;fail = 0;
		......
		return EXIT_FASTPATH_NONE;
	}

	trace_kvm_entry(vcpu);
	......

	/* &#x83B7;&#x53D6;HOST&#x4E2D;CR3&#x3001;CR4&#x5BC4;&#x5B58;&#x5668;&#x72B6;&#x6001; */
	cr3 = __get_current_cr3_fast();
	......
	cr4 = cr4_read_shadow();
	......

	/* &#x6267;&#x884C;VMLAUNCH&#x6216;&#x8005;VMRESUME&#xFF0C;&#x5E76;&#x5728;&#x5B8C;&#x6210;&#x540E;&#x9000;&#x51FA; */
	vmx_vcpu_enter_exit(vcpu, __vmx_vcpu_run_flags(vmx));

	/* &#x540E;&#x8FB9;&#x4E3B;&#x8981;&#x662F;&#x865A;&#x62DF;&#x673A;&#x9000;&#x51FA;&#x540E;&#xFF0C;&#x4EE3;&#x7801;&#x4F1A;&#x6267;&#x884C;&#x4E00;&#x7CFB;&#x5217;&#x6E05;&#x7406;&#x548C;&#x72B6;&#x6001;&#x540C;&#x6B65;&#x64CD;&#x4F5C; */
	if (kvm_is_using_evmcs()) {
		current_evmcs-&gt;hv_clean_fields |=
			HV_VMX_ENLIGHTENED_CLEAN_FIELD_ALL;

		current_evmcs-&gt;hv_vp_id = kvm_hv_get_vpindex(vcpu);
	}
	......

	if (unlikely(vmx-&gt;fail))
		return EXIT_FASTPATH_NONE;

	if (unlikely((u16)vmx-&gt;exit_reason.basic == EXIT_REASON_MCE_DURING_VMENTRY))
		kvm_machine_check();

	/* &#x5B8C;&#x6210;vcpu&#x751F;&#x547D;&#x5468;&#x671F;&#x540E;&#x5219;&#x4F1A;&#x9000;&#x51FA;&#x865A;&#x62DF;&#x673A; */
	trace_kvm_exit(vcpu, KVM_ISA_VMX);
	.....
	if (is_guest_mode(vcpu))
		return EXIT_FASTPATH_NONE;

	return vmx_exit_handlers_fastpath(vcpu);
}
</code></pre><p>&#x4E0A;&#x8FB9;&#x7684;&#x51FD;&#x6570;&#x6700;&#x7EC8;&#x4F1A;&#x8C03;&#x7528;&#x5230;<code>arch/x86/kvm/vmx/vmenter.S</code>&#x4E2D;&#x7684;<code>__vmx_vcpu_run</code>&#x7684;&#x6C47;&#x7F16;&#x51FD;&#x6570;&#x8FDB;&#x5165;&#x5230;&#x865A;&#x62DF;&#x673A;&#x4E2D;&#xFF0C;&#x5E76;&#x901A;&#x8FC7;&#x4F20;&#x53C2;flag&#x5224;&#x65AD;&#x5177;&#x4F53;&#x662F;<code>resume</code>&#x8FD8;&#x662F;<code>launch</code>&#x3002;</p><pre><code class="language-cpp">/**
 * __vmx_vcpu_run - Run a vCPU via a transition to VMX guest mode
 * @vmx:	struct vcpu_vmx *
 * @regs:	unsigned long * (to guest registers)
 * @flags:	VMX_RUN_VMRESUME:	use VMRESUME instead of VMLAUNCH
 *		VMX_RUN_SAVE_SPEC_CTRL: save guest SPEC_CTRL into vmx-&gt;spec_ctrl
 *
 * Returns:
 *	0 on VM-Exit, 1 on VM-Fail
 */
</code></pre><h4 id="222-%E9%80%80%E5%87%BA%E8%99%9A%E6%8B%9F%E6%9C%BA">2.2.2-&#x9000;&#x51FA;&#x865A;&#x62DF;&#x673A;</h4><p>&#x800C;&#x5982;&#x679C;guest&#x5185;&#x6838;&#x4E2D;&#x6267;&#x884C;&#x90E8;&#x5206;<code>&#x7279;&#x6743;&#x547D;&#x4EE4;</code>&#xFF08;&#x5982;I/O&#x8BBF;&#x95EE;&#xFF09;&#x65F6;&#xFF0C;&#x5219;&#x4F1A;&#x89E6;&#x53D1;CPU&#x9677;&#x5165;&#x7684;&#x52A8;&#x4F5C;&#xFF0C;&#x6B64;&#x65F6;&#x5219;&#x4F1A;&#x9000;&#x51FA;guest <code>VM exit</code>&#xFF0C;CPU&#x5219;&#x4ECE;<code>non-Root Mode</code>&#x5207;&#x6362;&#x56DE;<code>root Mode</code>&#xFF0C;&#x7136;&#x540E;VMM&#x5219;&#x6355;&#x83B7;&#x8FD9;&#x4E9B;&#x7279;&#x6743;&#x547D;&#x4EE4;&#xFF0C;&#x7531;&#x5176;&#x6A21;&#x62DF;&#x8BE5;&#x547D;&#x4EE4;&#xFF0C;&#x4EE3;&#x66FF;&#x865A;&#x62DF;&#x673A;&#x5185;&#x6838;&#x6267;&#x884C;&#x3002;&#x9020;&#x6210;VM Exit&#x7684;&#x5E38;&#x89C1;&#x60C5;&#x51B5;&#x5305;&#x62EC;&#x8BBF;&#x95EE;I/O&#x7AEF;&#x53E3;&#x3001;&#x5904;&#x7406;&#x5916;&#x90E8;&#x4E2D;&#x65AD;&#x7B49;&#x3002;</p><p>&#x9000;&#x51FA;&#x7684;&#x5B9E;&#x9645;&#x64CD;&#x4F5C;&#x5728;<code>vmx_vcpu_run</code>&#x4E2D;&#xFF0C;&#x5E76;&#x4E14;&#x4F1A;&#x6839;&#x636E;&#x4E0D;&#x540C;&#x7684;&#x9000;&#x51FA;&#x539F;&#x56E0;&#x6267;&#x884C;&#x5BF9;&#x5E94;&#x7684;&#x903B;&#x8F91;&#x3002;</p><pre><code class="language-cpp">static fastpath_t vmx_exit_handlers_fastpath(struct kvm_vcpu *vcpu)
{
	switch (to_vmx(vcpu)-&gt;exit_reason.basic) {
	case EXIT_REASON_MSR_WRITE:
		return handle_fastpath_set_msr_irqoff(vcpu);
	case EXIT_REASON_PREEMPTION_TIMER:
		return handle_fastpath_preemption_timer(vcpu);
	default:
		return EXIT_FASTPATH_NONE;
	}
}
</code></pre><p>&#x5176;&#x4E2D;&#x9000;&#x51FA;&#x7684;&#x539F;&#x56E0;&#x5206;&#x6790;&#x5982;&#x4E0B;</p><ul><li><strong><code>EXIT_REASON_MSR_WRITE</code></strong>&#xFF1A;<ul><li>&#x5F53;&#x865A;&#x62DF;&#x673A;&#x5C1D;&#x8BD5;&#x5199;&#x5165;&#x4E00;&#x4E2A;&#x6A21;&#x578B;&#x7279;&#x5B9A;&#x5BC4;&#x5B58;&#x5668;&#xFF08;MSR&#xFF09;&#x65F6;&#xFF0C;&#x4F1A;&#x89E6;&#x53D1;&#x6B64;&#x7C7B;VM Exit&#x3002;</li><li><code>handle_fastpath_set_msr_irqoff</code>&#x51FD;&#x6570;&#x5904;&#x7406;&#x8FD9;&#x79CD;&#x7C7B;&#x578B;&#x7684;VM Exit&#xFF0C;&#x5B83;&#x4F1A;&#x5FEB;&#x901F;&#x54CD;&#x5E94;MSR&#x5199;&#x64CD;&#x4F5C;&#x3002;&#x8FD9;&#x901A;&#x5E38;&#x6D89;&#x53CA;&#x5230;&#x66F4;&#x65B0;&#x865A;&#x62DF;&#x673A;&#x7684;MSR&#x503C;&#xFF0C;&#x800C;&#x4E0D;&#x9700;&#x8981;&#x590D;&#x6742;&#x7684;&#x6A21;&#x62DF;&#x6216;&#x72B6;&#x6001;&#x66F4;&#x65B0;&#x3002;&#x8FD9;&#x79CD;&#x5904;&#x7406;&#x901A;&#x5E38;&#x6BD4;&#x5B8C;&#x5168;&#x6A21;&#x62DF;MSR&#x5199;&#x64CD;&#x4F5C;&#x66F4;&#x9AD8;&#x6548;&#x3002;</li></ul></li><li><strong><code>EXIT_REASON_PREEMPTION_TIMER</code></strong>&#xFF1A;<ul><li>&#x5F53;VMX&#x9884;&#x5904;&#x7406;&#x8BA1;&#x65F6;&#x5668;&#x5230;&#x671F;&#x65F6;&#xFF0C;&#x4F1A;&#x89E6;&#x53D1;&#x8FD9;&#x79CD;VM Exit&#x3002;</li><li><code>handle_fastpath_preemption_timer</code>&#x51FD;&#x6570;&#x5904;&#x7406;&#x8FD9;&#x79CD;&#x7C7B;&#x578B;&#x7684;VM Exit&#xFF0C;&#x5B83;&#x901A;&#x5E38;&#x6D89;&#x53CA;&#x5230;&#x66F4;&#x65B0;&#x865A;&#x62DF;&#x673A;&#x7684;&#x8BA1;&#x65F6;&#x5668;&#x72B6;&#x6001;&#x6216;&#x8C03;&#x5EA6;&#x4FE1;&#x606F;&#x3002;&#x8FD9;&#x53EF;&#x4EE5;&#x7528;&#x4E8E;&#x786E;&#x4FDD;&#x865A;&#x62DF;&#x673A;&#x4E0D;&#x4F1A;&#x5360;&#x7528;&#x8FC7;&#x591A;&#x7684;&#x5BBF;&#x4E3B;CPU&#x65F6;&#x95F4;&#xFF0C;&#x4ECE;&#x800C;&#x5141;&#x8BB8;&#x5BBF;&#x4E3B;&#x64CD;&#x4F5C;&#x7CFB;&#x7EDF;&#x66F4;&#x516C;&#x5E73;&#x5730;&#x5206;&#x914D;&#x5904;&#x7406;&#x5668;&#x8D44;&#x6E90;&#x7ED9;&#x5176;&#x4ED6;&#x4EFB;&#x52A1;&#x3002;</li></ul></li></ul><p>&#x800C;KVM&#x6A21;&#x5757;&#x4E2D;&#x7684;<code>handle_exit</code>&#x4EE5;&#x53CA;<code>__vmx_handle_exit</code>&#x53EA;&#x662F;&#x7528;&#x6765;&#x5904;&#x7406;&#x5DF2;&#x7ECF;&#x9000;&#x51FA;&#x7684;&#x865A;&#x62DF;&#x673A;&#x540E;&#x7EED;&#x72B6;&#x6001;&#xFF0C;&#x800C;&#x4E0D;&#x662F;&#x76F4;&#x63A5;&#x6267;&#x884C;&#x9000;&#x51FA;&#x7684;&#x5B9E;&#x9645;&#x903B;&#x8F91;&#x3002;&#x901A;&#x8FC7;&#x4E0A;&#x8FF0;&#x903B;&#x8F91;&#x5927;&#x6982;&#x4E5F;&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;&#x865A;&#x62DF;&#x673A;&#x9000;&#x51FA;&#x65F6;&#x4E3B;&#x8981;&#x662F;&#x88AB;&#x52A8;&#x9000;&#x51FA;&#xFF0C;&#x800C;&#x4E0D;&#x662F;&#x7C7B;&#x4F3C;&#x4E8E;&#x8FDB;&#x5165;&#x65F6;&#x7684;&#x4E3B;&#x52A8;&#x8C03;&#x7528;&#x3002;</p><pre><code class="language-cpp">static int vmx_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath)
{
	int ret = __vmx_handle_exit(vcpu, exit_fastpath);

	......
	return ret;
}
</code></pre><h4 id="223-vcpu%E4%B8%8A%E4%B8%8B%E6%96%87">2.2.3-vcpu&#x4E0A;&#x4E0B;&#x6587;</h4><p><strong>VMCS&#xFF08;Virtual Machine Control Structure&#xFF09;</strong>&#xFF1A;&#x5728;VT-x&#x4E2D;&#xFF0C;VMCS&#x662F;&#x7528;&#x6765;&#x4FDD;&#x5B58;&#x865A;&#x62DF;&#x673A;&#x7684;&#x72B6;&#x6001;&#x548C;&#x63A7;&#x5236;&#x865A;&#x62DF;&#x673A;&#x6267;&#x884C;&#x7684;&#x6570;&#x636E;&#x7ED3;&#x6784;&#x3002;&#x6BCF;&#x4E2A;VCPU&#x90FD;&#x6709;&#x4E00;&#x4E2A;&#x5BF9;&#x5E94;&#x7684;VMCS&#xFF0C;&#x5B83;&#x5305;&#x542B;&#x4E86;&#x5173;&#x4E8E;VCPU&#x7684;&#x6267;&#x884C;&#x72B6;&#x6001;&#x3001;&#x63A7;&#x5236;&#x5B57;&#x6BB5;&#x548C;&#x5176;&#x4ED6;&#x7BA1;&#x7406;&#x4FE1;&#x606F;&#x3002;</p><p>&#x5728;<code>v6.6</code>&#x4E2D;&#x88AB;&#x5B9A;&#x4E49;&#x5728;&#x4E86;<code>arch/x86/kvm/vmx/vmcs.h</code>&#xFF0C;&#x4E3B;&#x8981;&#x5305;&#x542B;&#x4EE5;&#x4E0B;&#x51E0;&#x4E2A;&#x7ED3;&#x6784;&#x4F53;</p><pre><code class="language-cpp">struct vmcs_hdr {
	u32 revision_id:31;   // VMCS&#x6570;&#x636E;&#x7ED3;&#x6784;&#x7684;&#x7248;&#x672C;&#x53F7;&#xFF0C;&#x7528;&#x4E8E;&#x786E;&#x4FDD;VMCS&#x7684;&#x517C;&#x5BB9;&#x6027;
	u32 shadow_vmcs:1;    // &#x6307;&#x793A;&#x662F;&#x5426;&#x4F7F;&#x7528;&#x5F71;&#x5B50;VMCS&#xFF0C;&#x7528;&#x4E8E;&#x5D4C;&#x5957;&#x865A;&#x62DF;&#x5316;
};

struct vmcs {
	struct vmcs_hdr hdr;  // &#x5305;&#x542B;VMCS&#x5934;&#x90E8;&#x4FE1;&#x606F;
	u32 abort;            // &#x5982;&#x679C;VMCS&#x64CD;&#x4F5C;&#x5931;&#x8D25;&#xFF0C;&#x6B64;&#x5B57;&#x6BB5;&#x88AB;&#x8BBE;&#x7F6E;
	char data[];          // &#x52A8;&#x6001;&#x5927;&#x5C0F;&#x7684;&#x6570;&#x7EC4;&#xFF0C;&#x7528;&#x4E8E;&#x5B58;&#x50A8;VMCS&#x6570;&#x636E;
};
DECLARE_PER_CPU(struct vmcs *, current_vmcs); // &#x6BCF;&#x4E2A;CPU&#x6838;&#x5FC3;&#x7684;&#x5F53;&#x524D;VMCS&#x6307;&#x9488;

struct vmcs_host_state {
	unsigned long cr3;   // &#x5BBF;&#x4E3B;&#x673A;&#x7684;CR3&#x5BC4;&#x5B58;&#x5668;&#x503C;&#xFF0C;&#x53EF;&#x80FD;&#x4E0E;&#x5B9E;&#x9645;&#x7684;CR3&#x4E0D;&#x540C;
	unsigned long cr4;   // &#x5BBF;&#x4E3B;&#x673A;&#x7684;CR4&#x5BC4;&#x5B58;&#x5668;&#x503C;&#xFF0C;&#x53EF;&#x80FD;&#x4E0E;&#x5B9E;&#x9645;&#x7684;CR4&#x4E0D;&#x540C;
	unsigned long gs_base; // GS&#x6BB5;&#x7684;&#x57FA;&#x5740;
	unsigned long fs_base; // FS&#x6BB5;&#x7684;&#x57FA;&#x5740;
	unsigned long rsp;     // &#x5BBF;&#x4E3B;&#x673A;&#x7684;&#x6808;&#x6307;&#x9488;

	u16           fs_sel, gs_sel, ldt_sel; // FS&#x3001;GS&#x548C;LDT&#x7684;&#x9009;&#x62E9;&#x5B50;
#ifdef CONFIG_X86_64
	u16           ds_sel, es_sel;         // DS&#x548C;ES&#x7684;&#x9009;&#x62E9;&#x5B50;&#xFF08;&#x4EC5;&#x5728;x86_64&#x4F53;&#x7CFB;&#x7ED3;&#x6784;&#x4E2D;&#xFF09;
#endif
};

struct vmcs_controls_shadow {
	u32 vm_entry;        // VM Entry&#x76F8;&#x5173;&#x7684;&#x63A7;&#x5236;&#x5B57;&#x6BB5;
	u32 vm_exit;         // VM Exit&#x76F8;&#x5173;&#x7684;&#x63A7;&#x5236;&#x5B57;&#x6BB5;
	u32 pin;             // &#x5904;&#x7406;&#x5668;&#x76F8;&#x5173;&#x7684;&#x63A7;&#x5236;&#x5B57;&#x6BB5;
	u32 exec;            // &#x6267;&#x884C;&#x63A7;&#x5236;&#x5B57;&#x6BB5;
	u32 secondary_exec;  // &#x8F85;&#x52A9;&#x6267;&#x884C;&#x63A7;&#x5236;&#x5B57;&#x6BB5;
	u64 tertiary_exec;   // &#x7B2C;&#x4E09;&#x7EA7;&#x6267;&#x884C;&#x63A7;&#x5236;&#x5B57;&#x6BB5;&#xFF08;&#x5982;&#x679C;&#x53EF;&#x7528;&#xFF09;
};

struct loaded_vmcs {
	struct vmcs *vmcs;        // &#x6307;&#x5411;&#x5F53;&#x524D;VMCS&#x7684;&#x6307;&#x9488;
	struct vmcs *shadow_vmcs; // &#x6307;&#x5411;&#x5F71;&#x5B50;VMCS&#x7684;&#x6307;&#x9488;&#xFF08;&#x7528;&#x4E8E;&#x5D4C;&#x5957;&#x865A;&#x62DF;&#x5316;&#xFF09;
	int cpu;                  // VMCS&#x6240;&#x5728;&#x7684;CPU&#x7F16;&#x53F7;&#xFF0C;&#x5982;&#x679C;&#x672A;&#x52A0;&#x8F7D;&#x5219;&#x4E3A;-1
	bool launched;            // &#x6307;&#x793A;VMCS&#x662F;&#x5426;&#x5DF2;&#x7ECF;&#x88AB;VMLAUNCH&#x6307;&#x4EE4;&#x542F;&#x52A8;
	bool nmi_known_unmasked;  // &#x6307;&#x793A;NMI&#xFF08;&#x975E;&#x5C4F;&#x853D;&#x4E2D;&#x65AD;&#xFF09;&#x662F;&#x5426;&#x5DF2;&#x77E5;&#x4E3A;&#x672A;&#x5C4F;&#x853D;
	bool hv_timer_soft_disabled; // &#x6307;&#x793A;&#x662F;&#x5426;&#x8F6F;&#x7981;&#x7528;&#x4E86;&#x865A;&#x62DF;&#x5316;&#x5B9A;&#x65F6;&#x5668;
	int soft_vnmi_blocked;    // &#x652F;&#x6301;&#x6CA1;&#x6709;vnmi&#x7684;CPU&#xFF0C;&#x8BB0;&#x5F55;vnmi&#x88AB;&#x8F6F;&#x5C4F;&#x853D;&#x7684;&#x72B6;&#x6001;
	ktime_t entry_time;       // &#x8BB0;&#x5F55;&#x8FDB;&#x5165;&#x865A;&#x62DF;&#x673A;&#x7684;&#x65F6;&#x95F4;&#x70B9;
	s64 vnmi_blocked_time;    // vnmi&#x88AB;&#x5C4F;&#x853D;&#x7684;&#x6301;&#x7EED;&#x65F6;&#x95F4;
	unsigned long *msr_bitmap; // &#x6307;&#x5411;MSR&#x4F4D;&#x56FE;&#x7684;&#x6307;&#x9488;
	struct list_head loaded_vmcss_on_cpu_link; // &#x94FE;&#x63A5;&#x5230;&#x540C;&#x4E00;CPU&#x4E0A;&#x7684;&#x5176;&#x4ED6;VMCS
	struct vmcs_host_state host_state; // &#x5BBF;&#x4E3B;&#x673A;&#x72B6;&#x6001;&#x7684;&#x7F13;&#x5B58;
	struct vmcs_controls_shadow controls_shadow; // &#x63A7;&#x5236;&#x5B57;&#x6BB5;&#x7684;&#x9634;&#x5F71;&#x526F;&#x672C;
};

</code></pre><h4 id="224-%E6%80%BB%E7%BB%93">2.2.4-&#x603B;&#x7ED3;</h4><p>&#x5177;&#x5907;VMX&#x7684;CPU&#x76F8;&#x6BD4;&#x5982;&#x5176;&#x4ED6;CPU&#x5177;&#x6709;&#x5982;&#x4E0B;&#x7279;&#x70B9;&#xFF1A;</p><ol><li>&#x865A;&#x62DF;&#x673A;&#x7684;&#x7CFB;&#x7EDF;&#x8C03;&#x7528;&#x662F;&#x76F4;&#x63A5;&#x9677;&#x5165;&#x7684;guest&#x5185;&#x6838;&#x7A7A;&#x95F4;&#xFF0C;&#x800C;&#x4E0D;&#x662F;host&#x7684;&#x5185;&#x6838;&#x7A7A;&#x95F4;&#x3002;</li><li>&#x5916;&#x90E8;&#x4E2D;&#x65AD;&#x7684;&#x5B9E;&#x9645;&#x5904;&#x7406;&#x4ECD;&#x6709;HOST&#x5185;&#x6838;&#x5B8C;&#x6210;&#xFF0C;&#x4F46;&#x662F;&#x63A5;&#x6536;&#x4E2D;&#x65AD;&#x5219;&#x662F;guest&#x5B9E;&#x73B0;&#xFF0C;guest&#x5B8C;&#x6210;&#x63A5;&#x6536;&#x540E;&#x8981;&#x9000;&#x51FA;&#x865A;&#x62DF;&#x673A;&#x4EA4;&#x7531;host&#x5185;&#x6838;&#x8FDB;&#x4E00;&#x6B65;&#x5904;&#x7406;&#x8D44;&#x6E90;&#x3002;&#xFF08;IO&#x900F;&#x4F20;&#x6280;&#x672F;&#x5219;&#x4F1A;&#x907F;&#x514D;&#x9000;&#x51FA;&#x865A;&#x62DF;&#x7684;&#x95EE;&#x9898;&#xFF09;</li><li>&#x53EA;&#x6709;&#x654F;&#x611F;&#x6307;&#x4EE4;&#x624D;&#x4F1A;&#x4ECE;<code>guest</code>&#x9677;&#x5165;<code>host</code>&#xFF0C;&#x7531;VMM&#x4EE3;&#x66FF;&#x865A;&#x62DF;&#x673A;&#x5B8C;&#x6210;&#x5177;&#x4F53;&#x64CD;&#x4F5C;&#x3002;</li></ol><h2 id="3%E3%80%81qemu%E3%80%81kvm%E3%80%81libvirt%E3%80%81virsh%E4%B9%8B%E9%97%B4%E7%9A%84%E5%85%B3%E7%B3%BB">3&#x3001;QEMU&#x3001;KVM&#x3001;libvirt&#x3001;virsh&#x4E4B;&#x95F4;&#x7684;&#x5173;&#x7CFB;</h2><h3 id="31-%E5%85%B7%E4%BD%93%E4%BB%8B%E7%BB%8D">3.1-&#x5177;&#x4F53;&#x4ECB;&#x7ECD;</h3><ol><li>qemu</li></ol><p>QEMU&#x662F;&#x4E00;&#x79CD;&#x5F00;&#x6E90;&#x7684;&#x673A;&#x5668;&#x6A21;&#x62DF;&#x5668;&#x548C;&#x865A;&#x62DF;&#x5316;&#x5668;&#x3002;&#x5B83;&#x53EF;&#x4EE5;&#x6A21;&#x62DF;&#x591A;&#x79CD;&#x786C;&#x4EF6;&#xFF0C;&#x4F7F;&#x5F97;&#x5B83;&#x53EF;&#x4EE5;&#x5728;&#x4E0D;&#x540C;&#x67B6;&#x6784;&#x4E0A;&#x8FD0;&#x884C;&#x5404;&#x79CD;&#x64CD;&#x4F5C;&#x7CFB;&#x7EDF;&#x3002;&#x5728;&#x4E0D;&#x4F7F;&#x7528;KVM&#x7684;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;QEMU&#x4F7F;&#x7528;&#x8F6F;&#x4EF6;&#x6A21;&#x62DF;&#x6765;&#x6267;&#x884C;&#x865A;&#x62DF;&#x673A;&#x4E2D;&#x7684;&#x6307;&#x4EE4;&#x3002;</p><ul><li><strong>QEMU&#xFF08;Quick Emulator&#xFF09;</strong> &#x662F;&#x4E00;&#x4E2A;&#x5F00;&#x6E90;&#x7684;&#x786C;&#x4EF6;&#x865A;&#x62DF;&#x5316;&#x4EA7;&#x54C1;&#xFF0C;&#x5B83;&#x53EF;&#x4EE5;&#x6A21;&#x62DF;&#x5404;&#x79CD;&#x786C;&#x4EF6;&#x5E73;&#x53F0;&#xFF0C;&#x5141;&#x8BB8;&#x7528;&#x6237;&#x5728;&#x4E00;&#x4E2A;&#x4E3B;&#x673A;&#x4E0A;&#x8FD0;&#x884C;&#x591A;&#x4E2A;&#x64CD;&#x4F5C;&#x7CFB;&#x7EDF;&#x3002;</li><li>QEMU&#x672C;&#x8EAB;&#x53EF;&#x4EE5;&#x63D0;&#x4F9B;&#x8F6F;&#x4EF6;&#x6A21;&#x62DF;&#x7684;&#x865A;&#x62DF;&#x5316;&#xFF0C;&#x4F46;&#x5F53;&#x7ED3;&#x5408;KVM&#x4F7F;&#x7528;&#x65F6;&#xFF0C;&#x53EF;&#x4EE5;&#x5229;&#x7528;&#x786C;&#x4EF6;&#x8F85;&#x52A9;&#xFF0C;&#x5927;&#x5927;&#x63D0;&#x9AD8;&#x865A;&#x62DF;&#x5316;&#x7684;&#x6027;&#x80FD;&#x3002;</li></ul><ol start="2"><li>KVM</li></ol><p>KVM&#x662F;Linux&#x5185;&#x6838;&#x7684;&#x4E00;&#x90E8;&#x5206;&#xFF0C;&#x5B83;&#x5229;&#x7528;&#x4E86;&#x786C;&#x4EF6;&#x8F85;&#x52A9;&#x865A;&#x62DF;&#x5316;&#x6280;&#x672F;&#xFF0C;&#x7279;&#x522B;&#x662F;Intel&#x7684;VT-x&#x6216;AMD&#x7684;AMD-V&#x3002;&#x5F53;&#x4E0E;QEMU&#x7ED3;&#x5408;&#x4F7F;&#x7528;&#x65F6;&#xFF0C;KVM&#x80FD;&#x591F;&#x63D0;&#x4F9B;&#x63A5;&#x8FD1;&#x539F;&#x751F;&#x7684;&#x6027;&#x80FD;&#xFF0C;&#x56E0;&#x4E3A;&#x5B83;&#x5141;&#x8BB8;&#x76F4;&#x63A5;&#x5728;&#x786C;&#x4EF6;&#x4E0A;&#x8FD0;&#x884C;&#x865A;&#x62DF;&#x673A;&#x7684;&#x4EE3;&#x7801;&#x3002;</p><ul><li><strong>KVM&#xFF08;Kernel-based Virtual Machine&#xFF09;</strong> &#x662F;&#x4E00;&#x4E2A;Linux&#x5185;&#x6838;&#x6A21;&#x5757;&#xFF0C;&#x5B83;&#x5C06;Linux&#x8F6C;&#x53D8;&#x4E3A;&#x4E00;&#x4E2A;&#x7C7B;&#x578B;1&#xFF08;&#x88F8;&#x673A;&#xFF09;&#x7684;&#x865A;&#x62DF;&#x673A;&#x76D1;&#x63A7;&#x5668;&#xFF08;Hypervisor&#xFF09;&#x3002;</li><li>KVM&#x4F9D;&#x8D56;&#x4E8E;&#x786C;&#x4EF6;&#x865A;&#x62DF;&#x5316;&#x7279;&#x6027;&#xFF08;&#x5982;Intel VT&#x6216;AMD-V&#xFF09;&#xFF0C;&#x63D0;&#x4F9B;&#x9AD8;&#x6548;&#x7684;&#x865A;&#x62DF;&#x5316;&#x89E3;&#x51B3;&#x65B9;&#x6848;&#x3002;</li><li>KVM&#x5141;&#x8BB8;QEMU&#x5229;&#x7528;&#x786C;&#x4EF6;&#x52A0;&#x901F;&#x529F;&#x80FD;&#xFF0C;&#x63D0;&#x9AD8;&#x5176;&#x865A;&#x62DF;&#x5316;&#x6027;&#x80FD;&#x3002;</li></ul><ol start="3"><li>libvirt</li></ol><ul><li><strong>libvirt</strong> &#x662F;&#x4E00;&#x4E2A;&#x5F00;&#x6E90;&#x7684;&#x865A;&#x62DF;&#x5316;API&#x5E93;&#xFF0C;&#x4E3A;&#x7BA1;&#x7406;&#x865A;&#x62DF;&#x5316;&#x5E73;&#x53F0;&#x63D0;&#x4F9B;&#x4E86;&#x4E00;&#x4E2A;&#x901A;&#x7528;&#x548C;&#x7A33;&#x5B9A;&#x7684;&#x5C42;&#x3002;</li><li>&#x5B83;&#x652F;&#x6301;&#x591A;&#x79CD;&#x865A;&#x62DF;&#x5316;&#x6280;&#x672F;&#xFF0C;&#x5305;&#x62EC;KVM&#x3001;QEMU&#x3001;Xen&#x7B49;&#x3002;</li><li>libvirt&#x63D0;&#x4F9B;&#x4E86;&#x4E00;&#x5957;&#x7EDF;&#x4E00;&#x7684;API&#x6765;&#x7BA1;&#x7406;&#x865A;&#x62DF;&#x673A;&#x548C;&#x5176;&#x4ED6;&#x865A;&#x62DF;&#x5316;&#x8D44;&#x6E90;&#xFF0C;&#x4F7F;&#x5F97;&#x7BA1;&#x7406;&#x5458;&#x53EF;&#x4EE5;&#x900F;&#x8FC7;&#x7EDF;&#x4E00;&#x7684;&#x63A5;&#x53E3;&#x8FDB;&#x884C;&#x865A;&#x62DF;&#x673A;&#x7684;&#x90E8;&#x7F72;&#x3001;&#x76D1;&#x63A7;&#x548C;&#x7BA1;&#x7406;&#x3002;</li></ul><ol start="4"><li>virsh</li></ol><ul><li><strong>virsh&#xFF08;Virtualization Shell&#xFF09;</strong> &#x662F;&#x4E00;&#x4E2A;&#x57FA;&#x4E8E;&#x547D;&#x4EE4;&#x884C;&#x7684;&#x5DE5;&#x5177;&#xFF0C;&#x7528;&#x4E8E;&#x4F7F;&#x7528;libvirt&#x5E93;&#x6765;&#x7BA1;&#x7406;&#x865A;&#x62DF;&#x673A;&#x548C;&#x5176;&#x4ED6;&#x865A;&#x62DF;&#x5316;&#x8D44;&#x6E90;&#x3002;</li><li>virsh&#x5141;&#x8BB8;&#x7528;&#x6237;&#x6267;&#x884C;&#x5404;&#x79CD;&#x865A;&#x62DF;&#x5316;&#x76F8;&#x5173;&#x7684;&#x4EFB;&#x52A1;&#xFF0C;&#x5982;&#x521B;&#x5EFA;&#x3001;&#x4FEE;&#x6539;&#x3001;&#x542F;&#x52A8;&#x548C;&#x505C;&#x6B62;&#x865A;&#x62DF;&#x673A;&#x3002;</li><li>&#x5B83;&#x662F;&#x4E00;&#x4E2A;&#x4E0E;libvirt&#x4EA4;&#x4E92;&#x7684;&#x524D;&#x7AEF;&#x5DE5;&#x5177;&#xFF0C;&#x4E3A;&#x7528;&#x6237;&#x63D0;&#x4F9B;&#x4E86;&#x4E00;&#x4E2A;&#x7B80;&#x5355;&#x4F46;&#x529F;&#x80FD;&#x5F3A;&#x5927;&#x7684;&#x65B9;&#x5F0F;&#x6765;&#x7BA1;&#x7406;&#x865A;&#x62DF;&#x5316;&#x73AF;&#x5883;&#x3002;</li></ul><h3 id="32-%E6%80%BB%E7%BB%93">3.2 &#x603B;&#x7ED3;</h3><p>KVM&#x662F;&#x96C6;&#x6210;&#x5728;linux kernel&#x4E2D;&#x7684;&#x4E00;&#x90E8;&#x5206;&#xFF0C;&#x4ED6;&#x63D0;&#x4F9B;&#x51FA;&#x4E86;&#x4E00;&#x4E9B;&#x7528;&#x6237;&#x6001;&#x7684;&#x63A5;&#x53E3;<code>/dev/kvm</code>&#x6765;&#x4F9B;&#x7528;&#x6237;&#x6001;&#x7684;&#x8FDB;&#x7A0B;&#x7BA1;&#x7406;&#x865A;&#x62DF;&#x673A;&#xFF0C;&#x4F46;&#x662F;&#x5176;&#x672C;&#x8EAB;&#x662F;&#x4E0D;&#x5177;&#x5907;&#x865A;&#x62DF;&#x673A;&#x6A21;&#x62DF;&#x7684;&#x80FD;&#x529B;&#x7684;&#xFF0C;&#x56E0;&#x6B64;&#x5185;&#x6838;&#x57FA;&#x4E8E;qemu&#x5F00;&#x53D1;&#x51FA;&#x4E86;&#x4E00;&#x5957;&#x9002;&#x914D;kvm&#x7684;&#x5DE5;&#x5177;&#xFF0C;&#x4E5F;&#x5C31;&#x662F;kvm-qemu&#xFF0C;&#x901A;&#x8FC7;&#x6807;&#x51C6;&#x7684;&#x6587;&#x4EF6;&#x64CD;&#x4F5C;&#x4F8B;&#x5982;<code>open</code>&#x3001;<code>write</code>&#x3001;<code>ioctl</code>&#x7B49;&#x8C03;&#x7528;&#x5185;&#x6838;&#x7684;<code>KVM</code>&#x63A5;&#x53E3;&#x3002;&#x6240;&#x4EE5;&#x53EF;&#x4EE5;&#x770B;&#x505A;qemu&#x662F;&#x662F;&#x865A;&#x62DF;&#x673A;&#x7684;&#x7528;&#x6237;&#x6001;&#x5DE5;&#x5177;&#xFF0C;&#x800C;qemu&#x5728;CPU&#x4E0E;&#x5185;&#x5B58;&#x865A;&#x62DF;&#x5316;&#x90E8;&#x5206;&#x4F9D;&#x8D56;KVM&#x57FA;&#x4E8E;CPU&#x5E73;&#x53F0;&#x786C;&#x4EF6;&#x865A;&#x62DF;&#x5316;&#x6240;&#x66B4;&#x9732;&#x51FA;&#x6765;&#x7684;&#x63A5;&#x53E3;&#x3002;</p><p>&#x53E6;&#x5916;KVM&#x53EA;&#x63D0;&#x4F9B;&#x4E86;&#x5185;&#x5B58;&#x548C;CPU&#x7684;&#x865A;&#x62DF;&#x5316;&#x80FD;&#x529B;&#xFF0C;&#x6240;&#x4EE5;&#x4E3A;&#x4E86;&#x5B9E;&#x73B0;&#x4E00;&#x4E2A;&#x53EF;&#x7528;&#x7684;&#x8BA1;&#x7B97;&#x673A;&#x7CFB;&#x7EDF;&#xFF0C;&#x8FD8;&#x9700;&#x8981;IO&#x5916;&#x8BBE;&#xFF0C;&#x4F8B;&#x5982;&#x7F51;&#x5361;&#x548C;&#x786C;&#x76D8;&#xFF0C;&#x8FD9;&#x90E8;&#x5206;&#x80FD;&#x529B;&#x5219;&#x9700;&#x8981;&#x7531;qemu&#x63D0;&#x4F9B;&#x3002;</p><p>&#x800C;libvirt&#x5219;&#x662F;&#x7528;&#x6765;&#x7EDF;&#x4E00;&#x5404;&#x4E2A;&#x865A;&#x62DF;&#x5316;&#x63A5;&#x53E3;&#x7684;&#x5E93;&#xFF0C;virsh&#x5219;&#x662F;libvirt&#x7684;&#x547D;&#x4EE4;&#x884C;&#x5DE5;&#x5177;&#xFF0C;&#x5373;&#x6211;&#x4EEC;&#x5728;&#x547D;&#x4EE4;&#x884C;&#x4E2D;&#x6267;&#x884C;&#x7684;&#x4E0B;&#x4EE4;&#x547D;&#x4EE4;</p><pre><code class="language-bash">virsh list 
virsh create xxx
</code></pre><h2 id="4%E3%80%81%E6%80%BB%E7%BB%93">4&#x3001;&#x603B;&#x7ED3;</h2><p>&#x865A;&#x62DF;&#x5316;&#x6280;&#x672F;&#xFF0C;&#x5728;&#x7279;&#x522B;&#x662F;CPU&#x865A;&#x62DF;&#x5316;&#x9886;&#x57DF;&#xFF0C;&#x5DF2;&#x7ECF;&#x6210;&#x4E3A;&#x73B0;&#x4EE3;&#x8BA1;&#x7B97;&#x67B6;&#x6784;&#x7684;&#x4E00;&#x4E2A;&#x57FA;&#x77F3;&#x3002;&#x4ECE;&#x65E9;&#x671F;&#x7684;&#x8F6F;&#x4EF6;&#x6A21;&#x62DF;&#x5230;&#x73B0;&#x5728;&#x7684;&#x786C;&#x4EF6;&#x8F85;&#x52A9;&#x865A;&#x62DF;&#x5316;&#xFF0C;&#x5B83;&#x4E0D;&#x65AD;&#x8FDB;&#x5316;&#xFF0C;&#x63D0;&#x9AD8;&#x4E86;&#x6548;&#x7387;&#x548C;&#x5B89;&#x5168;&#x6027;&#x3002;&#x901A;&#x8FC7;&#x50CF;QEMU&#x548C;KVM&#x8FD9;&#x6837;&#x7684;&#x5DE5;&#x5177;&#xFF0C;&#x6211;&#x4EEC;&#x53EF;&#x4EE5;&#x8F7B;&#x677E;&#x5730;&#x5728;&#x5355;&#x4E2A;&#x7269;&#x7406;&#x673A;&#x5668;&#x4E0A;&#x8FD0;&#x884C;&#x591A;&#x4E2A;&#x64CD;&#x4F5C;&#x7CFB;&#x7EDF;&#x5B9E;&#x4F8B;&#xFF0C;&#x6781;&#x5927;&#x5730;&#x63D0;&#x9AD8;&#x4E86;&#x8D44;&#x6E90;&#x7684;&#x5229;&#x7528;&#x7387;&#x548C;&#x7075;&#x6D3B;&#x6027;&#x3002;</p><p>&#x968F;&#x7740;&#x6280;&#x672F;&#x7684;&#x4E0D;&#x65AD;&#x53D1;&#x5C55;&#xFF0C;&#x6211;&#x4EEC;&#x53EF;&#x4EE5;&#x671F;&#x5F85;&#x865A;&#x62DF;&#x5316;&#x6280;&#x672F;&#x5728;&#x6027;&#x80FD;&#x3001;&#x5B89;&#x5168;&#x6027;&#x548C;&#x6613;&#x7528;&#x6027;&#x65B9;&#x9762;&#x7684;&#x8FDB;&#x4E00;&#x6B65;&#x63D0;&#x5347;&#xFF0C;&#x4E3A;&#x672A;&#x6765;&#x7684;&#x8BA1;&#x7B97;&#x6A21;&#x5F0F;&#x94FA;&#x5E73;&#x9053;&#x8DEF;&#x3002;</p>]]></content:encoded></item><item><title><![CDATA[ghost配置总结]]></title><description><![CDATA[<p>[TOC]</p>
<h2 id="1%E3%80%81%E9%85%8D%E7%BD%AE%E5%AE%89%E8%A3%85">1&#x3001;&#x914D;&#x7F6E;&#x5B89;&#x88C5;</h2>
<p>&#x817E;&#x8BAF;&#x4E91;&#x6307;&#x5F15;&#x6587;&#x6863;&#xFF1A;<a href="https://cloud.tencent.com/document/product/213/38620?ref=korantli.com.cn">&#x624B;&#x52A8;&#x642D;&#x5EFA; Ghost &#x535A;&#x5BA2;</a></p>
<h2 id="2%E3%80%81post%E9%85%8D%E7%BD%AE%E8%AF%84%E8%AE%BA%E5%8C%BA">2&#x3001;post&#x914D;&#x7F6E;&#x8BC4;&#x8BBA;&#x533A;</h2>
<p>&#x5B98;&#x65B9;&#x6307;&#x5F15;&#xFF1A;<a href="https://ghost.org/integrations/disqus/?ref=korantli.com.cn">Disqus + Ghost</a></p>
<ol>
<li>
<p>&#x9996;&#x5148;&#x6CE8;&#x518C;<code>Disqus</code>&#x8D26;&#x53F7;&#xFF1A;<a href="https://disqus.com/profile/signup/?ref=korantli.com.cn">Disqus sign up</a></p>
</li>
<li>
<p>&#x7136;&#x540E;</p></li></ol>]]></description><link>http://www.korantli.com.cn/ghostpei-zhi-zong-jie/</link><guid isPermaLink="false">65810c2ed6a33a3b4ceabd19</guid><dc:creator><![CDATA[李星辉]]></dc:creator><pubDate>Tue, 19 Dec 2023 03:22:53 GMT</pubDate><media:content url="http://www.korantli.com.cn/content/images/2023/12/ghost.png" medium="image"/><content:encoded><![CDATA[<img src="http://www.korantli.com.cn/content/images/2023/12/ghost.png" alt="ghost&#x914D;&#x7F6E;&#x603B;&#x7ED3;"><p>[TOC]</p>
<h2 id="1%E3%80%81%E9%85%8D%E7%BD%AE%E5%AE%89%E8%A3%85">1&#x3001;&#x914D;&#x7F6E;&#x5B89;&#x88C5;</h2>
<p>&#x817E;&#x8BAF;&#x4E91;&#x6307;&#x5F15;&#x6587;&#x6863;&#xFF1A;<a href="https://cloud.tencent.com/document/product/213/38620?ref=korantli.com.cn">&#x624B;&#x52A8;&#x642D;&#x5EFA; Ghost &#x535A;&#x5BA2;</a></p>
<h2 id="2%E3%80%81post%E9%85%8D%E7%BD%AE%E8%AF%84%E8%AE%BA%E5%8C%BA">2&#x3001;post&#x914D;&#x7F6E;&#x8BC4;&#x8BBA;&#x533A;</h2>
<p>&#x5B98;&#x65B9;&#x6307;&#x5F15;&#xFF1A;<a href="https://ghost.org/integrations/disqus/?ref=korantli.com.cn">Disqus + Ghost</a></p>
<ol>
<li>
<p>&#x9996;&#x5148;&#x6CE8;&#x518C;<code>Disqus</code>&#x8D26;&#x53F7;&#xFF1A;<a href="https://disqus.com/profile/signup/?ref=korantli.com.cn">Disqus sign up</a></p>
</li>
<li>
<p>&#x7136;&#x540E;&#x9009;&#x62E9;<code>comment on my site</code></p>
</li>
<li>
<p>&#x914D;&#x7F6E;<code>shortname</code>&#xFF0C;&#x628A;<code>shortname</code>&#x914D;&#x7F6E;&#x5230;<code>/var/www/ghost/content/themes/[CurrentTheme]/post.hbs</code>&#x4E2D;&#x7684;<code>EXAPLE</code>&#x5B57;&#x6BB5;</p>
</li>
</ol>
<pre><code class="language-xml">        &lt;section class=&quot;article-comments gh-canvas&quot;&gt;
            &lt;div id=&quot;disqus_thread&quot;&gt;&lt;/div&gt;
            &lt;script&gt;
                var disqus_config = function () {
                    this.page.url = &quot;{{url absolute=&quot;true&quot;}}&quot;;
                    this.page.identifier = &quot;ghost-{{comment_id}}&quot;
                };
                (function() {
                var d = document, s = d.createElement(&apos;script&apos;);
                s.src = &apos;https://EXAPLE.disqus.com/embed.js&apos;;
                s.setAttribute(&apos;data-timestamp&apos;, +new Date());
                (d.head || d.body).appendChild(s);
                })();
            &lt;/script&gt;
        &lt;/section&gt;
</code></pre>
<ol start="4">
<li>&#x91CD;&#x542F;ghost</li>
</ol>
<pre><code class="language-bash">ghost restart
</code></pre>
<h2 id="3%E3%80%81%E9%85%8D%E7%BD%AEpost%E6%8E%92%E5%BA%8F">3&#x3001;&#x914D;&#x7F6E;post&#x6392;&#x5E8F;</h2>
<ol>
<li>
<p>&#x6784;&#x5EFA;<code>collection</code>&#xFF1A;</p>
<p>&#x5B98;&#x65B9;&#x6307;&#x5F15;&#xFF1A;<a href="https://ghost.org/tutorials/content-collections/?ref=korantli.com.cn#define-a-content-collection-with-tags">Building content collections</a></p>
</li>
<li>
<p>&#x4FEE;&#x6539;&#x6392;&#x5E8F;&#xFF1A;</p>
<p>&#x5B98;&#x65B9;&#x6307;&#x5F15;&#xFF1A;<a href="https://ghost.org/tutorials/change-post-order/?ref=korantli.com.cn#define-a-custom-route">Define a custom route</a></p>
</li>
</ol>
<h2 id="4%E3%80%81%E5%8D%87%E7%BA%A7ghost%E7%89%88%E6%9C%AC">4&#x3001;&#x5347;&#x7EA7;ghost&#x7248;&#x672C;</h2>
<p>&#x5B98;&#x65B9;&#x6587;&#x6863;&#xFF1A;<a href="https://ghost.org/docs/faq/node-versions/?ref=korantli.com.cn">Supported Node versions</a></p>
<ol>
<li>&#x5207;&#x6362;&#x5230;&#x521B;&#x5EFA;ghost&#x7684;&#x7528;&#x6237;</li>
</ol>
<pre><code class="language-bash">su user
</code></pre>
<ol start="2">
<li>&#x8FDB;&#x5165;&#x5230;ghost&#x76EE;&#x5F55;&#xFF0C;&#x6267;&#x884C;&#x5347;&#x7EA7;</li>
</ol>
<pre><code class="language-bash">cd /var/www/ghost
ghost update
</code></pre>
<ol start="3">
<li>&#x4F46;&#x662F;&#x6CE8;&#x610F;&#xFF0C;&#x7531;&#x4E8E;<code>ghost</code>&#x9700;&#x8981;<code>node.js</code>&#x652F;&#x6301;&#xFF0C;&#x6240;&#x6709;&#x5347;&#x7EA7;<code>ghost</code>&#x7684;&#x540C;&#x65F6;&#x4E5F;&#x53EF;&#x80FD;&#x9700;&#x8981;&#x5347;&#x7EA7;<code>node</code>&#xFF0C;&#x5347;&#x7EA7;&#x8FC7;&#x7A0B;&#x4E2D;&#x6CE8;&#x610F;&#x53C2;&#x8003;&#x5B98;&#x65B9;&#x6587;&#x6863;&#x3002;</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[inux中断-硬中断]]></title><description><![CDATA[<h2 id="0%E3%80%81%E5%89%8D%E8%A8%80">0&#x3001;&#x524D;&#x8A00;</h2>
<p>&#x4E2D;&#x65AD;&#x5B50;&#x7CFB;&#x7EDF;&#x6709;&#x4E00;&#x6B21;&#x5927;&#x6539;&#x9020;&#xFF0C;&#x5148;mark&#x4E00;&#x4E0B;</p>
<p><a href="https://lore.kernel.org/all/20200521200513.656533920@linutronix.de/?ref=korantli.com.cn">https://lore.kernel.org/all/20200521200513.656533920@linutronix.de/</a></p>
<p>arm64&#x53C2;&#x8003;&#xFF1A;<a href="https://zhuanlan.zhihu.com/p/482668070?ref=korantli.com.cn">Linux &#x4E2D;&#x65AD;&#x7BA1;&#x7406;&#x673A;&#x5236;</a></p>
<h2 id="1%E3%80%81%E6%A6%82%E8%BF%B0">1&#x3001;&#x6982;&#x8FF0;</h2>
<p>&#x5E7F;&#x4E49;&#x4E0A;&#x7684;&#x4E2D;&#x65AD;</p>]]></description><link>http://www.korantli.com.cn/inuxzhong-duan-ying-zhong-duan/</link><guid isPermaLink="false">6690d9c72bc2afda5bd2ed28</guid><category><![CDATA[linux内核特性]]></category><dc:creator><![CDATA[李星辉]]></dc:creator><pubDate>Fri, 12 Jul 2024 07:24:27 GMT</pubDate><content:encoded><![CDATA[<h2 id="0%E3%80%81%E5%89%8D%E8%A8%80">0&#x3001;&#x524D;&#x8A00;</h2>
<p>&#x4E2D;&#x65AD;&#x5B50;&#x7CFB;&#x7EDF;&#x6709;&#x4E00;&#x6B21;&#x5927;&#x6539;&#x9020;&#xFF0C;&#x5148;mark&#x4E00;&#x4E0B;</p>
<p><a href="https://lore.kernel.org/all/20200521200513.656533920@linutronix.de/?ref=korantli.com.cn">https://lore.kernel.org/all/20200521200513.656533920@linutronix.de/</a></p>
<p>arm64&#x53C2;&#x8003;&#xFF1A;<a href="https://zhuanlan.zhihu.com/p/482668070?ref=korantli.com.cn">Linux &#x4E2D;&#x65AD;&#x7BA1;&#x7406;&#x673A;&#x5236;</a></p>
<h2 id="1%E3%80%81%E6%A6%82%E8%BF%B0">1&#x3001;&#x6982;&#x8FF0;</h2>
<p>&#x5E7F;&#x4E49;&#x4E0A;&#x7684;&#x4E2D;&#x65AD;&#x4E3B;&#x8981;&#x5206;&#x4E3A;&#x540C;&#x6B65;&#x4E2D;&#x65AD;&#x548C;&#x5F02;&#x6B65;&#x4E2D;&#x65AD;&#x4E24;&#x79CD;</p>
<ul>
<li>&#x540C;&#x6B65;&#xFF08;synchronous&#xFF09;&#x4E2D;&#x65AD;&#xFF1A;&#x5F53;&#x6307;&#x4EE4;&#x6267;&#x884C;&#x65F6;&#x7531;CPU&#x63A7;&#x5236;&#x5355;&#x5143;&#x4EA7;&#x751F;&#x7684;&#x3002;</li>
<li>&#x5F02;&#x6B65;&#xFF08;asynchronous&#xFF09;&#x4E2D;&#x65AD;&#xFF1A;&#x7531;&#x5176;&#x4ED6;&#x786C;&#x4EF6;&#x8BBE;&#x5907;&#x4F9D;&#x7167;CPU&#x65F6;&#x949F;&#x4FE1;&#x53F7;&#x968F;&#x673A;&#x4EA7;&#x751F;&#x7684;&#x3002;</li>
</ul>
<p>&#x5728;x86&#x548C;arm&#x4E2D;&#xFF0C;&#x5176;&#x5B9E;&#x540C;&#x6B65;&#x4E2D;&#x65AD;&#x5C31;&#x662F;&#x5F02;&#x5E38;&#xFF0C;&#x800C;&#x5F02;&#x6B65;&#x4E2D;&#x65AD;&#x5219;&#x662F;&#x6211;&#x4EEC;&#x5E38;&#x8BF4;&#x7684;&#x4E2D;&#x65AD;&#xFF08;interrupt&#xFF09;&#x3002;&#x800C;&#x6211;&#x4EEC;&#x672C;&#x6587;&#x4E2D;&#x4E3B;&#x8981;&#x8BA8;&#x8BBA;&#x7684;&#x5C31;&#x662F;&#x540E;&#x8005;&#xFF0C;&#x5F02;&#x6B65;&#x4E2D;&#x65AD;&#x3002;</p>
<p>&#x4E5F;&#x53EF;&#x4EE5;&#x7406;&#x89E3;&#x4E3A;&#x5F02;&#x6B65;&#x4E2D;&#x65AD;&#x662F;&#x7531;&#x4E2D;&#x65AD;&#x63A7;&#x5236;&#x5668;&#x5904;&#x7406;&#x7684;&#xFF0C;arm&#x4E0A;&#x662F;GIC&#xFF08;Generic Interrupt Controller&#xFF09;&#xFF0C;&#x800C;x86&#x4E0A;&#x53EB;&#x505A;APIC&#xFF08;Advanced Programmable Interrupt Controllers&#xFF09;&#xFF0C;&#x800C;&#x5F02;&#x6B65;&#x4E2D;&#x65AD;&#x5219;&#x662F;&#x5728;CPU&#x5185;&#x5B8C;&#x6210;&#x7684;</p>
<h2 id="2%E3%80%81%E7%A1%AC%E4%BB%B6%E4%B8%AD%E6%96%AD">2&#x3001;&#x786C;&#x4EF6;&#x4E2D;&#x65AD;</h2>
<p>&#x4E2A;&#x4EBA;&#x7406;&#x89E3;&#x8BA4;&#x4E3A;&#xFF0C;&#x5F02;&#x6B65;&#x4E2D;&#x65AD;&#x5C31;&#x662F;&#x6211;&#x4EEC;&#x5E38;&#x63D0;&#x5230;&#x7684;&#x786C;&#x4E2D;&#x65AD;&#xFF0C;&#x7531;&#x5916;&#x8BBE;&#x4EA7;&#x751F;&#x7684;&#x4E2D;&#x65AD;&#x4FE1;&#x53F7;&#xFF0C;&#x7ECF;&#x7531;&#x4E2D;&#x65AD;&#x63A7;&#x5236;&#x5668;&#x4EA4;&#x7531;&#x5BF9;&#x5E94;&#x7684;CPU&#x8FDB;&#x884C;&#x5904;&#x7406;&#x3002;</p>
<p>&#x800C;&#x5728;linux&#x4E2D;&#xFF0C;&#x6211;&#x4EEC;&#x53C8;&#x53EF;&#x4EE5;&#x5C06;&#x786C;&#x4EF6;&#x4E2D;&#x65AD;&#xFF08;&#x5F02;&#x6B65;&#x4E2D;&#x65AD;&#xFF09;&#x5206;&#x4E3A;&#x5982;&#x4E0B;&#x5982;&#x4E0B;&#x4E24;&#x7C7B;&#xFF1A;</p>
<ul>
<li>&#x53EF;&#x5C4F;&#x853D;&#x4E2D;&#x65AD;&#xFF1A;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x8BBE;&#x7F6E;eflags&#x5BC4;&#x5B58;&#x5668;&#x7684;IF&#x6807;&#x5FD7;&#x6765;&#x5C4F;&#x853D;&#x5BF9;&#x5E94;CPU&#x7684;&#x4E2D;&#x65AD;&#xFF0C;<code>sti</code>&#x5F00;&#x542F;&#x4E2D;&#x65AD;&#xFF0C;<code>cli</code>&#x5C4F;&#x853D;&#x4E2D;&#x65AD;&#x3002;
<ul>
<li>&#x666E;&#x901A;&#x786C;&#x4EF6;&#x4E2D;&#x65AD;&#xFF1A;&#x4F8B;&#x5982;I/O&#x8BBE;&#x5907;&#x5B8C;&#x6210;&#x6570;&#x636E;&#x4F20;&#x8F93;&#x3001;&#x5B9A;&#x65F6;&#x5668;&#x5230;&#x671F;&#x7B49;&#x3002;</li>
<li>&#x6838;&#x95F4;&#x4E2D;&#x65AD;&#xFF1A;&#x7528;&#x4E8E;&#x5728;&#x591A;&#x6838;&#x5904;&#x7406;&#x5668;&#x7CFB;&#x7EDF;&#x4E2D;&#x5B9E;&#x73B0;&#x6838;&#x95F4;&#x901A;&#x4FE1;&#x3002;&#x5B83;&#x4EEC;&#x901A;&#x5E38;&#x7528;&#x4E8E;&#x5904;&#x7406;&#x8FDB;&#x7A0B;&#x8C03;&#x5EA6;&#x3001;&#x8FDB;&#x7A0B;&#x8FC1;&#x79FB;&#x7B49;&#x4EFB;&#x52A1;&#x3002;</li>
</ul>
</li>
<li>&#x4E0D;&#x53EF;&#x5C4F;&#x853D;&#x4E2D;&#x65AD;&#xFF1A;NMI&#x901A;&#x5E38;&#x7528;&#x4E8E;&#x5904;&#x7406;&#x5173;&#x952E;&#x9519;&#x8BEF;&#x548C;&#x7D27;&#x6025;&#x4EFB;&#x52A1;&#xFF0C;&#x5982;&#x786C;&#x4EF6;&#x6545;&#x969C;&#x3001;&#x7CFB;&#x7EDF;&#x5D29;&#x6E83;&#x7B49;&#xFF0C;&#x9700;&#x8981;&#x7ACB;&#x5373;&#x5F97;&#x5230;&#x5904;&#x7406;&#xFF0C;&#x5370;&#x8C61;&#x4E2D;&#x5F88;&#x591A;BMC&#x53D1;&#x8FC7;&#x6765;&#x7684;&#x4E2D;&#x65AD;&#x90FD;&#x662F;&#x4E0D;&#x53EF;&#x5C4F;&#x853D;&#x4E2D;&#x65AD;&#x3002;</li>
</ul>
<h2 id="3-%E4%B8%AD%E6%96%AD%E6%8E%A7%E5%88%B6%E5%99%A8">3-&#x4E2D;&#x65AD;&#x63A7;&#x5236;&#x5668;</h2>
<h3 id="31-apic%EF%BC%88x86%EF%BC%89">3.1-APIC&#xFF08;x86&#xFF09;</h3>
<p>&#x53EF;&#x4EE5;&#x53C2;&#x8003;&#xFF1A;<a href="https://www.cnblogs.com/wsg1100/p/14055863.html?ref=korantli.com.cn#2-%E9%AB%98%E7%BA%A7%E5%8F%AF%E7%BC%96%E7%A8%8B%E4%B8%AD%E6%96%AD%E6%8E%A7%E5%88%B6%E5%99%A8apic">&#x9AD8;&#x7EA7;&#x53EF;&#x7F16;&#x7A0B;&#x4E2D;&#x65AD;&#x63A7;&#x5236;&#x5668;&#xFF08;APIC&#xFF09;</a></p>
<p>&#x73B0;&#x4EE3;SMP&#x67B6;&#x6784;&#x7684;&#x5904;&#x7406;&#x5668;&#x7684;APIC&#x7531;&#x4E24;&#x90E8;&#x5206;&#x7EC4;&#x6210;&#xFF0C;&#x4E00;&#x4E2A;&#x662F;local APIC&#xFF0C;&#x4E00;&#x4E2A;&#x662F;I/O APIC&#x3002;&#x5176;&#x4E2D;local-APIC&#x662F;&#x5B58;&#x5728;&#x4E8E;CPU&#x5185;&#x7684;&#xFF0C;&#x5916;&#x90E8;&#x7684;&#x4E2D;&#x65AD;&#x8BBE;&#x5907;&#x901A;&#x5E38;&#x662F;&#x901A;&#x8FC7;I/O APIC&#x8BBE;&#x5907;&#xFF0C;&#x8F6C;&#x53D1;&#x7ED9;&#x5BF9;&#x5E94;&#x7684;local APIC&#x3002;</p>
<p><img src="http://www.korantli.com.cn/content/images/2024/07/image-20240124193223874.png" alt="image-20240124193223874.png" loading="lazy"></p>
<p>&#x901A;&#x5E38;&#x6765;&#x8BF4;LAPIC &#x4E3B;&#x8981;&#x5904;&#x7406;&#x4EE5;&#x4E0B;&#x4E2D;&#x65AD;&#xFF1A;</p>
<ul>
<li>APIC Timer &#x4EA7;&#x751F;&#x7684;&#x4E2D;&#x65AD;(APIC timer generated interrupts)</li>
<li>Performance Monitoring Counter &#x5728; overflow &#x65F6;&#x4EA7;&#x751F;&#x7684;&#x4E2D;&#x65AD;(Performance monitoring counter interrupts)</li>
<li>&#x6E29;&#x5EA6;&#x4F20;&#x611F;&#x5668;&#x4EA7;&#x751F;&#x7684;&#x4E2D;&#x65AD;(Thermal Sensor interrupts)</li>
<li>LAPIC &#x5185;&#x90E8;&#x9519;&#x8BEF;&#x65F6;&#x4EA7;&#x751F;&#x7684;&#x4E2D;&#x65AD;(APIC internal error interrupts)</li>
<li>&#x672C;&#x5730;&#x76F4;&#x8FDE; IO &#x8BBE;&#x5907; (Locally connected I/O devices) &#x901A;&#x8FC7; LINT0 &#x548C; LINT1 &#x5F15;&#x811A;&#x53D1;&#x6765;&#x7684;&#x4E2D;&#x65AD;</li>
<li>&#x5176;&#x4ED6; CPU (&#x751A;&#x81F3;&#x662F;&#x81EA;&#x5DF1;&#xFF0C;&#x79F0;&#x4E3A; self-interrupt)&#x53D1;&#x6765;&#x7684; IPI(Inter-processor interrupts)</li>
<li>IOAPIC &#x53D1;&#x6765;&#x7684;&#x4E2D;&#x65AD;</li>
</ul>
<p>&#x800C;IOAPIC (I/O Advanced Programmable Interrupt Controller) &#x5C5E;&#x4E8E;Intel&#x82AF;&#x7247;&#x7EC4;&#x7684;&#x4E00;&#x90E8;&#x5206;&#x3002;&#x4ED6;&#x8D1F;&#x8D23;&#x8FDE;&#x63A5;&#x5916;&#x90E8;&#x7684;I\O&#x8BBE;&#x5907;&#xFF0C;&#x8D1F;&#x8D23;&#x63A5;&#x6536;&#x5176;&#x53D1;&#x6765;&#x7684;&#x5916;&#x90E8;&#x4E2D;&#x65AD;&#xFF0C;&#x901A;&#x5E38;IOAPIC &#x6709; 24 &#x4E2A; input &#x7BA1;&#x811A;(INTIN0~INTIN23)&#xFF0C;&#x6CA1;&#x6709;&#x4F18;&#x5148;&#x7EA7;&#x4E4B;&#x5206;&#x3002;</p>
<h4 id="311-apic%E9%A9%B1%E5%8A%A8">3.1.1-APIC&#x9A71;&#x52A8;</h4>
<p>x86&#x5E73;&#x53F0;&#x7684;APIC&#x9A71;&#x52A8;&#x4E3B;&#x8981;&#x653E;&#x5728;<code>arch/x86/kernel/apic/</code>&#x4E2D;</p>
<h3 id="32-gic%EF%BC%88arm64%EF%BC%89">3.2-GIC&#xFF08;ARM64&#xFF09;</h3>
<p>&#x5BF9;&#x4E8E;ARM64&#x6765;&#x8BF4;&#xFF0C;&#x4E2D;&#x65AD;&#x63A7;&#x5236;&#x5668;&#x88AB;&#x53EB;&#x505A;<code>GIC&#xFF08;Generic Interrupt Controller&#xFF09;</code>&#x3002;</p>
<p>GIC&#x7684;&#x6574;&#x4F53;&#x529F;&#x80FD;&#x4E0E;APIC&#x7C7B;&#x4F3C;&#xFF0C;&#x4F46;&#x662F;&#x5BF9;&#x4E8E;GIC&#x6765;&#x8BF4;&#xFF0C;&#x662F;&#x4E0D;&#x5B58;&#x5728;<code>IDT</code>&#x8FD9;&#x4E2A;&#x6982;&#x5FF5;&#x7684;&#xFF0C;ARM64&#x4E3B;&#x8981;&#x901A;&#x8FC7;<code>&#x5F02;&#x5E38;&#x5411;&#x91CF;&#x8868;</code>&#x6765;&#x5B9E;&#x73B0;&#x4E2D;&#x65AD;&#x5904;&#x7406;&#x51FD;&#x6570;&#x7684;&#x5904;&#x7406;&#x3002;&#x5728;GICv3&#xFF08;&#x8FD8;&#x6CA1;&#x89C1;&#x8FC7;&#x4F7F;&#x7528;GICv4&#x7684;soc&#xFF09;&#x4E2D;&#x4E2D;&#x65AD;&#x4E3B;&#x8981;&#x5206;&#x4E3A;&#x5982;&#x4E0B;&#x51E0;&#x79CD;</p>
<ul>
<li>
<p>SGI (Software Generated Interrupt)&#xFF1A;</p>
<p>&#x8F6F;&#x4EF6;&#x751F;&#x6210;&#x7684;&#x4E2D;&#x65AD;&#xFF0C;&#x7528;&#x4E8E;&#x5904;&#x7406;&#x5668;&#x5185;&#x6838;&#x4E4B;&#x95F4;&#x7684;&#x901A;&#x4FE1;&#x3002;SGI&#x662F;&#x7531;&#x8F6F;&#x4EF6;&#x663E;&#x5F0F;&#x89E6;&#x53D1;&#x7684;&#xFF0C;&#x901A;&#x5E38;&#x7528;&#x4E8E;&#x5B9E;&#x73B0;&#x8FDB;&#x7A0B;&#x8C03;&#x5EA6;&#x3001;&#x8D1F;&#x8F7D;&#x5747;&#x8861;&#x7B49;&#x529F;&#x80FD;&#x3002;&#x4E00;&#x4E2A;&#x5904;&#x7406;&#x5668;&#x53EF;&#x4EE5;&#x5411;&#x5176;&#x4ED6;&#x5904;&#x7406;&#x5668;&#x6216;&#x81EA;&#x5DF1;&#x53D1;&#x9001;SGI&#x3002;&#x5728;x86&#x4E2D;&#x88AB;&#x5B9A;&#x4E49;&#x4E3A;IPI&#x3002;</p>
</li>
<li>
<p>SPI (Shared Peripheral Interrupt)&#xFF1A;</p>
<p>&#x5171;&#x4EAB;&#x5916;&#x8BBE;&#x4E2D;&#x65AD;&#xFF0C;&#x7528;&#x4E8E;&#x5904;&#x7406;&#x4E0E;&#x591A;&#x4E2A;&#x5904;&#x7406;&#x5668;&#x6838;&#x5FC3;&#x5171;&#x4EAB;&#x7684;&#x5916;&#x8BBE;&#x4E8B;&#x4EF6;&#x3002;SPI&#x662F;&#x7CFB;&#x7EDF;&#x8303;&#x56F4;&#x5185;&#x7684;&#x4E2D;&#x65AD;&#xFF0C;&#x53EF;&#x4EE5;&#x88AB;&#x8DEF;&#x7531;&#x5230;&#x4EFB;&#x4F55;&#x5904;&#x7406;&#x5668;&#x3002;&#x8FD9;&#x4E9B;&#x4E2D;&#x65AD;&#x901A;&#x5E38;&#x7528;&#x4E8E;&#x5904;&#x7406;&#x901A;&#x7528;&#x786C;&#x4EF6;&#x4E8B;&#x4EF6;&#xFF0C;&#x4F8B;&#x5982;USB&#x3001;&#x7F51;&#x7EDC;&#x3001;&#x78C1;&#x76D8;&#x7B49;&#x3002;</p>
</li>
<li>
<p>PPI (Private Peripheral Interrupt)&#xFF1A;</p>
<p>&#x79C1;&#x6709;&#x5916;&#x8BBE;&#x4E2D;&#x65AD;&#xFF0C;&#x7528;&#x4E8E;&#x5904;&#x7406;&#x4E0E;&#x7279;&#x5B9A;&#x5904;&#x7406;&#x5668;&#x6838;&#x5FC3;&#x5173;&#x8054;&#x7684;&#x5916;&#x8BBE;&#x4E8B;&#x4EF6;&#x3002;PPI&#x662F;&#x9488;&#x5BF9;&#x5355;&#x4E2A;&#x5904;&#x7406;&#x5668;&#x7684;&#xFF0C;&#x6BCF;&#x4E2A;&#x5904;&#x7406;&#x5668;&#x90FD;&#x6709;&#x81EA;&#x5DF1;&#x7684;&#x4E00;&#x7EC4;PPI&#x3002;&#x8FD9;&#x4E9B;&#x4E2D;&#x65AD;&#x901A;&#x5E38;&#x7528;&#x4E8E;&#x5904;&#x7406;&#x4E0E;&#x7279;&#x5B9A;&#x5904;&#x7406;&#x5668;&#x76F8;&#x5173;&#x7684;&#x786C;&#x4EF6;&#x4E8B;&#x4EF6;&#xFF0C;&#x4F8B;&#x5982;&#x5B9A;&#x65F6;&#x5668;&#x3001;&#x9519;&#x8BEF;&#x68C0;&#x6D4B;&#x7B49;&#x3002;</p>
</li>
<li>
<p>LPI (Locality-specific Peripheral Interrupt)&#xFF1A;</p>
<p>&#x5C40;&#x90E8;&#x7279;&#x5B9A;&#x5916;&#x8BBE;&#x4E2D;&#x65AD;&#xFF0C;&#x662F;GICv3&#x5F15;&#x5165;&#x7684;&#x4E00;&#x79CD;&#x65B0;&#x4E2D;&#x65AD;&#x7C7B;&#x578B;&#x3002;LPI&#x7528;&#x4E8E;&#x5904;&#x7406;&#x4E0E;&#x7279;&#x5B9A;&#x5904;&#x7406;&#x5668;&#x7EC4;&#xFF08;&#x4F8B;&#x5982;NUMA&#x8282;&#x70B9;&#xFF09;&#x5173;&#x8054;&#x7684;&#x5916;&#x8BBE;&#x4E8B;&#x4EF6;&#x3002;LPI&#x76F8;&#x5BF9;&#x4E8E;SPI&#x5177;&#x6709;&#x66F4;&#x9AD8;&#x7684;&#x53EF;&#x6269;&#x5C55;&#x6027;&#xFF0C;&#x53EF;&#x4EE5;&#x652F;&#x6301;&#x5927;&#x91CF;&#x7684;&#x4E2D;&#x65AD;&#x6E90;&#x3002;&#x8FD9;&#x4E9B;&#x4E2D;&#x65AD;&#x901A;&#x5E38;&#x7528;&#x4E8E;&#x5904;&#x7406;&#x5927;&#x578B;&#x591A;&#x5904;&#x7406;&#x5668;&#x7CFB;&#x7EDF;&#x4E2D;&#x7684;&#x786C;&#x4EF6;&#x4E8B;&#x4EF6;&#x3002;</p>
</li>
</ul>
<h4 id="321-gic%E9%A9%B1%E5%8A%A8">3.2.1-GIC&#x9A71;&#x52A8;</h4>
<p>GICv3&#x7684;&#x9A71;&#x52A8;&#x4E3B;&#x8981;&#x5728;<code>drivers/irqchip/irq-gic-v3.c</code>&#x4E2D;&#xFF0C;GIC&#x8BBE;&#x5907;&#x7684;&#x521D;&#x59CB;&#x5316;&#x6709;&#x4E24;&#x79CD;&#x65B9;&#x5F0F;&#xFF0C;&#x4E00;&#x79CD;&#x662F;&#x901A;&#x8FC7;dtsi&#x8BBE;&#x5907;&#x6811;&#xFF0C;&#x4E00;&#x79CD;&#x662F;&#x901A;&#x8FC7;ACPI&#x4ECE;BIOS&#x91CC;&#x76F4;&#x63A5;&#x521D;&#x59CB;&#x5316;&#xFF0C;&#x5177;&#x4F53;&#x7684;&#x8C03;&#x7528;&#x5982;&#x4E0B;</p>
<ol>
<li>dtsi</li>
</ol>
<pre><code class="language-cpp">IRQCHIP_DECLARE(gic_v3, &quot;arm,gic-v3&quot;, gic_of_init);
</code></pre>
<p>&#x8BBE;&#x5907;&#x5728;&#x521D;&#x59CB;&#x5316;&#x7684;&#x8FC7;&#x7A0B;&#x4E2D;&#xFF0C;&#x6216;&#x5C1D;&#x8BD5;&#x89E3;&#x6790;&#x5BF9;&#x5E94;&#x7684;&#x8BBE;&#x5907;&#x6811;&#x6587;&#x4EF6;&#xFF0C;&#x5BF9;GIC&#x8FDB;&#x884C;&#x521D;&#x59CB;&#x5316;</p>
<p>&#x5728;&#x8BBE;&#x5907;&#x6811;&#x4E2D;&#x4F1A;&#x5982;&#x4E0B;&#x5B9A;&#x4E49;&#x4E00;&#x4E2A;GIC&#xFF0C;&#x4EE5;rk3399&#x5177;&#x4F53;&#x8BF4;&#x660E;(<code>scripts/dtc/include-prefixes/arm64/rockchip/rk3399.dtsi</code>)</p>
<pre><code class="language-makefile">	gic: interrupt-controller@fee00000 { # &#x5B9A;&#x4E49;&#x4E00;&#x4E2A;&#x540D;&#x4E3A;gic&#x7684;&#x8282;&#x70B9;&#xFF0C;&#x8868;&#x793A;&#x4E00;&#x4E2A;&#x4F4D;&#x4E8E;0xfee00000&#x5730;&#x5740;&#x7684;&#x4E2D;&#x65AD;&#x63A7;&#x5236;&#x5668;&#x3002;
		compatible = &quot;arm,gic-v3&quot;;
		#interrupt-cells = &lt;4&gt;;
		#address-cells = &lt;2&gt;;
		#size-cells = &lt;2&gt;;
		ranges;
		interrupt-controller; # &#x8868;&#x793A;&#x8FD9;&#x4E2A;&#x8282;&#x70B9;&#x4EE3;&#x8868;&#x4E00;&#x4E2A;&#x4E2D;&#x65AD;&#x63A7;&#x5236;&#x5668;&#x3002;

		# &#x5B9A;&#x4E49;&#x4E86;GIC&#x4E2D;&#x7684;&#x5404;&#x4E2A;&#x5BC4;&#x5B58;&#x5668;&#x5730;&#x5740;&#x548C;&#x5927;&#x5C0F;&#x3002;
		reg = &lt;0x0 0xfee00000 0 0x10000&gt;, /* GICD */
		      &lt;0x0 0xfef00000 0 0xc0000&gt;, /* GICR */
		      &lt;0x0 0xfff00000 0 0x10000&gt;, /* GICC */
		      &lt;0x0 0xfff10000 0 0x10000&gt;, /* GICH */
		      &lt;0x0 0xfff20000 0 0x10000&gt;; /* GICV */
    # &#x5B9A;&#x4E49;&#x4E86;GIC&#x7684;&#x4E2D;&#x65AD;&#x4FE1;&#x606F;&#xFF0C;&#x8FD9;&#x91CC;&#x6307;&#x5B9A;&#x4E86;&#x4E00;&#x4E2A;PPI&#x7C7B;&#x578B;&#x7684;&#x4E2D;&#x65AD;&#xFF0C;&#x4E2D;&#x65AD;&#x53F7;&#x4E3A;9&#xFF0C;&#x89E6;&#x53D1;&#x7C7B;&#x578B;&#x4E3A;&#x9AD8;&#x7535;&#x5E73;&#x89E6;&#x53D1;&#x3002;
		interrupts = &lt;GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH 0&gt;; 
		# &#x5B9A;&#x4E49;&#x4E86;&#x4E00;&#x4E2A;&#x540D;&#x4E3A;its&#x7684;&#x8282;&#x70B9;&#xFF0C;&#x8868;&#x793A;&#x4E00;&#x4E2A;&#x4F4D;&#x4E8E;0xfee20000&#x5730;&#x5740;&#x7684;MSI&#x63A7;&#x5236;&#x5668;&#x3002;
		its: msi-controller@fee20000 {
			compatible = &quot;arm,gic-v3-its&quot;;
			msi-controller;
			#msi-cells = &lt;1&gt;;
			reg = &lt;0x0 0xfee20000 0x0 0x20000&gt;;
		};

		ppi-partitions { # &#x63CF;&#x8FF0;PPI&#x4E2D;&#x65AD;&#x7684;&#x5206;&#x533A;&#x4FE1;&#x606F;&#x3002;&#x5B9A;&#x4E49;&#x4E86;&#x4E24;&#x4E2A;PPI&#x5206;&#x533A;&#xFF1A;ppi_cluster0&#x548C;ppi_cluster1&#x3002;
			ppi_cluster0: interrupt-partition-0 { # &#x7ED1;&#x5B9A;&#x5728;&#x5C0F;&#x6838;0-3&#x4E0A;
				affinity = &lt;&amp;cpu_l0 &amp;cpu_l1 &amp;cpu_l2 &amp;cpu_l3&gt;;
			};

			ppi_cluster1: interrupt-partition-1 { # &#x7ED1;&#x5B9A;&#x5728;&#x5927;&#x6838;0-1&#x4E0A;
				affinity = &lt;&amp;cpu_b0 &amp;cpu_b1&gt;;
			};
		};
	};
</code></pre>
<p>&#x8FD9;&#x5176;&#x4E2D;GIC&#x7684;&#x5BC4;&#x5B58;&#x5668;&#x5206;&#x522B;&#x4EE3;&#x8868;&#x5982;&#x4E0B;&#x5185;&#x5BB9;</p>
<ul>
<li>GICD&#xFF08;GIC Distributor&#xFF09;&#xFF1A;GIC&#x5206;&#x53D1;&#x5668;&#xFF0C;&#x8D1F;&#x8D23;&#x7BA1;&#x7406;&#x548C;&#x5206;&#x53D1;&#x4E2D;&#x65AD;&#x3002;GICD&#x7EF4;&#x62A4;&#x4E86;&#x4E00;&#x4E2A;&#x4E2D;&#x65AD;&#x4F18;&#x5148;&#x7EA7;&#x8868;&#xFF0C;&#x53EF;&#x4EE5;&#x5C06;&#x4E2D;&#x65AD;&#x5206;&#x53D1;&#x7ED9;&#x7279;&#x5B9A;&#x7684;CPU&#x6216;&#x4E00;&#x7EC4;CPU&#x3002;</li>
<li>GICR&#xFF08;GIC Redistributor&#xFF09;&#xFF1A;GIC&#x518D;&#x5206;&#x53D1;&#x5668;&#xFF0C;&#x7528;&#x4E8E;&#x652F;&#x6301;&#x591A;&#x4E2A;&#x5904;&#x7406;&#x5668;&#x3002;&#x6BCF;&#x4E2A;&#x5904;&#x7406;&#x5668;&#x90FD;&#x6709;&#x4E00;&#x4E2A;&#x5173;&#x8054;&#x7684;GICR&#xFF0C;&#x7528;&#x4E8E;&#x5904;&#x7406;&#x8BE5;&#x5904;&#x7406;&#x5668;&#x7684;SGI&#xFF08;Software Generated Interrupt&#xFF09;&#x548C;PPI&#xFF08;Private Peripheral Interrupt&#xFF09;&#x3002;</li>
<li>GICC&#xFF08;GIC CPU Interface&#xFF09;&#xFF1A;GIC CPU&#x63A5;&#x53E3;&#xFF0C;&#x63D0;&#x4F9B;&#x4E86;&#x5904;&#x7406;&#x5668;&#x548C;GIC&#x4E4B;&#x95F4;&#x7684;&#x63A5;&#x53E3;&#x3002;&#x5904;&#x7406;&#x5668;&#x901A;&#x8FC7;GICC&#x63A5;&#x6536;&#x4E2D;&#x65AD;&#xFF0C;&#x53D1;&#x9001;EOI&#xFF08;End of Interrupt&#xFF09;&#x4FE1;&#x53F7;&#xFF0C;&#x4EE5;&#x53CA;&#x83B7;&#x53D6;&#x5F53;&#x524D;&#x6B63;&#x5728;&#x5904;&#x7406;&#x7684;&#x4E2D;&#x65AD;&#x7B49;&#x3002;</li>
<li>GICH&#xFF08;GIC Virtual Interface&#xFF09;&#xFF1A;GIC&#x865A;&#x62DF;&#x63A5;&#x53E3;&#xFF0C;&#x7528;&#x4E8E;&#x652F;&#x6301;&#x865A;&#x62DF;&#x5316;&#x3002;GICH&#x63D0;&#x4F9B;&#x4E86;&#x4E00;&#x4E2A;&#x865A;&#x62DF;&#x5217;&#x8868;&#xFF0C;&#x7528;&#x4E8E;&#x5B58;&#x50A8;&#x6765;&#x81EA;&#x865A;&#x62DF;&#x673A;&#x7684;&#x4E2D;&#x65AD;&#x3002;</li>
<li>GICV&#xFF08;GIC Virtual CPU Interface&#xFF09;&#xFF1A;GIC&#x865A;&#x62DF;CPU&#x63A5;&#x53E3;&#xFF0C;&#x63D0;&#x4F9B;&#x4E86;&#x865A;&#x62DF;&#x673A;&#x548C;GIC&#x4E4B;&#x95F4;&#x7684;&#x63A5;&#x53E3;&#x3002;&#x865A;&#x62DF;&#x673A;&#x901A;&#x8FC7;GICV&#x63A5;&#x6536;&#x4E2D;&#x65AD;&#xFF0C;&#x53D1;&#x9001;EOI&#x4FE1;&#x53F7;&#xFF0C;&#x4EE5;&#x53CA;&#x83B7;&#x53D6;&#x5F53;&#x524D;&#x6B63;&#x5728;&#x5904;&#x7406;&#x7684;&#x4E2D;&#x65AD;&#x7B49;&#x3002;</li>
</ul>
<ol start="2">
<li>acpi</li>
</ol>
<p>Linux&#x5185;&#x6838;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;ACPI&#x6765;&#x83B7;&#x53D6;&#x786C;&#x4EF6;&#x4FE1;&#x606F;&#x548C;&#x914D;&#x7F6E;&#x3002;Linux&#x5185;&#x6838;&#x5305;&#x542B;&#x4E86;&#x4E00;&#x4E2A;ACPI&#x89E3;&#x91CA;&#x5668;&#xFF0C;&#x53EF;&#x4EE5;&#x89E3;&#x6790;&#x548C;&#x6267;&#x884C;ACPI&#x8868;&#x4E2D;&#x7684;AML&#x4EE3;&#x7801;&#x3002;</p>
<pre><code class="language-cpp">IRQCHIP_ACPI_DECLARE(gic_v3, ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR,
		     acpi_validate_gic_table, ACPI_MADT_GIC_VERSION_V3,
		     gic_acpi_init);
</code></pre>
<h2 id="4%E3%80%81%E4%B8%AD%E6%96%AD%E6%98%A0%E5%B0%84">4&#x3001;&#x4E2D;&#x65AD;&#x6620;&#x5C04;</h2>
<h3 id="41-idt-x86">4.1-IDT x86</h3>
<p>&#x6211;&#x4EEC;&#x901A;&#x8FC7;&#x4E0A;&#x8FF0;&#x7684;&#x671F;&#x95F4;&#x53EF;&#x4EE5;&#x5B9E;&#x73B0;&#x4E2D;&#x65AD;&#x786C;&#x4EF6;&#x4E0A;&#x7684;&#x6355;&#x6349;&#x3001;&#x5206;&#x53D1;&#xFF0C;&#x4F46;&#x662F;&#x5728;linux&#x4E2D;&#x901A;&#x5E38;&#x5728;&#x63A5;&#x53D7;&#x5230;&#x4E2D;&#x65AD;&#x540E;&#x8FD8;&#x4F1A;&#x7EE7;&#x7EED;&#x6267;&#x884C;&#x8F6F;&#x4EF6;&#x64CD;&#x4F5C;&#xFF0C;&#x800C;&#x5185;&#x6838;&#x5219;&#x662F;&#x901A;&#x8FC7;<code>&#x4E2D;&#x65AD;&#x63CF;&#x8FF0;&#x7B26;&#x8868;(Interrupt Descriptor Table)</code>&#x6765;&#x5C06;&#x4E0D;&#x540C;&#x7684;&#x4E2D;&#x65AD;&#x6307;&#x5411;&#x7279;&#x5B9A;&#x7684;&#x7A0B;&#x5E8F;&#x5165;&#x53E3;&#xFF0C;&#x800C;&#x4E2D;&#x65AD;&#x5904;&#x7406;&#x7684;&#x7A0B;&#x5E8F;&#x5219;&#x88AB;&#x79F0;&#x4E3A;<code>&#x95E8;&#xFF08;gates&#xFF09;</code>&#x3002;&#x56E0;&#x6B64;&#x521D;&#x59CB;&#x5316;IDT&#x662F;&#x5185;&#x6838;&#x542F;&#x52A8;&#x9636;&#x6BB5;&#x91CD;&#x8981;&#x7684;&#x5DE5;&#x4F5C;&#x3002;</p>
<p>IDT&#x88AB;CPU&#x52A0;&#x8F7D;&#x5728;<code>idtr</code>&#x5BC4;&#x5B58;&#x5668;&#x4E2D;&#xFF0C;&#x7528;&#x4EE5;&#x53D1;&#x751F;&#x4E2D;&#x65AD;&#x65F6;&#x5206;&#x914D;&#x4E2D;&#x65AD;&#x7684;&#x5904;&#x7406;&#x51FD;&#x6570;&#xFF0C;&#x901A;&#x8FC7;<code>idtr</code>&#x4E2D;&#x7684;<code>idt</code>&#x57FA;&#x5730;&#x5740;+&#x4E2D;&#x65AD;&#x53F7;&#x504F;&#x79FB;&#xFF0C;&#x4ECE;&#x800C;&#x83B7;&#x53D6;&#x4E2D;&#x65AD;&#x5904;&#x7406;&#x51FD;&#x6570;&#x7684;&#x5165;&#x53E3;&#x5730;&#x5740;&#x3002;</p>
<p>&#x5728;x86&#x67B6;&#x6784;&#x7684;Linux&#x5185;&#x6838;&#x4E2D;&#xFF0C;IDT&#x4E3B;&#x8981;&#x5B58;&#x50A8;&#x4E86;&#x4E2D;&#x65AD;&#x5411;&#x91CF;&#x4E0E;&#x5176;&#x5BF9;&#x5E94;&#x7684;&#x5E95;&#x5C42;&#x4E2D;&#x65AD;&#x5904;&#x7406;&#x7A0B;&#x5E8F;&#xFF08;&#x4E5F;&#x79F0;&#x4E3A;&#x4E2D;&#x65AD;&#x5904;&#x7406;&#x7A0B;&#x5E8F;&#x7684;&#x5165;&#x53E3;&#x70B9;&#xFF09;&#x4E4B;&#x95F4;&#x7684;&#x6620;&#x5C04;&#x5173;&#x7CFB;&#x3002;&#x5F53;&#x53D1;&#x751F;&#x4E2D;&#x65AD;&#x65F6;&#xFF0C;&#x5904;&#x7406;&#x5668;&#x4F1A;&#x6839;&#x636E;IDT&#x627E;&#x5230;&#x5BF9;&#x5E94;&#x7684;&#x5E95;&#x5C42;&#x4E2D;&#x65AD;&#x5904;&#x7406;&#x7A0B;&#x5E8F;&#xFF0C;&#x5E76;&#x8DF3;&#x8F6C;&#x5230;&#x8FD9;&#x4E2A;&#x7A0B;&#x5E8F;&#x7684;&#x5165;&#x53E3;&#x70B9;&#x5F00;&#x59CB;&#x6267;&#x884C;&#x3002;&#x7136;&#x540E;&#xFF0C;&#x5E95;&#x5C42;&#x4E2D;&#x65AD;&#x5904;&#x7406;&#x7A0B;&#x5E8F;&#x4F1A;&#x8C03;&#x7528;&#x5185;&#x6838;&#x7684;&#x4E2D;&#x65AD;&#x5904;&#x7406;&#x5B50;&#x7CFB;&#x7EDF;&#xFF0C;&#x6700;&#x540E;&#x7531;&#x5185;&#x6838;&#x7684;&#x4E2D;&#x65AD;&#x5904;&#x7406;&#x5B50;&#x7CFB;&#x7EDF;&#x8C03;&#x7528;&#x76F8;&#x5E94;&#x7684;&#x5904;&#x7406;&#x51FD;&#x6570;&#xFF08;&#x4F8B;&#x5982;my_irq_handler&#xFF09;&#x6765;&#x5904;&#x7406;&#x4E2D;&#x65AD;&#x3002;</p>
<p>&#x5185;&#x6838;&#x901A;&#x8FC7;<code>idt_setup_apic_and_irq_gates</code>&#x51FD;&#x6570;&#x521D;&#x59CB;&#x5316;<code>IDT</code>&#x3002;</p>
<pre><code class="language-cpp">void __init idt_setup_apic_and_irq_gates(void)
{
	int i = FIRST_EXTERNAL_VECTOR;
	void *entry;

	idt_setup_from_table(idt_table, apic_idts, ARRAY_SIZE(apic_idts), true); // &#x8BBE;&#x7F6E;APIC and SMP idt&#xFF0C;&#x901A;&#x5E38;&#x662F;&#x9519;&#x8BEF;&#x4E2D;&#x65AD;&#x3001;IPI

	for_each_clear_bit_from(i, system_vectors, FIRST_SYSTEM_VECTOR) { // &#x5C06;&#x5916;&#x90E8;IRQ&#x4E2D;&#x65AD;&#x5904;&#x7406;&#x7A0B;&#x5E8F;&#x7684;&#x5165;&#x53E3;&#x8BBE;&#x7F6E;&#x5230;IDT&#x4E2D;
		entry = irq_entries_start + IDT_ALIGN * (i - FIRST_EXTERNAL_VECTOR); // &#x4E2D;&#x65AD;&#x5904;&#x7406;&#x51FD;&#x6570;&#x5165;&#x53E3;
		set_intr_gate(i, entry);// &#x8BBE;&#x7F6E;&#x4E2D;&#x65AD;&#x95E8;
	}

#ifdef CONFIG_X86_LOCAL_APIC
	for_each_clear_bit_from(i, system_vectors, NR_VECTORS) { // &#x5C06;&#x672C;&#x5730;APIC IRQ&#x4E2D;&#x65AD;&#x5904;&#x7406;&#x7A0B;&#x5E8F;&#x7684;&#x5165;&#x53E3;&#x8BBE;&#x7F6E;&#x5230;IDT&#x4E2D;
		/*
		 * Don&apos;t set the non assigned system vectors in the
		 * system_vectors bitmap. Otherwise they show up in
		 * /proc/interrupts.
		 */
		entry = spurious_entries_start + IDT_ALIGN * (i - FIRST_SYSTEM_VECTOR); // &#x4E2D;&#x65AD;&#x5904;&#x7406;&#x51FD;&#x6570;&#x5165;&#x53E3;
		set_intr_gate(i, entry); // &#x8BBE;&#x7F6E;&#x4E2D;&#x65AD;&#x95E8;
	}
#endif
	......

	idt_setup_done = true; // &#x5B8C;&#x6210;IDT&#x7684;&#x521D;&#x59CB;&#x5316;&#x8BBE;&#x7F6E;
}
</code></pre>
<p>&#x5176;&#x4E2D;&#x5BF9;&#x5E94;&#x7684;&#x5E95;&#x5C42;&#x5904;&#x7406;&#x51FD;&#x6570;&#x5165;&#x53E3;&#x5177;&#x4F53;&#x88AB;&#x5B9A;&#x4E49;&#x5728;&#x4E86;&#x5982;&#x4E0B;&#x4EE3;&#x7801;&#x4E2D;</p>
<pre><code class="language-cpp">SYM_CODE_START(irq_entries_start)
    vector=FIRST_EXTERNAL_VECTOR
    .rept NR_EXTERNAL_VECTORS
	UNWIND_HINT_IRET_REGS
0 :
	ENDBR
	.byte	0x6a, vector
	jmp	asm_common_interrupt // &#x8DF3;&#x8F6C;&#x5230;asm_common_interrupt&#x6807;&#x7B7E;&#x5BF9;&#x5E94;&#x7684;&#x4F4D;&#x7F6E;&#xFF0C;&#x8FD9;&#x4E2A;&#x4F4D;&#x7F6E;&#x5B9A;&#x4E49;&#x4E86;&#x4E00;&#x6BB5;&#x901A;&#x7528;&#x7684;IRQ&#x5904;&#x7406;&#x7A0B;&#x5E8F;
	/* Ensure that the above is IDT_ALIGN bytes max */
	.fill 0b + IDT_ALIGN - ., 1, 0xcc
	vector = vector+1
    .endr
SYM_CODE_END(irq_entries_start)
    
SYM_CODE_START(spurious_entries_start)
    vector=FIRST_SYSTEM_VECTOR
    .rept NR_SYSTEM_VECTORS
	UNWIND_HINT_IRET_REGS
0 :
	ENDBR
	.byte	0x6a, vector
	jmp	asm_spurious_interrupt
	/* Ensure that the above is IDT_ALIGN bytes max */
	.fill 0b + IDT_ALIGN - ., 1, 0xcc
	vector = vector+1
    .endr
SYM_CODE_END(spurious_entries_start)    
</code></pre>
<p>&#x5176;&#x4E2D;<code>asm_common_interrupt</code>&#x4E0E;<code>asm_spurious_interrupt</code>&#x88AB;&#x5B9A;&#x4E49;&#x5728;&#x4E86;&#x5982;&#x4E0B;&#x4EE3;&#x7801;&#x4E2D;</p>
<pre><code class="language-cpp">/* Device interrupts common/spurious */
DECLARE_IDTENTRY_IRQ(X86_TRAP_OTHER,	common_interrupt);
#ifdef CONFIG_X86_LOCAL_APIC
DECLARE_IDTENTRY_IRQ(X86_TRAP_OTHER,	spurious_interrupt);
#endif
</code></pre>
<p>&#x7EE7;&#x7EED;&#x901A;&#x8FC7;&#x5B8F;&#x5C55;&#x5F00;&#x5C06;&#x4E8C;&#x8005;&#x5173;&#x8054;&#x8D77;&#x6765;</p>
<pre><code class="language-cpp">#define DECLARE_IDTENTRY_IRQ(vector, func)				\
	DECLARE_IDTENTRY_ERRORCODE(vector, func)

#define DECLARE_IDTENTRY_ERRORCODE(vector, func)			\
	asmlinkage void asm_##func(void);				\
	asmlinkage void xen_asm_##func(void);				\
	__visible void func(struct pt_regs *regs, unsigned long error_code)
</code></pre>
<p>&#x6700;&#x540E;&#x58F0;&#x660E;&#x4E86;&#x4E00;&#x4E2A;&#x540D;&#x4E3A;<code>common_interrupt</code>&#x548C;<code>spurious_interrupt</code>&#x7684;&#x51FD;&#x6570;&#xFF0C;&#x800C;&#x8FD9;&#x4E24;&#x4E2A;&#x51FD;&#x6570;&#x5B9E;&#x9645;&#x7684;&#x5B9A;&#x4E49;&#x5219;&#x662F;</p>
<pre><code class="language-cpp">DEFINE_IDTENTRY_IRQ(common_interrupt)
{
	struct pt_regs *old_regs = set_irq_regs(regs); // &#x4FDD;&#x5B58;&#x5BC4;&#x5B58;&#x5668;&#x72B6;&#x6001;
	......
	desc = __this_cpu_read(vector_irq[vector]); // &#x83B7;&#x53D6;vector&#x4E2D;&#x65AD;&#x53F7;&#x5BF9;&#x5E94;&#x7684;&#x4E2D;&#x65AD;&#x63CF;&#x8FF0;&#x7B26;
	if (likely(!IS_ERR_OR_NULL(desc))) { // &#x5982;&#x679C;&#x4E2D;&#x65AD;&#x63CF;&#x8FF0;&#x7B26;&#x6709;&#x6548;
		handle_irq(desc, regs); // &#x8C03;&#x7528;handle_irq&#x5904;&#x7406;&#x51FD;&#x6570;&#xFF0C;&#x8FD9;&#x91CC;&#x8FDB;&#x4E00;&#x6B65;&#x7684;&#x5C31;&#x4F1A;&#x8C03;&#x7528;&#x5230;&#x6CE8;&#x518C;&#x8FC7;&#x7684;irq&#x56DE;&#x8C03;&#x51FD;&#x6570;
	} else {
		apic_eoi();

		if (desc == VECTOR_UNUSED) {
			pr_emerg_ratelimited(&quot;%s: %d.%u No irq handler for vector\n&quot;,
					     __func__, smp_processor_id(),
					     vector);
		} else {
			__this_cpu_write(vector_irq[vector], VECTOR_UNUSED);// &#x5F53;&#x524D;CPU&#x4E0A;&#x7684;&#x65E0;&#x6548;&#x7684;&#x4E2D;&#x65AD;&#x63CF;&#x8FF0;&#x7B26;&#x8BBE;&#x7F6E;&#x4E3A;VECTOR_UNUSED&#x3002;
		}
	}

	set_irq_regs(old_regs); // &#x6062;&#x590D;&#x5BC4;&#x5B58;&#x5668;&#x72B6;&#x6001;
}
</code></pre>
<p>&#x5916;&#x90E8;&#x4E2D;&#x65AD;&#x4F1A;&#x5148;&#x8DF3;&#x5230;<code>common_interrupt</code>&#x7684;&#x5165;&#x53E3;&#x51FD;&#x6570;&#x4E2D;&#xFF0C;&#x5E76;&#x4E14;&#x901A;&#x8FC7;&#x67E5;&#x627E;&#x5BF9;&#x5E94;&#x7684;<code>vector_irq</code>&#x6765;&#x83B7;&#x53D6;&#x4E2D;&#x65AD;&#x63CF;&#x8FF0;&#x7B26;&#xFF0C;&#x518D;&#x8FDB;&#x4E00;&#x6B65;&#x901A;&#x8FC7;&#x6CE8;&#x518C;&#x4E2D;&#x65AD;&#x7684;&#x65F6;&#x5019;&#x7ED1;&#x5B9A;&#x7684;<code>desc-&gt;handler</code>&#x6765;&#x6267;&#x884C;&#x5BF9;&#x5E94;&#x7684;&#x4E2D;&#x65AD;&#x5904;&#x7406;&#x51FD;&#x6570;&#x3002;</p>
<p>&#x4EE5;&#x53CA;</p>
<pre><code class="language-cpp">DEFINE_IDTENTRY_IRQ(spurious_interrupt)
{
	handle_spurious_interrupt(vector);
}
</code></pre>
<h3 id="42-%E4%B8%AD%E6%96%AD%E5%90%91%E9%87%8F%E8%A1%A8arm64">4.2-&#x4E2D;&#x65AD;&#x5411;&#x91CF;&#x8868;arm64</h3>
<p>&#x5728;arm64&#x4E2D;&#xFF0C;&#x591A;&#x4E86;&#x4E00;&#x4E2A;<code>irq_domian</code>&#x7684;&#x6982;&#x5FF5;&#xFF0C;&#x4ED6;&#x662F;<code>irq_desc-&gt;irq_data</code>&#x4E2D;&#x7684;&#x4E00;&#x4E2A;&#x6210;&#x5458;&#x3002;</p>
<pre><code class="language-cpp">struct irq_data {
	u32			mask;
	unsigned int		irq;
	unsigned long		hwirq;
	struct irq_common_data	*common;
	struct irq_chip		*chip;
	struct irq_domain	*domain;
#ifdef	CONFIG_IRQ_DOMAIN_HIERARCHY
	struct irq_data		*parent_data;
#endif
	void			*chip_data;
};
</code></pre>
<p>&#x8FD9;&#x91CC;&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;<code>irq</code>&#x5C31;&#x662F;&#x4E2D;&#x65AD;&#x5728;linux&#x7684;<code>&#x4E2D;&#x65AD;&#x865A;&#x62DF;&#x4E2D;&#x65AD;&#x53F7;</code>&#xFF0C;&#x800C;<code>hwirq</code>&#x5219;&#x662F;&#x5BF9;&#x5E94;&#x4E2D;&#x65AD;&#x7684;&#x5B9E;&#x9645;&#x4E2D;&#x65AD;&#x53F7;&#xFF0C;irq_domain&#x4F5C;&#x4E3A;&#x4E00;&#x4E2A;&#x6620;&#x5C04;&#x5C42;&#xFF0C;&#x5C06;&#x786C;&#x4EF6;&#x4E2D;&#x65AD;&#x53F7;&#x6620;&#x5C04;&#x5230;&#x5185;&#x6838;&#x4E2D;&#x7684;&#x865A;&#x62DF;&#x4E2D;&#x65AD;&#x53F7;&#x3002;&#x800C;&#x786C;&#x4EF6;&#x4E2D;&#x65AD;&#x53F7;<code>hwirq</code>&#x5219;&#x662F;&#x5B9A;&#x4E49;&#x5728;&#x4EA7;&#x751F;&#x4E2D;&#x65AD;&#x7684;&#x8BBE;&#x5907;&#x6240;&#x5BF9;&#x5E94;&#x7684;&#x8BBE;&#x5907;&#x6811;&#x6587;&#x4EF6;&#x6216;&#x8005;bios&#x6587;&#x4EF6;&#x4E2D;&#x7684;&#x3002;</p>
<p>&#x800C;&#x4E2D;&#x65AD;&#x6620;&#x5C04;&#x7684;&#x8FC7;&#x7A0B;&#x5219;&#x662F;&#x901A;&#x8FC7;&#x53D1;&#x751F;&#x7684;&#x786C;&#x4EF6;&#x4E2D;&#x65AD;hwirq&#xFF0C;&#x627E;&#x5230;&#x5185;&#x6838;&#x5BF9;&#x5E94;&#x7684;virq&#xFF0C;&#x5E76;&#x8FD0;&#x884C;&#x5BF9;&#x5E94;&#x7684;&#x4E2D;&#x65AD;&#x5904;&#x7406;&#x51FD;&#x6570;&#x3002;</p>
<p>&#x800C;hwirq&#x4E0E;virq&#x7684;&#x5219;&#x662F;&#x8BBE;&#x5907;&#x7684;&#x9A71;&#x52A8;&#x5728;&#x521D;&#x59CB;&#x5316;&#x7684;&#x65F6;&#x5019;&#x53EF;&#x4EE5;&#x8C03;&#x7528; irq_of_parse_and_map &#x8FD9;&#x4E2A;&#x63A5;&#x53E3;&#x51FD;&#x6570;&#x8FDB;&#x884C;&#x8BE5; device node &#x4E2D;&#x548C;&#x4E2D;&#x65AD;&#x76F8;&#x5173;&#x7684;&#x5185;&#x5BB9;&#x7684;&#x89E3;&#x6790;&#xFF0C;&#x5E76;&#x5EFA;&#x7ACB;&#x6620;&#x5C04;&#x5173;&#x7CFB;&#x3002;</p>
<p><a href="https://www.kernel.org/doc/html/v5.15/translations/zh_CN/core-api/irq/irq-domain.html?ref=korantli.com.cn">irq_domain &#x4E2D;&#x65AD;&#x53F7;&#x6620;&#x5C04;&#x5E93;</a></p>
<p>ARM64&#x662F;&#x901A;&#x8FC7;&#x5F02;&#x5E38;&#x5411;&#x91CF;&#x8868;&#x6765;&#x5B9E;&#x73B0;&#x4E2D;&#x65AD;&#x7684;&#x5904;&#x7406;&#x548C;&#x6620;&#x5C04;&#x7684;&#xFF0C;&#x5176;&#x5B58;&#x5728;&#x653E;<code>VBAR_EL1</code>&#x548C;<code>VBAR_EL2</code>&#x4E4B;&#x4E2D;&#x3002;</p>
<p>&#x800C;&#x53D1;&#x751F;&#x786C;&#x4EF6;&#x4E2D;&#x65AD;&#x540E;&#xFF0C;&#x5219;&#x4F1A;&#x6839;&#x636E;&#x4E2D;&#x65AD;&#x5411;&#x91CF;&#x8868;&#x8FDB;&#x884C;&#x8DF3;&#x8F6C;&#xFF0C;&#x5176;&#x88AB;&#x5B9A;&#x4E49;&#x5728;&#x4E86;<code>arch/arm64/kernel/entry.S</code></p>
<pre><code class="language-assembly">SYM_CODE_START(vectors)
	kernel_ventry	1, t, 64, sync		// Synchronous EL1t
	kernel_ventry	1, t, 64, irq		// IRQ EL1t
	kernel_ventry	1, t, 64, fiq		// FIQ EL1t
	kernel_ventry	1, t, 64, error		// Error EL1t

	kernel_ventry	1, h, 64, sync		// Synchronous EL1h
	kernel_ventry	1, h, 64, irq		// IRQ EL1h
	kernel_ventry	1, h, 64, fiq		// FIQ EL1h
	kernel_ventry	1, h, 64, error		// Error EL1h

	kernel_ventry	0, t, 64, sync		// Synchronous 64-bit EL0
	kernel_ventry	0, t, 64, irq		// IRQ 64-bit EL0
	kernel_ventry	0, t, 64, fiq		// FIQ 64-bit EL0
	kernel_ventry	0, t, 64, error		// Error 64-bit EL0

	kernel_ventry	0, t, 32, sync		// Synchronous 32-bit EL0
	kernel_ventry	0, t, 32, irq		// IRQ 32-bit EL0
	kernel_ventry	0, t, 32, fiq		// FIQ 32-bit EL0
	kernel_ventry	0, t, 32, error		// Error 32-bit EL0
SYM_CODE_END(vectors)
</code></pre>
<p>&#x6839;&#x636E;&#x53D1;&#x751F;&#x4E2D;&#x65AD;&#x7684;&#x7EA7;&#x522B;&#x4E0D;&#x540C;&#xFF0C;&#x6709;&#x4E0D;&#x540C;&#x7684;&#x8DF3;&#x8F6C;&#x903B;&#x8F91;&#xFF0C;EL0&#x4E0B;&#x7684;IRQ&#x4F1A;&#x8DF3;&#x8F6C;&#x5230;</p>
<pre><code class="language-cpp">asmlinkage void noinstr el0t_64_irq_handler(struct pt_regs *regs)
{
	__el0_irq_handler_common(regs);
}
</code></pre>
<p>EL1&#x4E0B;&#x7684;IRQ&#x4F1A;&#x8DF3;&#x8F6C;&#x5230;</p>
<pre><code class="language-CPP">asmlinkage void noinstr el1h_64_irq_handler(struct pt_regs *regs)
{
	el1_interrupt(regs, handle_arch_irq);
}
</code></pre>
<h2 id="5%E3%80%81%E4%B8%AD%E6%96%AD%E6%B3%A8%E5%86%8C">5&#x3001;&#x4E2D;&#x65AD;&#x6CE8;&#x518C;</h2>
<h3 id="51-%E6%B3%A8%E5%86%8C%E4%B8%AD%E6%96%AD%E5%8F%B7">5.1-&#x6CE8;&#x518C;&#x4E2D;&#x65AD;&#x53F7;</h3>
<p>&#x7531;&#x4E8E;&#x4ECE;&#x786C;&#x4EF6;&#x89E6;&#x53D1;&#x7684;&#x4E2D;&#x65AD;&#x5BF9;&#x5E94;&#x7740;&#x5177;&#x4F53;&#x7684;&#x4E2D;&#x65AD;&#x53F7;&#xFF0C;&#x8FD9;&#x6837;&#x624D;&#x80FD;&#x5728;&#x5185;&#x6838;&#x4E2D;&#x901A;&#x8FC7;&#x6CE8;&#x518C;&#x5BF9;&#x5E94;&#x4E2D;&#x65AD;&#x53F7;&#x7684;&#x8F6F;&#x4EF6;&#x5904;&#x7406;&#x51FD;&#x6570;&#xFF0C;&#x6240;&#x4EE5;&#x5728;&#x8FDE;&#x63A5;&#x597D;&#x4E2D;&#x65AD;&#x7684;&#x786C;&#x4EF6;&#x7535;&#x8DEF;&#x540E;&#xFF0C;&#x6211;&#x9700;&#x8981;&#x4E3A;&#x8FD9;&#x4E2A;&#x8FD9;&#x4E2A;&#x786C;&#x4EF6;&#x4E2D;&#x65AD;&#x5206;&#x914D;&#x4E00;&#x4E2A;&#x4E2D;&#x65AD;&#x53F7;&#x3002;</p>
<ul>
<li>x86</li>
</ul>
<p>&#x5BF9;&#x4E8E;x86&#x6765;&#x8BF4;&#xFF0C;&#x8FD9;&#x4E2A;&#x4E2D;&#x65AD;&#x53F7;&#x662F;&#x5B9A;&#x4E49;&#x5728;BIOS&#x91CC;&#x7684;&#xFF0C;&#x5185;&#x6838;&#x901A;&#x8FC7;ACPI&#x6765;&#x83B7;&#x53D6;&#x5BF9;&#x5E94;&#x8BBE;&#x5907;&#x7684;&#x7EC8;&#x7AEF;&#x53F7;&#x3002;</p>
<ul>
<li>ARM64</li>
</ul>
<p>&#x5BF9;&#x4E8E;ARM64&#x6765;&#x8BF4;&#xFF0C;&#x901A;&#x8FC7;&#x8BBE;&#x5907;&#x6811;&#x521D;&#x59CB;&#x5316;&#x7684;&#x5E73;&#x53F0;&#xFF0C;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x5B9A;&#x4E49;&#x5728;dtsi&#x4E2D;&#x7684;&#x6587;&#x4EF6;&#x6765;&#x89E3;&#x6790;&#x5177;&#x4F53;&#x7684;&#x4E2D;&#x65AD;&#x53F7;</p>
<pre><code class="language-cpp">/* &#x4ECE;&#x8BBE;&#x5907;&#x6811;&#x8282;&#x70B9;&#x4E2D;&#x83B7;&#x53D6;&#x4E2D;&#x65AD;&#x4FE1;&#x606F; */
int irq = irq_of_parse_and_map(dev_node, 0); // &#x7B2C;&#x4E8C;&#x4E2A;&#x53C2;&#x6570;0&#x8868;&#x793A;&#x83B7;&#x53D6;&#x7B2C;&#x4E00;&#x4E2A;&#x4E2D;&#x65AD;&#x4FE1;&#x606F;
</code></pre>
<p>&#x5BF9;&#x4E8E;&#x4F7F;&#x7528;&#x80FD;&#x4E86;ACPI&#x7684;ARM&#x8BBE;&#x5907;&#xFF0C;&#x4E5F;&#x4F1A;&#x540C;x86&#x4E00;&#x6837;&#xFF0C;&#x901A;&#x8FC7;ACPI&#x63A5;&#x53E3;&#x76F4;&#x63A5;&#x4ECE;BIOS&#x4E2D;&#x83B7;&#x53D6;&#x5BF9;&#x5E94;&#x8BBE;&#x5907;&#x7684;&#x4E2D;&#x65AD;&#x53F7;&#x3002;</p>
<p>&#x4EE5;UFS&#x8BBE;&#x5907;&#x7684;&#x4E2D;&#x65AD;&#x6CE8;&#x518C;&#x4E3A;&#x4F8B;</p>
<pre><code class="language-cpp">int platform_get_irq_optional(struct platform_device *dev, unsigned int num)
{
	int ret;
#ifdef CONFIG_SPARC
	/* sparc does not have irqs represented as IORESOURCE_IRQ resources */
	if (!dev || num &gt;= dev-&gt;archdata.num_irqs)
		goto out_not_found;
	ret = dev-&gt;archdata.irqs[num];
	goto out;
#else
	struct fwnode_handle *fwnode = dev_fwnode(&amp;dev-&gt;dev);
	struct resource *r;

	if (is_of_node(fwnode)) { // &#x5982;&#x679C;&#x662F;&#x8BBE;&#x5907;&#x6811;&#x8282;&#x70B9;
		ret = of_irq_get(to_of_node(fwnode), num); // &#x901A;&#x8FC7;&#x8BBE;&#x5907;&#x83B7;&#x53D6;&#x4E2D;&#x65AD;&#x53F7;
		if (ret &gt; 0 || ret == -EPROBE_DEFER)
			goto out;
	}

	r = platform_get_resource(dev, IORESOURCE_IRQ, num);
	if (is_acpi_device_node(fwnode)) { // &#x5982;&#x679C;&#x662F;acpi&#x8282;&#x70B9;
		if (r &amp;&amp; r-&gt;flags &amp; IORESOURCE_DISABLED) {
			ret = acpi_irq_get(ACPI_HANDLE_FWNODE(fwnode), num, r); // &#x901A;&#x8FC7;ACPU&#x83B7;&#x53D6;&#x4E2D;&#x65AD;&#x53F7;
			if (ret)
				goto out;
		}
	}
	......

#endif
out_not_found:
	ret = -ENXIO;
out:
	if (WARN(!ret, &quot;0 is an invalid IRQ number\n&quot;))
		return -EINVAL;
	return ret;
}
EXPORT_SYMBOL_GPL(platform_get_irq_optional);
</code></pre>
<h3 id="52-%E6%B3%A8%E5%86%8C%E5%AF%B9%E5%BA%94%E4%B8%AD%E6%96%AD%E5%A4%84%E7%90%86%E5%87%BD%E6%95%B0">5.2-&#x6CE8;&#x518C;&#x5BF9;&#x5E94;&#x4E2D;&#x65AD;&#x5904;&#x7406;&#x51FD;&#x6570;</h3>
<p>&#x5728;&#x6211;&#x4EEC;&#x83B7;&#x53D6;&#x5230;&#x4E86;&#x5177;&#x4F53;&#x8BBE;&#x5907;&#x4E2D;&#x65AD;&#x6240;&#x5BF9;&#x5E94;&#x7684;&#x4E2D;&#x65AD;&#x53F7;&#x540E;&#xFF0C;&#x5C31;&#x53EF;&#x4EE5;&#x5229;&#x7528;&#x8FD9;&#x4E2A;&#x4E2D;&#x65AD;&#x53F7;&#x5BF9;&#x4E2D;&#x65AD;&#x5904;&#x7406;&#x51FD;&#x6570;&#x8FDB;&#x884C;&#x6CE8;&#x518C;&#x3002;</p>
<pre><code class="language-cpp">#include &lt;linux/interrupt.h&gt;
#include &lt;linux/kernel.h&gt;

static irqreturn_t my_interrupt_handler(int irq, void *dev_id)
{
    printk(KERN_INFO &quot;Interrupt handled: irq %d\n&quot;, irq);
    return IRQ_HANDLED;
}
</code></pre>
<pre><code class="language-cpp">#include &lt;linux/interrupt.h&gt;
#include &lt;linux/module.h&gt;

static int my_irq = 123; // Replace with the actual IRQ number

static int __init my_module_init(void)
{
    int ret;

    ret = request_irq(my_irq, my_interrupt_handler, IRQF_SHARED, &quot;my_interrupt&quot;, NULL);
    if (ret) {
        printk(KERN_ERR &quot;Failed to register interrupt handler: %d\n&quot;, ret);
        return ret;
    }

    printk(KERN_INFO &quot;Registered interrupt handler for IRQ %d\n&quot;, my_irq);
    return 0;
}

static void __exit my_module_exit(void)
{
    free_irq(my_irq, NULL);
    printk(KERN_INFO &quot;Unregistered interrupt handler for IRQ %d\n&quot;, my_irq);
}

module_init(my_module_init);
module_exit(my_module_exit);

MODULE_LICENSE(&quot;GPL&quot;);
</code></pre>
<h2 id="6%E3%80%81%E4%B8%AD%E6%96%AD%E5%A4%84%E7%90%86%E6%B5%81%E7%A8%8B">6&#x3001;&#x4E2D;&#x65AD;&#x5904;&#x7406;&#x6D41;&#x7A0B;</h2>
<h3 id="61-x86">6.1-x86</h3>
<h3 id="62-arm64">6.2-arm64</h3>
<p>&#x53D1;&#x751F;&#x4E00;&#x4E2A; EL0&#x7684;irq&#x65F6;&#xFF0C;&#x6839;&#x636E;&#x4E2D;&#x65AD;&#x5411;&#x91CF;&#x8868;</p>
<pre><code class="language-assembly">kernel_ventry	0, t, 64, irq		// IRQ 64-bit EL0
</code></pre>
<p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#x4F1A;&#x8DF3;&#x8F6C;&#x5230;&#x5236;&#x5B9A;&#x7684;&#x6C47;&#x7F16;&#x4EE3;&#x7801;&#xFF0C;&#x5E76;&#x4F20;&#x5165;&#x7279;&#x5B9A;&#x7684;&#x53C2;&#x6570;</p>
<pre><code class="language-assembly">	.macro kernel_ventry, el:req, ht:req, regsize:req, label:req
	.align 7
.Lventry_start\@:
	.if	\el == 0
	/*
	 * This must be the first instruction of the EL0 vector entries. It is
	 * skipped by the trampoline vectors, to trigger the cleanup.
	 */
	b	.Lskip_tramp_vectors_cleanup\@
	.if	\regsize == 64
	mrs	x30, tpidrro_el0
	msr	tpidrro_el0, xzr
	.else
	mov	x30, xzr
	.endif
.Lskip_tramp_vectors_cleanup\@:
	.endif

	sub	sp, sp, #PT_REGS_SIZE
#ifdef CONFIG_VMAP_STACK
	/*
	 * Test whether the SP has overflowed, without corrupting a GPR.
	 * Task and IRQ stacks are aligned so that SP &amp; (1 &lt;&lt; THREAD_SHIFT)
	 * should always be zero.
	 */
	add	sp, sp, x0			// sp&apos; = sp + x0
	sub	x0, sp, x0			// x0&apos; = sp&apos; - x0 = (sp + x0) - x0 = sp
	tbnz	x0, #THREAD_SHIFT, 0f
	sub	x0, sp, x0			// x0&apos;&apos; = sp&apos; - x0&apos; = (sp + x0) - sp = x0
	sub	sp, sp, x0			// sp&apos;&apos; = sp&apos; - x0 = (sp + x0) - x0 = sp
	b	el\el\ht\()_\regsize\()_\label
</code></pre>
<p>&#x4FDD;&#x5B58;&#x5B8C;&#x5BC4;&#x5B58;&#x5668;&#x72B6;&#x6001;&#x540E;&#xFF0C;&#x5219;&#x4F1A;&#x8DF3;&#x8F6C;&#x5230;<code>el0t_64_irq_handler</code>-&gt;<code>__el0_irq_handler_common</code>-&gt;<code>el0_interrupt</code></p>
<pre><code class="language-cpp">static void noinstr __el0_irq_handler_common(struct pt_regs *regs)
{
	el0_interrupt(regs, handle_arch_irq);
}
</code></pre>
<p>&#x8FD9;&#x91CC;&#x53EF;&#x4EE5;&#x770B;&#x5230;&#x6709;&#x7ED1;&#x5B9A;&#x4E86;&#x4E00;&#x4E2A;&#x4E2D;&#x65AD;&#x7684;&#x56DE;&#x8C03;&#x51FD;&#x6570;&#xFF0C;&#x8FD9;&#x91CC;&#x7684;&#x56DE;&#x8C03;&#x662F;&#x5BF9;&#x5E94;&#x7684;gic&#x7684;&#x5904;&#x7406;&#x51FD;&#x6570;&#xFF0C;&#x5728;gic&#x521D;&#x59CB;&#x5316;&#x7684;&#x8FC7;&#x7A0B;&#x4E2D;&#x7ED1;&#x5B9A;</p>
<pre><code class="language-cpp">static int __init gic_init_bases(phys_addr_t dist_phys_base,
				 void __iomem *dist_base,
				 struct redist_region *rdist_regs,
				 u32 nr_redist_regions,
				 u64 redist_stride,
				 struct fwnode_handle *handle)
{
  ......
	set_handle_irq(gic_handle_irq);
  ......
}
</code></pre>
<p>&#x901A;&#x8FC7;<code>gic_handle_irq</code>-&gt;<code>__gic_handle_irq_from_irqson</code>&#x8FDB;&#x4E00;&#x6B65;&#x8C03;&#x7528;</p>
<pre><code class="language-cpp">static void __gic_handle_irq_from_irqson(struct pt_regs *regs)
{
	bool is_nmi;
	u32 irqnr;

	irqnr = gic_read_iar(); // &#x83B7;&#x53D6;&#x5F53;&#x524D;&#x4E2D;&#x65AD;&#x7684;&#x786C;&#x4EF6;&#x4E2D;&#x65AD;&#x53F7;

	is_nmi = gic_rpr_is_nmi_prio();

	if (is_nmi) {
		nmi_enter();
		__gic_handle_nmi(irqnr, regs); // &#x5982;&#x679C;&#x662F;nmi&#x4E2D;&#x65AD;&#x6267;&#x884C;&#x7279;&#x5B9A;&#x51FD;&#x6570;
		nmi_exit();
	}

	if (gic_prio_masking_enabled()) {
		gic_pmr_mask_irqs();
		gic_arch_enable_irqs();
	}

	if (!is_nmi)
		__gic_handle_irq(irqnr, regs); // &#x8FDB;&#x4E00;&#x6B65;&#x6267;&#x884C;&#x4E2D;&#x65AD;&#x8C03;&#x7528;
}
</code></pre>
<p>&#x800C;<code>__gic_handle_irq</code>&#x4E2D;&#x5219;&#x5229;&#x7528;<code>irqnr</code>&#x8FDB;&#x4E00;&#x6B65;&#x83B7;&#x53D6;&#x4E2D;&#x65AD;&#x7684;&#x53F7;</p>
<pre><code class="language-cpp">static void __gic_handle_irq(u32 irqnr, struct pt_regs *regs)
{
	if (gic_irqnr_is_special(irqnr))
		return;

	gic_complete_ack(irqnr);

	if (generic_handle_domain_irq(gic_data.domain, irqnr)) {
		WARN_ONCE(true, &quot;Unexpected interrupt (irqnr %u)\n&quot;, irqnr);
		gic_deactivate_unhandled(irqnr);
	}
}

int generic_handle_domain_irq(struct irq_domain *domain, unsigned int hwirq)
{
	return handle_irq_desc(irq_resolve_mapping(domain, hwirq));
}
EXPORT_SYMBOL_GPL(generic_handle_domain_irq);
</code></pre>
<p>&#x800C;&#x5728;<code>irq_resolve_mapping(domain, hwirq)</code>&#x5219;&#x662F;&#x901A;&#x8FC7;domain&#xFF0C;&#x6765;&#x67E5;&#x627E;hwirq&#x5BF9;&#x5E94;&#x7684;irq_desc&#xFF0C;&#x6700;&#x7EC8;&#x518D;&#x901A;&#x8FC7;&#x6700;&#x521D;&#x7ED1;&#x5B9A;&#x7684;handler&#x6765;&#x8C03;&#x7528;&#x771F;&#x6B63;&#x7684;&#x4E2D;&#x65AD;&#x5904;&#x7406;&#x51FD;&#x6570;&#x3002;</p>
<h2 id="8%E3%80%81irq%E4%BC%98%E5%85%88%E7%BA%A7">8&#x3001;irq&#x4F18;&#x5148;&#x7EA7;</h2>
<p>&#x5BF9;&#x4E8E;linux kernel&#x800C;&#x8A00;&#xFF0C;&#x672C;&#x8EAB;&#x662F;&#x4E0D;&#x5B58;&#x5728;&#x4E2D;&#x65AD;&#x4F18;&#x5148;&#x7EA7;&#x533A;&#x5206;&#x7684;&#xFF0C;&#x8FD9;&#x90E8;&#x5206;&#x5DE5;&#x4F5C;&#x5219;&#x7531;&#x4E2D;&#x65AD;&#x63A7;&#x5236;&#x5668;&#x6765;&#x5B9E;&#x73B0;&#xFF0C;&#x901A;&#x8FC7;&#x7F16;&#x7A0B;&#x8BBE;&#x7F6E;&#x4E0D;&#x540C;&#x4E2D;&#x65AD;&#x7684;&#x4F18;&#x5148;&#x7EA7;&#xFF0C;&#x6765;&#x5B9E;&#x73B0;&#x63A5;&#x6536;&#x5230;&#x7684;&#x5916;&#x90E8;&#x4E2D;&#x65AD;&#x6309;&#x7167;&#x4F18;&#x5148;&#x7EA7;&#x53D1;&#x9001;&#x7ED9;CPU&#x8FDB;&#x4E00;&#x6B65;&#x54CD;&#x5E94;&#x3002;</p>
<p>&#x5728;arm64&#x4E2D;&#xFF0C;gicv3&#x662F;&#x5728;&#x5982;&#x4E0B;&#x4F4D;&#x7F6E;&#x8FDB;&#x884C;&#x7684;&#x4E2D;&#x65AD;&#x4F18;&#x5148;&#x7EA7;&#x8BBE;&#x5B9A;</p>
<p><code>gic_dist_init</code>-&gt;<code>gic_dist_config</code></p>
<pre><code class="language-cpp">void gic_dist_config(void __iomem *base, int gic_irqs,
		     void (*sync_access)(void))
{
	unsigned int i;

	/*
	 * Set all global interrupts to be level triggered, active low.
	 */
	for (i = 32; i &lt; gic_irqs; i += 16)
		writel_relaxed(GICD_INT_ACTLOW_LVLTRIG,
					base + GIC_DIST_CONFIG + i / 4);

	/*
	 * Set priority on all global interrupts.
	 */
	for (i = 32; i &lt; gic_irqs; i += 4)
		writel_relaxed(GICD_INT_DEF_PRI_X4, base + GIC_DIST_PRI + i); // &#x4ECE;32&#x53F7;&#x4E2D;&#x65AD;&#x5F00;&#x59CB;&#xFF0C;&#x5C06;&#x6240;&#x6709;&#x7684;ppi&#x5916;&#x90E8;&#x4E2D;&#x65AD;&#x8BBE;&#x5B9A;&#x4E3A;&#x4E00;&#x6837;&#x7684;&#x4F18;&#x5148;&#x7EA7;
  ......
}
</code></pre>
<p>&#x9700;&#x8981;&#x8865;&#x5145;&#x8BF4;&#x660E;&#x7684;&#x662F;&#xFF0C;&#x8FD9;&#x91CC;&#x5904;&#x7406;&#x7684;&#x5176;&#x5B9E;&#x90FD;&#x662F;irq&#x4F18;&#x5148;&#x7EA7;&#xFF0C;&#x8FD9;&#x4E0E;<code>&#x4E2D;&#x65AD;&#x7684;&#x4F18;&#x5148;&#x7EA7;</code>&#x662F;&#x5305;&#x542B;&#x5173;&#x7CFB;&#x7684;&#xFF0C;&#x5728;arm64&#x4E2D;&#xFF1A;</p>
<p>&#x4E2D;&#x65AD;&#x548C;&#x5F02;&#x5E38;&#x6709;&#x4E00;&#x4E2A;&#x56FA;&#x5B9A;&#x7684;&#x4F18;&#x5148;&#x7EA7;&#x987A;&#x5E8F;&#xFF0C;&#x8FD9;&#x4E2A;&#x4F18;&#x5148;&#x7EA7;&#x987A;&#x5E8F;&#x662F;&#x7531;ARM&#x7684;&#x786C;&#x4EF6;&#x8BBE;&#x8BA1;&#x51B3;&#x5B9A;&#x7684;&#xFF0C;&#x4E0D;&#x540C;&#x7684;&#x4E2D;&#x65AD;&#x548C;&#x5F02;&#x5E38;&#x7C7B;&#x578B;&#x6709;&#x4E0D;&#x540C;&#x7684;&#x4F18;&#x5148;&#x7EA7;&#x3002;&#x5F53;&#x591A;&#x4E2A;&#x4E2D;&#x65AD;&#x6216;&#x5F02;&#x5E38;&#x540C;&#x65F6;&#x53D1;&#x751F;&#x65F6;&#xFF0C;&#x786C;&#x4EF6;&#x4F1A;&#x6309;&#x7167;&#x8FD9;&#x4E2A;&#x4F18;&#x5148;&#x7EA7;&#x987A;&#x5E8F;&#x6765;&#x51B3;&#x5B9A;&#x9996;&#x5148;&#x5904;&#x7406;&#x54EA;&#x4E00;&#x4E2A;&#x3002;</p>
<p>&#x4EE5;&#x4E0B;&#x662F;ARM&#x67B6;&#x6784;&#x4E2D;&#x7684;&#x4E2D;&#x65AD;&#x548C;&#x5F02;&#x5E38;&#x7684;&#x4F18;&#x5148;&#x7EA7;&#x987A;&#x5E8F;&#xFF1A;</p>
<ol>
<li>&#x590D;&#x4F4D;&#xFF08;Reset&#xFF09;&#xFF1A;&#x8FD9;&#x662F;&#x6700;&#x9AD8;&#x4F18;&#x5148;&#x7EA7;&#x7684;&#x5F02;&#x5E38;&#xFF0C;&#x5F53;&#x7CFB;&#x7EDF;&#x590D;&#x4F4D;&#x65F6;&#x4F1A;&#x89E6;&#x53D1;&#x8FD9;&#x4E2A;&#x5F02;&#x5E38;&#x3002;</li>
<li>&#x6570;&#x636E;&#x4E2D;&#x6B62;&#xFF08;Data Abort&#xFF09;&#xFF1A;&#x8FD9;&#x4E2A;&#x5F02;&#x5E38;&#x662F;&#x7531;&#x4E8E;&#x5185;&#x5B58;&#x8BBF;&#x95EE;&#x9519;&#x8BEF;&#xFF08;&#x5982;&#x975E;&#x6CD5;&#x8BBF;&#x95EE;&#x3001;&#x8BBF;&#x95EE;&#x672A;&#x5BF9;&#x9F50;&#x7B49;&#xFF09;&#x5F15;&#x8D77;&#x7684;&#x3002;</li>
<li>FIQ&#xFF08;Fast Interrupt&#xFF09;&#xFF1A;&#x8FD9;&#x662F;&#x4E00;&#x79CD;&#x9AD8;&#x4F18;&#x5148;&#x7EA7;&#x7684;&#x4E2D;&#x65AD;&#xFF0C;&#x901A;&#x5E38;&#x7528;&#x4E8E;&#x9700;&#x8981;&#x5FEB;&#x901F;&#x54CD;&#x5E94;&#x7684;&#x786C;&#x4EF6;&#x4E8B;&#x4EF6;&#x3002;</li>
<li>IRQ&#xFF08;Interrupt Request&#xFF09;&#xFF1A;&#x8FD9;&#x662F;&#x4E00;&#x79CD;&#x666E;&#x901A;&#x4F18;&#x5148;&#x7EA7;&#x7684;&#x4E2D;&#x65AD;&#xFF0C;&#x7528;&#x4E8E;&#x5904;&#x7406;&#x5E38;&#x89C4;&#x7684;&#x786C;&#x4EF6;&#x4E8B;&#x4EF6;&#x3002;</li>
<li>&#x9884;&#x53D6;&#x4E2D;&#x6B62;&#xFF08;Prefetch Abort&#xFF09;&#xFF1A;&#x8FD9;&#x4E2A;&#x5F02;&#x5E38;&#x662F;&#x7531;&#x4E8E;&#x6307;&#x4EE4;&#x9884;&#x53D6;&#x9519;&#x8BEF;&#xFF08;&#x5982;&#x8BBF;&#x95EE;&#x975E;&#x6CD5;&#x5730;&#x5740;&#x7B49;&#xFF09;&#x5F15;&#x8D77;&#x7684;&#x3002;</li>
<li>&#x672A;&#x5B9A;&#x4E49;&#x6307;&#x4EE4;&#xFF08;Undefined Instruction&#xFF09;&#x548C;&#x8F6F;&#x4EF6;&#x4E2D;&#x65AD;&#xFF08;Software Interrupt&#xFF09;&#xFF1A;&#x8FD9;&#x4E24;&#x79CD;&#x5F02;&#x5E38;&#x7684;&#x4F18;&#x5148;&#x7EA7;&#x662F;&#x6700;&#x4F4E;&#x7684;&#xFF0C;&#x5F53;&#x6267;&#x884C;&#x4E00;&#x6761;&#x672A;&#x5B9A;&#x4E49;&#x7684;&#x6307;&#x4EE4;&#x6216;&#x8005;&#x8F6F;&#x4EF6;&#x89E6;&#x53D1;&#x4E00;&#x4E2A;&#x4E2D;&#x65AD;&#x65F6;&#xFF0C;&#x4F1A;&#x4EA7;&#x751F;&#x8FD9;&#x4E24;&#x79CD;&#x5F02;&#x5E38;&#x3002;</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[kdump调试]]></title><description><![CDATA[<h2 id="1-%E8%83%8C%E6%99%AF">1-&#x80CC;&#x666F;</h2>
<p>kdump&#x662F;linux&#x7528;&#x6765;&#x5206;&#x6790;crash&#x95EE;&#x9898;&#x7684;&#x4E00;&#x79CD;&#x624B;&#x6BB5;&#xFF0C;&#x5728;&#x5185;&#x6838;&#x53D1;&#x751F;crash&#x540E;&#xFF0C;&#x4F1A;&#x4E3B;&#x52A8;&#x542F;&#x52A8;&#x7B2C;&#x4E8C;&#x5185;&#x6838;&#xFF0C;&#x5C06;&#x5F53;&#x524D;&#x5185;&#x5B58;&#x4E2D;&#x7684;&#x6240;&#x6709;&#x72B6;&#x6001;&#x8F6C;&#x5B58;</p>]]></description><link>http://www.korantli.com.cn/linux/kdump/</link><guid isPermaLink="false">6639c82a2bc2afda5bd2ed00</guid><category><![CDATA[linux工具]]></category><category><![CDATA[linux技术总结]]></category><dc:creator><![CDATA[李星辉]]></dc:creator><pubDate>Tue, 07 May 2024 06:21:42 GMT</pubDate><content:encoded><![CDATA[<h2 id="1-%E8%83%8C%E6%99%AF">1-&#x80CC;&#x666F;</h2>
<p>kdump&#x662F;linux&#x7528;&#x6765;&#x5206;&#x6790;crash&#x95EE;&#x9898;&#x7684;&#x4E00;&#x79CD;&#x624B;&#x6BB5;&#xFF0C;&#x5728;&#x5185;&#x6838;&#x53D1;&#x751F;crash&#x540E;&#xFF0C;&#x4F1A;&#x4E3B;&#x52A8;&#x542F;&#x52A8;&#x7B2C;&#x4E8C;&#x5185;&#x6838;&#xFF0C;&#x5C06;&#x5F53;&#x524D;&#x5185;&#x5B58;&#x4E2D;&#x7684;&#x6240;&#x6709;&#x72B6;&#x6001;&#x8F6C;&#x5B58;&#x81F3;&#x672C;&#x5730;&#x6587;&#x4EF6;vmcore&#x4E2D;&#x3002;</p>
<p>&#x4F46;&#x662F;&#x6709;&#x4E9B;&#x670D;&#x52A1;&#x5668;&#x603B;&#x662F;&#x65E0;&#x6CD5;&#x6B63;&#x5E38;&#x751F;&#x4EA7;vmcore&#xFF0C;&#x6211;&#x4EEC;&#x8FD9;&#x91CC;&#x603B;&#x7ED3;&#x4E00;&#x4E9B;&#x7B80;&#x5355;&#x7684;&#x8C03;&#x8BD5;&#x624B;&#x6BB5;&#x3002;</p>
<p>&#x6211;&#x4EEC;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x4E3B;&#x52A8;&#x89E6;&#x53D1;&#x4E00;&#x4E2A;crash&#x6765;&#x9A8C;&#x8BC1;&#x673A;&#x5668;&#x662F;&#x5426;&#x53EF;&#x4EE5;&#x751F;&#x6210;kdump</p>
<pre><code class="language-bash">echo c &gt; /proc/sysrq-trigger
</code></pre>
<h2 id="2-%E7%94%A8%E6%88%B7%E6%80%81%E6%9C%8D%E5%8A%A1">2-&#x7528;&#x6237;&#x6001;&#x670D;&#x52A1;</h2>
<p>kdump&#x5B58;&#x5728;&#x4E00;&#x4E2A;&#x7528;&#x6237;&#x6001;&#x670D;&#x52A1;<code>kdump.service</code>&#xFF0C;&#x6211;&#x4EEC;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x67E5;&#x770B;&#x8FD9;&#x4E2A;&#x670D;&#x52A1;&#x72B6;&#x6001;&#x68C0;&#x67E5;&#x7528;&#x6237;&#x6001;&#x662F;&#x5426;&#x5DF2;&#x7ECF;&#x4F4F;&#x5907;&#x597D;&#x4E86;&#x6B63;&#x5E38;&#x6355;&#x83B7;&#x5185;&#x6838;panic&#x4E8B;&#x4EF6;&#x3002;</p>
<p>&#x5982;&#x4E0B;&#x662F;&#x4E00;&#x4E2A;&#x6B63;&#x5E38;&#x7684;kdump.service&#x72B6;&#x6001;</p>
<pre><code class="language-bash">$ systemctl status kdump.service
&#x25CF; kdump.service - Crash recovery kernel arming
   Loaded: loaded (/usr/lib/systemd/system/kdump.service; enabled; vendor preset: enabled)
   Active: active (exited) since Mon 2024-04-29 11:43:40 CST; 1 weeks 0 days ago
  Process: 1308 ExecStart=/usr/bin/kdumpctl start (code=exited, status=0/SUCCESS)
 Main PID: 1308 (code=exited, status=0/SUCCESS)
    Tasks: 0 (limit: 410253)
   Memory: 0B
   CGroup: /system.slice/kdump.service

Warning: Journal has been rotated since unit was started. Log output is incomplete or unavailable.
</code></pre>
<p>&#x5982;&#x679C;&#x670D;&#x52A1;&#x5B58;&#x5728;&#x5F02;&#x5E38;&#xFF0C;&#x5219;&#x8981;&#x901A;&#x8FC7;&#x5177;&#x4F53;&#x7684;&#x62A5;&#x9519;&#x4FE1;&#x606F;&#x89E3;&#x51B3;&#xFF0C;&#x6B63;&#x5E38;&#x6765;&#x8BF4;<code>kdump.service</code>&#x4F1A;&#x5728;&#x5F02;&#x5E38;&#x540E;&#x6253;&#x5370;log&#x5E76;&#x8F6C;&#x5B58;&#xFF0C;&#x5177;&#x4F53;&#x7684;&#x8DEF;&#x5F84;&#x53EF;&#x4EE5;&#x5728;&#x4E0A;&#x8FF0;&#x547D;&#x4EE4;&#x7684;&#x8FD4;&#x56DE;&#x4E2D;&#x68C0;&#x67E5;&#x3002;</p>
<h2 id="3-%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6">3-&#x914D;&#x7F6E;&#x6587;&#x4EF6;</h2>
<p>kdump&#x7684;&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x4F4D;&#x4E8E;<code> /etc/kdump.conf</code>&#xFF0C;&#x4F8B;&#x5982;&#x5982;&#x4E0B;&#x5185;&#x5BB9;</p>
<pre><code class="language-python">path /var/crash
core_collector makedumpfile -l --message-level 7 -d 31
extra_bins /bin/sort /bin/df /bin/wc /bin/find
keep_old_dumps 1
</code></pre>
<ul>
<li>&#x7B2C;&#x4E00;&#x884C;&#xFF1A;&#x6307;&#x4EE3;&#x5B58;&#x5728;dump&#x4F4D;&#x7F6E;</li>
<li>&#x7B2C;&#x4E8C;&#x884C;&#xFF1A;&#x4F7F;&#x7528;makedumpfile&#x547D;&#x4EE4;&#x6765;&#x6536;&#x96C6;&#x5D29;&#x6E83;&#x8F6C;&#x50A8;&#xFF0C;-l&#x9009;&#x9879;&#x8868;&#x793A;&#x4F7F;&#x7528;lzo&#x538B;&#x7F29;&#xFF0C;--message-level 7&#x8868;&#x793A;&#x8BBE;&#x7F6E;&#x6D88;&#x606F;&#x7EA7;&#x522B;&#x4E3A;7&#xFF0C;-d 31&#x8868;&#x793A;&#x8FC7;&#x6EE4;&#x6240;&#x6709;&#x4E0D;&#x5FC5;&#x8981;&#x7684;&#x4FE1;&#x606F;&#x3002;</li>
<li>&#x7B2C;&#x4E09;&#x884C;&#xFF1A;&#x5B9A;&#x4E49;&#x4E86;&#x5728;&#x521D;&#x59CB;&#x5316;ramdisk&#x4E2D;&#x5305;&#x542B;&#x7684;&#x989D;&#x5916;&#x7684;&#x53EF;&#x6267;&#x884C;&#x6587;&#x4EF6;</li>
<li>&#x7B2C;&#x56DB;&#x884C;&#xFF1A;&#x8FD9;&#x4E2A;&#x5B57;&#x6BB5;&#x5B9A;&#x4E49;&#x4E86;&#x4FDD;&#x7559;&#x65E7;&#x7684;kdump&#x6587;&#x4EF6;&#x7684;&#x6570;&#x91CF;</li>
</ul>
<h2 id="4-%E5%90%AF%E5%8A%A8%E8%A1%8C%E5%91%BD%E4%BB%A4">4-&#x542F;&#x52A8;&#x884C;&#x547D;&#x4EE4;</h2>
<p>&#x5728;&#x542F;&#x52A8;&#x884C;&#x4E2D;&#xFF0C;&#x4F1A;&#x5728;&#x6709;&#x5B9A;&#x4E49;kdump&#x5927;&#x5C0F;&#x7684;&#x547D;&#x4EE4;&#xFF0C;&#x5982;&#x679C;&#x8FD9;&#x91CC;&#x914D;&#x7F6E;&#x7684;&#x4E0D;&#x5408;&#x7406;&#x4E5F;&#x53EF;&#x80FD;&#x4F1A;&#x8F6C;&#x5B58;&#x5931;&#x8D25;</p>
<pre><code>crashkernel=1800M-64G:256M,64G-128G:512M,128G-:768M
</code></pre>
<p>&#x8FD9;&#x91CC;&#x7684;&#x542B;&#x4E49;&#x662F;&#x524D;&#x8FB9;&#x5927;&#x5C0F;&#x8868;&#x793A;&#x670D;&#x52A1;&#x5668;&#x5185;&#x5B58;&#x5927;&#x5C0F;&#xFF0C;&#x540E;&#x8FB9;&#x8868;&#x793A;&#x6B64;&#x65F6;kdump&#x7684;&#x5927;&#x5C0F;</p>
<h2 id="5-%E7%AC%AC%E4%BA%8C%E5%86%85%E6%A0%B8%E9%97%AE%E9%A2%98">5-&#x7B2C;&#x4E8C;&#x5185;&#x6838;&#x95EE;&#x9898;</h2>
<p>&#x7531;&#x4E8E;&#x8F6C;&#x5B58;vmcore&#x9700;&#x8981;&#x542F;&#x52A8;&#x7B2C;&#x4E8C;&#x5185;&#x6838;&#x8FDB;&#x884C;&#x6355;&#x83B7;&#xFF0C;&#x9047;&#x5230;&#x8FC7;&#x7B2C;&#x4E8C;&#x5185;&#x6838;&#x5728;&#x542F;&#x52A8;&#x4E2D;&#x5B58;&#x5728;&#x6545;&#x969C;&#xFF0C;&#x6BCF;&#x6B21;&#x542F;&#x52A8;&#x540E;&#x90FD;&#x4F1A;&#x5728;&#x7B2C;&#x4E8C;&#x5185;&#x6838;&#x4E2D;&#x518D;&#x6B21;crash&#x7684;&#x95EE;&#x9898;&#x3002;</p>
<p>&#x9047;&#x5230;&#x8FD9;&#x79CD;&#x95EE;&#x9898;&#x5C31;&#x9700;&#x8981;&#x4E32;&#x53E3;&#x8F93;&#x51FA;&#x5230;&#x63A7;&#x5236;&#x53F0;&#x4E0A;&#xFF0C;&#x5177;&#x4F53;&#x5206;&#x6790;&#x7B2C;&#x4E8C;&#x5185;&#x6838;&#x542F;&#x52A8;&#x9636;&#x6BB5;&#x7684;&#x65E5;&#x5FD7;&#xFF0C;&#x6240;&#x4EE5;&#x8FD9;&#x79CD;&#x95EE;&#x9898;&#x4F7F;&#x7528;&#x53EF;&#x4EE5;&#x63A7;&#x5236;&#x7684;&#x865A;&#x62DF;&#x673A;&#x6216;&#x8005;&#x7269;&#x7406;&#x673A;&#x4F1A;&#x6BD4;&#x8F83;&#x597D;&#x5206;&#x6790;&#x3002;</p>
]]></content:encoded></item><item><title><![CDATA[linux进程管理-1描述符和状态]]></title><description><![CDATA[<h2 id="1%E3%80%81taskstruct%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84">1&#x3001;task_struct&#x6570;&#x636E;&#x7ED3;&#x6784;</h2>
<p>&#x63CF;&#x8FF0;&#x8FDB;&#x7A0B;&#x72B6;&#x6001;&#x7684;&#x57FA;&#x7840;&#x6570;&#x636E;&#x7ED3;&#x6784;&#x540D;&#x79F0;&#x662F;<code>task_struct</code>&#xFF0C;&#x5728;&#x5185;&#x6838;&#x7684;<code>include/linux/sched.h</code>&#x4E2D;&#x5B9A;&#x4E49;&#x3002;</p>
<p>&#x968F;&#x7740;&#x5185;&#x6838;&#x7684;&#x53D1;&#x5C55;&#xFF0C;&#x8FD9;&#x4E2A;&#x7ED3;</p>]]></description><link>http://www.korantli.com.cn/linux/linuxjin-cheng-guan-li-1miao-shu-fu-he-zhuang-tai/</link><guid isPermaLink="false">6588682c2bc2afda5bd2ec47</guid><category><![CDATA[linux进程管理]]></category><category><![CDATA[linux技术总结]]></category><dc:creator><![CDATA[李星辉]]></dc:creator><pubDate>Sun, 24 Dec 2023 17:26:25 GMT</pubDate><media:content url="http://www.korantli.com.cn/content/images/2023/12/DALL-E-2023-12-25-01.24.29---An-eye-catching-cover-image-for-a-Linux-process-management-technical-article--featuring-a-clear-Linux-command-line-interface-with-process-management-c.jpg" medium="image"/><content:encoded><![CDATA[<h2 id="1%E3%80%81taskstruct%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84">1&#x3001;task_struct&#x6570;&#x636E;&#x7ED3;&#x6784;</h2>
<img src="http://www.korantli.com.cn/content/images/2023/12/DALL-E-2023-12-25-01.24.29---An-eye-catching-cover-image-for-a-Linux-process-management-technical-article--featuring-a-clear-Linux-command-line-interface-with-process-management-c.jpg" alt="linux&#x8FDB;&#x7A0B;&#x7BA1;&#x7406;-1&#x63CF;&#x8FF0;&#x7B26;&#x548C;&#x72B6;&#x6001;"><p>&#x63CF;&#x8FF0;&#x8FDB;&#x7A0B;&#x72B6;&#x6001;&#x7684;&#x57FA;&#x7840;&#x6570;&#x636E;&#x7ED3;&#x6784;&#x540D;&#x79F0;&#x662F;<code>task_struct</code>&#xFF0C;&#x5728;&#x5185;&#x6838;&#x7684;<code>include/linux/sched.h</code>&#x4E2D;&#x5B9A;&#x4E49;&#x3002;</p>
<p>&#x968F;&#x7740;&#x5185;&#x6838;&#x7684;&#x53D1;&#x5C55;&#xFF0C;&#x8FD9;&#x4E2A;&#x7ED3;&#x6784;&#x4F53;&#x91CC;&#x7684;&#x5185;&#x5BB9;&#x8D8A;&#x6765;&#x8D8A;&#x591A;&#xFF0C;6.6&#x7684;&#x7248;&#x672C;&#x4E0A;&#xFF0C;&#x73B0;&#x5728;&#x76F4;&#x63A5;800+&#x884C;&#xFF0C;&#x4E0B;&#x8FB9;&#x622A;&#x53D6;&#x4E00;&#x4E9B;&#x5173;&#x952E;&#x7684;&#x7247;&#x6BB5;&#x3002;</p>
<pre><code class="language-c">struct task_struct {
#ifdef CONFIG_THREAD_INFO_IN_TASK
	/*
	 * For reasons of header soup (see current_thread_info()), this
	 * must be the first element of task_struct.
	 */
	struct thread_info		thread_info;
#endif
	unsigned int			__state; // &#x8FDB;&#x7A0B;&#x7684;&#x51E0;&#x79CD;&#x72B6;&#x6001;&#xFF0C;running&#x3001;dead&#x3001;zombie&#x3001;d&#x72B6;&#x6001;&#x7B49;
......
	int				prio; // &#x8FDB;&#x7A0B;&#x4F18;&#x5148;&#x7EA7;
	int				static_prio;
	int				normal_prio;
	unsigned int			rt_priority;
	struct sched_entity		se; // &#x8FDB;&#x7A0B;&#x7684;&#x8C03;&#x5EA6;&#x6570;&#x636E;&#x7ED3;&#x6784;
	struct sched_rt_entity		rt;
	struct sched_dl_entity		dl;
	const struct sched_class	*sched_class;
#ifdef CONFIG_CGROUP_SCHED
	struct task_group		*sched_task_group; // &#x8FDB;&#x7A0B;&#x8C03;&#x5EA6;&#x7684;cgroup&#x7EC4;
#endif
......
	unsigned int			policy;
	int				nr_cpus_allowed; // &#x5141;&#x8BB8;&#x8C03;&#x5EA6;&#x7684;CPU
	const cpumask_t			*cpus_ptr; // &#x8FDB;&#x7A0B;&#x6240;&#x5728;&#x7684;CPU mask&#x6570;&#x636E;&#x7ED3;&#x6784;
	cpumask_t			*user_cpus_ptr;
	cpumask_t			cpus_mask;
	void				*migration_pending;
	struct sched_info		sched_info; // &#x6709;&#x5173;&#x4EFB;&#x52A1;&#x8C03;&#x5EA6;&#x7684;&#x7EDF;&#x8BA1;&#x4FE1;&#x606F;
	struct list_head		tasks;
	struct mm_struct		*mm; // &#x8FDB;&#x7A0B;&#x7684;&#x5185;&#x5B58;&#x76F8;&#x5173;&#x4FE1;&#x606F;
	struct mm_struct		*active_mm;
	...... // &#x540E;&#x8FB9;&#x90FD;&#x662F;&#x8868;&#x793A;&#x5185;&#x5B58;&#x7684;&#x6570;&#x636E;&#x7ED3;&#x6784;
	struct restart_block		restart_block;
	pid_t				pid; // &#x8868;&#x793A;&#x8FDB;&#x7A0B;&#x57FA;&#x7840;&#x7684;pid&#x548C;tgid&#xFF08;&#x8FDB;&#x7A0B;&#x7EC4;&#x53F7;&#xFF09;
	pid_t				tgid;
	/* Real parent process: */
	struct task_struct __rcu	*real_parent; // &#x4E00;&#x4E2A;&#x53CC;&#x5411;&#x94FE;&#x8868;&#x539F;&#x6765;&#x7BA1;&#x7406;task struct&#xFF08;&#x521B;&#x5EFA;&#x8BE5;&#x8FDB;&#x7A0B;&#x7684;&#x7236;&#x8FDB;&#x7A0B;&#xFF09;
	/* Recipient of SIGCHLD, wait4() reports: */
	struct task_struct __rcu	*parent; // &#x63A5;&#x6536;&#x5230; SIGCHLD &#x4FE1;&#x53F7;&#x7684;&#x8FDB;&#x7A0B;
	/*
	 * Children/sibling form the list of natural children:
	 */
	struct list_head		children; // &#x6811;&#x72B6;&#x7ED3;&#x6784;&#x6765;&#x7BA1;&#x7406;&#x5404;&#x4E2A;task strcut
	struct list_head		sibling;
	struct task_struct		*group_leader;
	/* PID/PID hash table linkage. */
	struct pid			*thread_pid; // &#x5404;&#x4E2A;task struct&#x7684;hash&#x8868;
	struct hlist_node		pid_links[PIDTYPE_MAX];
	struct list_head		thread_group;
	struct list_head		thread_node;
	/*
	 * executable name, excluding path.
	 *
	 * - normally initialized setup_new_exec()
	 * - access it with [gs]et_task_comm()
	 * - lock it with task_lock()
	 */
	char				comm[TASK_COMM_LEN]; //&#x8FDB;&#x7A0B;&#x540D;&#xFF0C;&#x6700;&#x5927;16&#x4E2A;&#x5B57;&#x7B26;
	struct nameidata		*nameidata;
	/* Filesystem information: */
	struct fs_struct		*fs; // &#x8FDB;&#x7A0B;&#x7684;&#x6587;&#x4EF6;&#x7CFB;&#x7EDF;&#x76F8;&#x5173;&#x8D44;&#x6E90;
	/* Open file information: */
	struct files_struct		*files; // &#x8FDB;&#x7A0B;&#x7684;&#x6587;&#x4EF6;&#x76F8;&#x5173;&#x8D44;&#x6E90;
	/* Signal handlers: */
	struct signal_struct		*signal; // &#x8FDB;&#x7A0B;&#x8C03;&#x5EA6;&#x4FE1;&#x606F;
	/* Protection against (de-)allocation: mm, files, fs, tty, keyrings, mems_allowed, mempolicy: */
	spinlock_t			alloc_lock; // &#x8BE5;&#x8FDB;&#x7A0B;&#x7684;&#x65CB;&#x9501;
	struct wake_q_node		wake_q; // &#x7528;&#x6765;&#x5524;&#x9192;&#x8FDB;&#x7A0B;&#x8C03;&#x5EA6;&#xFF0C;&#x5373;&#x8C03;&#x5EA6;&#x7684;&#x65F6;&#x5019;&#x4F53;&#x73B0;&#x51FA;&#x6765;&#x7684;wakeup&#x4E8B;&#x4EF6;
	/* CPU-specific state of this task: */
	struct thread_struct		thread;
	/*
	 * WARNING: on x86, &apos;thread_struct&apos; contains a variable-sized
	 * structure.  It *MUST* be at the end of &apos;task_struct&apos;.
	 *
	 * Do not put anything below here!
	 */
};
</code></pre>
<p>&#x4ECE;<code>task_struct</code>&#x4E2D;&#x53EF;&#x4EE5;&#x4E0D;&#x96BE;&#x770B;&#x5230;&#xFF0C;&#x5185;&#x6838;&#x4E2D;&#x7BA1;&#x7406;&#x5404;&#x4E2A;&#x8FDB;&#x7A0B;&#x7684;&#x65B9;&#x5F0F;&#x4E00;&#x5171;&#x6709;&#x4E09;&#x79CD;&#xFF1A;</p>
<ul>
<li>&#x53CC;&#x5411;&#x94FE;&#x8868;</li>
<li>&#x6811;</li>
</ul>
<p>&#x53EF;&#x4EE5;&#x6BD4;&#x8F83;&#x65B9;&#x4FBF;&#x7684;&#x7528;&#x6765;&#x67E5;&#x770B;&#x8FDB;&#x7A0B;&#x4E4B;&#x95F4;&#x7684;&#x7236;&#x5B50;&#x5173;&#x7CFB;</p>
<ul>
<li>&#x54C8;&#x5E0C;</li>
</ul>
<p>&#x5176;&#x5B9E;&#x4E3B;&#x8981;&#x662F;&#x901A;&#x8FC7;&#x4E00;&#x4E2A;&#x8868;&#x793A;&#x8FDB;&#x7A0B;pid&#x7684;hash&#x6765;&#x7BA1;&#x7406;&#xFF0C;&#x65B9;&#x4FBF;&#x901A;&#x8FC7;pid&#x53F7;&#x76F4;&#x63A5;&#x627E;&#x5230;&#x5BF9;&#x5E94;&#x8FDB;&#x7A0B;&#x7684;task_struct&#x4FE1;&#x606F;&#x3002;</p>
<p>&#x901A;&#x8FC7;<code>kernel/pid.c</code>&#x91CC;&#x7684;&#x76F8;&#x5173;&#x51FD;&#x6570;&#x8FDB;&#x884C;&#x7BA1;&#x7406;&#xFF0C;&#x6BD4;&#x5982;<code>find_pid_ns</code>&#x6216;&#x8005;<code>find_vpid</code>&#xFF0C;&#x800C;&#x7F51;&#x4E0A;&#x5E38;&#x8BF4;&#x7684;&#x5176;&#x5B9E;&#x65E9;&#x5DF2;&#x7ECF;&#x88AB;&#x5220;&#x9664;&#x4E86;&#x3002;</p>
<pre><code class="language-cpp">#define pid_hashfn(x)    hash_long((unsigned long)x, pidhash_shift)  
</code></pre>
<p>&#xFF08;&#x8FD9;&#x91CC;&#x5410;&#x69FD;&#x4E00;&#x4E0B;&#xFF0C;&#x4E2D;&#x6587;&#x4E92;&#x8054;&#x7F51;&#x771F;&#x7684;&#x662F;&#x559C;&#x6B22;&#x4F20;&#x64AD;&#x65E7;&#x7684;&#x4E1C;&#x897F;&#x3002;&#x4E00;&#x4E2A;v2.6&#x7684;&#x4EE3;&#x7801;&#xFF0C;&#x88AB;&#x65E0;&#x6570;&#x4EBA;&#x7C98;&#x8D34;&#x590D;&#x5236;&#xFF0C;&#x8FD9;&#x7BC7;2023&#x5E74;&#x7684;&#x6587;&#x7AE0;&#xFF0C;&#x8FD8;&#x5728;&#x7528;&#x8FD9;&#x4E2A;&#x5B8F;<a href="https://developer.aliyun.com/article/1204882%E3%80%82%EF%BC%89?ref=korantli.com.cn">https://developer.aliyun.com/article/1204882&#x3002;&#xFF09;</a></p>
<p>&#x4F46;&#x662F;&#x5F88;&#x5947;&#x602A;&#x7684;&#x662F;&#xFF0C;&#x4E0B;&#x8FB9;&#x8FD9;&#x4E2A;commit&#x53C8;&#x8BF4;&#x5220;&#x9664;&#x4E86;pidhash&#x7684;&#x76F8;&#x5173;&#x6570;&#x636E;&#x7ED3;&#x6784;&#xFF0C;&#x8FD9;&#x91CC;&#x53EF;&#x80FD;&#x8FD8;&#x6709;&#x540E;&#x534A;&#x518D;&#x770B;&#x4E0B;&#xFF0C;&#x662F;&#x4E0D;&#x662F;&#x5C06;pidhash&#x7684;&#x6570;&#x636E;&#x7ED3;&#x6784;&#x653E;&#x5728;&#x4E86; idr&#xFF08;ID Radix &#x6811;&#xFF09;&#x4E2D;&#xFF0C;&#x800C;&#x4E14;&#x786E;&#x5B9E;&#x4ECE;&#x4EE3;&#x7801;&#x4E2D;&#x53D1;&#x73B0;&#xFF0C;&#x53EA;&#x5269;&#x4E0B;idr init&#xFF0C;&#x800C;&#x6CA1;&#x6709;&#x4E86;hash init&#x3002;</p>
<pre><code class="language-bash">From e8cfbc245e24887e3c30235f71e9e9405e0cfc39 Mon Sep 17 00:00:00 2001
From: Gargi Sharma &lt;gs051095@gmail.com&gt;
Date: Fri, 17 Nov 2017 15:30:34 -0800
Subject: [PATCH] pid: remove pidhash

pidhash is no longer required as all the information can be looked up
from idr tree.  nr_hashed represented the number of pids that had been
hashed.  Since, nr_hashed and PIDNS_HASH_ADDING are no longer relevant,
it has been renamed to pid_allocated and PIDNS_ADDING respectively.
</code></pre>
<h2 id="2%E3%80%81%E8%BF%9B%E7%A8%8B%E7%8A%B6%E6%80%81">2&#x3001;&#x8FDB;&#x7A0B;&#x72B6;&#x6001;</h2>
<p>Linux&#x7684;&#x8FDB;&#x7A0B;&#x4E2D;&#x4E3B;&#x8981;&#x6709;5&#x79CD;&#x72B6;&#x6001;:</p>
<ul>
<li>R (TASK_RUNNING)&#xFF0C;&#x5C31;&#x7EEA;&#x6001;&#x3002;</li>
<li>S (TASK_INTERRUPTIBLE)&#xFF0C;&#x53EF;&#x4E2D;&#x65AD;&#x7684;&#x7761;&#x7720;&#x72B6;&#x6001;</li>
<li>D (TASK_UNINTERRUPTIBLE)&#xFF0C;&#x4E0D;&#x53EF;&#x4E2D;&#x65AD;&#x7684;&#x7761;&#x7720;&#x72B6;&#x6001;&#x3002;</li>
<li>Z (TASK_DEAD - EXIT_ZOMBIE)&#xFF0C;&#x50F5;&#x5C38;&#x6001;&#x3002;</li>
<li>T (TASK_STOPPED or TASK_TRACED)&#xFF0C;&#x6682;&#x505C;&#x72B6;&#x6001;&#x6216;&#x8DDF;&#x8E2A;&#x72B6;&#x6001;&#x3002;</li>
</ul>
<pre><code class="language-cpp">#define TASK_RUNNING			0x00000000
#define TASK_INTERRUPTIBLE		0x00000001
#define TASK_UNINTERRUPTIBLE		0x00000002
#define __TASK_STOPPED			0x00000004
#define __TASK_TRACED			0x00000008
/* Used in tsk-&gt;exit_state: */
#define EXIT_DEAD			0x00000010
#define EXIT_ZOMBIE			0x00000020
</code></pre>
<h3 id="21-%E5%B0%B1%E7%BB%AA%E6%80%81">2.1 &#x5C31;&#x7EEA;&#x6001;</h3>
<p>&#x8FDB;&#x7A0B;&#x4F1A;&#x5728;&#x4EE5;&#x4E0B;&#x51E0;&#x79CD;&#x60C5;&#x51B5;&#x4E0B;&#x5207;&#x6362;&#x5230;TASK_RUNNING&#x72B6;&#x6001;&#xFF08;&#x4E0D;&#x662F;&#x5168;&#x90E8;&#xFF0C;&#x4E3E;&#x4F8B;&#x8BF4;&#x660E;&#xFF09;&#xFF1A;</p>
<ol>
<li>
<p>&#x8FDB;&#x7A0B;&#x521A;&#x88AB;&#x521B;&#x5EFA;&#x65F6;&#x3002;</p>
<p>&#x5F53;&#x4E00;&#x4E2A;&#x65B0;&#x8FDB;&#x7A0B;&#x88AB;&#x521B;&#x5EFA;&#x65F6;&#xFF0C;&#x5B83;&#x7684;&#x521D;&#x59CB;&#x72B6;&#x6001;&#x662F;TASK_RUNNING&#x3002;</p>
<p>&#x5728;&#x65E9;&#x671F;&#x7684;&#x5185;&#x6838;&#x4E2D;&#xFF0C;&#x8FDB;&#x7A0B;&#x662F;&#x901A;&#x8FC7;<code>_do_fork</code>&#x6765;&#x8FDB;&#x884C;&#x521B;&#x5EFA;&#x8FDB;&#x7A0B;&#xFF0C;&#x5728;<code>v5.10</code>&#x4E2D;&#x7684;commit&#x5C06;&#x5176;&#x66F4;&#x540D;&#x4E3A;<code>kernel_clone</code></p>
<pre><code class="language-bash">commit cad6967ac10843a70842cd39c7b53412901dd21f
Author: Christian Brauner &lt;brauner@kernel.org&gt;
Date:   Wed Aug 19 12:46:45 2020 +0200

    fork: introduce kernel_clone()
</code></pre>
<p>&#x5728;&#x8FD9;&#x4E2A;&#x51FD;&#x6570;&#x4E2D;</p>
<pre><code class="language-cpp">pid_t kernel_clone(struct kernel_clone_args *args)
{
  ......
	wake_up_new_task(p);
  ......
}

void wake_up_new_task(struct task_struct *p)
{
	struct rq_flags rf;
	struct rq *rq;

	raw_spin_lock_irqsave(&amp;p-&gt;pi_lock, rf.flags);
	WRITE_ONCE(p-&gt;__state, TASK_RUNNING);
  ......
}
</code></pre>
</li>
<li>
<p>&#x8FDB;&#x7A0B;&#x4ECE;&#x7B49;&#x5F85;&#x72B6;&#x6001;&#xFF08;TASK_INTERRUPTIBLE&#x6216;TASK_UNINTERRUPTIBLE&#xFF09;&#x5524;&#x9192;&#x3002;</p>
<p>&#x5F53;&#x8FDB;&#x7A0B;&#x7B49;&#x5F85;&#x67D0;&#x4E2A;&#x4E8B;&#x4EF6;&#xFF08;&#x5982;I/O&#x5B8C;&#x6210;&#x3001;&#x4FE1;&#x53F7;&#x91CF;&#x53EF;&#x7528;&#x7B49;&#xFF09;&#x65F6;&#xFF0C;&#x5B83;&#x4F1A;&#x8FDB;&#x5165;&#x7B49;&#x5F85;&#x72B6;&#x6001;&#x3002;&#x5F53;&#x4E8B;&#x4EF6;&#x53D1;&#x751F;&#x65F6;&#xFF0C;&#x8FDB;&#x7A0B;&#x4F1A;&#x88AB;&#x5524;&#x9192;&#x5E76;&#x5207;&#x6362;&#x5230;TASK_RUNNING&#x72B6;&#x6001;&#x3002;</p>
<p>&#x6BD4;&#x8F83;&#x5E38;&#x89C1;&#x7684;&#x662F;&#x901A;&#x8FC7;<code>__wake_up_common</code>&#x6765;&#x5524;&#x9192;&#x8FDB;&#x7A0B;&#xFF0C;&#x5E76;&#x7EE7;&#x7EED;&#x6267;&#x884C;&#x76F8;&#x5173;&#x7684;&#x8C03;&#x5EA6;&#x3002;</p>
<pre><code class="language-cpp"> static int __wake_up_common(struct wait_queue_head *wq_head, unsigned int mode,
			int nr_exclusive, int wake_flags, void *key,
			wait_queue_entry_t *bookmark)
{
	wait_queue_entry_t *curr, *next;
	......
		ret = curr-&gt;func(curr, mode, wake_flags, key);
  ......
}
</code></pre>
<p>&#x901A;&#x5E38;&#x4F7F;&#x7528;<code>include/linux/wait.h</code>&#x4E2D;&#x5B9A;&#x4E49;&#x7684;<code>.func		= default_wake_function,</code>&#x6765;&#x5B9E;&#x73B0;wake&#x64CD;&#x4F5C;&#x3002;</p>
<pre><code class="language-cpp">int try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags)
{
		......
		trace_sched_waking(p);
		ttwu_do_wakeup(p);
    ......
}

static inline void ttwu_do_wakeup(struct task_struct *p)
{
	WRITE_ONCE(p-&gt;__state, TASK_RUNNING);
	trace_sched_wakeup(p);
}
</code></pre>
</li>
<li>
<p>&#x8FDB;&#x7A0B;&#x4ECE;&#x6682;&#x505C;&#x72B6;&#x6001;&#xFF08;TASK_STOPPED&#x6216;TASK_TRACED&#xFF09;&#x6062;&#x590D;&#x3002;</p>
<p>&#x5F53;&#x8FDB;&#x7A0B;&#x56E0;&#x4E3A;&#x63A5;&#x6536;&#x5230;SIGSTOP&#x3001;SIGTSTP&#x3001;SIGTTIN&#x6216;SIGTTOU&#x4FE1;&#x53F7;&#x800C;&#x6682;&#x505C;&#x65F6;&#xFF0C;&#x5B83;&#x4F1A;&#x8FDB;&#x5165;TASK_STOPPED&#x6216;TASK_TRACED&#x72B6;&#x6001;&#x3002;&#x5F53;&#x8FDB;&#x7A0B;&#x63A5;&#x6536;&#x5230;SIGCONT&#x4FE1;&#x53F7;&#x65F6;&#xFF0C;&#x5B83;&#x4F1A;&#x6062;&#x590D;&#x8FD0;&#x884C;&#x5E76;&#x5207;&#x6362;&#x5230;TASK_RUNNING&#x72B6;&#x6001;&#x3002;</p>
<pre><code class="language-cpp">static bool prepare_signal(int sig, struct task_struct *p, bool force)
{
	......
	} else if (sig == SIGCONT) {
		unsigned int why;
		/*
		 * Remove all stop signals from all queues, wake all threads.
		 */
		siginitset(&amp;flush, SIG_KERNEL_STOP_MASK);
		flush_sigqueue_mask(&amp;flush, &amp;signal-&gt;shared_pending);
		for_each_thread(p, t) {
				......
				wake_up_state(t, __TASK_STOPPED);
				......
}
</code></pre>
<p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;&#x8FD9;&#x91CC;&#x5C31;&#x662F;&#x4ECE;&#x4E00;&#x4E2A;<code>stop</code>&#x72B6;&#x6001;&#x7684;&#x8FDB;&#x7A0B;&#x5207;&#x6362;&#x56DE;&#x8FD0;&#x884C;&#x6001;&#x3002;</p>
</li>
<li>
<p>&#x6267;&#x884C;&#x6B63;&#x5E38;&#x8C03;&#x5EA6;&#x7684;&#x65F6;&#x5019;</p>
<p>&#x8FD9;&#x91CC;&#x662F;&#x6307;&#xFF0C;&#x5728;&#x8C03;&#x7528;<code>schedule()</code>&#x5BF9;queue&#x91CC;&#x7684;task&#x8FDB;&#x884C;&#x8C03;&#x5EA6;&#x65F6;&#xFF0C;&#x4F1A;&#x81EA;&#x7136;&#x5C06;&#x8FDB;&#x7A0B;&#x5207;&#x6362;&#x4E3A;running&#x6001;&#x3002;</p>
<p>&#x9996;&#x5148;&#x662F;&#x5728;<code>__schedule</code>&#x4E2D;&#xFF0C;&#x5224;&#x65AD;&#x5F53;&#x524D;&#x7684;&#x8FDB;&#x7A0B;&#xFF08;&#x5C06;&#x8981;&#x88AB;&#x5207;&#x6362;&#x8D70;&#x7684;&#xFF09;&#x662F;&#x4E0D;&#x662F;&#x6709;&#x672A;&#x5904;&#x7406;&#x7684;&#x4FE1;&#x53F7;&#xFF0C;&#x5982;&#x679C;&#x6709;&#xFF0C;&#x5219;&#x76F4;&#x63A5;&#x5C06;&#x8FD9;&#x4E2A;&#x5207;&#x6210;<code>runnnig</code></p>
<pre><code class="language-cpp">		if (signal_pending_state(prev_state, prev)) {
			WRITE_ONCE(prev-&gt;__state, TASK_RUNNING);
		} 
</code></pre>
<p>&#x63A5;&#x4E0B;&#x6765;&#xFF0C;&#x5219;&#x662F;&#x901A;&#x8FC7;cfs&#xFF0C;&#x5F00;&#x59CB;&#x9009;&#x62E9;&#x4E0B;&#x4E00;&#x4E2A;&#x6267;&#x884C;&#x7684;task&#xFF0C;&#x5E76;&#x5728;context_switch&#x91CC;&#x66F4;&#x6362;&#x4E3A;running&#x72B6;&#x6001;&#x3002;</p>
<pre><code class="language-cpp">next = pick_next_task(rq, prev, &amp;rf);
......
rq = context_switch(rq, prev, next, &amp;rf);
</code></pre>
<p>&#xFF08;gpt&#x8BF4;&#x7684;&#xFF0C;&#x6839;&#x672C;&#x6CA1;&#x627E;&#x5230;&#xFF0C;&#x8FD9;&#x91CC;&#x611F;&#x89C9;&#x6839;&#x672C;&#x5C31;&#x4E0D;&#x4F1A;&#xFF0C;cfs&#x5728;&#x6311;&#x9009;&#x7684;&#x65F6;&#x5019;&#x5B9E;&#x5728;rq&#x4E2D;&#x9009;&#x4E00;&#x4E2A;task&#xFF0C;&#x800C;rq&#x4E2D;&#x7684;task&#x5DF2;&#x7ECF;&#x662F;running&#x7684;&#x4E86;&#xFF0C;gpt&#x5728;&#x80E1;&#x626F;&#xFF09;</p>
</li>
</ol>
<h3 id="22-taskinterruptible">2.2-TASK_INTERRUPTIBLE</h3>
<p>&#x5E38;&#x89C1;&#x4E8E;&#x8FDB;&#x7A0B;&#x5B8C;&#x6210;&#x5F53;&#x524D;&#x8C03;&#x5EA6;&#x4EFB;&#x52A1;&#x540E;&#x4E3B;&#x52A8;&#x8FDB;&#x5165;&#x4F11;&#x7720;&#xFF0C;&#x4E5F;&#x53EF;&#x4EE5;&#x7528;&#x4E0E;&#x7B49;&#x5F85;&#x90E8;&#x5206;IO&#x8D44;&#x6E90;&#x3002;</p>
<p>&#x4F8B;&#x5982;&#x4E0B;&#x5217;&#x8FD9;&#x79CD;&#x7528;&#x6CD5;&#xFF0C;vcpu&#x7EBF;&#x7A0B;&#x5728;&#x6267;&#x884C;&#x5B8C;&#x5F53;&#x524D;&#x5468;&#x671F;&#x540E;&#x4E3B;&#x52A8;&#x4F1A;&#x9677;&#x5165;sleep&#xFF0C;&#x5E76;&#x8BA9;&#x51FA;CPU&#xFF0C;&#x7B49;&#x5F85;&#x4E0B;&#x4E00;&#x6B21;&#x8C03;&#x5EA6;&#x5524;&#x9192;&#x3002;</p>
<pre><code class="language-cpp">bool kvm_vcpu_block(struct kvm_vcpu *vcpu)
{
	struct rcuwait *wait = kvm_arch_vcpu_get_wait(vcpu);
	bool waited = false;

	vcpu-&gt;stat.generic.blocking = 1;

	preempt_disable();
	kvm_arch_vcpu_blocking(vcpu);
	prepare_to_rcuwait(wait);
	preempt_enable();

	for (;;) {
		set_current_state(TASK_INTERRUPTIBLE); // &#x8BBE;&#x7F6E;&#x81EA;&#x8EAB;&#x72B6;&#x6001;&#x4E3A;TASK_INTERRUPTIBLE

		if (kvm_vcpu_check_block(vcpu) &lt; 0)
			break;

		waited = true;
		schedule(); // &#x4E3B;&#x52A8;&#x8BA9;&#x51FA;CPU&#xFF0C;&#x6B63;&#x5F0F;sleep
	}

	preempt_disable();
	finish_rcuwait(wait);
	kvm_arch_vcpu_unblocking(vcpu);
	preempt_enable();

	vcpu-&gt;stat.generic.blocking = 0;

	return waited;
}
</code></pre>
<p>&#x53EF;&#x88AB;signal&#x5524;&#x9192;&#x3002;</p>
<h3 id="23-taskuninterruptible">2.3-TASK_UNINTERRUPTIBLE</h3>
<p>&#x4E3B;&#x8981;&#x662F;&#x5728;&#x7B49;&#x5F85;&#x8D44;&#x6E90;&#xFF0C;&#x4F8B;&#x5982;&#x5173;&#x952E;&#x7684;IO&#x8D44;&#x6E90;&#xFF0C;&#x4F8B;&#x5982;&#x4E0B;&#x5217;&#x8FD9;&#x6BB5;<code>md_bitmap_startwrite</code>&#x90E8;&#x5206;&#x51FD;&#x6570;</p>
<pre><code class="language-cpp">if (unlikely(COUNTER(*bmc) == COUNTER_MAX)) {
    DEFINE_WAIT(__wait);
    /* note that it is safe to do the prepare_to_wait
     * after the test as long as we do it before dropping
     * the spinlock.
     */
    prepare_to_wait(&amp;bitmap-&gt;overflow_wait, &amp;__wait,
            TASK_UNINTERRUPTIBLE);
    spin_unlock_irq(&amp;bitmap-&gt;counts.lock);
    schedule();
    finish_wait(&amp;bitmap-&gt;overflow_wait, &amp;__wait);
    continue;
}
</code></pre>
<p>&#x6709;&#x65F6;&#x5728;&#x8FDB;&#x7A0B;&#x8FDB;&#x5165;&#x5173;&#x952E;&#x6D41;&#x7A0B;&#x540E;&#xFF0C;&#x4E5F;&#x4F1A;&#x5C06;&#x5176;&#x8BBE;&#x7F6E;&#x4E3A;<code>TASK_UNINTERRUPTIBLE</code>&#xFF0C;&#x6BD4;&#x5982;&#x5728;kthread_stop&#x4E2D;&#x7B49;&#x5F85;&#x8FDB;&#x7A0B;&#x5B8C;&#x6210;&#x5E76;&#x8FD4;&#x56DE;&#x65F6;&#xFF0C;&#x4F1A;&#x5C06;&#x81EA;&#x8EAB;&#x8BBE;&#x7F6E;&#x6210;<code>TASK_UNINTERRUPTIBLE</code>&#xFF0C;&#x907F;&#x514D;&#x88AB;&#x518D;&#x6B21;&#x5176;&#x4ED6;&#x4FE1;&#x53F7;&#x610F;&#x5916;&#x5524;&#x9192;&#x3002;</p>
<pre><code class="language-cpp">void __sched wait_for_completion(struct completion *x)
{
	wait_for_common(x, MAX_SCHEDULE_TIMEOUT, TASK_UNINTERRUPTIBLE);
}
</code></pre>
<p>&#x4E0D;&#x53EF;&#x88AB;signal&#x5524;&#x9192;&#xFF0C;&#x53EA;&#x80FD;&#x9760;&#x81EA;&#x8EAB;&#x8C03;&#x5EA6;&#x5524;&#x9192;&#x3002;</p>
<h3 id="24-exitzombieexitdead">2.4-<code>EXIT_ZOMBIE</code>&amp;<code>EXIT_DEAD</code></h3>
<p>&#x5F53;&#x4E00;&#x4E2A;&#x5B50;&#x8FDB;&#x7A0B;&#x7ED3;&#x675F;&#x6267;&#x884C;&#xFF08;&#x5373;&#x5B8C;&#x6210;&#x5B83;&#x7684;&#x4EFB;&#x52A1;&#x6216;&#x88AB;&#x7EC8;&#x6B62;&#xFF09;&#xFF0C;&#x4F46;&#x5176;&#x7236;&#x8FDB;&#x7A0B;&#x5C1A;&#x672A;&#x901A;&#x8FC7;&#x8C03;&#x7528; <code>wait()</code> &#x7CFB;&#x5217;&#x51FD;&#x6570;&#x6765;&#x8BFB;&#x53D6;&#x5B50;&#x8FDB;&#x7A0B;&#x7684;&#x9000;&#x51FA;&#x72B6;&#x6001;&#x65F6;&#xFF0C;&#x5B50;&#x8FDB;&#x7A0B;&#x4F1A;&#x8FDB;&#x5165; <code>EXIT_ZOMBIE</code> &#x72B6;&#x6001;&#x3002;&#x5728;&#x8FD9;&#x79CD;&#x72B6;&#x6001;&#x4E0B;&#xFF0C;&#x5B50;&#x8FDB;&#x7A0B;&#x7684;&#x5927;&#x90E8;&#x5206;&#x8D44;&#x6E90;&#x90FD;&#x88AB;&#x91CA;&#x653E;&#x4E86;&#xFF0C;&#x4F46;&#x5B83;&#x5728;&#x8FDB;&#x7A0B;&#x8868;&#x4E2D;&#x4FDD;&#x7559;&#x4E86;&#x4E00;&#x4E2A;&#x6761;&#x76EE;&#xFF0C;&#x5176;&#x4E2D;&#x5305;&#x542B;&#x4E86;&#x9000;&#x51FA;&#x72B6;&#x6001;&#x3001;&#x8FDB;&#x7A0B;ID&#x7B49;&#x4FE1;&#x606F;&#xFF0C;&#x4EE5;&#x4FBF;&#x7236;&#x8FDB;&#x7A0B;&#x7A0D;&#x540E;&#x67E5;&#x8BE2;&#x3002;&#x5728;<code>do_exit()</code>&#x4E2D;&#x901A;&#x77E5;&#x7236;&#x8FDB;&#x7A0B;&#x7684;&#x51FD;&#x6570;&#x503C;&#x4F1A;&#x8BBE;&#x7F6E;&#x8FDB;&#x7A0B;&#x7684;&#x50F5;&#x5C38;&#x6001;&#x3002;</p>
<pre><code class="language-cpp">static void exit_notify(struct task_struct *tsk, int group_dead)
{
	bool autoreap;
	struct task_struct *p, *n;
	LIST_HEAD(dead);

	......

	tsk-&gt;exit_state = EXIT_ZOMBIE;
  ......
}
</code></pre>
<p>&#x5F53;&#x7236;&#x8FDB;&#x7A0B;&#x901A;&#x8FC7; <code>wait()</code> &#x7CFB;&#x5217;&#x51FD;&#x6570;&#x8BFB;&#x53D6;&#x4E86;&#x50F5;&#x5C38;&#x5B50;&#x8FDB;&#x7A0B;&#x7684;&#x9000;&#x51FA;&#x72B6;&#x6001;&#x540E;&#xFF0C;&#x5B50;&#x8FDB;&#x7A0B;&#x7684;&#x72B6;&#x6001;&#x4F1A;&#x53D8;&#x4E3A; <code>EXIT_DEAD</code>&#x3002;&#x5728;&#x8FD9;&#x4E2A;&#x72B6;&#x6001;&#x4E0B;&#xFF0C;&#x5B50;&#x8FDB;&#x7A0B;&#x7684;&#x8FDB;&#x7A0B;&#x8868;&#x6761;&#x76EE;&#x548C;&#x5269;&#x4F59;&#x8D44;&#x6E90;&#x5C06;&#x88AB;&#x5F7B;&#x5E95;&#x91CA;&#x653E;&#x548C;&#x56DE;&#x6536;&#x3002;&#x5728;<code>wait_task_zombie</code>&#x4E2D;&#x4F1A;&#x8BBE;&#x7F6E;&#x76F8;&#x5173;&#x72B6;&#x6001;&#x3002;</p>
<pre><code class="language-cpp">/*
 * Handle sys_wait4 work for one task in state EXIT_ZOMBIE.  We hold
 * read_lock(&amp;tasklist_lock) on entry.  If we return zero, we still hold
 * the lock and this task is uninteresting.  If we return nonzero, we have
 * released the lock and the system call should return.
 */
static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)
{
  ......
	if (state == EXIT_TRACE) {
		write_lock_irq(&amp;tasklist_lock);
		/* We dropped tasklist, ptracer could die and untrace */
		ptrace_unlink(p);

		/* If parent wants a zombie, don&apos;t release it now */
		state = EXIT_ZOMBIE;
		if (do_notify_parent(p, p-&gt;exit_signal))
			state = EXIT_DEAD;
		p-&gt;exit_state = state;
		write_unlock_irq(&amp;tasklist_lock);
	}
	if (state == EXIT_DEAD)
		release_task(p);
  ......
}
</code></pre>
<h3 id="25-tasktracedtasktraced">2.5-<code>__TASK_TRACED</code>&amp;<code>__TASK_TRACED</code></h3>
<p>__TASK_TRACED&#x8FDB;&#x7A0B;&#x88AB;&#x8FFD;&#x8E2A;&#x4E4B;&#x540E;&#x7684;&#x72B6;&#x6001;&#x3002;</p>
<pre><code class="language-cpp">static inline void ptrace_signal_wake_up(struct task_struct *t, bool resume)
{
	unsigned int state = 0;
	if (resume) {
		t-&gt;jobctl &amp;= ~JOBCTL_TRACED;
		state = __TASK_TRACED;
	}
	signal_wake_up_state(t, state);
}
</code></pre>
<p><code>__TASK_STOPPED</code> &#x72B6;&#x6001;&#x8868;&#x793A;&#x8FDB;&#x7A0B;&#x5DF2;&#x7ECF;&#x505C;&#x6B62;&#x6267;&#x884C;&#xFF0C;&#x901A;&#x5E38;&#x662F;&#x56E0;&#x4E3A;&#x6536;&#x5230;&#x4E86;&#x5982; <code>SIGSTOP</code>&#x3001;<code>SIGTSTP</code>&#x3001;<code>SIGTTIN</code> &#x6216; <code>SIGTTOU</code> &#x7B49;&#x4FE1;&#x53F7;&#x3002;</p>
<p>&#x4F8B;&#x5982;<code>do_signal_stop</code>&#x4E2D;&#x4F1A;&#x8BBE;&#x7F6E;&#x8FDB;&#x7A0B;&#x4E3A;<code>set_special_state(TASK_STOPPED);</code></p>
<h2 id="3%E3%80%81%E8%BF%9B%E7%A8%8B%E7%8A%B6%E6%80%81%E7%9A%84%E8%BD%AC%E6%8D%A2">3&#x3001;&#x8FDB;&#x7A0B;&#x72B6;&#x6001;&#x7684;&#x8F6C;&#x6362;</h2>
<p><img src="http://www.korantli.com.cn/content/images/2023/12/image-20231225004831497.png" alt="linux&#x8FDB;&#x7A0B;&#x7BA1;&#x7406;-1&#x63CF;&#x8FF0;&#x7B26;&#x548C;&#x72B6;&#x6001;" loading="lazy"></p>
]]></content:encoded></item><item><title><![CDATA[linux进程管理-2进程创建]]></title><description><![CDATA[<h2 id="0%E3%80%81%E5%89%8D%E8%A8%80">0&#x3001;&#x524D;&#x8A00;</h2>
<p>&#x4E3B;&#x8981;&#x5206;&#x6790;&#x8FDB;&#x7A0B;&#x521B;&#x5EFA;fork&#xFF0C;&#x7EBF;&#x7A0B;&#x3001;&#x8FDB;&#x7A0B;&#x5173;&#x7CFB;&#x3001;copy_on_write&#x3002;</p>
<h2 id="1%E3%80%81%E5%A4%8D%E5%88%B6%E8%BF%9B%E7%A8%8B">1&#x3001;&#x590D;&#x5236;&#x8FDB;&#x7A0B;</h2>
<p>fork&#x662F;&#x901A;&#x8FC7;<code>&#x590D;&#x5236;</code>&#x7236;&#x8FDB;&#x7A0B;&#x7684;&#x65B9;&#x5F0F;&#x6765;&#x521B;&#x5EFA;&#x4E00;&#x4E2A;&#x65B0;</p>]]></description><link>http://www.korantli.com.cn/linux/linuxjin-cheng-guan-li-2jin-cheng-chuang-jian/</link><guid isPermaLink="false">65886a482bc2afda5bd2ec5a</guid><category><![CDATA[linux进程管理]]></category><category><![CDATA[linux技术总结]]></category><dc:creator><![CDATA[李星辉]]></dc:creator><pubDate>Sun, 24 Dec 2023 17:31:22 GMT</pubDate><media:content url="http://www.korantli.com.cn/content/images/2023/12/DALL-E-2023-12-25-01.24.29---An-eye-catching-cover-image-for-a-Linux-process-management-technical-article--featuring-a-clear-Linux-command-line-interface-with-process-management-c-1.jpg" medium="image"/><content:encoded><![CDATA[<h2 id="0%E3%80%81%E5%89%8D%E8%A8%80">0&#x3001;&#x524D;&#x8A00;</h2>
<img src="http://www.korantli.com.cn/content/images/2023/12/DALL-E-2023-12-25-01.24.29---An-eye-catching-cover-image-for-a-Linux-process-management-technical-article--featuring-a-clear-Linux-command-line-interface-with-process-management-c-1.jpg" alt="linux&#x8FDB;&#x7A0B;&#x7BA1;&#x7406;-2&#x8FDB;&#x7A0B;&#x521B;&#x5EFA;"><p>&#x4E3B;&#x8981;&#x5206;&#x6790;&#x8FDB;&#x7A0B;&#x521B;&#x5EFA;fork&#xFF0C;&#x7EBF;&#x7A0B;&#x3001;&#x8FDB;&#x7A0B;&#x5173;&#x7CFB;&#x3001;copy_on_write&#x3002;</p>
<h2 id="1%E3%80%81%E5%A4%8D%E5%88%B6%E8%BF%9B%E7%A8%8B">1&#x3001;&#x590D;&#x5236;&#x8FDB;&#x7A0B;</h2>
<p>fork&#x662F;&#x901A;&#x8FC7;<code>&#x590D;&#x5236;</code>&#x7236;&#x8FDB;&#x7A0B;&#x7684;&#x65B9;&#x5F0F;&#x6765;&#x521B;&#x5EFA;&#x4E00;&#x4E2A;&#x65B0;&#x7684;&#x8FDB;&#x7A0B;&#xFF0C;&#x5185;&#x6838;&#x4E2D;&#x76F8;&#x5173;&#x952E;&#x51FD;&#x6570;&#x548C;&#x6D41;&#x7A0B;&#x4E3B;&#x8981;&#x662F;&#x88AB;&#x5B9A;&#x4E49;&#x5728;&#x4E86;<code>kernel/fork.c</code>&#x4E4B;&#x4E2D;&#xFF0C;&#x901A;&#x8FC7;<code>fork.c</code>&#x91CC;&#x6211;&#x4EEC;&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;&#x6709;&#x51E0;&#x4E2A;&#x5E38;&#x7528;&#x7684;sys_call:</p>
<ul>
<li><code>fork</code></li>
<li><code>vfork</code></li>
</ul>
<pre><code class="language-cpp">#ifdef __ARCH_WANT_SYS_FORK
SYSCALL_DEFINE0(fork)
{
#ifdef CONFIG_MMU
	struct kernel_clone_args args = {
		.exit_signal = SIGCHLD,
	};

	return kernel_clone(&amp;args);
#else
	/* can not support in nommu mode */
	return -EINVAL;
#endif
}
#endif

#ifdef __ARCH_WANT_SYS_VFORK
SYSCALL_DEFINE0(vfork)
{
	struct kernel_clone_args args = {
		.flags		= CLONE_VFORK | CLONE_VM,
		.exit_signal	= SIGCHLD,
	};

	return kernel_clone(&amp;args);
}
#endif
</code></pre>
<p>&#x63A5;&#x4E0B;&#x91CC;&#x7684;&#x5185;&#x5BB9;&#x6211;&#x4EEC;&#x5C31;&#x4F1A;&#x5206;&#x6790;&#x4E00;&#x4E0B;&#x8FD9;&#x4E9B;&#x8C03;&#x7528;&#x6D41;&#x7A0B;&#x3002;</p>
<h3 id="11-fork">1.1-fork</h3>
<p>fork&#x7684;&#x4F5C;&#x7528;&#x662F;&#xFF1A;&#x5B8C;&#x5168;&#x590D;&#x5236;&#x7236;&#x8FDB;&#x7A0B;&#xFF0C;<code>fork</code> &#x521B;&#x5EFA;&#x7684;&#x5B50;&#x8FDB;&#x7A0B;&#x662F;&#x7236;&#x8FDB;&#x7A0B;&#x7684;&#x4E00;&#x4E2A;&#x5B8C;&#x6574;&#x526F;&#x672C;&#xFF0C;&#x5305;&#x62EC;&#x7236;&#x8FDB;&#x7A0B;&#x7684;&#x6570;&#x636E;&#x6BB5;&#x3001;&#x5806;&#x548C;&#x6808;&#x7684;&#x526F;&#x672C;&#x3002;</p>
<p>&#x901A;&#x8FC7;<code>fork</code>&#x7684;&#x5B9A;&#x4E49;&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;&#x5728;&#x8C03;&#x7528;<code>kernel_clone</code>&#x4E4B;&#x524D;&#xFF0C;&#x586B;&#x5145;&#x4E86;<code>kernel_clone_args</code>&#x7ED3;&#x6784;&#x4F53;&#x3002;</p>
<pre><code class="language-cpp">	struct kernel_clone_args args = {
		.exit_signal = SIGCHLD,
	};
</code></pre>
<p>&#x8FD9;&#x91CC;&#x7684;<code>exit_signal</code>&#x8868;&#x793A;&#x5F53;&#x5B50;&#x8FDB;&#x7A0B;&#x9000;&#x51FA;&#x65F6;&#xFF0C;&#x7528;&#x6765;&#x901A;&#x77E5;&#x7236;&#x8FDB;&#x7A0B;&#x7684;&#x4FE1;&#x53F7;&#xFF0C;&#x6BD4;&#x5982; <code>SIGCHLD</code>&#x3002;</p>
<p>&#x800C;&#x6240;&#x8C13;&#x7684;&#x7236;&#x8FDB;&#x7A0B;&#x4E5F;&#x5C31;&#x662F;&#x521B;&#x5EFA;&#x4ED6;&#x7684;&#x8FDB;&#x7A0B;&#xFF0C;&#x5F53;&#x7236;&#x8FDB;&#x7A0B;&#x63A5;&#x6536;&#x5230;&#x4E86;&#x8FD9;&#x4E2A;&#x4FE1;&#x53F7;&#x540E;&#xFF0C;&#x5C31;&#x4F1A;&#x5BF9;&#x5176;&#x8FDB;&#x884C;&#x540E;&#x7EED;&#x7684;&#x76F8;&#x5173;&#x5904;&#x7406;&#xFF0C;&#x8FD9;&#x91CC;&#x5177;&#x4F53;&#x7684;<code>&#x6536;&#x5C38;</code>&#x64CD;&#x4F5C;&#x6211;&#x4EEC;&#x540E;&#x7EED;&#x4E00;&#x8D77;&#x5206;&#x6790;&#x3002;</p>
<p>&#x53E6;&#x5916;&#x4E3A;&#x4E86;&#x8282;&#x7701;&#x64CD;&#x4F5C;&#xFF0C;<code>fork</code>&#x5728;&#x521B;&#x5EFA;&#x8FDB;&#x7A0B;&#x7684;&#x65F6;&#x5019;&#xFF0C;&#x6682;&#x65F6;&#x4E0D;&#x4F1A;&#x5728;&#x521B;&#x5EFA;&#x8FDB;&#x7A0B;&#x7684;&#x65F6;&#x5019;&#x5C31;&#x4E3A;&#x5B50;&#x8FDB;&#x7A0B;&#x51C6;&#x5907;&#x597D;&#x5177;&#x4F53;&#x7684;&#x5185;&#x5B58;&#x7A7A;&#x95F4;&#xFF0C;&#x53EA;&#x5728;&#x5177;&#x4F53;&#x4FEE;&#x6539;&#x65F6;&#x624D;&#x4F1A;&#x5206;&#x914D;&#x5B9E;&#x9645;&#x7684;&#x5185;&#x5B58;&#x7A7A;&#x95F4;&#xFF0C;&#x8FD9;&#x5C31;&#x662F;<code>copy-on-write</code>&#x4E5F;&#x5C31;&#x662F;&#x5199;&#x65F6;&#x590D;&#x5236;&#x7684;&#x64CD;&#x4F5C;&#x3002;</p>
<h3 id="12-vfork">1.2-vfork</h3>
<p>&#x800C;&#x5728;<code>vfork</code>&#x4E2D;&#xFF0C;&#x4F20;&#x9012;&#x7684;&#x53C2;&#x6570;&#x6709;&#x70B9;&#x533A;&#x522B;&#x3002;</p>
<pre><code class="language-cpp">	struct kernel_clone_args args = {
		.flags		= CLONE_VFORK | CLONE_VM,
		.exit_signal	= SIGCHLD,
	};
</code></pre>
<p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;&#x8FD9;&#x91CC;&#x5728;&#x4F20;&#x9012;<code>flag</code>&#x4E2D;&#x589E;&#x52A0;&#x4E86;&#x4E24;&#x4E2A;&#x6807;&#x8BB0;&#xFF0C;&#x800C;&#x5176;&#x4F5C;&#x7528;&#x4E3B;&#x8981;&#x662F;&#x5728;&#x540E;&#x7EED;&#x6D41;&#x7A0B;&#x4E2D;&#x533A;&#x5206;<code>vfork</code>&#x64CD;&#x4F5C;&#xFF0C;<code>vfork</code>&#x521B;&#x5EFA;&#x7684;&#x5B50;&#x8FDB;&#x7A0B;&#x4E0E;&#x7236;&#x8FDB;&#x7A0B;&#x5171;&#x4EAB;&#x76F8;&#x540C;&#x7684;&#x5185;&#x5B58;&#x7A7A;&#x95F4;&#x3002;</p>
<p>&#x4F46;&#x662F;&#x8C8C;&#x4F3C;<code>vfork</code>&#x7684;&#x4F7F;&#x7528;&#x6BD4;&#x8F83;&#x5C11;&#xFF0C;&#x5C24;&#x5176;&#x662F;&#x5728;<code>fork</code>&#x5B58;&#x5728;<code>copy-on-write</code>&#x7684;&#x80CC;&#x666F;&#x4E0B;&#x3002;</p>
<h3 id="13-kernelclone">1.3-kernel_clone</h3>
<p>&#x4E0D;&#x8BBA;&#x662F;<code>fork</code>&#x8FD8;&#x662F;<code>vfork</code>&#xFF0C;&#x6700;&#x7EC8;&#x90FD;&#x4F1A;&#x8C03;&#x7528;&#x5230;<code>kernel_clone</code>&#x3002;</p>
<p><code>kernel_clone</code>&#x5728;v5.10&#x91CC;&#x88AB;&#x5F15;&#x5165;&#x5230;&#x5185;&#x6838;&#x4E4B;&#x4E2D;&#xFF0C;&#x5728;&#x65E7;&#x7684;&#x7248;&#x672C;&#x4E2D;&#x662F;<code>do_fork</code>&#x3002;</p>
<pre><code>commit cad6967ac10843a70842cd39c7b53412901dd21f
Author: Christian Brauner &lt;brauner@kernel.org&gt;
Date:   Wed Aug 19 12:46:45 2020 +0200

    fork: introduce kernel_clone()
</code></pre>
<p>&#x63A5;&#x4E0B;&#x6765;&#x6211;&#x4EEC;&#x5206;&#x6790;&#x4E00;&#x4E0B;kerne_clone&#x7684;&#x5177;&#x4F53;&#x5185;&#x5BB9;&#xFF0C;&#x6838;&#x5FC3;&#x7684;&#x64CD;&#x4F5C;&#x662F;&#x8C03;&#x7528;<code>copy_process</code>&#x590D;&#x5236;&#x8FDB;&#x7A0B;&#x3002;</p>
<pre><code class="language-cpp">pid_t kernel_clone(struct kernel_clone_args *args)
{
	......
	p = copy_process(NULL, trace, NUMA_NO_NODE, args); // &#x4E3B;&#x8981;&#x8FDB;&#x884C;&#x8FDB;&#x7A0B;&#x590D;&#x5236;
	add_latent_entropy(); // &#x521B;&#x5EFA;&#x65B0;&#x8FDB;&#x7A0B;&#x65F6;&#x589E;&#x52A0;&#x4E00;&#x4E9B;&#x968F;&#x673A;&#x6027;&#xFF0C;&#x4ECE;&#x800C;&#x63D0;&#x9AD8;&#x7CFB;&#x7EDF;&#x7684;&#x71B5;
	......

	pid = get_task_pid(p, PIDTYPE_PID); // &#x5206;&#x914D;&#x4E00;&#x4E2A;pid&#x7ED9;&#x5F53;&#x524D;&#x8FDB;&#x7A0B;
	nr = pid_vnr(pid);
	......
	if (clone_flags &amp; CLONE_VFORK) { // &#x5206;&#x914D;vfork&#x5DE5;&#x4F5C;
		p-&gt;vfork_done = &amp;vfork;
		init_completion(&amp;vfork);
		get_task_struct(p);
	}

	if (IS_ENABLED(CONFIG_LRU_GEN) &amp;&amp; !(clone_flags &amp; CLONE_VM)) { // &#x5904;&#x7406;&#x4E00;&#x4E0B;&#x8FDB;&#x7A0B;lru&#x7684;&#x76F8;&#x5173;&#x6570;&#x636E;
		/* lock the task to synchronize with memcg migration */
		task_lock(p);
		lru_gen_add_mm(p-&gt;mm);
		task_unlock(p);
	}

	wake_up_new_task(p); // &#x5524;&#x9192;&#x5F53;&#x524D;&#x8FDB;&#x7A0B;
	......
	put_pid(pid);
	return nr;
}
</code></pre>
<p><code>copy_process</code>&#x7684;&#x6D41;&#x7A0B;&#x5F88;&#x957F;&#xFF0C;&#x5C31;&#x4E0D;&#x4E00;&#x4E00;&#x5206;&#x6790;&#x4E86;&#xFF0C;&#x5176;&#x4E2D;&#x4E3B;&#x8981;&#x6D41;&#x7A0B;&#x5982;&#x4E0B;&#xFF1A;</p>
<ol>
<li>&#x9996;&#x5148;&#xFF0C;&#x51FD;&#x6570;&#x4F1A;&#x68C0;&#x67E5;<code>clone_flags</code>&#x4E2D;&#x7684;&#x4E00;&#x4E9B;&#x6807;&#x5FD7;&#xFF0C;&#x4EE5;&#x786E;&#x5B9A;&#x65B0;&#x8FDB;&#x7A0B;&#x7684;&#x4E00;&#x4E9B;&#x5C5E;&#x6027;&#x3002;&#x4F8B;&#x5982;&#xFF0C;&#x5982;&#x679C;&#x8BBE;&#x7F6E;&#x4E86;<code>CLONE_NEWNS</code>&#x548C;<code>CLONE_FS</code>&#x6807;&#x5FD7;&#xFF0C;&#x65B0;&#x8FDB;&#x7A0B;&#x5C06;&#x5728;&#x65B0;&#x7684;&#x547D;&#x540D;&#x7A7A;&#x95F4;&#x4E2D;&#xFF0C;&#x5E76;&#x4E14;&#x4E0E;&#x7236;&#x8FDB;&#x7A0B;&#x5171;&#x4EAB;&#x6587;&#x4EF6;&#x7CFB;&#x7EDF;&#x3002;</li>
<li>&#x7136;&#x540E;&#xFF0C;&#x51FD;&#x6570;&#x4F1A;&#x521B;&#x5EFA;&#x4E00;&#x4E2A;&#x65B0;&#x7684;<code>task_struct</code>&#x7ED3;&#x6784;&#x4F53;&#x5B9E;&#x4F8B;&#xFF0C;&#x8FD9;&#x4E2A;&#x7ED3;&#x6784;&#x4F53;&#x7528;&#x4E8E;&#x8868;&#x793A;&#x65B0;&#x7684;&#x8FDB;&#x7A0B;&#x3002;&#x65B0;&#x8FDB;&#x7A0B;&#x7684;&#x6240;&#x6709;&#x4FE1;&#x606F;&#x90FD;&#x5C06;&#x5B58;&#x50A8;&#x5728;&#x8FD9;&#x4E2A;&#x7ED3;&#x6784;&#x4F53;&#x4E2D;&#x3002;</li>
<li>&#x63A5;&#x7740;&#xFF0C;&#x51FD;&#x6570;&#x4F1A;&#x590D;&#x5236;&#x7236;&#x8FDB;&#x7A0B;&#x7684;&#x5404;&#x79CD;&#x5C5E;&#x6027;&#x5230;&#x65B0;&#x8FDB;&#x7A0B;&#x4E2D;&#x3002;&#x8FD9;&#x5305;&#x62EC;&#x8FDB;&#x7A0B;&#x7684;&#x51ED;&#x636E;&#xFF08;&#x5982;&#x7528;&#x6237;ID&#x548C;&#x7EC4;ID&#xFF09;&#x3001;&#x8D44;&#x6E90;&#x9650;&#x5236;&#x3001;&#x6587;&#x4EF6;&#x63CF;&#x8FF0;&#x7B26;&#x8868;&#x3001;&#x6587;&#x4EF6;&#x7CFB;&#x7EDF;&#x4E0A;&#x4E0B;&#x6587;&#x3001;&#x4FE1;&#x53F7;&#x5904;&#x7406;&#x51FD;&#x6570;&#x3001;&#x5185;&#x5B58;&#x7BA1;&#x7406;&#x7ED3;&#x6784;&#x3001;&#x547D;&#x540D;&#x7A7A;&#x95F4;&#x7B49;&#x3002;</li>
<li>&#x7136;&#x540E;&#xFF0C;&#x51FD;&#x6570;&#x4F1A;&#x5BF9;&#x65B0;&#x8FDB;&#x7A0B;&#x8FDB;&#x884C;&#x4E00;&#x4E9B;&#x521D;&#x59CB;&#x5316;&#x64CD;&#x4F5C;&#xFF0C;&#x4F8B;&#x5982;&#x8BBE;&#x7F6E;&#x8FDB;&#x7A0B;&#x7684;&#x72B6;&#x6001;&#x3001;&#x521D;&#x59CB;&#x5316;&#x8FDB;&#x7A0B;&#x7684;&#x8BA1;&#x65F6;&#x5668;&#x3001;&#x8BBE;&#x7F6E;&#x8FDB;&#x7A0B;&#x7684;&#x7236;&#x8FDB;&#x7A0B;&#x548C;&#x5B50;&#x8FDB;&#x7A0B;&#x5217;&#x8868;&#x7B49;&#x3002;</li>
<li>&#x5728;&#x6240;&#x6709;&#x8FD9;&#x4E9B;&#x64CD;&#x4F5C;&#x5B8C;&#x6210;&#x4E4B;&#x540E;&#xFF0C;&#x65B0;&#x8FDB;&#x7A0B;&#x5C06;&#x88AB;&#x6DFB;&#x52A0;&#x5230;&#x7CFB;&#x7EDF;&#x7684;&#x8FDB;&#x7A0B;&#x5217;&#x8868;&#x4E2D;&#xFF0C;&#x8FD9;&#x4F7F;&#x5F97;&#x5B83;&#x53EF;&#x4EE5;&#x88AB;&#x7CFB;&#x7EDF;&#x7684;&#x8C03;&#x5EA6;&#x5668;&#x770B;&#x5230;&#x5E76;&#x4E14;&#x5F00;&#x59CB;&#x8FD0;&#x884C;&#x3002;</li>
<li>&#x6700;&#x540E;&#xFF0C;&#x5982;&#x679C;&#x6240;&#x6709;&#x64CD;&#x4F5C;&#x90FD;&#x6210;&#x529F;&#x5B8C;&#x6210;&#xFF0C;<code>copy_process</code>&#x51FD;&#x6570;&#x5C06;&#x8FD4;&#x56DE;&#x4E00;&#x4E2A;&#x6307;&#x5411;&#x65B0;&#x8FDB;&#x7A0B;&#x7684;<code>task_struct</code>&#x7ED3;&#x6784;&#x4F53;&#x7684;&#x6307;&#x9488;&#x3002;&#x5982;&#x679C;&#x5728;&#x521B;&#x5EFA;&#x65B0;&#x8FDB;&#x7A0B;&#x7684;&#x8FC7;&#x7A0B;&#x4E2D;&#x53D1;&#x751F;&#x9519;&#x8BEF;&#xFF0C;&#x51FD;&#x6570;&#x5C06;&#x8FD4;&#x56DE;&#x4E00;&#x4E2A;&#x9519;&#x8BEF;&#x6307;&#x9488;&#x3002;</li>
</ol>
<p>&#x5728;<code>kernel_clone</code>&#x5176;&#x4E2D;<code>vfork</code>&#x7684;&#x4E00;&#x4E2A;&#x533A;&#x522B;&#x64CD;&#x4F5C;&#x662F;&#x586B;&#x5145;<code>vfork_done</code>&#x7ED3;&#x6784;&#x4F53;&#xFF0C;&#x7528;&#x6765;&#x6807;&#x8BC6;<code>vfork</code>&#x64CD;&#x4F5C;&#x5B8C;&#x6210;&#x3002;</p>
<pre><code class="language-cpp">	if (clone_flags &amp; CLONE_VFORK) { // &#x5206;&#x914D;vfork&#x5DE5;&#x4F5C;
		p-&gt;vfork_done = &amp;vfork;
		init_completion(&amp;vfork);
		get_task_struct(p);
	}
</code></pre>
<p>&#x5982;&#x679C;&#x5305;&#x542B;&#xFF0C;&#x90A3;&#x4E48;&#x5C31;&#x8BBE;&#x7F6E;&#x65B0;&#x8FDB;&#x7A0B;&#x7684;<code>vfork_done</code>&#x5B57;&#x6BB5;&#x4E3A;<code>&amp;vfork</code>&#xFF0C;&#x8FD9;&#x4E2A;&#x5B57;&#x6BB5;&#x7528;&#x4E8E;&#x6307;&#x793A;<code>vfork</code>&#x64CD;&#x4F5C;&#x4F55;&#x65F6;&#x5B8C;&#x6210;&#x3002;&#x7136;&#x540E;&#xFF0C;&#x8C03;&#x7528;<code>init_completion</code>&#x51FD;&#x6570;&#x521D;&#x59CB;&#x5316;<code>vfork</code>&#x5B8C;&#x6210;&#x53D8;&#x91CF;&#xFF0C;&#x8FD9;&#x4E2A;&#x51FD;&#x6570;&#x5C06;&#x5B8C;&#x6210;&#x53D8;&#x91CF;&#x7684;&#x72B6;&#x6001;&#x8BBE;&#x7F6E;&#x4E3A;&#x672A;&#x5B8C;&#x6210;&#x3002;</p>
<p>&#x95EE;&#x9898;&#xFF1A;fork&#x590D;&#x5236;&#x4E86;&#x65B0;&#x7684;&#x5185;&#x5B58;&#x7A7A;&#x95F4;&#xFF0C;&#x90A3;&#x6709;&#x54EA;&#x4E9B;&#x5177;&#x4F53;&#x7684;&#x5185;&#x5B58;&#x6216;&#x8005;&#x8D44;&#x6E90;&#x88AB;&#x590D;&#x5236;&#x4E86;&#x3002;</p>
<p>&#x4F8B;&#x5982;&#x5728;<code>copy_mm</code>&#x4E2D;&#xFF0C;&#x5982;&#x679C;&#x662F;vfork&#xFF0C;&#x5219;&#x628A;&#x5F53;&#x524D;&#x7684;mm&#x7ED3;&#x6784;&#x4F53;&#x6307;&#x5411;&#x7236;&#x8FDB;&#x7A0B;&#x7684;&#x3002;</p>
<pre><code class="language-cpp">	if (clone_flags &amp; CLONE_VM) {
		mmget(oldmm);
		mm = oldmm;
	} else {
		mm = dup_mm(tsk, current-&gt;mm);
		if (!mm)
			return -ENOMEM;
	}
</code></pre>
<p>&#x53E6;&#x5916;&#xFF0C;<code>copy_namespaces</code>&#x5982;&#x679C;&#x662F;<code>vfork</code>&#x7684;&#x8BDD;&#x4E5F;&#x4E0D;&#x4F1A;&#x6267;&#x884C;&#x76F8;&#x5173;&#x7684;&#x903B;&#x8F91;&#xFF0C;&#x800C;&#x662F;&#x76F4;&#x63A5;&#x8FD4;&#x56DE;&#x3002;</p>
<h3 id="14-clone3">1.4-clone3</h3>
<p>&#x53E6;&#x5916;&#x8FD8;&#x6709;&#x4E00;&#x4E2A;&#x4E0B;&#x5217;&#x5E38;&#x7528;&#x7684;<code>sys_call</code>&#xFF0C;clone3&#x53EF;&#x4EE5;&#x770B;&#x4F5C;&#x662F;&#x66F4;&#x7CBE;&#x7EC6;&#x7684;fork&#x64CD;&#x4F5C;&#x3002;&#x5141;&#x8BB8;&#x7EC6;&#x7C92;&#x5EA6;&#x63A7;&#x5236;&#x5B50;&#x8FDB;&#x7A0B;&#x7684;&#x5C5E;&#x6027;&#xFF0C;&#x5305;&#x62EC;&#x5185;&#x5B58;&#x5171;&#x4EAB;&#x3001;&#x4FE1;&#x53F7;&#x5904;&#x7406;&#x7B49;&#x3002;&#x56E0;&#x6B64;&#xFF0C;&#x66F4;&#x9002;&#x5408;&#x4E8E;&#x9700;&#x8981;&#x590D;&#x6742;&#x8FDB;&#x7A0B;&#x7BA1;&#x7406;&#x7684;&#x73B0;&#x4EE3;&#x5E94;&#x7528;&#xFF0C;&#x5982;&#x5BB9;&#x5668;&#x548C;&#x865A;&#x62DF;&#x5316;&#x3002;</p>
<pre><code class="language-cpp">SYSCALL_DEFINE2(clone3, struct clone_args __user *, uargs, size_t, size)
{
	int err;

	struct kernel_clone_args kargs;
	pid_t set_tid[MAX_PID_NS_LEVEL];

	kargs.set_tid = set_tid;

	err = copy_clone_args_from_user(&amp;kargs, uargs, size); // &#x5728;&#x7CFB;&#x7EDF;&#x8C03;&#x7528;&#x65F6;&#xFF0C;&#x6211;&#x4EEC;&#x53EF;&#x4EE5;&#x6307;&#x5B9A;&#x4F20;&#x53C2;clone_flags
	if (err)
		return err;

	if (!clone3_args_valid(&amp;kargs))
		return -EINVAL;

	return kernel_clone(&amp;kargs); // &#x6309;&#x7167;&#x7528;&#x6237;&#x6001;&#x5B9A;&#x4E49;&#x7684;clone_flags&#x6765;&#x6267;&#x884C;&#x8FDB;&#x7A0B;&#x590D;&#x5236;&#x64CD;&#x4F5C;&#x3002;
}
</code></pre>
<h2 id="2%E3%80%81%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AA%E5%85%A8%E6%96%B0%E8%BF%9B%E7%A8%8B">2&#x3001;&#x521B;&#x5EFA;&#x4E00;&#x4E2A;&#x5168;&#x65B0;&#x8FDB;&#x7A0B;</h2>
<p>&#x5F53;&#x5728;&#x7528;&#x6237;&#x6001;&#x6267;&#x884C;<code>./bin</code>&#x7684;&#x65F6;&#x5019;&#x5C31;&#x4F1A;&#x8C03;&#x7528;&#x5230;<code>execve</code>&#x7684;&#x7CFB;&#x7EDF;&#x8C03;&#x7528;&#x8FDB;&#x7A0B;&#x8FDB;&#x7A0B;&#x7684;&#x521B;&#x5EFA;&#x3002;</p>
<p>&#x5185;&#x6838;&#x4E2D;&#x901A;&#x8FC7;<code>fs/exec.c</code>&#x4E2D;&#x7684;&#x51FD;&#x6570;&#x521B;&#x5EFA;&#x4E00;&#x4E2A;&#x5168;&#x65B0;&#x7684;&#x8FDB;&#x7A0B;&#xFF0C;&#x800C;&#x4E0D;&#x662F;&#x901A;&#x8FC7;&#x590D;&#x5236;&#x7684;&#x65B9;&#x5F0F;&#x3002; <code>execve()</code>&#x7CFB;&#x7EDF;&#x8C03;&#x7528;&#x7528;&#x4E8E;&#x5728;&#x65B0;&#x521B;&#x5EFA;&#x7684;&#x8FDB;&#x7A0B;&#x4E2D;&#x52A0;&#x8F7D;&#x5E76;&#x6267;&#x884C;&#x4E00;&#x4E2A;&#x65B0;&#x7A0B;&#x5E8F;&#xFF0C;&#x66FF;&#x6362;&#x5F53;&#x524D;&#x8FDB;&#x7A0B;&#x7684;&#x5730;&#x5740;&#x7A7A;&#x95F4;&#x3002;</p>
<pre><code class="language-cpp">SYSCALL_DEFINE3(execve,
		const char __user *, filename,
		const char __user *const __user *, argv,
		const char __user *const __user *, envp)
{
	return do_execve(getname(filename), argv, envp);
}
</code></pre>
<p>&#x7ECF;&#x8FC7;&#x4E00;&#x7CFB;&#x5217;&#x7684;&#x8C03;&#x7528;&#xFF0C;&#x6700;&#x7EC8;&#x4F1A;&#x901A;&#x8FC7;<code>bprm_execve</code>&#x6765;&#x521B;&#x5EFA;&#x65B0;&#x7684;&#x8FDB;&#x7A0B;&#x3002;</p>
<pre><code class="language-cpp">/*
 * sys_execve() executes a new program.
 */
static int bprm_execve(struct linux_binprm *bprm,
		       int fd, struct filename *filename, int flags)
{
	struct file *file;
	int retval;

	retval = prepare_bprm_creds(bprm); // &#x51C6;&#x5907;&#x65B0;&#x8FDB;&#x7A0B;&#x7684;&#x51ED;&#x8BC1;&#xFF08;&#x5982;UID&#x3001;GID&#x7B49;&#xFF09;
	if (retval)
		return retval;

	/*
	 * Check for unsafe execution states before exec_binprm(), which
	 * will call back into begin_new_exec(), into bprm_creds_from_file(),
	 * where setuid-ness is evaluated.
	 */
	check_unsafe_exec(bprm);
	current-&gt;in_execve = 1; // &#x6807;&#x8BB0;&#x5F53;&#x524D;&#x8FDB;&#x7A0B;&#x6B63;&#x5728;&#x6267;&#x884C;execve
	sched_mm_cid_before_execve(current);

	file = do_open_execat(fd, filename, flags); // open&#x5F53;&#x524D;&#x7684;&#x6587;&#x4EF6;
	......
	sched_exec();
	......
	/* Set the unchanging part of bprm-&gt;cred */
	retval = security_bprm_creds_for_exec(bprm); // &#x68C0;&#x67E5;&#x8981;&#x6267;&#x884C;&#x8FDB;&#x7A0B;&#x7684;&#x5B89;&#x5168;&#x6027;&#xFF0C;&#x4F8B;&#x5982;selinux
	......
	retval = exec_binprm(bprm); // &#x6267;&#x884C;&#x4E8C;&#x8FDB;&#x5236;&#xFF0C;&#x521B;&#x5EFA;&#x8FDB;&#x7A0B;
    ......
	/* &#x6267;&#x884C;&#x6210;&#x529F;&#x540E;&#xFF0C;&#x8981;&#x91CD;&#x7F6E;&#x4E00;&#x4E0B;&#x8FDB;&#x7A0B;&#x7684;&#x7EDF;&#x8BA1;&#x4FE1;&#x606F; */
	current-&gt;fs-&gt;in_exec = 0;
	current-&gt;in_execve = 0;
	rseq_execve(current);
	user_events_execve(current);
	acct_update_integrals(current);
	task_numa_free(current, false);
	return retval;
	......
}
</code></pre>
<p>&#x800C;<code>exec_binprm</code>&#x5219;&#x4E2D;&#x4F1A;&#x8C03;&#x7528;<code>search_binary_handler</code>&#x6765;&#x641C;&#x7D22;&#x5F53;&#x524D;&#x4E8C;&#x8FDB;&#x5236;&#x7684;&#x6267;&#x884C;&#x65B9;&#x6CD5;&#xFF0C;&#x4F8B;&#x5982;&#x5982;&#x679C;&#x662F;<code>elf</code>&#x4E8C;&#x8FDB;&#x5236;&#x5219;&#x8C03;&#x7528;<code>load_elf_binary</code>&#xFF0C;&#x800C;&#x5728;&#x5176;&#x4E2D;&#x5219;&#x4F1A;&#x8BBE;&#x7F6E;&#x4E8C;&#x8FDB;&#x5236;&#x7684;&#x5165;&#x53E3;&#x51FD;&#x6570;<code>e_entry = elf_ex-&gt;e_entry + load_bias;</code>&#xFF0C;&#x5E76;&#x4E14;&#x4E5F;&#x4F1A;&#x505A;&#x597D;&#x5185;&#x5B58;&#x7A7A;&#x95F4;&#x7684;&#x51C6;&#x5907;</p>
<pre><code class="language-cpp">static int load_elf_binary(struct linux_binprm *bprm)
{
    ...

    /* &#x83B7;&#x53D6;ELF&#x5934;&#x90E8;&#x4FE1;&#x606F; */
    elf_ex = (struct elfhdr *)bprm-&gt;buf;

    /* &#x68C0;&#x67E5;ELF&#x5934;&#x90E8;&#x7684;&#x6709;&#x6548;&#x6027; */
    if (memcmp(elf_ex-&gt;e_ident, ELFMAG, SELFMAG) != 0)
        return -ENOEXEC;

    /* &#x8BFB;&#x53D6;&#x7A0B;&#x5E8F;&#x5934;&#x8868; */
    elf_phdata = load_elf_phdrs(elf_ex, bprm-&gt;file);
    if (!elf_phdata)
        return -ENOMEM;

    /* &#x8BBE;&#x7F6E;&#x7A0B;&#x5E8F;&#x7684;&#x5185;&#x5B58;&#x5E03;&#x5C40; */
    for (i = 0; i &lt; elf_ex-&gt;e_phnum; i++) {
        struct elf_phdr *elf_ppnt = &amp;elf_phdata[i];

        if (elf_ppnt-&gt;p_type == PT_LOAD) {
            error = elf_load_segment(bprm-&gt;file, bprm-&gt;vma, elf_ppnt, ...);
            ...
            if (!load_addr_set) {
                load_addr_set = 1;
                load_addr = elf_ppnt-&gt;p_vaddr - elf_ppnt-&gt;p_offset;
            }
        }
        ...
    }

    /* &#x8BBE;&#x7F6E;&#x4E8C;&#x8FDB;&#x5236;&#x7684;bss&#x548C;brk */
    elf_bss = ...;
    elf_brk = ...;

    /* &#x8BBE;&#x7F6E;&#x5F00;&#x59CB;&#x548C;&#x7ED3;&#x675F;&#x4EE3;&#x7801;/&#x6570;&#x636E;&#x5730;&#x5740; */
    start_code = ...; end_code = ...;
    start_data = ...; end_data = ...;

    /* &#x8BBE;&#x7F6E;&#x8FDB;&#x7A0B;&#x7684;&#x5165;&#x53E3;&#x70B9; */
    bprm-&gt;p = arch_align_stack(bprm-&gt;p);
    bprm-&gt;exec = bprm-&gt;p;
    retval = setup_arg_pages(bprm, ...);
    ...
    install_exec_creds(bprm);
    ...
    set_binfmt(&amp;elf_format);

    /* &#x8BBE;&#x7F6E;&#x65B0;&#x7684;&#x5806;&#x6808; */
    retval = setup_new_exec(bprm);
    ...

    /* &#x66F4;&#x65B0;&#x5F53;&#x524D;&#x8FDB;&#x7A0B;&#x7684;&#x4FE1;&#x606F; */
    current-&gt;mm-&gt;start_code = start_code;
    current-&gt;mm-&gt;end_code = end_code;
    current-&gt;mm-&gt;start_data = start_data;
    current-&gt;mm-&gt;end_data = end_data;
    current-&gt;mm-&gt;start_brk = current-&gt;mm-&gt;brk = elf_brk;
    current-&gt;mm-&gt;start_stack = bprm-&gt;p;

    /* &#x8BBE;&#x7F6E;&#x8FDB;&#x7A0B;&#x7684;&#x5165;&#x53E3;&#x5730;&#x5740; */
    current-&gt;mm-&gt;start_stack = bprm-&gt;p;
    retval = arch_setup_additional_pages(bprm, ...);
    ...
    start_thread(regs, elf_ex-&gt;e_entry, bprm-&gt;p); // &#x5F00;&#x59CB;&#x51C6;&#x5907;&#x5728;&#x7528;&#x6237;&#x6001;&#x6267;&#x884C;&#x8FDB;&#x7A0B;&#xFF0C;&#x8FD9;&#x4E2A;&#x51FD;&#x6570;&#x662F;&#x8DDF;&#x67B6;&#x6784;&#x6709;&#x5173;&#x7684;
    ...
    return 0;
}

</code></pre>
<p>&#x800C;<code>start_thread</code>&#x5219;&#x6700;&#x4F1A;&#x8C03;&#x7528;&#x5230;<code>start_thread_common</code>&#xFF0C;&#x6700;&#x7EC8;&#x8BBE;&#x7F6E;&#x7528;&#x6237;&#x6001;&#x8FDB;&#x7A0B;&#x7684;&#x51FD;&#x6570;&#x6307;&#x9488;&#xFF0C;&#x4ECE;&#x800C;&#x5728;&#x5207;&#x56DE;&#x7528;&#x6237;&#x6001;&#x65F6;&#xFF0C;&#x5F00;&#x59CB;&#x6267;&#x884C;&#x6211;&#x4EEC;&#x52A0;&#x8F7D;&#x7684;&#x4E8C;&#x8FDB;&#x5236;&#x6587;&#x4EF6;&#x3002;</p>
<pre><code class="language-cpp">static void
start_thread_common(struct pt_regs *regs, unsigned long new_ip,
		    unsigned long new_sp,
		    unsigned int _cs, unsigned int _ss, unsigned int _ds)
{
	WARN_ON_ONCE(regs != current_pt_regs());

	if (static_cpu_has(X86_BUG_NULL_SEG)) {
		/* Loading zero below won&apos;t clear the base. */
		loadsegment(fs, __USER_DS);
		load_gs_index(__USER_DS);
	}

	reset_thread_features();

	loadsegment(fs, 0);
	loadsegment(es, _ds);
	loadsegment(ds, _ds);
	load_gs_index(0);

    /*&#x66F4;&#x65B0;&#x51FD;&#x6570;&#x7684;&#x6307;&#x9488;&#x5730;&#x5740;&#xFF0C;&#x4FDD;&#x8BC1;&#x5207;&#x56DE;&#x7528;&#x6237;&#x6001;&#x65F6;&#x4F1A;&#x6267;&#x884C;&#x65B0;&#x8FDB;&#x7A0B;&#xFF08;&#x4E8C;&#x8FDB;&#x5236;&#x6587;&#x4EF6;&#xFF09;*/
	regs-&gt;ip		= new_ip;
	regs-&gt;sp		= new_sp;
	regs-&gt;cs		= _cs;
	regs-&gt;ss		= _ss;
	regs-&gt;flags		= X86_EFLAGS_IF;
}
</code></pre>
<h2 id="3%E3%80%81%E8%BF%9B%E7%A8%8B%E9%94%80%E6%AF%81">3&#x3001;&#x8FDB;&#x7A0B;&#x9500;&#x6BC1;</h2>
<h3 id="31-exit">3.1-exit</h3>
<p>&#x6211;&#x4EEC;&#x5728;&#x7528;&#x6237;&#x6001;&#x4E2D;&#x7ECF;&#x5E38;&#x901A;&#x8FC7;<code>exit()</code>&#x51FD;&#x6570;&#x6765;&#x5B9E;&#x73B0;&#x8FDB;&#x7A0B;&#x7684;&#x9000;&#x51FA;&#xFF0C;&#x8FD9;&#x4E2A;sys_call&#x88AB;&#x5B9A;&#x4E49;&#x5728;&#x4E86;<code>kernel/exit.c</code>&#xFF0C;&#x56E0;&#x6B64;exit&#x4F7F;&#x7528;&#x6765;&#x7ED3;&#x675F;&#x81EA;&#x5DF1;&#x8EAB;&#x8FDB;&#x7A0B;&#x7684;&#x3002;</p>
<pre><code class="language-cpp">SYSCALL_DEFINE1(exit, int, error_code)
{
	do_exit((error_code&amp;0xff)&lt;&lt;8);
}
</code></pre>
<p>&#x8FDB;&#x7A0B;&#x4E3B;&#x52A8;&#x9000;&#x51FA;&#x7684;&#x65F6;&#x5019;&#xFF0C;&#x4F1A;&#x6267;&#x884C;<code>do_exit</code>&#x76F8;&#x5173;&#x903B;&#x8F91;&#xFF0C;&#x8FD9;&#x91CC;&#x4F1A;&#x4E3B;&#x52A8;&#x5904;&#x7406;&#x6389;&#x8FDB;&#x7A0B;&#x5728;linux kernel&#x4E2D;&#x7684;&#x76F8;&#x5173;&#x8D44;&#x6E90;&#xFF0C;&#x503C;&#x5F97;&#x6CE8;&#x610F;&#x7684;&#x662F;&#x8FD9;&#x662F;&#x4E00;&#x4E2A;<code>noreturn</code>&#x7684;&#x51FD;&#x6570;&#x3002;</p>
<pre><code class="language-cpp">void __noreturn do_exit(long code)
{
	struct task_struct *tsk = current;
	int group_dead;

	WARN_ON(irqs_disabled()); // &#x5728;&#x4E2D;&#x65AD;&#x6267;&#x884C;&#x8FC7;&#x7A0B;&#x4E2D;&#x5173;&#x95ED;&#x4E2D;&#x65AD;&#xFF0C;&#x907F;&#x514D;&#x6D41;&#x7A0B;&#x88AB;&#x6253;&#x65AD;&#x3002;

	synchronize_group_exit(tsk, code); // &#x5904;&#x7406;&#x8FDB;&#x7A0B;&#x7EC4;&#x7684;&#x9000;&#x51FA;&#x540C;&#x6B65;
	......
	coredump_task_exit(tsk); // &#x8F6C;&#x5B58;&#x5F53;&#x524D;&#x8FDB;&#x7A0B;&#x7684;coredump
	......
	exit_signals(tsk);  /* &#x7528;&#x6765;&#x5904;&#x7406;&#x9000;&#x51FA;&#x4FE1;&#x53F7; */
	.....
	group_dead = atomic_dec_and_test(&amp;tsk-&gt;signal-&gt;live);
	if (group_dead) { // &#x5982;&#x679C;&#x4E00;&#x4E2A;group&#x4E4B;&#x4E2D;&#x7684;&#x6240;&#x6709;&#x8FDB;&#x7A0B;&#x90FD;&#x6D88;&#x4EA1;&#x4E86;&#xFF0C;&#x5C31;&#x505A;&#x66F4;&#x591A;&#x7684;&#x4E8B;&#x60C5;
		......
#ifdef CONFIG_POSIX_TIMERS
		hrtimer_cancel(&amp;tsk-&gt;signal-&gt;real_timer); // &#x53D6;&#x6D88;&#x5B9A;&#x65F6;&#x5668;
		exit_itimers(tsk);
#endif
		if (tsk-&gt;mm)
			setmax_mm_hiwater_rss(&amp;tsk-&gt;signal-&gt;maxrss, tsk-&gt;mm); // &#x589E;&#x52A0;&#x5185;&#x5B58;&#x6700;&#x5927;&#x7684;rss
	}
	......
	taskstats_exit(tsk, group_dead); // &#x5728;&#x9000;&#x51FA;&#x65F6;&#x6536;&#x96C6;&#x4EFB;&#x52A1;&#x7EDF;&#x8BA1;&#x4FE1;&#x606F;

	exit_mm(); // &#x9000;&#x51FA;&#x5185;&#x5B58;
	......
	exit_sem(tsk); // &#x91CA;&#x653E;&#x8FDB;&#x7A0B;&#x4F7F;&#x7528;&#x7684;&#x4FE1;&#x53F7;&#x91CF;
	exit_shm(tsk); // &#x91CA;&#x653E;&#x8FDB;&#x7A0B;&#x4F7F;&#x7528;&#x7684;&#x5171;&#x4EAB;&#x5185;&#x5B58;
	exit_files(tsk);// &#x91CA;&#x653E;&#x8FDB;&#x7A0B;&#x4F7F;&#x7528;&#x7684;&#x6587;&#x4EF6;&#x63CF;&#x8FF0;&#x7B26;
	exit_fs(tsk);// &#x91CA;&#x653E;&#x8FDB;&#x7A0B;&#x4F7F;&#x7528;&#x7684;&#x6587;&#x4EF6;&#x7CFB;&#x7EDF;
	if (group_dead)
		disassociate_ctty(1); // &#x53D6;&#x6D88;&#x8FDB;&#x7A0B;&#x7684;controlling tty
	exit_task_namespaces(tsk); // &#x91CA;&#x653E;&#x8FDB;&#x7A0B;&#x7684;&#x547D;&#x540D;&#x7A7A;&#x95F4;
	exit_task_work(tsk); // &#x5904;&#x7406;&#x8FDB;&#x7A0B;&#x7ED1;&#x5B9A;&#x7684;task_work
	exit_thread(tsk); // &#x5904;&#x7406;&#x7EBF;&#x7A0B;&#x76F8;&#x5173;&#x7684;&#x5DE5;&#x4F5C;
	......
	flush_ptrace_hw_breakpoint(tsk); // &#x6E05;&#x9664;&#x786C;&#x4EF6;&#x65AD;&#x70B9;
	.....
	exit_notify(tsk, group_dead); // &#x901A;&#x77E5;&#x5176;&#x4ED6;&#x8FDB;&#x7A0B;&#x8FD9;&#x4E2A;&#x8FDB;&#x7A0B;&#x5DF2;&#x7ECF;&#x9000;&#x51FA;&#xFF0C;&#x5E76;&#x4E14;&#x4F1A;&#x901A;&#x77E5;&#x7236;&#x8FDB;&#x7A0B;&#x7ED1;&#x5B9A;&#x597D;&#x7684;task-&gt;sig
	proc_exit_connector(tsk); // &#x53D1;&#x9001;&#x8FDB;&#x7A0B;&#x9000;&#x51FA;&#x7684;&#x8FDE;&#x63A5;&#x5668;&#x4E8B;&#x4EF6;
	mpol_put_task_policy(tsk); // &#x91CA;&#x653E;&#x8FDB;&#x7A0B;&#x7684;&#x5185;&#x5B58;&#x7B56;&#x7565;
	......
	debug_check_no_locks_held(); // &#x68C0;&#x67E5;&#x5F53;&#x524D;&#x6709;&#x6CA1;&#x6709;&#x6301;&#x9501;&#x88AB;&#x5F02;&#x5E38;&#x91CA;&#x653E;&#x4E86;

	if (tsk-&gt;io_context)
		exit_io_context(tsk); // &#x91CA;&#x653E;&#x8FDB;&#x7A0B;&#x7684;io&#x8D44;&#x6E90;

	if (tsk-&gt;splice_pipe)
		free_pipe_info(tsk-&gt;splice_pipe); // &#x91CA;&#x653E;&#x8FDB;&#x7A0B;&#x7684;splice&#x7BA1;&#x9053;

	if (tsk-&gt;task_frag.page)
		put_page(tsk-&gt;task_frag.page); // &#x91CA;&#x653E;&#x8FDB;&#x7A0B;&#x7684;&#x4EFB;&#x52A1;&#x7247;&#x6BB5;&#x9875;

	validate_creds_for_do_exit(tsk); // &#x9A8C;&#x8BC1;&#x8FDB;&#x7A0B;&#x7684;`creds`
	exit_task_stack_account(tsk); 

	check_stack_usage(); // &#x68C0;&#x67E5;&#x6808;&#x7684;&#x4F7F;&#x7528;&#x60C5;&#x51B5;
	preempt_disable(); // &#x7981;&#x6B62;&#x5185;&#x6838;&#x62A2;&#x5360;
	if (tsk-&gt;nr_dirtied) // &#x5982;&#x679C;&#x8FDB;&#x7A0B;&#x6709;&#x810F;&#x9875;
		__this_cpu_add(dirty_throttle_leaks, tsk-&gt;nr_dirtied); // &#x6DFB;&#x52A0;&#x5230;&#x5F53;&#x524D;CPU&#x7684;dirty_throttle_leaks&#x8BA1;&#x6570;&#xFF0C;&#x65B9;&#x4FBF;&#x540E;&#x7EED;&#x56DE;&#x6536;
	exit_rcu();
	exit_tasks_rcu_finish();

	lockdep_free_task(tsk); // &#x91CA;&#x653E;&#x8FDB;&#x7A0B;&#x7684;&#x9501;&#x4F9D;&#x8D56;&#x4FE1;&#x606F;
	do_task_dead(); // &#x5C06;&#x5F53;&#x524D;&#x8FDB;&#x6807;&#x8BB0;&#x4E3A;&#x5DF2;&#x6B7B;&#x4EA1;&#xFF08;TASK_DEAD&#xFF09;
}
</code></pre>
<p>&#x8FD9;&#x91CC;&#x503C;&#x5F97;&#x4E00;&#x63D0;&#x7684;&#x662F;<code>creds</code>&#xFF08;&#x5373;&#x51ED;&#x636E;&#xFF09;&#x662F;&#x4E00;&#x4E2A;&#x8868;&#x793A;&#x8FDB;&#x7A0B;&#x5B89;&#x5168;&#x5C5E;&#x6027;&#x7684;&#x7ED3;&#x6784;&#xFF0C;&#x5305;&#x542B;&#x4E86;&#x8FDB;&#x7A0B;&#x7684;&#x7528;&#x6237;ID&#x3001;&#x7EC4;ID&#x3001;&#x9644;&#x52A0;&#x7EC4;ID&#x3001;&#x5B89;&#x5168;&#x80FD;&#x529B;&#x7B49;&#x4FE1;&#x606F;&#x3002;&#x8FD9;&#x4E9B;&#x4FE1;&#x606F;&#x7528;&#x4E8E;&#x51B3;&#x5B9A;&#x8FDB;&#x7A0B;&#x53EF;&#x4EE5;&#x8BBF;&#x95EE;&#x54EA;&#x4E9B;&#x8D44;&#x6E90;&#x4EE5;&#x53CA;&#x6267;&#x884C;&#x54EA;&#x4E9B;&#x64CD;&#x4F5C;&#x3002;</p>
<p>&#x800C;<code>do_exit</code>&#x901A;&#x8FC7;&#x8C03;&#x7528;<code>exit_notify</code>&#x4E2D;&#x7684;<code>do_notify_parent</code>&#x7528;SIG&#x901A;&#x8FC7;&#x7236;&#x8FDB;&#x7A0B;&#x5B50;&#x8FDB;&#x7A0B;&#x5DF2;&#x7ECF;&#x6D88;&#x4EA1;&#x4E86;&#x3002;</p>
<h3 id="32-wait4">3.2-wait4</h3>
<p>&#x53E6;&#x5916;&#x8FD8;&#x6709;&#x4E00;&#x4E2A;<code>wait4</code>&#xFF0C;&#x662F;&#x7236;&#x8FDB;&#x7A0B;&#x7528;&#x6765;&#x8C03;&#x7528;&#xFF0C;&#x7B49;&#x5F85;&#x5B50;&#x8FDB;&#x7A0B;&#x6D88;&#x4EA1;&#xFF0C;&#x4E5F;&#x5C31;&#x662F;&#x6211;&#x4EEC;&#x4E4B;&#x524D;&#x8BF4;&#x5230;&#x7684;&#x7531;&#x7236;&#x8FDB;&#x7A0B;&#x4E3A;&#x5B50;&#x8FDB;&#x7A0B;&#x8FDB;&#x884C;<code>&#x6536;&#x5C38;</code>&#x3002;</p>
<pre><code class="language-cpp">SYSCALL_DEFINE4(wait4, pid_t, upid, int __user *, stat_addr,
		int, options, struct rusage __user *, ru)
{
	struct rusage r;
	long err = kernel_wait4(upid, stat_addr, options, ru ? &amp;r : NULL);

	if (err &gt; 0) {
		if (ru &amp;&amp; copy_to_user(ru, &amp;r, sizeof(struct rusage)))
			return -EFAULT;
	}
	return err;
}
</code></pre>
<p><img src="http://www.korantli.com.cn/content/images/2023/12/wait---3040375.jpg" alt="linux&#x8FDB;&#x7A0B;&#x7BA1;&#x7406;-2&#x8FDB;&#x7A0B;&#x521B;&#x5EFA;" loading="lazy"></p>
<p>&#x800C;<code>wait4</code>-&gt;<code>kernel_wait4</code>-&gt;<code>do_wait</code>-&gt;<code>__do_wait</code>-&gt;<code>do_wait_pid</code>-&gt;<code>wait_consider_task</code>-&gt;<code>wait_task_zombie</code>-&gt;<code>release_task</code>&#xFF0C;&#x6309;&#x7167;&#x4E0A;&#x8FF0;&#x6D41;&#x7A0B;&#x8C03;&#x7528;&#xFF0C;&#x6700;&#x7EC8;&#x91CA;&#x653E;&#x6389;<code>task_struct</code>&#x7ED3;&#x6784;&#x4F53;&#x3002;</p>
<pre><code class="language-cpp">static long do_wait(struct wait_opts *wo)
{
	int retval;

	trace_sched_process_wait(wo-&gt;wo_pid);

	init_waitqueue_func_entry(&amp;wo-&gt;child_wait, child_wait_callback); // &#x521D;&#x59CB;&#x5316;&#x4E00;&#x4E2A;waitqueue
	wo-&gt;child_wait.private = current;
	add_wait_queue(&amp;current-&gt;signal-&gt;wait_chldexit, &amp;wo-&gt;child_wait); // &#x628A;&#x81EA;&#x5DF1;&#x52A0;&#x5165;&#x5230;&#x8FD9;&#x4E2A;&#x961F;&#x5217;&#x4E0A;

	do {
		set_current_state(TASK_INTERRUPTIBLE);
		retval = __do_wait(wo); // &#x8FDB;&#x5165;&#x5FAA;&#x73AF;&#x7B49;&#x5F85;
		if (retval != -ERESTARTSYS)
			break;
		if (signal_pending(current)) // &#x7236;&#x8FDB;&#x7A0B;&#x5982;&#x679C;&#x6709;&#x5176;&#x4ED6;&#x4FE1;&#x53F7;&#x5904;&#x7406;&#xFF0C;&#x5219;&#x9000;&#x51FA;
			break;
		schedule(); // &#x7B49;&#x5F85;&#x7684;&#x65F6;&#x5019;&#x8BA9;&#x51FA;&#x8C03;&#x5EA6;
	} while (1); // &#x5FAA;&#x73AF;&#x7B49;&#x5F85;&#x5B50;&#x8FDB;&#x7A0B;&#x6D88;&#x4EA1;

	__set_current_state(TASK_RUNNING);
	remove_wait_queue(&amp;current-&gt;signal-&gt;wait_chldexit, &amp;wo-&gt;child_wait);
	return retval;
}
</code></pre>
<p>&#x518D;wait4&#x4E2D;&#x4F1A;&#x5C06;&#x7C7B;&#x578B;&#x8BBE;&#x7F6E;&#x4E3A;<code>PIDTYPE_TGID</code>&#xFF0C;&#x56E0;&#x6B64;&#x6700;&#x7EC8;&#x4F1A;&#x8C03;&#x7528;<code>do_wait_pid</code>&#x3002;</p>
<p>&#x53E6;&#x5916;&#x5982;&#x679C;&#x7236;&#x8FDB;&#x7A0B;&#x6CA1;&#x6709;&#x663E;&#x793A;&#x7684;&#x8C03;&#x7528;<code>wait4</code>&#x7B49;&#x7B49;&#x5904;&#x7406;&#x51FD;&#x6570;&#xFF0C;&#x5219;&#x4F1A;&#x5728;<code>&#x4FE1;&#x53F7;&#x5904;&#x7406;</code>&#x7684;&#x6D41;&#x7A0B;&#x4E2D;&#x5904;&#x7406;&#x6D88;&#x4EA1;&#x8FDB;&#x7A0B;&#x53D1;&#x9001;&#x8FC7;&#x6765;&#x7684;&#x4FE1;&#x53F7;&#xFF0C;&#x5E76;&#x5BF9;&#x5B50;&#x8FDB;&#x7A0B;&#x7684;&quot;&#x9057;&#x4F53;&quot;&#x8FDB;&#x884C;&#x5904;&#x7406;&#xFF0C;&#x4E2A;&#x4EBA;&#x7406;&#x89E3;&#xFF0C;&#x7236;&#x8FDB;&#x7A0B;&#x53EF;&#x4EE5;&#x7ED1;&#x5B9A;&#x4E00;&#x4E2A;<code>SIGCHLD</code>&#x7684;&#x5904;&#x7406;&#x5668;&#xFF0C;&#x8FD9;&#x6837;&#x5F53;&#x7236;&#x8FDB;&#x7A0B;&#x63A5;&#x5230;&#x4FE1;&#x53F7;<code>SIGCHLD</code>&#x7684;&#x65F6;&#x5019;&#x5C31;&#x4F1A;&#x8C03;&#x7528;&#x7C7B;&#x4F3C;&#x4E8E;<code>wait4</code>&#x7684;api&#x5BF9;&#x5B50;&#x8FDB;&#x7A0B;&#x8FDB;&#x884C;&#x5904;&#x7406;&#x3002;&#x7C7B;&#x4F3C;&#x4E8E;<code>exit_to_user_mode_loop</code>&#x4E2D;</p>
<pre><code class="language-cpp">static unsigned long exit_to_user_mode_loop(struct pt_regs *regs,
					    unsigned long ti_work)
{
	......
		if (ti_work &amp; (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
			arch_do_signal_or_restart(regs); // &#x5982;&#x679C;&#x6709;&#x4FE1;&#x53F7;&#xFF0C;&#x5219;&#x5904;&#x7406;&#x4E0B;&#x8FD9;&#x4E2A;&#x4FE1;&#x53F7;
  ......
}
</code></pre>
<p>&#x53E6;&#x5916;&#x8FD8;&#x6709;&#x4E2D;&#x65AD;&#x8FD4;&#x56DE;&#x65F6;&#x4E5F;&#x4F1A;&#x5904;&#x7406;&#x4FE1;&#x53F7;&#x91CF;&#xFF0C;&#x4FE1;&#x53F7;&#x5904;&#x7406;&#x7684;&#x8BE6;&#x7EC6;&#x6D41;&#x7A0B;&#x53EF;&#x4EE5;&#x53C2;&#x8003;&#x4EE5;&#x540E;&#x7684;&#x4FE1;&#x53F7;&#x91CF;&#x5206;&#x6790;&#x3002;</p>
<h3 id="33-%E4%BA%8C%E8%80%85%E5%8C%BA%E5%88%AB">3.3-&#x4E8C;&#x8005;&#x533A;&#x522B;</h3>
<ol>
<li>&#x4F5C;&#x7528;&#x5BF9;&#x8C61;</li>
</ol>
<ul>
<li><code>exit</code>: &#x7531;&#x5F53;&#x524D;&#x8FDB;&#x7A0B;&#x8C03;&#x7528;&#xFF0C;&#x7528;&#x4E8E;&#x7ED3;&#x675F;&#x81EA;&#x8EAB;&#x3002;</li>
<li><code>wait4</code>: &#x7531;&#x7236;&#x8FDB;&#x7A0B;&#x8C03;&#x7528;&#xFF0C;&#x7528;&#x4E8E;&#x7B49;&#x5F85;&#x5B50;&#x8FDB;&#x7A0B;&#x7ED3;&#x675F;&#x3002;</li>
</ul>
<ol start="2">
<li>&#x4F5C;&#x7528;&#x7ED3;&#x679C;</li>
</ol>
<ul>
<li><code>exit</code>: &#x5BFC;&#x81F4;&#x8C03;&#x7528;&#x5B83;&#x7684;&#x8FDB;&#x7A0B;&#x7ED3;&#x675F;&#x3002;</li>
<li><code>wait4</code>: &#x5E76;&#x4E0D;&#x7ED3;&#x675F;&#x4EFB;&#x4F55;&#x8FDB;&#x7A0B;&#xFF0C;&#x800C;&#x662F;&#x7B49;&#x5F85;&#x5176;&#x4ED6;&#x8FDB;&#x7A0B;&#x7ED3;&#x675F;&#x3002;</li>
</ul>
<ol start="3">
<li>&#x8FDB;&#x7A0B;&#x95F4;&#x901A;&#x4FE1;</li>
</ol>
<ul>
<li><code>exit</code> &#x63D0;&#x4F9B;&#x4E86;&#x4E00;&#x79CD;&#x901A;&#x8FC7;&#x9000;&#x51FA;&#x72B6;&#x6001;&#x4E0E;&#x7236;&#x8FDB;&#x7A0B;&#x901A;&#x4FE1;&#x7684;&#x65B9;&#x5F0F;&#x3002;</li>
<li><code>wait4</code> &#x4F7F;&#x7236;&#x8FDB;&#x7A0B;&#x80FD;&#x591F;&#x83B7;&#x53D6;&#x5B50;&#x8FDB;&#x7A0B;&#x7684;&#x9000;&#x51FA;&#x72B6;&#x6001;&#x3002;</li>
</ul>
<ol start="4">
<li>&#x8D44;&#x6E90;&#x7BA1;&#x7406;</li>
</ol>
<ul>
<li><code>exit</code> &#x89E6;&#x53D1;&#x8D44;&#x6E90;&#x7684;&#x91CA;&#x653E;&#x3002;</li>
<li><code>wait4</code> &#x786E;&#x4FDD;&#x8FD9;&#x4E9B;&#x8D44;&#x6E90;&#x88AB;&#x7CFB;&#x7EDF;&#x56DE;&#x6536;&#x3002;</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[linux进程管理-kthread]]></title><description><![CDATA[<h2 id="0%E3%80%81%E8%83%8C%E6%99%AF">0&#x3001;&#x80CC;&#x666F;</h2>
<p>kthread&#x662F;&#x6307;&#x4EE3;&#x7279;&#x6B8A;&#x7684;&#x5728;&#x5185;&#x6838;&#x6001;&#x8FD0;&#x884C;&#x7684;&#x7EBF;&#x7A0B;&#xFF0C;&#x5176;&#x521B;&#x5EFA;&#x3001;&#x7BA1;&#x7406;&#x7684;&#x903B;&#x8F91;&#x4E0E;&#x666E;&#x901A;&#x96C6;&#x6210;&#x6709;&#x6240;&#x533A;&#x522B;&#xFF0C;&#x4F46;&#x5728;&#x8C03;&#x5EA6;&#x4E0A;&#x8FD8;&#x662F;&#x4E0E;&#x5176;&#x4ED6;</p>]]></description><link>http://www.korantli.com.cn/linux/linuxjin-cheng-guan-li-kthread/</link><guid isPermaLink="false">65797687b936e6d99568ccaa</guid><category><![CDATA[linux进程管理]]></category><category><![CDATA[linux技术总结]]></category><dc:creator><![CDATA[李星辉]]></dc:creator><pubDate>Wed, 13 Dec 2023 09:20:02 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1607799279861-4dd421887fb3?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDl8fGNvZGVyfGVufDB8fHx8MTcwMjQ1OTEzNnww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<h2 id="0%E3%80%81%E8%83%8C%E6%99%AF">0&#x3001;&#x80CC;&#x666F;</h2>
<img src="https://images.unsplash.com/photo-1607799279861-4dd421887fb3?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDl8fGNvZGVyfGVufDB8fHx8MTcwMjQ1OTEzNnww&amp;ixlib=rb-4.0.3&amp;q=80&amp;w=2000" alt="linux&#x8FDB;&#x7A0B;&#x7BA1;&#x7406;-kthread"><p>kthread&#x662F;&#x6307;&#x4EE3;&#x7279;&#x6B8A;&#x7684;&#x5728;&#x5185;&#x6838;&#x6001;&#x8FD0;&#x884C;&#x7684;&#x7EBF;&#x7A0B;&#xFF0C;&#x5176;&#x521B;&#x5EFA;&#x3001;&#x7BA1;&#x7406;&#x7684;&#x903B;&#x8F91;&#x4E0E;&#x666E;&#x901A;&#x96C6;&#x6210;&#x6709;&#x6240;&#x533A;&#x522B;&#xFF0C;&#x4F46;&#x5728;&#x8C03;&#x5EA6;&#x4E0A;&#x8FD8;&#x662F;&#x4E0E;&#x5176;&#x4ED6;&#x8FDB;&#x7A0B;&#x6216;&#x8005;&#x7EBF;&#x7A0B;&#x662F;&#x7C7B;&#x4F3C;&#x7684;&#x3002;</p>
<h2 id="1%E3%80%81%E5%88%9B%E5%BB%BA">1&#x3001;&#x521B;&#x5EFA;</h2>
<p>&#x5185;&#x6838;&#x7EBF;&#x7A0B;&#x7684;&#x521B;&#x5EFA;&#x4E3B;&#x8981;&#x662F;&#x901A;&#x8FC7;<code>kthread_create</code>&#xFF0C;&#x53E6;&#x5916;<code>kthread_run</code>&#x4E5F;&#x53EF;&#x521B;&#x5EFA;&#x7EBF;&#x7A0B;&#xFF0C;&#x533A;&#x522B;&#x662F;&#x5728;&#x521B;&#x5EFA;&#x7684;&#x540C;&#x65F6;&#x8FD8;&#x4F1A;&#x76F4;&#x63A5;&#x8FD0;&#x884C;&#x8FD9;&#x4E2A;&#x7EBF;&#x7A0B;&#x3002;</p>
<p>&#x53EF;&#x4EE5;&#x770B;&#x5230;<code>kthread_create</code>&#x7684;&#x5B9E;&#x9645;&#x539F;&#x578B;&#x662F;<code>kthread_create_on_node</code>&#x3002;</p>
<pre><code class="language-cpp">#define kthread_create(threadfn, data, namefmt, arg...) \
	kthread_create_on_node(threadfn, data, NUMA_NO_NODE, namefmt, ##arg)
</code></pre>
<p>&#x6700;&#x7EC8;&#x4F1A;&#x8C03;&#x7528;&#x5230;<code>__kthread_create_on_node</code>&#x8FDB;&#x884C;&#x521B;&#x5EFA;&#xFF0C;&#x800C;&#x5B9E;&#x9645;&#x4E0A;&#x521B;&#x5EFA;kthread&#x7684;&#x5DE5;&#x4F5C;&#x5B9E;&#x9645;&#x4E0A;&#x662F;&#x4E00;&#x4E2A;&#x7531;<code>kthreadd_task</code>&#x7EBF;&#x7A0B;&#x5B8C;&#x6210;</p>
<pre><code class="language-cpp">struct task_struct *__kthread_create_on_node(int (*threadfn)(void *data),
						    void *data, int node,
						    const char namefmt[],
						    va_list args)
{
	DECLARE_COMPLETION_ONSTACK(done);
	struct task_struct *task;
	struct kthread_create_info *create = kmalloc(sizeof(*create), 
						     GFP_KERNEL); // &#x521B;&#x5EFA;&#x4E00;&#x4E2A;ktherad_create&#x6570;&#x636E;&#x4E0A;&#x4E0B;&#x6587;

	if (!create)
		return ERR_PTR(-ENOMEM);
  /*&#x586B;&#x5145;create&#x7ED3;&#x6784;&#x4F53;*/
	create-&gt;threadfn = threadfn; // kthread&#x7684;&#x5B9E;&#x9645;&#x903B;&#x8F91;&#x51FD;&#x6570;&#x6307;&#x9488;
	......
	spin_lock(&amp;kthread_create_lock);
	list_add_tail(&amp;create-&gt;list, &amp;kthread_create_list); // &#x628A;&#x521B;&#x5EFA;&#x597D;&#x7684;create&#x7ED3;&#x6784;&#x4F53;&#x52A0;&#x5165;&#x5230;&#x94FE;&#x8868;&#x4E0A;
	spin_unlock(&amp;kthread_create_lock);

	wake_up_process(kthreadd_task); // &#x5524;&#x9192;&#x521B;&#x5EFA;kthread&#x7684;&#x7EBF;&#x7A0B;
	......
	if (unlikely(wait_for_completion_killable(&amp;done))) { // &#x4F7F;&#x7528;wait_for&#x5FAA;&#x73AF;&#x7B49;&#x5F85;&#x521B;&#x5EFA;&#x5DE5;&#x4F5C;&#x7ED3;&#x675F;
		......
		wait_for_completion(&amp;done);
	}
	task = create-&gt;result;
free_create:
	kfree(create);
	return task;
}
</code></pre>
<p>&#x800C;&#x8FD9;&#x4E2A;&#x8FDB;&#x7A0B;&#x662F;&#x5728;<code>init</code>&#x7684;&#x521B;&#x5EFA;&#x6D41;&#x7A0B;&#x4E2D;&#x88AB;&#x521B;&#x5EFA;&#x7684;&#xFF0C;&#x5B9E;&#x9645;&#x662F;&#x771F;&#x6B63;&#x6267;&#x884C;&#x7684;&#x539F;&#x578B;&#x662F;<code>kthreadd</code></p>
<pre><code class="language-cpp">	noinline void __ref __noreturn rest_init(void)
{
  ......
	numa_default_policy();
	pid = kernel_thread(kthreadd, NULL, NULL, CLONE_FS | CLONE_FILES);
	rcu_read_lock();
	kthreadd_task = find_task_by_pid_ns(pid, &amp;init_pid_ns);
	rcu_read_unlock();
  ......
}
</code></pre>
<p>&#x6211;&#x4EEC;&#x53EF;&#x4EE5;&#x770B;&#x5230;<code>kthreadd</code>&#x7684;&#x4E3B;&#x8981;&#x5DE5;&#x4F5C;&#x5C31;&#x662F;&#x904D;&#x5386;<code>kthread_create_list</code>&#x94FE;&#x8868;&#x521B;&#x5EFA;&#x7EBF;&#x7A0B;&#x3002;</p>
<pre><code class="language-cpp">int kthreadd(void *unused)
{
	......
	set_cpus_allowed_ptr(tsk, housekeeping_cpumask(HK_TYPE_KTHREAD)); // &#x8BBE;&#x7F6E;cpu&#x4EB2;&#x6838;&#x6027;
	set_mems_allowed(node_states[N_MEMORY]); // &#x8BBE;&#x7F6E;&#x5185;&#x5B58;&#x8282;&#x70B9;
	......
	for (;;) {
		set_current_state(TASK_INTERRUPTIBLE); // &#x5148;&#x628A;&#x81EA;&#x8EAB;&#x8BBE;&#x7F6E;&#x6210;&#x4F11;&#x7720;
		if (list_empty(&amp;kthread_create_list)) // &#x5982;&#x679C;&#x6CA1;&#x6709;&#x9700;&#x8981;&#x521B;&#x5EFA;&#x7684;&#x7EBF;&#x7A0B;&#xFF0C;&#x5C31;&#x8BA9;&#x51FA;&#x8C03;&#x5EA6;
			schedule();
		__set_current_state(TASK_RUNNING); // &#x6709;&#x7EBF;&#x7A0B;&#x9700;&#x8981;&#x521B;&#x5EFA;&#x5219;&#x91CD;&#x65B0;&#x8BBE;&#x7F6E;&#x6210;running

		spin_lock(&amp;kthread_create_lock);
		while (!list_empty(&amp;kthread_create_list)) { // &#x904D;&#x5386;&#x94FE;&#x8868;
			struct kthread_create_info *create;

			create = list_entry(kthread_create_list.next,
					    struct kthread_create_info, list);
			list_del_init(&amp;create-&gt;list);
			spin_unlock(&amp;kthread_create_lock);

			create_kthread(create); // &#x521B;&#x5EFA;&#x8FD9;&#x4E2A;&#x7EBF;&#x7A0B;

			spin_lock(&amp;kthread_create_lock);
		}
		spin_unlock(&amp;kthread_create_lock);
	}

	return 0;
}
</code></pre>
<p>&#x521B;&#x5EFA;&#x7684;&#x5B9E;&#x9645;&#x903B;&#x8F91;&#x6BD4;&#x8F83;&#x7B80;&#x5355;&#xFF0C;&#x5C31;&#x662F;&#x901A;&#x8FC7;<code>fork.c</code>&#x91CC;&#x901A;&#x8FC7;<code>kernel_thread</code>&#x521B;&#x5EFA;&#x7EBF;&#x7A0B;&#x3002;</p>
<pre><code class="language-cpp">static void create_kthread(struct kthread_create_info *create)
{
	int pid;

#ifdef CONFIG_NUMA
	current-&gt;pref_node_fork = create-&gt;node;
#endif
	/* We want our own signal handler (we take no signals by default). */
	pid = kernel_thread(kthread, create, create-&gt;full_name,
			    CLONE_FS | CLONE_FILES | SIGCHLD); // &#x901A;&#x8FC7;fork.c&#x4E2D;&#x7684;kernel_thread&#x521B;&#x5EFA;&#x7EBF;&#x7A0B;
	if (pid &lt; 0) {
		/* Release the structure when caller killed by a fatal signal. */
		struct completion *done = xchg(&amp;create-&gt;done, NULL);

		kfree(create-&gt;full_name);
		if (!done) {
			kfree(create);
			return;
		}
		create-&gt;result = ERR_PTR(pid);
		complete(done); // &#x586B;&#x5145;create-&gt;done&#x7ED3;&#x6784;&#x4F53;
	}
}
</code></pre>
<h2 id="2%E3%80%81kthread">2&#x3001;kthread()</h2>
<h3 id="21-int-kthreadvoid-create">2.1-int kthread(void *_create)</h3>
<p><code>kthread()</code>&#x51FD;&#x6570;&#x662F;&#x7531;<code>kernel_thread</code>&#x5728;&#x521B;&#x5EFA;&#x7EBF;&#x7A0B;&#x65F6;&#x7ED1;&#x5B9A;&#x7684;&#xFF0C;&#x5185;&#x6838;&#x7EBF;&#x7A0B;&#x521B;&#x5EFA;&#x5B8C;&#x4F1A;&#x4E00;&#x76F4;&#x5219;&#x6267;&#x884C;<code>ret = threadfn(data);</code></p>
<pre><code class="language-cpp">static int kthread(void *_create)
{
	/* Copy data: it&apos;s on kthread&apos;s stack */
	struct kthread_create_info *create = _create;
	int (*threadfn)(void *data) = create-&gt;threadfn; // kthread&#x5B9E;&#x9645;&#x4E1A;&#x52A1;&#x903B;&#x8F91;
	void *data = create-&gt;data;
	struct kthread self; // kthread&#x7279;&#x522B;&#x7684;&#x6570;&#x636E;&#x7ED3;&#x6784;
	int ret;
  
  self = to_kthread(current); // &#x586B;&#x5145;kthread&#x7ED3;&#x6784;&#x4F53;

	/* OK, tell user we&apos;re spawned, wait for stop or wakeup */
	__set_current_state(TASK_UNINTERRUPTIBLE); // &#x5148;&#x4F11;&#x7720;
	......
	if (!test_bit(KTHREAD_SHOULD_STOP, &amp;self.flags)) {
		__kthread_parkme(&amp;self);
		ret = threadfn(data); // &#x5F00;&#x59CB;&#x6267;&#x884C;&#x5177;&#x4F53;ktread&#x903B;&#x8F91;
	}
	/* we can&apos;t just return, we must preserve &quot;self&quot; on stack */
	do_exit(ret);
}
</code></pre>
<h3 id="22-struct-kthread">2.2-struct kthread</h3>
<p>&#x800C;<code>struct kthread</code>&#x662F;&#x4E00;&#x4E2A;&#x5185;&#x6838;&#x7EBF;&#x7A0B;&#x4E13;&#x6709;&#x7684;&#x6570;&#x636E;&#x7ED3;&#x679C;&#xFF0C;&#x8FD9;&#x91CC;&#x4F1A;&#x4FDD;&#x5B58;&#x5185;&#x6838;&#x7EBF;&#x7A0B;&#x9700;&#x8981;&#x64CD;&#x4F5C;&#x7684;&#x57FA;&#x672C;&#x6570;&#x636E;&#x7ED3;&#x6784;</p>
<pre><code class="language-cpp">struct kthread {
	unsigned long flags; // &#x7EBF;&#x7A0B;&#x7684;&#x72B6;&#x6001;&#xFF08;&#x5982;&#x8FD0;&#x884C;&#x3001;&#x4F11;&#x7720;&#x7B49;&#xFF09;
	unsigned int cpu; // &#x7EBF;&#x7A0B;&#x7ED1;&#x5B9A;&#x7684;cpu
	int result; // &#x7EBF;&#x7A0B;&#x7684;return&#x503C;
	int (*threadfn)(void *); // &#x7EBF;&#x7A0B;&#x5B9E;&#x9645;&#x6267;&#x884C;&#x903B;&#x8F91;&#x51FD;&#x6570;&#x5730;&#x5740;
	void *data; // &#x5B58;&#x50A8;&#x6216;&#x4F20;&#x9012;&#x7ED9;&#x7EBF;&#x7A0B;&#x51FD;&#x6570;&#x7684;&#x6570;&#x636E;
	struct completion parked; // &#x7528;&#x6765;&#x8BB0;&#x5F55;&#x7EBF;&#x7A0B;&#x6682;&#x505C;&#x7684;&#x7ED3;&#x6784;&#x4F53;
	struct completion exited; // &#x7528;&#x6765;&#x8BB0;&#x5F55;&#x7EBF;&#x7A0B;&#x9000;&#x51FA;&#x7684;&#x7ED3;&#x6784;&#x4F53;
#ifdef CONFIG_BLK_CGROUP
	struct cgroup_subsys_state *blkcg_css; // &#x6307;&#x5411;cgroup&#x72B6;&#x6001;&#x7684;&#x6307;&#x9488;&#xFF0C;&#x7528;&#x4E8E;&#x5757;&#x8BBE;&#x5907;&#x63A7;&#x5236;&#x7EC4;&#x76F8;&#x5173;&#x7684;&#x529F;
#endif
	/* To store the full name if task comm is truncated. */
	char *full_name; // &#x7EBF;&#x7A0B;&#x540D;&#x79F0;
};
</code></pre>
<h2 id="3%E3%80%81%E5%94%A4%E9%86%92%E9%80%80%E5%87%BA">3&#x3001;&#x5524;&#x9192;&amp;&#x9000;&#x51FA;</h2>
<h3 id="31-%E5%94%A4%E9%86%92">3.1-&#x5524;&#x9192;</h3>
<p>&#x7531;&#x4E8E;&#x5F88;&#x591A;&#x5185;&#x6838;&#x7EBF;&#x7A0B;&#x90FD;&#x662F;&#x9636;&#x6BB5;&#x8FD0;&#x884C;&#x7684;&#xFF0C;&#x6240;&#x4EE5;&#x90E8;&#x5206;&#x5185;&#x6838;&#x7EBF;&#x7A0B;&#x4F1A;&#x4E3B;&#x52A8;&#x8FDB;&#x5165;&#x4F11;&#x7720;&#x72B6;&#x6001;&#xFF0C;&#x7136;&#x540E;&#x7B49;&#x5F85;&#x5176;&#x4ED6;&#x7EBF;&#x7A0B;&#x5524;&#x9192;&#x3002;</p>
<p>&#x5524;&#x9192;&#x7684;&#x65B9;&#x5F0F;&#x6BD4;&#x8F83;&#x5E38;&#x89C1;&#xFF0C;&#x5C31;&#x662F;&#x901A;&#x8FC7;<code>wake_up_process</code>&#x6765;&#x5524;&#x9192;&#x8FDB;&#x7A0B;&#x3002;</p>
<h3 id="32-%E9%80%80%E5%87%BA">3.2-&#x9000;&#x51FA;</h3>
<h4 id="321-%E6%AD%A3%E5%B8%B8%E9%80%80%E5%87%BA">3.2.1-&#x6B63;&#x5E38;&#x9000;&#x51FA;</h4>
<p>&#x5982;&#x4E0A;&#x8FF0;&#x5206;&#x6790;&#xFF0C;<code>kthread</code>&#x6B63;&#x5E38;&#x9000;&#x51FA;&#x540E;&#x4F1A;&#x6267;&#x884C;<code>kthread_exit(ret);</code></p>
<pre><code class="language-cpp">static int kthread(void *_create)
{
	......
	/* OK, tell user we&apos;re spawned, wait for stop or wakeup */
	__set_current_state(TASK_UNINTERRUPTIBLE);
	create-&gt;result = current;
	complete(&amp;create-&gt;done);
	schedule();

	ret = -EINTR;

	if (!test_bit(KTHREAD_SHOULD_STOP, &amp;self.flags)) {
		__kthread_parkme(&amp;self);
		ret = threadfn(data);
	}
	/* we can&apos;t just return, we must preserve &quot;self&quot; on stack */
	kthread_exit(ret);
}
</code></pre>
<p>&#x800C;<code>kthread_exit</code>&#x4E2D;&#x5219;&#x4F1A;&#x586B;&#x5145;<code>done</code>&#x76F8;&#x5173;&#x7684;&#x7ED3;&#x6784;&#x4F53;</p>
<pre><code class="language-cpp">void __noreturn kthread_exit(long result)
{
	struct kthread *kthread = to_kthread(current);
	kthread-&gt;result = result;
	do_exit(0);
}
</code></pre>
<p><code>kthread-&gt;exited</code>&#x7684;&#x7ED3;&#x6784;&#x4F53;&#x6700;&#x7EC8;&#x662F;&#x7531;<code>mm_release</code>&#x5B8C;&#x6210;&#x7684;&#xFF0C;&#x8C03;&#x7528;&#x6D41;&#x7A0B;&#x4E3A;&#xFF1A;<code>do_exit</code>-&gt;<code>exit_mm</code>-&gt;<code>exit_mm_release</code>-&gt;<code>mm_release</code>&#xFF0C;&#x5176;&#x4E2D;&#x64CD;&#x4F5C;&#x5982;&#x4E0B;&#xFF1A;</p>
<pre><code class="language-cpp">static void mm_release(struct task_struct *tsk, struct mm_struct *mm)
{
	uprobe_free_utask(tsk);
	......
	/*
	 * All done, finally we can wake up parent and return this mm to him.
	 * Also kthread_stop() uses this completion for synchronization.
	 */
	if (tsk-&gt;vfork_done)
		complete_vfork_done(tsk); // &#x901A;&#x8FC7;&#x64CD;&#x4F5C;vfork_done&#x5730;&#x5740;&#x6765;&#x586B;&#x5145;&#x7ED3;&#x6784;&#x4F53;
}
</code></pre>
<p>&#x4E0A;&#x8FB9;&#x7684;<code>vfork_done</code>&#x662F;&#x5728;&#x521D;&#x59CB;&#x5316;&#x8FC7;&#x7A0B;&#x4E2D;&#xFF0C;&#x6307;&#x5411;<code>exited</code>&#x7ED3;&#x6784;&#x4F53;&#x7684;</p>
<pre><code class="language-cpp">bool set_kthread_struct(struct task_struct *p)
{
	......
	init_completion(&amp;kthread-&gt;exited);
	init_completion(&amp;kthread-&gt;parked);
	p-&gt;vfork_done = &amp;kthread-&gt;exited;
	......
}
</code></pre>
<h4 id="322-kthreadstop">3.2.2-<code>kthread_stop</code></h4>
<p>&#x53E6;&#x5916;&#xFF0C;&#x6211;&#x4EEC;&#x4E5F;&#x53EF;&#x4EE5;&#x4E3B;&#x52A8;&#x8C03;&#x7528;<code>kthread_stop()</code>&#x6765;&#x7EC8;&#x6B62;&#x4E00;&#x4E2A;&#x5FAA;&#x73AF;&#x7EBF;&#x7A0B;&#xFF0C;&#x4F46;&#x662F;&#x540C;&#x65F6;&#x4E5F;&#x8981;&#x518D;&#x7EBF;&#x7A0B;&#x7684;&#x5FAA;&#x73AF;&#x4E2D;&#x589E;&#x52A0;<code>kthread_should_stop()</code>&#x7684;&#x68C0;&#x67E5;&#x3002;</p>
<pre><code class="language-cpp">int kthread_stop(struct task_struct *k)
{
	struct kthread *kthread;
	int ret;

	trace_sched_kthread_stop(k);

	get_task_struct(k);
	kthread = to_kthread(k); // &#x83B7;&#x53D6;&#x7EBF;&#x7A0B;&#x7684;kthread&#x7ED3;&#x6784;&#x4F53;
	set_bit(KTHREAD_SHOULD_STOP, &amp;kthread-&gt;flags); // &#x589E;&#x52A0;should_stop flag
	kthread_unpark(k); // &#x53D6;&#x6D88;park flag
	set_tsk_thread_flag(k, TIF_NOTIFY_SIGNAL); // &#x63D0;&#x524D;&#x53D6;&#x6D88;signal peding
	wake_up_process(k); // &#x5524;&#x9192;&#x7EBF;&#x7A0B;
	wait_for_completion(&amp;kthread-&gt;exited); // &#x7B49;&#x5F85;&#x7EBF;&#x7A0B;&#x5B8C;&#x6210;
	ret = kthread-&gt;result; // &#x628A;return&#x5B58;&#x5165;&#x7ED3;&#x6784;&#x4F53;&#x4E2D;
	put_task_struct(k); // &#x89E3;&#x5F15;&#x7528;

	trace_sched_kthread_stop_ret(ret);
	return ret;
}
</code></pre>
<p>&#x5176;&#x4E2D;&#x6BD4;&#x8F83;&#x5173;&#x952E;&#x7684;&#x64CD;&#x4F5C;&#x662F;<code>wait_for_completion</code>&#xFF0C;&#x4ED6;&#x4F1A;&#x6267;&#x884C;&#x4E00;&#x4E2A;&#x6CA1;&#x6709;timeout&#x7684;&#x5FAA;&#x73AF;&#x7B49;&#x5F85;&#xFF0C;&#x7B49;&#x5F85;&#x8FDB;&#x7A0B;&#x9000;&#x51FA;&#x3002;</p>
<pre><code class="language-cpp">void __sched wait_for_completion(struct completion *x)
{
	wait_for_common(x, MAX_SCHEDULE_TIMEOUT, TASK_UNINTERRUPTIBLE);
}
EXPORT_SYMBOL(wait_for_completion);

static long __sched
wait_for_common(struct completion *x, long timeout, int state)
{
	return __wait_for_common(x, schedule_timeout, timeout, state);
}

static inline long __sched
do_wait_for_common(struct completion *x,
		   long (*action)(long), long timeout, int state)
{
	if (!x-&gt;done) {
		DECLARE_SWAITQUEUE(wait);

		do {
			if (signal_pending_state(state, current)) { // &#x6709;&#x4FE1;&#x53F7;&#x6392;&#x961F;&#x7684;&#x65F6;&#x5019;&#x9000;&#x51FA;&#x5FAA;&#x73AF;
				timeout = -ERESTARTSYS;
				break;
			}
			__prepare_to_swait(&amp;x-&gt;wait, &amp;wait);
			__set_current_state(state); // &#x628A;&#x672C;&#x7EBF;&#x7A0B;&#x6807;&#x8BB0;&#x4E3A;&#x4E0D;&#x53EF;&#x4E2D;&#x65AD;&#x7684;&#x72B6;&#x6001;&#xFF0C;&#x9632;&#x6B62;&#x8BEF;&#x8C03;&#x5EA6;
			raw_spin_unlock_irq(&amp;x-&gt;wait.lock);
			timeout = action(timeout); // &#x4E0D;&#x4F1A;&#x91CD;&#x65B0;&#x5524;&#x9192;&#xFF0C;&#x5E94;&#x4E3A;timeout&#x662F;MAX_SCHEDULE_TIMEOUT
			raw_spin_lock_irq(&amp;x-&gt;wait.lock);
		} while (!x-&gt;done &amp;&amp; timeout); // &#x7B49;&#x5F85;kthread&#x7684;done&#x6807;&#x8BB0;&#x4E3A;&#x7F6E;1&#xFF0C;&#x7531;do_exit&#x5B8C;&#x6210;
		__finish_swait(&amp;x-&gt;wait, &amp;wait);
		if (!x-&gt;done)
			return timeout;
	}
	if (x-&gt;done != UINT_MAX)
		x-&gt;done--;
	return timeout ?: 1;
}

</code></pre>
]]></content:encoded></item><item><title><![CDATA[Makefile指南]]></title><description><![CDATA[<h2 id="0%E3%80%81%E5%89%8D%E8%A8%80">0&#x3001;&#x524D;&#x8A00;</h2>
<p>&#x5185;&#x6838;&#x7F16;&#x8BD1;&#x4EE5;&#x53CA;&#x5DE5;&#x5177;&#x5F00;&#x53D1;&#x8FC7;&#x7A0B;&#x4E2D;&#xFF0C;&#x7ECF;&#x5E38;&#x4F1A;&#x6D89;&#x53CA;&#x5230;<code>Makefile</code>&#x6587;&#x4EF6;&#xFF0C;&#x8FD9;&#x4E00;&#x6B21;&#x8BE6;&#x7EC6;&#x6765;&#x770B;&#x4E00;&#x4E0B;Makefile&#x76F8;&#x5173;&#x7684;&#x5185;&#x5BB9;&#x3002;</p>
<p>&#x5B98;&#x65B9;&#x624B;&#x518C;&#xFF1A;<a href="https://makefiletutorial.com/?ref=korantli.com.cn#getting-started">Learn</a></p>]]></description><link>http://www.korantli.com.cn/linux/makefilezhi-nan/</link><guid isPermaLink="false">6586bac2bdb46ffaf8f37c0e</guid><category><![CDATA[linux技术总结]]></category><category><![CDATA[linux工具]]></category><dc:creator><![CDATA[李星辉]]></dc:creator><pubDate>Sat, 23 Dec 2023 10:49:03 GMT</pubDate><media:content url="http://www.korantli.com.cn/content/images/2023/12/dependency_graph.png" medium="image"/><content:encoded><![CDATA[<h2 id="0%E3%80%81%E5%89%8D%E8%A8%80">0&#x3001;&#x524D;&#x8A00;</h2>
<img src="http://www.korantli.com.cn/content/images/2023/12/dependency_graph.png" alt="Makefile&#x6307;&#x5357;"><p>&#x5185;&#x6838;&#x7F16;&#x8BD1;&#x4EE5;&#x53CA;&#x5DE5;&#x5177;&#x5F00;&#x53D1;&#x8FC7;&#x7A0B;&#x4E2D;&#xFF0C;&#x7ECF;&#x5E38;&#x4F1A;&#x6D89;&#x53CA;&#x5230;<code>Makefile</code>&#x6587;&#x4EF6;&#xFF0C;&#x8FD9;&#x4E00;&#x6B21;&#x8BE6;&#x7EC6;&#x6765;&#x770B;&#x4E00;&#x4E0B;Makefile&#x76F8;&#x5173;&#x7684;&#x5185;&#x5BB9;&#x3002;</p>
<p>&#x5B98;&#x65B9;&#x624B;&#x518C;&#xFF1A;<a href="https://makefiletutorial.com/?ref=korantli.com.cn#getting-started">Learn Makefiles</a></p>
<p>&#x5F88;&#x597D;&#x7684;&#x5B66;&#x4E60;&#x6587;&#x7AE0;&#xFF1A;<a href="https://seisman.github.io/how-to-write-makefile/index.html?ref=korantli.com.cn">&#x8DDF;&#x6211;&#x4E00;&#x8D77;&#x5199;Makefile</a></p>
<h2 id="1%E3%80%81%E5%85%A5%E9%97%A8">1&#x3001;&#x5165;&#x95E8;</h2>
<h3 id="11-makefile%E7%9A%84%E4%BD%9C%E7%94%A8">1.1-Makefile&#x7684;&#x4F5C;&#x7528;</h3>
<p>&#x7F16;&#x8BD1;&#x4E00;&#x4E2A;&#x6700;&#x7B80;&#x5355;&#x7684;.c&#x6587;&#x4EF6;&#x901A;&#x5E38;&#x4F1A;&#x4F7F;&#x7528;&#x5230;</p>
<pre><code class="language-bash">gcc main.c
</code></pre>
<p>&#x4F46;&#x662F;&#x5728;&#x5927;&#x578B;&#x590D;&#x6742;&#x9879;&#x76EE;&#x5728;&#x6784;&#x5EFA;&#x7684;&#x65F6;&#x5019;&#xFF0C;&#x9700;&#x8981;&#x7684;&#x4F9D;&#x8D56;&#x6587;&#x4EF6;&#x6BD4;&#x8F83;&#x591A;&#x4E14;&#x590D;&#x6742;&#xFF0C;&#x8FD9;&#x4E2A;&#x65F6;&#x5019;&#x53EA;&#x7528;gcc&#x7B80;&#x5355;&#x7684;&#x8FDB;&#x884C;&#x7F16;&#x8BD1;&#x5DF2;&#x7ECF;&#x65E0;&#x6CD5;&#x5B9E;&#x73B0;&#x4E86;&#x3002;&#x53E6;&#x5916;<code>Makefile</code>&#x8FD8;&#x4F1A;&#x7528;&#x4E8E;&#x5E2E;&#x52A9;&#x51B3;&#x5B9A;&#x5927;&#x578B;&#x7A0B;&#x5E8F;&#x7684;&#x54EA;&#x4E9B;&#x90E8;&#x5206;&#x9700;&#x8981;&#x91CD;&#x65B0;&#x7F16;&#x8BD1;&#xFF0C;&#x8FD9;&#x6837;&#x53EA;&#x6709;&#x4E00;&#x4E2A;&#x6A21;&#x5757;&#x6587;&#x4EF6;&#x4FEE;&#x6539;&#x65F6;&#xFF0C;&#x5C31;&#x6CA1;&#x5FC5;&#x8981;&#x91CD;&#x7F16;&#x6574;&#x4E2A;&#x5DE5;&#x7A0B;&#x3002;</p>
<p>&#x800C;<code>Makefile</code>&#x4F9D;&#x8D56;&#x7684;&#x5DE5;&#x5177;&#x5219;&#x662F;<code>make</code>&#xFF0C;&#x4ED6;&#x4F1A;&#x5BFB;&#x627E;&#x5F53;&#x524D;&#x8DEF;&#x5F84;&#x4E0B;&#x7684;<code>Makefile</code>&#x6587;&#x4EF6;&#xFF0C;&#x5E76;&#x6267;&#x884C;&#x76F8;&#x5E94;&#x7684;&#x547D;&#x4EE4;&#x3002;<code>Makefile</code>&#x5219;&#x544A;&#x8BC9;<code>make</code>&#x547D;&#x4EE4;&#x9700;&#x8981;&#x600E;&#x4E48;&#x6837;&#x7684;&#x53BB;&#x7F16;&#x8BD1;&#x548C;&#x94FE;&#x63A5;&#x7A0B;&#x5E8F;&#x3002;</p>
<h3 id="12-makefile%E7%9A%84%E5%9F%BA%E7%A1%80%E8%A7%84%E5%88%99">1.2-Makefile&#x7684;&#x57FA;&#x7840;&#x89C4;&#x5219;</h3>
<p>&#x4E00;&#x4E2A;Makefile&#x7684;&#x6700;&#x57FA;&#x7840;&#x7EC4;&#x6210;&#x5982;&#x4E0B;</p>
<pre><code class="language-makefile">target ... : prerequisites ...
    recipe
    ...
    ...
</code></pre>
<p>&#x8FD9;&#x5176;&#x4E2D;&#xFF1A;</p>
<ul>
<li>
<p>target&#xFF1A;</p>
<p>&#x53EF;&#x4EE5;&#x662F;&#x4E00;&#x4E2A;object file&#xFF08;&#x76EE;&#x6807;&#x6587;&#x4EF6;&#xFF09;&#xFF0C;&#x4E5F;&#x53EF;&#x4EE5;&#x662F;&#x4E00;&#x4E2A;&#x53EF;&#x6267;&#x884C;&#x6587;&#x4EF6;&#xFF0C;&#x8FD8;&#x53EF;&#x4EE5;&#x662F;&#x4E00;&#x4E2A;&#x6807;&#x7B7E;&#xFF08;label&#xFF09;&#x3002;</p>
</li>
<li>
<p>prerequisites&#xFF1A;</p>
<p>&#x751F;&#x6210;&#x8BE5;target&#x6240;&#x4F9D;&#x8D56;&#x7684;&#x6587;&#x4EF6;&#xFF0C;&#x53EF;&#x4EE5;&#x7406;&#x89E3;&#x4E3A;&#x539F;&#x6750;&#x6599;&#x3002;</p>
</li>
<li>
<p>recipe&#xFF1A;</p>
<p>&#x751F;&#x6210;&#x8FD9;&#x4E2A;target&#x8981;&#x6267;&#x884C;&#x7684;&#x547D;&#x4EE4;&#xFF08;&#x4EFB;&#x610F;&#x7684;shell&#x547D;&#x4EE4;&#xFF09;&#x3002;</p>
</li>
</ul>
<p>&#x5982;&#x679C;&#x539F;&#x6750;&#x6599;&#x4E2D;&#x6709;&#x4EE3;&#x7801;&#x53D8;&#x66F4;&#x7684;&#x8BDD;&#xFF0C;&#x5C31;&#x4F1A;&#x6267;&#x884C;&#x76F8;&#x5E94;&#x7684;&#x7684;&#x547D;&#x4EE4;&#xFF0C;&#x91CD;&#x65B0;&#x6784;&#x5EFA;&#x76EE;&#x6807;&#x3002;</p>
<h3 id="13-%E4%BE%8B%E5%AD%90">1.3-&#x4F8B;&#x5B50;</h3>
<pre><code class="language-makefile">c: a.o b.o
	gcc -o c a.o b.o

a.o&#xFF1A;a.c d.h
	gcc a.c
 
b.o: b.c d.h
	gcc b.c

</code></pre>
<p>&#x4E0A;&#x8FB9;&#x7684;&#x4F8B;&#x5B50;&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;&#x6211;&#x4EEC;&#x4F1A;&#x6700;&#x7EC8;&#x7F16;&#x8BD1;&#x51FA;&#x4E00;&#x4E2A;c&#x7684;&#x4E8C;&#x8FDB;&#x5236;&#x6587;&#x4EF6;&#xFF0C;&#x800C;c&#x662F;&#x7531;<code>a.c</code>&#x4E0E;<code>b.c</code>&#x4E24;&#x4E2A;c&#x6587;&#x4EF6;&#x7EC4;&#x6210;&#x7684;&#xFF0C;&#x56E0;&#x6B64;&#x9700;&#x8981;&#x5C06;&#x4ED6;&#x4EEC;&#x7F16;&#x8BD1;&#x51FA;&#x7684;.o&#x6587;&#x4EF6;&#x8FDB;&#x884C;&#x94FE;&#x63A5;&#xFF0C;&#x800C;&#x8FD9;&#x4E24;&#x4E2A;.o&#x6587;&#x4EF6;&#x8FD8;&#x662F;&#x4E0E;<code>d.h</code>&#x6709;&#x5173;&#xFF0C;&#x6240;&#x6709;&#x5F53;&#x65F6;<code>d.h</code>&#x6709;&#x53D8;&#x5316;&#x65F6;&#xFF0C;&#x5219;&#x4F1A;&#x91CD;&#x7F16;&#x6574;&#x4E2A;&#x5DE5;&#x7A0B;&#x3002;</p>
<h2 id="2%E3%80%81%E8%A7%84%E5%88%99">2&#x3001;&#x89C4;&#x5219;</h2>
<p>&#x4F8B;&#x5982;&#x6211;&#x4EEC;&#x4E4B;&#x524D;&#x7684;&#x4E3E;&#x4F8B;&#xFF0C;&#x6700;&#x57FA;&#x7840;&#x7684;&#x89C4;&#x5219;&#x5982;&#x4E0B;</p>
<pre><code class="language-makefile">foo.o: foo.c defs.h       # foo&#x6A21;&#x5757;
    cc -c -g foo.c
</code></pre>
<p>&#x5728;&#x89C4;&#x5219;&#x4E2D;&#xFF0C;&#x4F7F;&#x7528;<code>\</code>&#x8FDB;&#x884C;&#x6362;&#x884C;&#xFF0C;&#x4F7F;&#x7528;<code>*</code>&#x8FDB;&#x884C;&#x901A;&#x914D;&#x3002;</p>
<h3 id="21-%E4%BC%AA%E7%9B%AE%E6%A0%87">2.1-&#x4F2A;&#x76EE;&#x6807;</h3>
<p>&#x5982;&#x679C;&#x76EE;&#x6807;&#x540E;&#x6CA1;&#x6709;&#x4F9D;&#x8D56;&#x6587;&#x4EF6;&#xFF0C;&#x5219;&#x76F8;&#x5F53;&#x4E8E;&#x4E00;&#x4E2A;<code>lable</code></p>
<pre><code class="language-makefile">clean :
    rm *.o
</code></pre>
<p>&#x5728;&#x6267;&#x884C;<code>make clean</code>&#x540E;&#x5219;&#x4F1A;&#x6267;&#x884C;&#x5BF9;&#x5E94;&#x7684;&#x547D;&#x4EE4;&#xFF0C;&#x4E5F;&#x5C31;&#x662F;&#x6E05;&#x7406;&#x6240;&#x6709;&#x7684;<code>.o</code>&#x6587;&#x4EF6;&#x3002;</p>
<p>&#x53E6;&#x5916;&#x4E5F;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x4E0B;&#x5217;&#x65B9;&#x5F0F;&#x6307;&#x5B9A;&#x7279;&#x5B9A;&#x76EE;&#x6807;&#x4E3A;&#x4F2A;&#x76EE;&#x6807;</p>
<pre><code class="language-makefile">.PHONY : clean
clean :
    rm *.o
</code></pre>
<h3 id="22-%E5%A4%9A%E7%9B%AE%E6%A0%87">2.2-&#x591A;&#x76EE;&#x6807;</h3>
<p>makefile&#x4E2D;&#x53EF;&#x4EE5;&#x591A;&#x4E2A;&#x76EE;&#x6807;&#x4F9D;&#x8D56;&#x4E00;&#x6837;&#x7684;&#x6587;&#x4EF6;&#xFF0C;&#x4E0B;&#x5217;&#x8FD9;&#x4E24;&#x4E2A;&#x79CD;&#x65B9;&#x5F0F;&#x662F;&#x7B49;&#x4EF7;&#x7684;</p>
<pre><code class="language-makefile">a b : c.o d.o
...
a : c.o d.o
b : c.o d.o
</code></pre>
<h3 id="23-%E8%87%AA%E5%8A%A8%E7%94%9F%E6%88%90%E4%BE%9D%E8%B5%96">2.3-&#x81EA;&#x52A8;&#x751F;&#x6210;&#x4F9D;&#x8D56;</h3>
<p>&#x5728;Makefile&#x4E2D;&#xFF0C;&#x6211;&#x4EEC;&#x53EF;&#x4EE5;&#x5229;&#x7528;GCC&#x7684;<code>-M</code>&#x9009;&#x9879;&#x751F;&#x6210;&#x4F9D;&#x8D56;&#x5173;&#x7CFB;&#xFF0C;&#x7136;&#x540E;&#x901A;&#x8FC7;<code>-include</code>&#x6307;&#x4EE4;&#x5C06;&#x8FD9;&#x4E9B;&#x4F9D;&#x8D56;&#x5173;&#x7CFB;&#x5305;&#x542B;&#x5230;Makefile&#x4E2D;&#x3002;&#x8FD9;&#x6837;&#xFF0C;&#x5F53;&#x6E90;&#x6587;&#x4EF6;&#x6216;&#x5934;&#x6587;&#x4EF6;&#x53D1;&#x751F;&#x53D8;&#x5316;&#x65F6;&#xFF0C;Makefile&#x4F1A;&#x81EA;&#x52A8;&#x91CD;&#x65B0;&#x7F16;&#x8BD1;&#x76F8;&#x5E94;&#x7684;&#x76EE;&#x6807;&#x6587;&#x4EF6;&#x3002;&#x4F8B;&#x5982;</p>
<pre><code class="language-makefile"># &#x5B9A;&#x4E49;&#x53D8;&#x91CF;
CC = gcc
CFLAGS = -Wall -g
SRCS = $(wildcard *.c)
OBJS = $(patsubst %.c,%.o,$(SRCS))
DEPS = $(patsubst %.c,%.d,$(SRCS))
TARGET = my_program

# &#x9ED8;&#x8BA4;&#x76EE;&#x6807;
all: $(TARGET)

# &#x94FE;&#x63A5;&#x76EE;&#x6807;&#x6587;&#x4EF6;&#xFF0C;&#x751F;&#x6210;&#x53EF;&#x6267;&#x884C;&#x6587;&#x4EF6;
$(TARGET): $(OBJS)
	$(CC) $(CFLAGS) -o $(TARGET) $(OBJS)

# &#x7F16;&#x8BD1;&#x6E90;&#x6587;&#x4EF6;&#xFF0C;&#x751F;&#x6210;&#x76EE;&#x6807;&#x6587;&#x4EF6;&#x548C;&#x4F9D;&#x8D56;&#x6587;&#x4EF6;
%.o: %.c
	$(CC) $(CFLAGS) -MMD -c $*.c -o $*.o

# &#x5305;&#x542B;&#x81EA;&#x52A8;&#x751F;&#x6210;&#x7684;&#x4F9D;&#x8D56;&#x6587;&#x4EF6;
-include $(DEPS)
</code></pre>
<h2 id="3%E3%80%81%E5%8F%98%E9%87%8F">3&#x3001;&#x53D8;&#x91CF;</h2>
<h3 id="31-%E5%9F%BA%E7%A1%80%E5%8F%98%E9%87%8F">3.1-&#x57FA;&#x7840;&#x53D8;&#x91CF;</h3>
<p>&#x5728;Makefile&#x4E2D;&#xFF0C;&#x53D8;&#x91CF;&#x7684;&#x8BED;&#x6CD5;&#x4E0E;<code>shell</code>&#x7C7B;&#x4F3C;&#xFF0C;&#x6BD4;&#x5982;</p>
<ol>
<li>&#x5B9A;&#x4E49;&#x7F16;&#x8BD1;&#x7684;&#x6587;&#x4EF6;</li>
</ol>
<pre><code class="language-makefile">object = a.o b.o
c: $(object)
	gcc -o c $(object)
</code></pre>
<ol start="2">
<li>&#x5B9A;&#x4E49;&#x547D;&#x4EE4;</li>
</ol>
<pre><code class="language-makefile">cc = gcc
c: a.o b.o
	$(cc) -o c a.o b.o
</code></pre>
<h3 id="32-%E8%BF%BD%E5%8A%A0%E5%8F%98%E9%87%8F">3.2-&#x8FFD;&#x52A0;&#x53D8;&#x91CF;</h3>
<p>&#x53EF;&#x4EE5;&#x4F7F;&#x7528;<code>+=</code>&#x7684;&#x65B9;&#x5F0F;&#x8FFD;&#x52A0;&#x53D8;&#x91CF;</p>
<pre><code class="language-makefile">object = a.o b.o
object += c.o
</code></pre>
<p>&#x8FD9;&#x4E2A;&#x65F6;&#x5019;<code>object = a.o b.o c.o</code>&#x3002;</p>
<h3 id="33-%E4%BC%A0%E5%8F%82">3.3-&#x4F20;&#x53C2;</h3>
<p>&#x5982;&#x679C;Makefile&#x4E2D;&#x6CA1;&#x6709;&#x5B9A;&#x4E49;&#x53D8;&#x91CF;&#x7684;&#x8BDD;&#xFF0C;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;<code>make DESTDIR=xxx</code>&#x7684;&#x65F6;&#x5019;&#x4F20;&#x5165;&#x53D8;&#x91CF;&#xFF0C;</p>
<pre><code class="language-makefile">install -d $(DESTDIR)/usr/local/sbin/
</code></pre>
<p>&#x7C7B;&#x4F3C;&#x4E0A;&#x8FF0;&#x547D;&#x4EE4;&#x7EC4;&#x4E2D;&#x4F1A;&#x5B89;&#x88C5;&#x5728;<code>xxx/usr/local/sbin/</code>&#x4E0A;&#x3002;</p>
<h3 id="34-%E6%9B%BF%E6%8D%A2">3.4-&#x66FF;&#x6362;</h3>
<p>&#x4E0B;&#x5217;&#x64CD;&#x4F5C;&#x4E2D;&#xFF0C;&#x4F1A;&#x628A;&#x53D8;&#x91CF; <code>$(sources)</code> &#x6240;&#x6709; <code>.c</code> &#x7684;&#x5B57;&#x4E32;&#x90FD;&#x66FF;&#x6362;&#x6210; <code>.d</code></p>
<pre><code>sources = foo.c bar.c

include $(sources:.c=.d)
</code></pre>
<h3 id="35-%E8%87%AA%E5%8A%A8%E5%8F%98%E9%87%8F">3.5-&#x81EA;&#x52A8;&#x53D8;&#x91CF;</h3>
<p><code>$@</code>&#xFF1A;&#x8868;&#x793A;&#x5F53;&#x524D;&#x89C4;&#x5219;&#x7684;&#x76EE;&#x6807;&#x6587;&#x4EF6;&#x3002;&#x5728;&#x547D;&#x4EE4;&#x884C;&#x4E2D;&#xFF0C;&#x6211;&#x4EEC;&#x53EF;&#x4EE5;&#x7528;<code>$@</code>&#x5F15;&#x7528;&#x76EE;&#x6807;&#x6587;&#x4EF6;&#xFF0C;&#x800C;&#x65E0;&#x9700;&#x663E;&#x5F0F;&#x5730;&#x6307;&#x5B9A;&#x76EE;&#x6807;&#x6587;&#x4EF6;&#x540D;&#x3002;</p>
<p><code>$^</code>&#xFF1A;&#x8868;&#x793A;&#x5F53;&#x524D;&#x89C4;&#x5219;&#x7684;&#x6240;&#x6709;&#x4F9D;&#x8D56;&#x6587;&#x4EF6;&#xFF0C;&#x4EE5;&#x7A7A;&#x683C;&#x5206;&#x9694;&#x3002;&#x5728;&#x547D;&#x4EE4;&#x884C;&#x4E2D;&#xFF0C;&#x6211;&#x4EEC;&#x53EF;&#x4EE5;&#x7528;<code>$^</code>&#x5F15;&#x7528;&#x6240;&#x6709;&#x4F9D;&#x8D56;&#x6587;&#x4EF6;&#xFF0C;&#x800C;&#x65E0;&#x9700;&#x663E;&#x5F0F;&#x5730;&#x6307;&#x5B9A;&#x5B83;&#x4EEC;&#x3002;</p>
<p><code>$&lt;</code>&#xFF1A;&#x8868;&#x793A;&#x5F53;&#x524D;&#x89C4;&#x5219;&#x7684;&#x7B2C;&#x4E00;&#x4E2A;&#x4F9D;&#x8D56;&#x6587;&#x4EF6;&#x3002;&#x5728;&#x547D;&#x4EE4;&#x884C;&#x4E2D;&#xFF0C;&#x6211;&#x4EEC;&#x53EF;&#x4EE5;&#x7528;<code>$&lt;</code>&#x5F15;&#x7528;&#x7B2C;&#x4E00;&#x4E2A;&#x4F9D;&#x8D56;&#x6587;&#x4EF6;&#xFF0C;&#x800C;&#x65E0;&#x9700;&#x663E;&#x5F0F;&#x5730;&#x6307;&#x5B9A;&#x5B83;&#x3002;</p>
<h2 id="4%E3%80%81if%E5%88%A4%E6%96%AD">4&#x3001;if&#x5224;&#x65AD;</h2>
<p>&#x6700;&#x57FA;&#x7840;&#x7684;&#x8BED;&#x6CD5;&#x662F;</p>
<pre><code class="language-makefile">&lt;conditional-directive&gt;
&lt;text-if-true&gt;
else
&lt;text-if-false&gt;
endif
</code></pre>
<p>Makefile&#x4E2D;&#x6709;&#x56DB;&#x79CD;if&#x8BED;&#x6CD5;&#x53CA;<code>&lt;conditional-directive&gt;</code></p>
<ol>
<li>&#x662F;&#x5426;&#x76F8;&#x7B49;</li>
</ol>
<pre><code class="language-makefile">ifeq (&lt;arg1&gt;, &lt;arg2&gt;)
</code></pre>
<ol start="2">
<li>&#x662F;&#x5426;&#x4E0D;&#x76F8;&#x7B49;</li>
</ol>
<pre><code class="language-makefile">ifneq (&lt;arg1&gt;, &lt;arg2&gt;)
</code></pre>
<ol start="3">
<li>&#x662F;&#x5426;&#x4E3A;&#x7A7A;</li>
</ol>
<pre><code class="language-makefile">ifdef arg1
</code></pre>
<ol start="4">
<li>&#x662F;&#x5426;&#x4E0D;&#x4E3A;&#x7A7A;</li>
</ol>
<pre><code class="language-makefile">ifndef arg1
</code></pre>
<p>&#x4E0A;&#x8FF0;&#x7684;&#x53C2;&#x6570;&#x53EF;&#x4EE5;&#x662F;&#x53D8;&#x91CF;&#xFF0C;&#x4E5F;&#x53EF;&#x4EE5;&#x662F;&#x5B57;&#x7B26;&#x4E32;&#xFF0C;&#x7C7B;&#x4F3C;&#x4E8E;&#x5224;&#x65AD; <code>$(CC)</code> &#x53D8;&#x91CF;&#x662F;&#x5426; <code>gcc</code></p>
<pre><code class="language-makefile">ifeq ($(CC),gcc)
</code></pre>
<h2 id="5%E3%80%81%E5%91%BD%E4%BB%A4">5&#x3001;&#x547D;&#x4EE4;</h2>
<p>Makefile&#x4E2D;&#x53EF;&#x4EE5;&#x76F4;&#x63A5;&#x6267;&#x884C;bash&#x547D;&#x4EE4;&#xFF0C;&#x4F46;&#x662F;&#x547D;&#x4EE4;&#x5FC5;&#x987B;&#x4EE5;<code>tab</code>&#x5F00;&#x5934;&#x3002;</p>
<h3 id="51-%E6%98%BE%E7%A4%BA%E5%91%BD%E4%BB%A4">5.1-&#x663E;&#x793A;&#x547D;&#x4EE4;</h3>
<p>makefile&#x53EF;&#x4EE5;&#x901A;&#x8FC7;<code>@</code>&#x6765;&#x5C4F;&#x853D;&#x8F93;&#x51FA;&#x547D;&#x4EE4;&#x672C;&#x8EAB;&#x3002;&#x6BD4;&#x5982;makefie&#x4E2D;&#x5B58;&#x5728;&#x8FD9;&#x6837;&#x4E00;&#x4E2A;&#x547D;&#x4EE4;</p>
<pre><code class="language-makefile">test:
	echo 123
	@echo 456
</code></pre>
<p>&#x8FD0;&#x884C;&#x8FD9;&#x4E2A;&#x811A;&#x672C;&#x7684;&#x6548;&#x679C;&#x5982;&#x4E0B;</p>
<pre><code class="language-bash">echo 123
123
456
</code></pre>
<p>&#x53E6;&#x5916;&#xFF0C;&#x4E5F;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;<code>make -s</code>&#x6765;&#x5C4F;&#x853D;&#x547D;&#x4EE4;&#x8F93;&#x51FA;&#xFF0C;&#x7528;<code>make -n</code>&#x53EA;&#x8F93;&#x51FA;&#x547D;&#x4EE4;&#xFF0C;&#x4E0D;&#x6267;&#x884C;&#x547D;&#x4EE4;&#xFF08;&#x7528;&#x4E8E;&#x8C03;&#x8BD5;&#xFF09;&#x3002;</p>
<h3 id="52-%E5%BF%BD%E7%95%A5%E6%8A%A5%E9%94%99">5.2-&#x5FFD;&#x7565;&#x62A5;&#x9519;</h3>
<p>&#x5728;makefile&#x4E2D;&#xFF0C;&#x5982;&#x679C;&#x547D;&#x4EE4;&#x6267;&#x884C;&#x5931;&#x8D25;&#xFF0C;&#x5219;&#x4F1A;&#x9000;&#x51FA;makefile&#xFF0C;&#x4E0D;&#x7EE7;&#x7EED;&#x6267;&#x884C;&#xFF0C;&#x800C;<code>-</code>&#x547D;&#x4EE4;&#x5219;&#x53EF;&#x4EE5;&#x5FFD;&#x7565;&#x62A5;&#x9519;&#x7EE7;&#x7EED;&#x6267;&#x884C;&#x3002;</p>
<pre><code class="language-makefile">test:
	abc
	echo 123
</code></pre>
<p>&#x8FD9;&#x65F6;</p>
<pre><code class="language-bash"># make test
abc
make: abc: Command not found
make: *** [Makefile:2: test] Error 127
</code></pre>
<p>&#x800C;&#x6DFB;&#x52A0;&#x4E86;<code>-</code></p>
<pre><code class="language-makefile">test:
	-abc
	echo 123
</code></pre>
<p>&#x5219;&#x4F1A;</p>
<pre><code class="language-bash"># make test
abc
make: abc: Command not found
make: [Makefile:2: test] Error 127 (ignored)
echo 123
123
</code></pre>
]]></content:encoded></item><item><title><![CDATA[perf使用简介]]></title><description><![CDATA[<h2 id="0%E3%80%81%E5%89%8D%E8%A8%80">0&#x3001;&#x524D;&#x8A00;</h2>
<p>perf&#x662F;&#x5185;&#x6838;&#x7684;&#x4E00;&#x4E2A;&#x6027;&#x80FD;&#x5DE5;&#x5177;&#x96C6;&#x5408;&#xFF0C;&#x53EF;&#x4EE5;&#x5F88;&#x65B9;&#x4FBF;&#x3001;&#x6709;&#x6548;&#x7684;&#x5BF9;&#x5185;&#x6838;&#x7684;&#x6027;&#x80FD;&#x6307;&#x6807;&#x8FDB;&#x884C;&#x5206;&#x6790;&#x3001;&#x8FFD;&#x8E2A;&#xFF0C;&#x53EF;&#x4EE5;&#x68C0;&#x6D4B; CPU &#x6027;&#x80FD;</p>]]></description><link>http://www.korantli.com.cn/linux/perf/</link><guid isPermaLink="false">653bd694b936e6d99568cc34</guid><category><![CDATA[linux工具]]></category><category><![CDATA[linux技术总结]]></category><dc:creator><![CDATA[李星辉]]></dc:creator><pubDate>Fri, 27 Oct 2023 15:26:55 GMT</pubDate><content:encoded><![CDATA[<h2 id="0%E3%80%81%E5%89%8D%E8%A8%80">0&#x3001;&#x524D;&#x8A00;</h2>
<p>perf&#x662F;&#x5185;&#x6838;&#x7684;&#x4E00;&#x4E2A;&#x6027;&#x80FD;&#x5DE5;&#x5177;&#x96C6;&#x5408;&#xFF0C;&#x53EF;&#x4EE5;&#x5F88;&#x65B9;&#x4FBF;&#x3001;&#x6709;&#x6548;&#x7684;&#x5BF9;&#x5185;&#x6838;&#x7684;&#x6027;&#x80FD;&#x6307;&#x6807;&#x8FDB;&#x884C;&#x5206;&#x6790;&#x3001;&#x8FFD;&#x8E2A;&#xFF0C;&#x53EF;&#x4EE5;&#x68C0;&#x6D4B; CPU &#x6027;&#x80FD;&#x8BA1;&#x6570;&#x5668;&#x3001;&#x8DDF;&#x8E2A;&#x70B9;&#x3001;kprobes &#x548C; uprobes&#xFF08;&#x52A8;&#x6001;&#x8DDF;&#x8E2A;&#xFF09;&#x3002;</p>
<p><a href="https://perf.wiki.kernel.org/index.php/Main_Page?ref=korantli.com.cn">Perf Main Page</a></p>
<p>perf&#x7684;&#x529F;&#x80FD;&#x5176;&#x5B9E;&#x975E;&#x5E38;&#x975E;&#x5E38;&#x5F3A;&#x5927;&#xFF0C;&#x4F7F;&#x7528;&#x7684;&#x65B9;&#x6CD5;&#x4EE5;&#x53CA;&#x53EF;&#x62D3;&#x5C55;&#x6027;&#x975E;&#x5E38;&#x975E;&#x5E38;&#x591A;&#xFF0C;&#x8FD9;&#x91CC;&#x53EA;&#x662F;&#x7B80;&#x5355;&#x4ECB;&#x7ECD;&#x4E00;&#x4E9B;&#x5E38;&#x7528;&#x7684;&#x5DE5;&#x5177;&#x3001;&#x547D;&#x4EE4;&#x96C6;&#x5408;&#xFF0C;&#x3002;</p>
<h2 id="1%E3%80%81%E5%9F%BA%E7%A1%80%E4%BD%BF%E7%94%A8">1&#x3001;&#x57FA;&#x7840;&#x4F7F;&#x7528;</h2>
<p>&#x5728;&#x4E00;&#x4E2A;linux&#x73AF;&#x5883;&#x4E0B;&#xFF0C;&#x6267;&#x884C;</p>
<pre><code class="language-bash">perf record -a -- sleep 30
</code></pre>
<p>&#x4F1A;&#x83B7;&#x53D6;&#x5230;&#x4E00;&#x4E2A;<code>perf.data</code>&#x6570;&#x636E;&#xFF0C;&#x8FD9;&#x91CC;&#x8BB0;&#x5F55;&#x4E86;&#x8FD9;30s&#x5185;&#x7CFB;&#x7EDF;&#x7684;&#x4E8B;&#x4EF6;&#xFF0C;&#x8FD9;&#x91CC;&#x662F;&#x901A;&#x8FC7;<code>&#x91C7;&#x6837;</code>&#x6765;&#x83B7;&#x53D6;&#x7684;&#x4E8B;&#x4EF6;<code>sample</code>&#x3002;</p>
<p>&#x5728;&#x5B8C;&#x6210;&#x540E;&#xFF0C;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x4E0B;&#x8FB9;&#x7684;&#x547D;&#x4EE4;&#x8FDB;&#x884C;&#x89E3;&#x6790;&#xFF0C;&#x83B7;&#x53D6;&#x5230;&#x76F8;&#x5173;&#x7684;&#x53EF;&#x8BFB;&#x76F8;&#x5173;&#x4FE1;&#x606F;&#x3002;</p>
<pre><code class="language-bash">perf report
</code></pre>
<p>&#x6B64;&#x5916;&#xFF0C;&#x8FD8;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;<code>perf script</code>&#x5BF9;<code>perf.data</code>&#x8FDB;&#x884C;&#x89E3;&#x6790;&#xFF0C;&#x5C06;&#x6355;&#x83B7;&#x7684;<code>sample</code>&#x6570;&#x636E;&#x751F;&#x6210;&#x6587;&#x672C;&#x683C;&#x5F0F;&#xFF0C;&#x65B9;&#x4FBF;&#x8FDB;&#x4E00;&#x6B65;&#x8FDB;&#x884C;&#x5206;&#x6790;&#x3002;&#xFF08;&#x53EF;&#x4EE5;&#x81EA;&#x5DF1;&#x6BD4;&#x7F16;&#x5199;&#x811A;&#x672C;&#xFF0C;&#x6216;&#x7528;&#x6765;&#x67E5;&#x627E;&#x7279;&#x5B9A;&#x65F6;&#x95F4;&#x70B9;&#x7684;&#x6570;&#x636E;&#xFF09;</p>
<p>perf&#x7684;&#x76F8;&#x5173;&#x5176;&#x4ED6;&#x76F8;&#x5173;&#x4E8B;&#x4EF6;&#x5982;&#x4E0B;</p>
<pre><code class="language-bash"> usage: perf [--version] [--help] [OPTIONS] COMMAND [ARGS]

 The most commonly used perf commands are:
   annotate        Read perf.data (created by perf record) and display annotated code
   archive         Create archive with object files with build-ids found in perf.data file
   bench           General framework for benchmark suites
   buildid-cache   Manage build-id cache.
   buildid-list    List the buildids in a perf.data file
   c2c             Shared Data C2C/HITM Analyzer.
   config          Get and set variables in a configuration file.
   data            Data file related processing
   diff            Read perf.data files and display the differential profile
   evlist          List the event names in a perf.data file
   ftrace          simple wrapper for kernel&apos;s ftrace functionality
   inject          Filter to augment the events stream with additional information
   kallsyms        Searches running kernel for symbols
   kmem            Tool to trace/measure kernel memory properties
   kvm             Tool to trace/measure kvm guest os
   list            List all symbolic event types
   lock            Analyze lock events
   mem             Profile memory accesses
   record          Run a command and record its profile into perf.data
   report          Read perf.data (created by perf record) and display the profile
   sched           Tool to trace/measure scheduler properties (latencies)
   script          Read perf.data (created by perf record) and display trace output
   stat            Run a command and gather performance counter statistics
   test            Runs sanity tests.
   timechart       Tool to visualize total system behavior during a workload
   top             System profiling tool.
   version         display the version of perf binary
   probe           Define new dynamic tracepoints
   trace           strace inspired tool
</code></pre>
<h2 id="2%E3%80%81probe">2&#x3001;Probe</h2>
<p><a href="https://man7.org/linux/man-pages/man1/perf-probe.1.html?ref=korantli.com.cn">perf-probe(1) &#x2014; Linux manual page</a></p>
<h3 id="2-1-%E4%BD%BF%E7%94%A8">2-1 &#x4F7F;&#x7528;</h3>
<p>&#x6BD4;&#x8F83;&#x5E38;&#x7528;&#x7684;&#x4E00;&#x4E2A;&#x529F;&#x80FD;&#x662F;&#x4F7F;&#x7528;probe&#x8FDB;&#x884C;&#x52A8;&#x6001;&#x63D2;&#x6869;&#x3002;&#x7531;&#x4E8E;&#x9759;&#x6001;&#x7684;tracepoint&#x5E76;&#x4E0D;&#x80FD;&#x5145;&#x5206;&#x6EE1;&#x8DB3;&#x5404;&#x79CD;&#x5404;&#x6837;&#x7684;&#x6027;&#x80FD;&#x95EE;&#x9898;&#xFF0C;&#x6240;&#x4EE5;&#x5185;&#x6838;&#x5F00;&#x53D1;&#x4E86;&#x4E00;&#x5957;&#x53EB;&#x505A;<code>probe</code>&#x7684;&#x52A8;&#x6001;&#x63D2;&#x6869;&#x5DE5;&#x5177;&#xFF0C;&#x8FD9;&#x4E2A;&#x4E5F;&#x88AB;&#x96C6;&#x5408;&#x5728;&#x4E86;perf&#x5DE5;&#x5177;&#x4E2D;&#x3002;</p>
<p>&#x57FA;&#x7840;&#x7684;&#x4F7F;&#x7528;&#x65B9;&#x6CD5;&#x5982;&#x4E0B;&#xFF0C;&#x5176;&#x4E2D;xxx&#x662F;&#x6211;&#x4EEC;&#x9700;&#x8981;&#x63D2;&#x6869;&#x7684;&#x51FD;&#x6570;&#x540D;&#x3002;</p>
<pre><code class="language-bash">perf probe -a xxx
</code></pre>
<p>&#x4F46;&#x662F;&#x8FD9;&#x91CC;&#x9700;&#x8981;&#x6CE8;&#x610F;&#x7684;&#x662F;&#xFF0C;probe&#x53EA;&#x80FD;&#x63D2;&#x6869;&#x975E;&#x5185;&#x8054;&#x7684;&#x51FD;&#x6570;&#xFF0C;&#x5982;&#x679C;&#x9047;&#x5230;&#x5185;&#x8054;&#x51FD;&#x6570;&#xFF0C;&#x53EF;&#x80FD;&#x5C31;&#x9700;&#x8981;&#x5C06;&#x51FD;&#x6570;&#x5F3A;&#x5236;&#x58F0;&#x660E;&#x4E3A;&#x975E;&#x5185;&#x8054;&#xFF0C;&#x5373;&#x589E;&#x52A0;<code>noinline</code>&#x6807;&#x7B7E;&#x3002;</p>
<p>&#x6B64;&#x5916;&#xFF0C;<code>perf probe</code>&#x8FD8;&#x652F;&#x6301;&#x5404;&#x79CD;&#x7279;&#x6B8A;&#x63D2;&#x6869;</p>
<pre><code class="language-bash">perf probe -a xxx:xx # &#x5728;xxx&#x51FD;&#x6570;&#x7684;xx&#x884C;&#x8FDB;&#x884C;&#x63D2;&#x6869;
perf probe -a xxx+xx # &#x5728;xxx&#x51FD;&#x6570;&#x7684;xxbit&#x504F;&#x79FB;&#x8FDB;&#x884C;&#x63D2;&#x6869;
perf probe -a xxx%retrun # &#x5728;xxx&#x51FD;&#x6570;&#x8FD4;&#x56DE;&#x5904;&#x8FDB;&#x884C;&#x63D2;&#x6869;
</code></pre>
<p>&#x8FD9;&#x91CC;&#x5176;&#x5B9E;&#x4E5F;&#x652F;&#x6301;&#x5728;&#x6307;&#x5B9A;&#x7684;&#x6E90;&#x7801;&#x6587;&#x4EF6;&#x4E2D;&#x8FDB;&#x884C;&#x63D2;&#x6869;&#xFF0C;&#x66F4;&#x8BE6;&#x7EC6;&#x7684;&#x4FE1;&#x606F;&#x53EF;&#x4EE5;&#x53C2;&#x8003;<code>perf probe --help</code>&#x4E2D;<code>PROBE SYNTAX</code>&#x5173;&#x952E;&#x5B57;</p>
<p>&#x6216;&#x8005;&#x53C2;&#x8003;<a href="https://man7.org/linux/man-pages/man1/perf-probe.1.html?ref=korantli.com.cn">perf-probe(1) &#x2014; Linux manual page</a></p>
<h3 id="2-2-%E5%8E%9F%E7%90%86">2-2 &#x539F;&#x7406;</h3>
<p>Perf probe&#x7684;&#x5E95;&#x5C42;&#x4F9D;&#x8D56;&#x662F;&#x5185;&#x6838;&#x7684;Kprobe&#x673A;&#x5236;&#xFF0C;kprobes &#x7684;&#x5B9E;&#x73B0;&#x539F;&#x7406;&#x57FA;&#x4E8E;&#x5185;&#x6838;&#x4E2D;&#x65AD;&#x548C;&#x5F02;&#x5E38;&#x5904;&#x7406;&#x673A;&#x5236;&#xFF0C;&#x901A;&#x8FC7;&#x5728;&#x6307;&#x5B9A;&#x5730;&#x5740;&#x5904;&#x63D2;&#x5165;&#x65AD;&#x70B9;&#x6307;&#x4EE4;&#xFF08;&#x4F8B;&#x5982; x86 &#x67B6;&#x6784;&#x4E0A;&#x7684; int3 &#x6307;&#x4EE4;&#xFF09;&#x6765;&#x89E6;&#x53D1;&#x4E2D;&#x65AD;&#xFF0C;&#x7136;&#x540E;&#x5728;&#x4E2D;&#x65AD;&#x5904;&#x7406;&#x7A0B;&#x5E8F;&#x4E2D;&#x6267;&#x884C;&#x7528;&#x6237;&#x6CE8;&#x518C;&#x7684;&#x63A2;&#x9488;&#x5904;&#x7406;&#x51FD;&#x6570;&#x3002;</p>
<p>perf&#x4E2D;probe&#x7684;&#x5B9E;&#x73B0;&#x539F;&#x7406;&#x6982;&#x8FF0;&#x5982;&#x4E0B;</p>
<ol>
<li>
<p>&#x89E3;&#x6790;&#x7528;&#x6237;&#x8F93;&#x5165;</p>
</li>
<li>
<p>&#x67E5;&#x627E;&#x5185;&#x6838;&#x7B26;&#x53F7;&#xFF1A;perf probe &#x4F7F;&#x7528;vmlinux&#x6765;&#x67E5;&#x627E;&#x6307;&#x5B9A;&#x51FD;&#x6570;&#x7684;&#x5185;&#x6838;&#x5730;&#x5740;&#x3002;&#x6B64;&#x5916;&#xFF0C;&#x5982;&#x679C;&#x7528;&#x6237;&#x6307;&#x5B9A;&#x4E86;&#x6E90;&#x4EE3;&#x7801;&#x884C;&#x53F7;&#xFF0C;perf probe &#x8FD8;&#x4F1A;&#x67E5;&#x627E;&#x8BE5;&#x884C;&#x53F7;&#x5BF9;&#x5E94;&#x7684;&#x5185;&#x6838;&#x5730;&#x5740;&#x3002;</p>
</li>
<li>
<p>&#x6CE8;&#x518C; perf_event&#xFF1A;perf probe &#x901A;&#x8FC7; perf_events &#x5B50;&#x7CFB;&#x7EDF;&#x5C06;&#x6307;&#x5B9A;&#x7684;&#x5185;&#x6838;&#x5730;&#x5740;&#x548C;&#x5173;&#x8054;&#x7684;&#x4E8B;&#x4EF6;&#x540D;&#x79F0;&#x6CE8;&#x518C;&#x5230;&#x5185;&#x6838;&#x4E2D;&#x3002;perf_events &#x5B50;&#x7CFB;&#x7EDF;&#x4F1A;&#x521B;&#x5EFA;&#x4E00;&#x4E2A;&#x65B0;&#x7684; perf_event&#xFF0C;&#x5176;&#x7C7B;&#x578B;&#x4E3A; PERF_TYPE_TRACEPOINT&#xFF0C;&#x5E76;&#x5C06;&#x5176;&#x4E0E; kprobes &#x6846;&#x67B6;&#x5173;&#x8054;&#x3002;</p>
</li>
<li>
<p>&#x63D2;&#x5165; kprobe&#xFF1A;</p>
<ol>
<li>
<p>perf_events &#x5B50;&#x7CFB;&#x7EDF;&#x8C03;&#x7528; kprobes API&#xFF08;&#x5982; register_kprobe() &#x6216; register_kretprobe()&#xFF09;&#x5728;&#x6307;&#x5B9A;&#x7684;&#x5185;&#x6838;&#x5730;&#x5740;&#x5904;&#x63D2;&#x5165;&#x4E00;&#x4E2A; kprobe &#x6216; kretprobe&#x3002;&#x8FD9;&#x4F1A;&#x5728;&#x76EE;&#x6807;&#x5730;&#x5740;&#x5904;&#x63D2;&#x5165;&#x4E00;&#x4E2A;&#x65AD;&#x70B9;&#x6307;&#x4EE4;&#xFF0C;&#x4EE5;&#x4FBF;&#x5728;&#x6267;&#x884C;&#x5230;&#x8BE5;&#x5730;&#x5740;&#x65F6;&#x89E6;&#x53D1;&#x4E2D;&#x65AD;&#x3002;</p>
<p>&#x4F8B;&#x5982;x86&#x4F1A;&#x5728;&#x6307;&#x5B9A;&#x5730;&#x5740;&#x63D2;&#x5165;&#x4E00;&#x4E2A;<code>0xcc</code>&#x7684;&#x64CD;&#x4F5C;&#x7801;&#xFF0C;&#x5904;&#x7406;&#x5668;&#x89E3;&#x6790;&#x540E;&#x901A;&#x8FC7;&#x4E2D;&#x65AD;&#x5411;&#x91CF;&#x8868;&#xFF0C;&#x5173;&#x8054;&#x4E3A;<code>int3</code>&#x6307;&#x4EE4;&#xFF0C;&#x5728;&#x8FD0;&#x884C;&#x540E;&#x4FBF;&#x4F1A;&#x89E6;&#x53D1;kprobe&#x4E8B;&#x4EF6;&#x3002;</p>
<pre><code class="language-c">#define BREAKPOINT_INSTRUCTION	0xcc

void arch_arm_kprobe(struct kprobe *p)
{
	text_poke(p-&gt;addr, ((unsigned char []){BREAKPOINT_INSTRUCTION}), 1);
}
</code></pre>
<p>arm64&#x4E2D;&#x5219;&#x662F;</p>
<pre><code class="language-c">#define BRK64_ESR_KPROBES	0x0004 -&gt; &#x4E2D;&#x65AD;&#x7C7B;&#x578B;&#x662F;kprobe
#define AARCH64_BREAK_MON	0xd4200000 -&gt; &#x8F6F;&#x4EF6;&#x65AD;&#x70B9;&#x89E6;&#x53D1;&#x4E2D;&#x65AD;

#define BRK64_OPCODE_KPROBES	(AARCH64_BREAK_MON | (BRK64_ESR_KPROBES &lt;&lt; 5))
</code></pre>
</li>
<li>
<p>&#x5728; kprobe &#x7684;&#x5904;&#x7406;&#x51FD;&#x6570;&#x4E2D;&#xFF0C;perf_events &#x5B50;&#x7CFB;&#x7EDF;&#x4F1A;&#x8C03;&#x7528; perf_tp_event() &#x51FD;&#x6570;&#xFF0C;&#x8BE5;&#x51FD;&#x6570;&#x8D1F;&#x8D23;&#x5C06; perf_event &#x4E0E; kprobe &#x5173;&#x8054;&#x3002;&#x8FD9;&#x610F;&#x5473;&#x7740;&#xFF0C;&#x5F53; kprobe &#x88AB;&#x89E6;&#x53D1;&#x65F6;&#xFF0C;perf_event &#x4F1A;&#x6536;&#x96C6;&#x548C;&#x8BB0;&#x5F55;&#x5185;&#x6838;&#x51FD;&#x6570;&#x7684;&#x6267;&#x884C;&#x4FE1;&#x606F;&#x3002;</p>
</li>
</ol>
</li>
<li>
<p>&#x6536;&#x96C6;&#x548C;&#x5206;&#x6790;&#x6570;&#x636E;&#xFF1A;&#x7528;&#x6237;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; perf record &#x548C; perf report &#x547D;&#x4EE4;&#x6765;&#x6536;&#x96C6;&#x548C;&#x5206;&#x6790;&#x5185;&#x6838;&#x51FD;&#x6570;&#x7684;&#x6267;&#x884C;&#x4FE1;&#x606F;&#x3002;&#x5728;&#x8FD9;&#x4E9B;&#x547D;&#x4EE4;&#x4E2D;&#xFF0C;perf &#x5DE5;&#x5177;&#x4F1A;&#x4F7F;&#x7528; perf_events &#x5B50;&#x7CFB;&#x7EDF;&#x6765;&#x8BA2;&#x9605;&#x548C;&#x8BFB;&#x53D6;&#x4E0E; kprobes &#x5173;&#x8054;&#x7684; perf_event &#x6570;&#x636E;&#x3002;</p>
</li>
</ol>
<h2 id="3%E3%80%81sched">3&#x3001;Sched</h2>
<p><a href="https://man7.org/linux/man-pages/man1/perf-sched.1.html?ref=korantli.com.cn">perf-sched(1)</a></p>
<h3 id="3-1-%E4%BD%BF%E7%94%A8">3-1 &#x4F7F;&#x7528;</h3>
<p>&#x6709;&#x65F6;&#x6211;&#x4EEC;&#x9700;&#x8981;&#x5206;&#x6790;&#x5185;&#x6838;&#x8C03;&#x5EA6;&#x4FE1;&#x606F;&#xFF0C;&#x53EF;&#x4EE5;&#x65B9;&#x4FBF;&#x7684;&#x65F6;&#x5019;<code>perf sched</code>&#x547D;&#x4EE4;&#x83B7;&#x53D6;&#x5185;&#x6838;&#x8C03;&#x5EA6;&#x4FE1;&#x606F;&#x3002;</p>
<p>&#x9996;&#x5148;&#x8BB0;&#x5F55;&#x8C03;&#x5EA6;&#x7C7B;&#x4FE1;&#x606F;&#x6570;&#x636E;</p>
<pre><code class="language-bash">perf sched record -- sleep 30
</code></pre>
<p>&#x7136;&#x540E;&#x4F7F;&#x7528;&#x5DE5;&#x5177;&#x89E3;&#x6790;&#x8C03;&#x5EA6;&#x65F6;&#x5EF6;&#x4FE1;&#x606F;</p>
<pre><code class="language-bash">perf sched latency -p
</code></pre>
<p>&#x8FD9;&#x6837;&#x4F60;&#x5C31;&#x4F1A;&#x83B7;&#x53D6;&#x5230;&#x4E00;&#x4E2A;&#x5982;&#x4E0B;&#x4E00;&#x4E2A;&#x8C03;&#x5EA6;&#x4FE1;&#x606F;&#x7684;&#x6C47;&#x603B;&#x53EF;&#x8BFB;&#x6587;&#x672C;</p>
<pre><code class="language-bash">  cpuPercentTest:21721  |   2996.171 ms |     1872 | avg:    0.017 ms | max:    1.586 ms | max at: 521094.021548 s
  cpuPercentTest:21727  |   2995.264 ms |     1857 | avg:    0.016 ms | max:    1.278 ms | max at: 521095.473709 s
  cpuPercentTest:21725  |   2998.391 ms |     1875 | avg:    0.016 ms | max:    0.895 ms | max at: 521090.525446 s
  cpuPercentTest:21723  |   2995.983 ms |     1860 | avg:    0.015 ms | max:    1.693 ms | max at: 521095.423880 s
	......
</code></pre>
<p>&#x6B64;&#x65F6;&#xFF0C;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;<code>perf script</code>&#x6765;&#x83B7;&#x53D6;&#x4E0A;&#x8FF0;&#x4FE1;&#x606F;&#x7684;&#x539F;&#x59CB;&#x6587;&#x672C;&#xFF0C;&#x901A;&#x8FC7;<code>max at: 521094.021548 s</code>&#x8FD9;&#x7C7B;&#x65F6;&#x95F4;&#x70B9;&#xFF0C;&#x6765;&#x68C0;&#x67E5;&#x5177;&#x4F53;&#x7684;&#x8C03;&#x5EA6;&#x4FE1;&#x606F;&#x3002;</p>
<p>&#x4F8B;&#x5982;&#x4E0A;&#x8FF0;&#x4E00;&#x6B21;&#x8C03;&#x5EA6;&#x7684;&#x5B9E;&#x9645;&#x60C5;&#x51B5;&#x5982;&#x4E0B;</p>
<pre><code class="language-bash">         swapper     0 [094] 521094.019960: sched:sched_migrate_task: comm=cpuPercentTest pid=21721 prio=120 orig_cpu=94 dest_cpu=72
  cpuPercentTest 21734 [024] 521094.019961: sched:sched_migrate_task: comm=cpuPercentTest pid=21729 prio=120 orig_cpu=24 dest_cpu=72
         swapper     0 [094] 521094.019962:       sched:sched_wakeup: comm=cpuPercentTest pid=21721 prio=120 target_cpu=072 # &#x5F00;&#x59CB;&#x5524;&#x9192;21721&#x8FDB;&#x7A0B;
  cpuPercentTest 21734 [024] 521094.019964:       sched:sched_wakeup: comm=cpuPercentTest pid=21729 prio=120 target_cpu=072
         swapper     0 [072] 521094.019966:       sched:sched_switch: prev_comm=swapper/72 prev_pid=0 prev_prio=120 prev_state=R ==&gt; next_comm=cpuPercentTest next_pid=21729 next_prio=120
  cpuPercentTest 21729 [072] 521094.020129: sched:sched_stat_runtime: comm=cpuPercentTest pid=21729 runtime=164651 [ns] vruntime=734902380619 [ns]
   ......
  cpuPercentTest 21733 [046] 521094.021546: sched:sched_migrate_task: comm=cpuPercentTest pid=21721 prio=120 orig_cpu=72 dest_cpu=46 # &#x7CFB;&#x7EDF;&#x518D;&#x6B21;&#x8FC1;&#x79FB;&#x4EFB;&#x52A1;&#x5230;46&#x6838;&#x6267;&#x884C;
  cpuPercentTest 21733 [046] 521094.021547: sched:sched_stat_runtime: comm=cpuPercentTest pid=21733 runtime=6907 [ns] vruntime=3761424387 [ns]
  cpuPercentTest 21733 [046] 521094.021548:       sched:sched_switch: prev_comm=cpuPercentTest prev_pid=21733 prev_prio=120 prev_state=S ==&gt; next_comm=cpuPercentTest next_pid=21721 next_prio=120 # &#x5B8C;&#x6210;&#x8FDB;&#x7A0B;&#x8C03;&#x5EA6;&#x5207;&#x6362;
</code></pre>
<p>&#x8FD9;&#x6B21;&#x7684;&#x8C03;&#x5EA6;&#x60C5;&#x51B5;&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;&#x5176;&#x5B9E;&#x662F;&#x5728;&#x539F;&#x6765;&#x7684;<code>72</code>&#x6838;&#x4E0A;&#x6709;&#x4E24;&#x4E2A;&#x8FDB;&#x7A0B;<code>21721</code>&#x4E0E;<code>21733</code>&#x540C;&#x65F6;&#x88AB;&#x5524;&#x9192;&#xFF0C;&#x800C;<code>21733</code>&#x5148;&#x88AB;&#x6267;&#x884C;&#xFF0C;&#x6240;&#x4EE5;&#x5BFC;&#x81F4;<code>21721</code>&#x4E00;&#x76F4;&#x672A;&#x88AB;&#x8C03;&#x5EA6;&#xFF0C;&#x6700;&#x7EC8;&#x5BFC;&#x81F4;&#x8FD9;&#x4E00;&#x6B21;sched&#x957F;&#x3002;</p>
<h3 id="3-2-%E5%8E%9F%E7%90%86">3-2 &#x539F;&#x7406;</h3>
<p><a href="https://www.brendangregg.com/blog/2017-03-16/perf-sched.html?ref=korantli.com.cn">perf sched for Linux CPU scheduler analysis</a></p>
<p>&#x5176;&#x5B9E;&#x901A;&#x8FC7;&#x4E0A;&#x8FB9;&#x7684;&#x4F8B;&#x5B50;&#x4E0D;&#x96BE;&#x770B;&#x51FA;<code>perf sched latency</code>&#x6240;&#x89E3;&#x6790;&#x7684;&#x4FE1;&#x606F;&#x662F;<code>sched:sched_switch</code>-<code>sched:sched_migrate_task</code>&#x7684;&#x503C;</p>
<pre><code class="language-bash">521094.021548s - 521094.019962s = 0.001586s = 1.586 ms
</code></pre>
<p>&#x6B64;&#x5916;&#xFF0C;<code>perf sched record</code>&#x5176;&#x5B9E;&#x5C31;&#x662F;&#x6574;&#x5408;&#x4E86;&#x51E0;&#x4E2A;&#x7279;&#x5B9A;&#x7684;&#x8C03;&#x5EA6;&#x76F8;&#x5173;<code>tracepoints</code>&#xFF08;&#x53EF;&#x80FD;&#x6CA1;&#x6709;&#x5217;&#x4E3E;&#x5168;&#xFF0C;&#x53EA;&#x5199;&#x4E86;&#x901A;&#x5E38;&#x80FD;&#x89C2;&#x5BDF;&#x5230;&#x7684;&#x51E0;&#x79CD;&#xFF09;</p>
<pre><code class="language-bash">sched:sched_switch # &#x4EFB;&#x52A1;&#x5207;&#x6362;
sched:sched_wakeup # &#x4EFB;&#x52A1;&#x5524;&#x9192;
sched:sched_migrate_task # &#x4EFB;&#x52A1;&#x8FC1;&#x79FB;
sched:sched_process_exec # &#x8FDB;&#x7A0B;&#x6267;&#x884C;&#x4E8B;&#x4EF6;
sched:sched_process_fork # &#x8FDB;&#x7A0B;&#x521B;&#x5EFA;&#xFF08;fork&#xFF09;&#x4E8B;&#x4EF6;
</code></pre>
<p>&#x8BE5;&#x529F;&#x80FD;&#x5176;&#x5B9E;&#x4E0E;&#x5982;&#x4E0B;&#x547D;&#x4EE4;&#x662F;&#x76F8;&#x540C;&#x7684;</p>
<pre><code class="language-bash">perf record -a -e &apos;sched:sched_switch,sched:sched_wakeup,sched:sched_migrate_task,sched:sched_process_exec,sched:sched_process_fork&apos; -- sleep 30
</code></pre>
<h2 id="4%E3%80%81%E7%81%AB%E7%84%B0%E5%9B%BE">4&#x3001;&#x706B;&#x7130;&#x56FE;</h2>
<p>&#x9996;&#x5148;&#x9700;&#x8981;&#x83B7;&#x53D6;perf&#x7684;&#x539F;&#x59CB;&#x6570;&#x636E;&#xFF0C;&#x5373;&#x6267;&#x884C;</p>
<pre><code class="language-bash">perf record -a -p xxx -- sleep 60
</code></pre>
<p>&#x7136;&#x540E;&#x8981;&#x5BF9;<code>perf.data</code>&#x8FDB;&#x884C;&#x89E3;&#x6790;</p>
<pre><code class="language-bash">perf script -i perf.data &amp;&gt; perf.unfold
</code></pre>
<p>&#x4E4B;&#x540E;&#x5C31;&#x8981;&#x7528;&#x5230;<code>flamegraph</code>&#x5DE5;&#x5177;</p>
<pre><code class="language-bash">git clone https://github.com/brendangregg/FlameGraph.git
</code></pre>
<p>&#x4E4B;&#x540E;&#x9700;&#x8981;&#x8C03;&#x7528;flame&#x9879;&#x76EE;&#x91CC;&#x7684;&#x811A;&#x672C;(&#x6CE8;&#x610F;&#x76F8;&#x5BF9;&#x8DEF;&#x5F84;)</p>
<pre><code class="language-bash">./../FlameGraph/stackcollapse-perf.pl perf.unfold &amp;&gt; perf.folded
</code></pre>
<p>&#x6700;&#x540E;&#x751F;&#x6210;svg&#x56FE;</p>
<pre><code class="language-bash">./../FlameGraph/flamegraph.pl perf.folded &gt; perf.svg
</code></pre>
]]></content:encoded></item><item><title><![CDATA[virto虚拟化]]></title><description><![CDATA[<h2 id="1-%E8%83%8C%E6%99%AF">1-&#x80CC;&#x666F;</h2>
<p>&#x5728;&#x5B8C;&#x5168;&#x865A;&#x62DF;&#x5316;&#x4E2D;&#xFF0C;CPU&#x4F1A;&#x53D1;&#x751F;<code>VM entry</code>&#x548C;<code>VM exit</code>&#x4E8B;&#x4EF6;&#xFF0C;&#x4ECE;&#x800C;&#x6EE1;&#x8DB3;&#x4E0D;&#x540C;&#x6743;&#x9650;&#x7EA7;&#x522B;&#x7684;&#x4E8B;&#x4EF6;&#x3002;&#x5728;&#x865A;&#x62DF;&#x673A;&#x6267;&#x884C;IO&#x4E8B;&#x4EF6;&#x65F6;&#xFF0C;&#x4F1A;&#x9891;</p>]]></description><link>http://www.korantli.com.cn/virtoxu-ni-hua/</link><guid isPermaLink="false">6690d7cf2bc2afda5bd2ed1b</guid><category><![CDATA[linux虚拟化]]></category><dc:creator><![CDATA[李星辉]]></dc:creator><pubDate>Fri, 12 Jul 2024 07:17:18 GMT</pubDate><content:encoded><![CDATA[<h2 id="1-%E8%83%8C%E6%99%AF">1-&#x80CC;&#x666F;</h2>
<p>&#x5728;&#x5B8C;&#x5168;&#x865A;&#x62DF;&#x5316;&#x4E2D;&#xFF0C;CPU&#x4F1A;&#x53D1;&#x751F;<code>VM entry</code>&#x548C;<code>VM exit</code>&#x4E8B;&#x4EF6;&#xFF0C;&#x4ECE;&#x800C;&#x6EE1;&#x8DB3;&#x4E0D;&#x540C;&#x6743;&#x9650;&#x7EA7;&#x522B;&#x7684;&#x4E8B;&#x4EF6;&#x3002;&#x5728;&#x865A;&#x62DF;&#x673A;&#x6267;&#x884C;IO&#x4E8B;&#x4EF6;&#x65F6;&#xFF0C;&#x4F1A;&#x9891;&#x7E41;&#x53D1;&#x751F;<code>entry</code>&#x548C;<code>exit</code>&#x4E8B;&#x4EF6;&#x800C;&#x5F71;&#x54CD;&#x865A;&#x62DF;&#x673A;&#x6027;&#x80FD;&#x3002;</p>
<p>virtio&#x8FD9;&#x79CD;&#x8F6F;&#x4EF6;&#x6A21;&#x62DF;&#x7684;&#x534A;&#x865A;&#x62DF;&#x5316;&#x6280;&#x672F;&#xFF0C;&#x5C31;&#x53EF;&#x4EE5;&#x907F;&#x514D;&#x4E0A;&#x8FF0;&#x8FD9;&#x79CD;&#x95EE;&#x9898;&#x3002;virtio&#x7684;&#x6838;&#x5FC3;&#x662F;&#x5229;&#x7528;<code>virtqueue</code>&#x7684;&#x65B9;&#x5F0F;&#x4F20;&#x8F93;&#x6570;&#x636E;&#xFF0C;&#x800C;&#x4E0D;&#x662F;&#x6807;&#x51C6;io&#x4E2D;&#x64CD;&#x4F5C;&#x7279;&#x5B9A;&#x5BC4;&#x5B58;&#x5668;&#x7684;&#x65B9;&#x5F0F;&#x3002;</p>
<h2 id="2-virtio%E5%8D%8F%E8%AE%AE">2-virtio&#x534F;&#x8BAE;</h2>
<p>virtio&#x7684;&#x672C;&#x8D28;&#x662F;&#x4E00;&#x4E2A;&#x524D;&#x540E;&#x7AEF;&#x7ED3;&#x6784;&#xFF0C;&#x5176;&#x63D0;&#x4F9B;&#x4E00;&#x79CD;&#x865A;&#x62DF;&#x5316;&#x573A;&#x666F;&#x7684;&#x5B50;&#x673A;(guest)&#x4E0E;&#x6BCD;&#x673A;(host)&#x4E4B;&#x95F4;&#x7684;&#x901A;&#x8BAF;&#x63A5;&#x53E3;&#x3002;&#x5728;&#x5B50;&#x673A;&#x5185;&#x662F;&#x4F5C;&#x4E3A;&#x524D;&#x7AEF;&#x9A71;&#x52A8;&#x5B58;&#x5728;&#xFF0C;&#x5728;&#x6BCD;&#x673A;&#x5185;&#x5219;&#x662F;&#x4F5C;&#x4E3A;&#x540E;&#x7AEF;&#x8BBE;&#x5907;&#x3002;&#x5E76;&#x4E14;&#x5176;&#x53EF;&#x4EE5;&#x5E94;&#x7528;&#x5728;&#x5404;&#x79CD;&#x865A;&#x62DF;&#x5316;&#x6280;&#x672F;&#x4E2D;&#xFF0C;&#x6211;&#x4EEC;&#x4E3B;&#x8981;&#x5173;&#x6CE8;&#x7684;&#x662F;KVM&#x4E2D;&#x7684;&#x5E94;&#x7528;&#x3002;</p>
<p><img src="http://www.korantli.com.cn/content/images/2024/07/a88866825457436ea45bb38f5c731a26-2.png" alt="a88866825457436ea45bb38f5c731a26.png" loading="lazy"></p>
<h3 id="21-%E5%89%8D%E7%AB%AF%E9%A9%B1%E5%8A%A8">2.1-&#x524D;&#x7AEF;&#x9A71;&#x52A8;</h3>
<p>&#x524D;&#x7AEF;&#x9A71;&#x52A8;&#x662F;&#x5B50;&#x673A;&#x4E2D;virt&#x7528;&#x6765;&#x6A21;&#x62DF;&#x8BBE;&#x5907;&#x5BF9;&#x5E94;&#x7684;&#x9A71;&#x52A8;&#xFF0C;&#x4E0D;&#x540C;&#x7684;&#x8BBE;&#x5907;&#x8981;&#x5BF9;&#x5E94;&#x4E0D;&#x540C;&#x7684;virtio&#x9A71;&#x52A8;&#xFF0C;&#x4F8B;&#x5982;&#x4E0A;&#x56FE;&#x4E2D;&#x5757;&#x8BBE;&#x5907;&#x3001;&#x7F51;&#x7EDC;&#x8BBE;&#x5907;&#x3001;scsi&#x8BBE;&#x5907;&#x90FD;&#x6709;&#x7279;&#x6B8A;&#x7684;&#x9A71;&#x52A8;&#x6A21;&#x5757;&#x3002;&#x8FD9;&#x4E9B;&#x9A71;&#x52A8;&#x5DF2;&#x7ECF;&#x88AB;&#x7EE7;&#x627F;&#x5728;&#x5185;&#x6838;&#x4EE3;&#x7801;&#x4E2D;&#xFF0C;&#x4F8B;&#x5982;<code>drivers\block\virtio_blk.c</code>&#x3002;</p>
<p>&#x524D;&#x7AEF;&#x8BBE;&#x5907;&#x7684;&#x4E3B;&#x8981;&#x4F5C;&#x7528;&#x662F;&#xFF1A;</p>
<ul>
<li>&#x63A5;&#x53D7;&#x5B50;&#x673A;&#x5185;&#x7684;&#x7528;&#x6237;&#x6001;&#x8BF7;&#x6C42;</li>
<li>&#x6309;&#x7167;virtio&#x534F;&#x8BAE;&#x5C01;&#x88C5;&#x8BF7;&#x6C42;</li>
<li>&#x5199;virtio&#x5B50;&#x673A;&#x7AEF;&#x53E3;&#xFF0C;&#x5E76;&#x53D1;&#x9001;&#x7ED9;&#x540E;&#x7AEF;&#x6BCD;&#x673A;&#x4E2D;&#x7684;&#x8BBE;&#x5907;</li>
</ul>
<h3 id="22-%E5%90%8E%E7%AB%AF%E8%AE%BE%E5%A4%87">2.2-&#x540E;&#x7AEF;&#x8BBE;&#x5907;</h3>
<p>&#x540E;&#x7AEF;&#x8BBE;&#x5907;&#x4E3B;&#x8981;&#x662F;&#x7528;&#x6765;&#x63A5;&#x53D7;&#x524D;&#x7AEF;&#x8BBE;&#x5907;&#x53D1;&#x9001;&#x8FC7;&#x6765;&#x7684;&#x8BF7;&#x6C42;&#x5E76;&#x6309;&#x7167;&#x89C4;&#x683C;&#x5F0F;&#x89E3;&#x6790;&#x8BF7;&#x6C42;&#x3002;&#x540E;&#x7AEF;&#x8BBE;&#x5907;&#x662F;&#x5728;&#x865A;&#x62DF;&#x5316;&#x5C42;&#x7684;&#xFF0C;&#x5728;qemu&#x4E2D;&#x5219;&#x662F;&#x6A21;&#x62DF;&#x7684;pci&#x8BBE;&#x5907;&#x3002;&#x6B64;&#x5916;&#xFF0C;&#x9664;&#x4E86;qemu&#x4E2D;&#x6A21;&#x62DF;&#x7684;pci&#x8BBE;&#x5907;&#xFF0C;&#x8FD8;&#x6709;&#x7ED9;dpdk&#x4F7F;&#x7528;&#x7684;vhost&#x8BBE;&#x5907;&#x3002;</p>
<h3 id="23-%E4%BC%A0%E8%BE%93%E5%B1%82-split-virtqueue">2.3-&#x4F20;&#x8F93;&#x5C42; split virtqueue</h3>
<p>&#x524D;&#x540E;&#x7AEF;&#x7684;&#x6570;&#x636E;&#x662F;&#x901A;&#x8FC7;<code>virtqueue</code>&#x6765;&#x4F20;&#x8F93;&#x7684;&#xFF0C;&#x4E00;&#x4E2A;&#x540E;&#x7AEF;&#x8BBE;&#x5907;&#x53EF;&#x4EE5;&#x6709;&#x591A;&#x4E2A;queue&#x7EC4;&#x6210;&#x3002;virtqueue&#x662F;&#x901A;&#x8FC7;vring&#x6765;&#x5B9E;&#x73B0;&#x529F;&#x80FD;&#xFF0C;vring&#x662F;&#x5B50;&#x673A;&#x548C;vmm&#xFF08;qemu/kvm&#xFF09;&#x7684;&#x4E2D;&#x5171;&#x4EAB;&#x4E00;&#x6BB5;&#x73AF;&#x5F62;&#x7F13;&#x51B2;&#x533A;&#x3002;</p>
<p><img src="http://www.korantli.com.cn/content/images/2024/07/32f26e4669d34a48b21b96049c70b7ab-1.png" alt="32f26e4669d34a48b21b96049c70b7ab.png" loading="lazy"></p>
<p>virtqueue&#x4E3B;&#x8981;&#x6709;&#x4E09;&#x90E8;&#x5206;&#x7EC4;&#x6210;</p>
<ul>
<li>&#x63CF;&#x8FF0;&#x7B26;&#x8868;&#xFF08;Descriptor Table&#xFF09;</li>
<li>&#x53EF;&#x7528;&#x63CF;&#x8FF0;&#x7B26;&#x533A;&#xFF08;Available Ring&#xFF09;</li>
<li>&#x5DF2;&#x7528;&#x63CF;&#x8FF0;&#x7B26;&#x533A;&#xFF08;Used Ring&#xFF09;</li>
</ul>
<p>&#x524D;&#x7AEF;&#x9A71;&#x52A8;&#x4ECE;&#x5B50;&#x673A;&#x4E2D;&#x83B7;&#x53D6;&#x6570;&#x636E;&#x5E76;&#x51C6;&#x5907;&#x597D;&#xFF0C;&#x5C06;&#x5176;&#x653E;&#x7F6E;&#x5728;&#x53EF;&#x7528;&#x63CF;&#x8FF0;&#x7B26;&#x533A;&#x7684;vring&#x4E2D;&#xFF0C;&#x5199;&#x4E00;&#x4E2A;io&#x7AEF;&#x53E3;&#x3002;</p>
<p>QEMU&#x4ECE;vring&#x4E2D;&#x83B7;&#x53D6;&#x6570;&#x636E;&#xFF0C;&#x5B8C;&#x6210;&#x8BF7;&#x6C42;&#x540E;&#xFF0C;&#x5C06;&#x5177;&#x4F53;&#x6570;&#x636E;&#x653E;&#x7F6E;&#x5728;&#x5DF2;&#x7528;&#x63CF;&#x8FF0;&#x7B26;&#x533A;&#x7684;vring&#x4E2D;&#xFF0C;&#x5B50;&#x673A;&#x5185;&#x7684;&#x524D;&#x7AEF;&#x9A71;&#x52A8;&#x5219;&#x4ECE;&#x5176;&#x83B7;&#x53D6;&#x6570;&#x636E;&#x3002;</p>
<h4 id="231-%E6%8F%8F%E8%BF%B0%E7%AC%A6">2.3.1-&#x63CF;&#x8FF0;&#x7B26;</h4>
<p>&#x63CF;&#x8FF0;&#x7B26;&#x8868;&#x7531;&#x63CF;&#x8FF0;&#x7B26;&#x7EC4;&#x6210;&#xFF0C;&#x5176;&#x53C8;&#x5206;&#x4E3A;<code>in</code>&#x548C;<code>out</code>&#x4E24;&#x79CD;&#xFF0C;<code>in</code>&#x8868;&#x793A;&#x8BFB;&#x6570;&#x636E;&#xFF0C;<code>out</code>&#x8868;&#x793A;&#x5199;&#x6570;&#x636E;&#x3002;</p>
<pre><code class="language-cpp">/**
 * struct vring_desc - Virtio ring descriptors,
 * 16 bytes long. These can chain together via @next.
 *
 * @addr: buffer address (guest-physical)
 * @len: buffer length
 * @flags: descriptor flags
 * @next: index of the next descriptor in the chain,
 *        if the VRING_DESC_F_NEXT flag is set. We chain unused
 *        descriptors via this, too.
 */
struct vring_desc {
	__virtio64 addr;
	__virtio32 len;
	__virtio16 flags;
	__virtio16 next;
};
</code></pre>
<p>&#x63CF;&#x8FF0;&#x7B26;&#x662F;&#x7531;&#x5982;&#x4E0B;&#x5B57;&#x6BB5;&#x7EC4;&#x6210;</p>
<ul>
<li>add&#xFF1A;&#x5B58;&#x50A8;&#x6570;&#x636E;&#x7684;&#x5185;&#x5B58;&#x5757;&#x7684;&#x8D77;&#x59CB;&#x5730;&#x5740;</li>
<li>len&#xFF1A;<code>out</code>&#x63CF;&#x8FF0;&#x7B26;&#x4E2D;&#x8868;&#x793A;&#x8BFB;&#x53D6;&#x6570;&#x636E;&#x91CF;&#xFF1B;<code>in</code>&#x63CF;&#x8FF0;&#x7B26;&#x4E2D;&#x8868;&#x793A;&#x53EF;&#x4EE5;&#x5199;&#x7684;&#x6700;&#x5927;&#x6570;&#x636E;&#x91CF;&#x3002;</li>
<li>flag&#xFF1A;&#x8868;&#x793A;&#x63CF;&#x8FF0;&#x7B26;&#x7684;&#x5C5E;&#x6027;&#x3002;</li>
<li>next&#xFF1A;&#x672C;&#x6B21;io&#x64CD;&#x4F5C;&#x7684;&#x63CF;&#x8FF0;&#x7B26;&#x662F;&#x5426;&#x8FD8;&#x6709;&#x4E0B;&#x4E00;&#x4E2A;&#x8FDE;&#x7EED;&#x7684;&#x63CF;&#x8FF0;&#x7B26;&#x3002;</li>
</ul>
<p>&#x4E00;&#x6B21;IO&#x64CD;&#x4F5C;&#x4F1A;&#x7531;&#x591A;&#x4E2A;&#x63CF;&#x8FF0;&#x7B26;&#x7EC4;&#x6210;&#xFF0C;&#x4ED6;&#x4EEC;&#x6574;&#x4F53;&#x88AB;&#x53EB;&#x505A;<code>&#x63CF;&#x8FF0;&#x7B26;&#x94FE;</code>&#xFF0C;&#x63CF;&#x8FF0;&#x7B26;&#x94FE;&#x4F1A;&#x5305;&#x542B;&#x4E00;&#x4E2A;header&#xFF0C;header&#x63CF;&#x8FF0;&#x7B26;&#x4F1A;&#x8BB0;&#x5F55;&#xFF1A;</p>
<ul>
<li>&#x547D;&#x4EE4;&#x7C7B;&#x578B;&#x2014;&#x2014;&#x8BFB;/&#x5199;</li>
<li>&#x64CD;&#x4F5C;&#x7684;&#x8D77;&#x59CB;&#x6247;&#x533A;</li>
</ul>
<p>header&#x540E;&#x7684;&#x662F;&#x6570;&#x636E;&#x63CF;&#x8FF0;&#x7B26;&#xFF0C;&#x6BCF;&#x4E00;&#x4E2A;&#x63CF;&#x8FF0;&#x7B26;&#x90FD;&#x4EE3;&#x8868;&#x7740;&#x4E00;&#x4E2A;&#x8FDE;&#x7EED;&#x5185;&#x5B58;&#x533A;&#x57DF;&#x7684;&#x8BFB;&#x5199;&#x3002;</p>
<p>&#x6700;&#x540E;&#x7684;&#x72B6;&#x6001;&#x63CF;&#x8FF0;&#x7B26;&#xFF0C;&#x5176;&#x8BB0;&#x5F55;&#x4E86;&#x8BBE;&#x5907;&#x7684;IO&#x6267;&#x884C;&#x72B6;&#x6001;&#x3002;</p>
<p><img src="http://www.korantli.com.cn/content/images/2024/07/image-20240622135048082-1.png" alt="image-20240622135048082.png" loading="lazy"></p>
<h4 id="232-%E5%8F%AF%E7%94%A8%E6%8F%8F%E8%BF%B0%E7%AC%A6%E5%8C%BA%E5%9F%9F">2.3.2-&#x53EF;&#x7528;&#x63CF;&#x8FF0;&#x7B26;&#x533A;&#x57DF;</h4>
<pre><code class="language-cpp">struct vring_avail {
	__virtio16 flags;
	__virtio16 idx;
	__virtio16 ring[];
};
</code></pre>
<ul>
<li>flags&#xFF1A;&#x8FD9;&#x4E2A;&#x6210;&#x5458;&#x53D8;&#x91CF;&#x8868;&#x793A;&#x53EF;&#x7528;&#x73AF;&#x7684;&#x6807;&#x5FD7;&#x3002;&#x5B83;&#x7528;&#x4E8E;&#x6307;&#x793A;&#x53EF;&#x7528;&#x73AF;&#x7684;&#x72B6;&#x6001;&#xFF0C;&#x4F8B;&#x5982;&#x662F;&#x5426;&#x9700;&#x8981;&#x901A;&#x77E5;&#x8BBE;&#x5907;&#x3002;</li>
<li>idx&#xFF1A;&#x5B83;&#x662F;&#x4E00;&#x4E2A;&#x9012;&#x589E;&#x7684;&#x8BA1;&#x6570;&#x5668;&#xFF0C;&#x7528;&#x4E8E;&#x8868;&#x793A;&#x4E0B;&#x4E00;&#x4E2A;&#x53EF;&#x7528;&#x7684;&#x7F13;&#x51B2;&#x533A;&#x63CF;&#x8FF0;&#x7B26;&#x5728; ring &#x6570;&#x7EC4;&#x4E2D;&#x7684;&#x4F4D;&#x7F6E;&#x3002;</li>
<li>ring&#xFF1A;&#x8FD9;&#x4E2A;&#x6210;&#x5458;&#x53D8;&#x91CF;&#x8868;&#x793A;&#x53EF;&#x7528;&#x73AF;&#x7684;&#x6570;&#x7EC4;&#x3002;&#x5B83;&#x662F;&#x4E00;&#x4E2A;&#x52A8;&#x6001;&#x6570;&#x7EC4;&#xFF0C;&#x7528;&#x4E8E;&#x5B58;&#x50A8;&#x53EF;&#x7528;&#x7684;&#x7F13;&#x51B2;&#x533A;&#x63CF;&#x8FF0;&#x7B26;&#x7684;&#x7D22;&#x5F15;&#x3002;</li>
</ul>
<p>&#x524D;&#x7AEF;&#x9A71;&#x52A8;&#x4F5C;&#x4E3A;&#x751F;&#x4EA7;&#x8005;&#xFF0C;&#x4F1A;&#x5C06;&#x51C6;&#x5907;&#x597D;I/O request&#x8F6C;&#x6362;&#x6210;&#x63CF;&#x8FF0;&#x7B26;&#x94FE;&#xFF0C;&#x5E76;&#x5C06;&#x4ED6;&#x4EEC;&#x63CF;&#x8FF0;&#x7B26;&#x94FE;&#x4E2D;&#x7684;<code>&#x9996;&#x63CF;&#x8FF0;&#x7B26;id</code>&#x653E;&#x7F6E;&#x5728;&#x53EF;&#x7528;&#x63CF;&#x8FF0;&#x533A;&#x91CC;&#x7684;ring&#x6570;&#x7EC4;&#x4E2D;&#x3002;</p>
<p>&#x6BCF;&#x6B21;cpu&#x4ECE;guest&#x5207;&#x6362;&#x81F3;host&#x4E2D;&#x65F6;&#xFF0C;&#x540E;&#x7AEF;&#x8BBE;&#x5907;&#x6D88;&#x8D39;&#x8005;&#x5C31;&#x4F1A;&#x5F00;&#x59CB;&#x6D88;&#x8D39;ring&#x4E2D;&#x7684;&#x5143;&#x7D20;&#xFF0C;&#x5E76;&#x901A;&#x8FC7;<code>last_avail_idx</code>&#x7D22;&#x5F15;&#x4E0A;&#x6B21;&#x6D88;&#x8D39;&#x7684;&#x4F4D;&#x7F6E;&#x3002;</p>
<p><img src="http://www.korantli.com.cn/content/images/2024/07/image-20240622142004374-1.png" alt="image-20240622142004374.png" loading="lazy"></p>
<h4 id="233-%E5%B7%B2%E7%94%A8%E6%8F%8F%E8%BF%B0%E7%AC%A6%E5%8C%BA%E5%9F%9F">2.3.3-&#x5DF2;&#x7528;&#x63CF;&#x8FF0;&#x7B26;&#x533A;&#x57DF;</h4>
<pre><code class="language-cpp">struct vring_used {
	__virtio16 flags;
	__virtio16 idx;
	vring_used_elem_t ring[];
};

/* u32 is used here for ids for padding reasons. */
struct vring_used_elem {
	/* Index of start of used descriptor chain. */
	__virtio32 id;
	/* Total length of the descriptor chain which was used (written to) */
	__virtio32 len;
};
</code></pre>
<ul>
<li>id&#xFF1A;&#x8868;&#x793A;&#x5DF2;&#x4F7F;&#x7528;&#x7684;&#x7F13;&#x51B2;&#x533A;&#x63CF;&#x8FF0;&#x7B26;&#x7684;&#x7D22;&#x5F15;&#x3002;&#x5B83;&#x662F;&#x8BE5;&#x7F13;&#x51B2;&#x533A;&#x63CF;&#x8FF0;&#x7B26;&#x5728;&#x63CF;&#x8FF0;&#x7B26;&#x8868;&#x4E2D;&#x7684;&#x4F4D;&#x7F6E;&#x3002;</li>
<li>len&#xFF1A;&#x8868;&#x793A;&#x5DF2;&#x4F7F;&#x7528;&#x7684;&#x7F13;&#x51B2;&#x533A;&#x63CF;&#x8FF0;&#x7B26;&#x94FE;&#x7684;&#x603B;&#x957F;&#x5EA6;&#x3002;&#x5B83;&#x8868;&#x793A;&#x8BBE;&#x5907;&#x5728;&#x8BE5;&#x63CF;&#x8FF0;&#x7B26;&#x94FE;&#x4E2D;&#x5199;&#x5165;&#x7684;&#x6570;&#x636E;&#x7684;&#x603B;&#x957F;&#x5EA6;&#x3002;</li>
</ul>
<p>&#x7C7B;&#x4F3C;&#x4E8E;&#x53EF;&#x7528;&#x63CF;&#x8FF0;&#x7B26;&#xFF0C;&#x5DF2;&#x7528;&#x63CF;&#x8FF0;&#x7B26;&#x662F;&#x7528;&#x6765;&#x7ED9;&#x524D;&#x7AEF;&#x9A71;&#x52A8;&#x8FD4;&#x56DE;&#x6570;&#x636E;&#x7684;&#x533A;&#x57DF;&#xFF0C;&#x540E;&#x7AEF;&#x8BBE;&#x5907;&#x5B8C;&#x6210;IO&#x8BF7;&#x6C42;&#x540E;&#xFF0C;&#x5219;&#x5C06;&#x63CF;&#x8FF0;&#x7B26;&#x6DFB;&#x52A0;&#x5230;vring_used&#x7684;ring&#x6570;&#x7EC4;&#x91CC;&#xFF0C;&#x5E76;&#x4E14;&#x8FD8;&#x4F1A;&#x8BB0;&#x5F55;&#x8FD4;&#x56DE;&#x6570;&#x636E;&#x7684;&#x957F;&#x5EA6;&#x3002;</p>
<p><img src="http://www.korantli.com.cn/content/images/2024/07/image-20240622143457435-1.png" alt="image-20240622143457435.png" loading="lazy"></p>
<h3 id="24-packed-queue">2.4-packed queue</h3>
<h4 id="241-packed-queue%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84">2.4.1-packed queue&#x6570;&#x636E;&#x7ED3;&#x6784;</h4>
<p>&#x5728;split queue&#x4E2D;&#x65F6;&#x5C06;availd&#x3001;free&#x3001;used&#x4E09;&#x79CD;uring&#xFF08;&#x73AF;&#xFF09;&#x533A;&#x5206;&#x5F00;&#x7684;&#xFF0C;&#x800C;packed queue&#x4E2D;&#x5219;&#x662F;&#x96C6;&#x5408;&#x5728;&#x4E00;&#x8D77;&#xFF0C;&#x5176;&#x63CF;&#x8FF0;&#x7B26;&#x7684;&#x6570;&#x636E;&#x7ED3;&#x6784;&#x5982;&#x4E0B;&#x6240;&#x793A;</p>
<pre><code class="language-cpp">struct vring_packed_desc {
	/* Buffer Address. */
	__le64 addr;
	/* Buffer Length. */
	__le32 len;
	/* Buffer ID. */
	__le16 id;
	/* The flags depending on descriptor type. */
	__le16 flags;
};
</code></pre>
<ol>
<li>
<p><code>addr</code>&#xFF1A;&#x8FD9;&#x662F;&#x4E00;&#x4E2A; 64 &#x4F4D;&#x5B57;&#x6BB5;&#xFF0C;&#x8868;&#x793A;&#x7F13;&#x51B2;&#x533A;&#x7684;&#x7269;&#x7406;&#x5730;&#x5740;&#x3002;&#x8BBE;&#x5907;&#xFF08;&#x5982; virtio-blk &#x6216; virtio-net&#xFF09;&#x5C06;&#x4F7F;&#x7528;&#x8FD9;&#x4E2A;&#x5730;&#x5740;&#x76F4;&#x63A5;&#x8BBF;&#x95EE;&#x5185;&#x5B58;&#x4E2D;&#x7684;&#x6570;&#x636E;&#xFF0C;&#x4EE5;&#x6267;&#x884C; I/O &#x64CD;&#x4F5C;&#x3002;</p>
</li>
<li>
<p><code>len</code>&#xFF1A;&#x8FD9;&#x662F;&#x4E00;&#x4E2A; 32 &#x4F4D;&#x5B57;&#x6BB5;&#xFF0C;&#x8868;&#x793A;&#x7F13;&#x51B2;&#x533A;&#x7684;&#x957F;&#x5EA6;&#xFF08;&#x4EE5;&#x5B57;&#x8282;&#x4E3A;&#x5355;&#x4F4D;&#xFF09;&#x3002;&#x8FD9;&#x4E2A;&#x5B57;&#x6BB5;&#x544A;&#x8BC9;&#x8BBE;&#x5907;&#x7F13;&#x51B2;&#x533A;&#x7684;&#x5927;&#x5C0F;&#xFF0C;&#x4EE5;&#x4FBF;&#x8BBE;&#x5907;&#x77E5;&#x9053;&#x53EF;&#x4EE5;&#x8BFB;&#x53D6;&#x6216;&#x5199;&#x5165;&#x7684;&#x6570;&#x636E;&#x91CF;&#x3002;</p>
</li>
<li>
<p><code>id</code>&#xFF1A;&#x8FD9;&#x662F;&#x4E00;&#x4E2A; 16 &#x4F4D;&#x5B57;&#x6BB5;&#xFF0C;&#x8868;&#x793A;&#x7F13;&#x51B2;&#x533A;&#x7684; ID&#x3002;&#x8FD9;&#x4E2A; ID &#x901A;&#x5E38;&#x4E0E;&#x63CF;&#x8FF0;&#x7B26;&#x5728;&#x63CF;&#x8FF0;&#x7B26;&#x8868;&#x4E2D;&#x7684;&#x7D22;&#x5F15;&#x76F8;&#x5BF9;&#x5E94;&#x3002;&#x5F53;&#x8BBE;&#x5907;&#x5B8C;&#x6210; I/O &#x64CD;&#x4F5C;&#x540E;&#xFF0C;&#x5B83;&#x4F1A;&#x5728;&#x54CD;&#x5E94;&#x4E2D;&#x8FD4;&#x56DE;&#x8FD9;&#x4E2A; ID&#xFF0C;&#x4EE5;&#x4FBF;&#x5BA2;&#x6237;&#x673A;&#xFF08;&#x865A;&#x62DF;&#x673A;&#xFF09;&#x53EF;&#x4EE5;&#x8BC6;&#x522B;&#x54EA;&#x4E2A;&#x8BF7;&#x6C42;&#x5DF2;&#x5B8C;&#x6210;&#x3002;</p>
</li>
<li>
<p><code>flags</code>&#xFF1A;&#x8FD9;&#x662F;&#x4E00;&#x4E2A; 16 &#x4F4D;&#x5B57;&#x6BB5;&#xFF0C;&#x8868;&#x793A;&#x63CF;&#x8FF0;&#x7B26;&#x7684;&#x7C7B;&#x578B;&#x548C;&#x72B6;&#x6001;&#x3002;<code>flags</code> &#x5B57;&#x6BB5;&#x53EF;&#x4EE5;&#x5305;&#x542B;&#x4EE5;&#x4E0B;&#x6807;&#x5FD7;&#xFF1A;</p>
<ul>
<li>
<p><code>VRING_DESC_F_NEXT</code>&#xFF1A;&#x8868;&#x793A;&#x63CF;&#x8FF0;&#x7B26;&#x94FE;&#x4E2D;&#x8FD8;&#x6709;&#x4E0B;&#x4E00;&#x4E2A;&#x63CF;&#x8FF0;&#x7B26;&#x3002;&#x5F53;&#x4E00;&#x4E2A;&#x8BF7;&#x6C42;&#x7684;&#x6570;&#x636E;&#x7F13;&#x51B2;&#x533A;&#x8DE8;&#x8D8A;&#x591A;&#x4E2A;&#x975E;&#x8FDE;&#x7EED;&#x5185;&#x5B58;&#x533A;&#x57DF;&#x65F6;&#xFF0C;&#x8FD9;&#x4E2A;&#x6807;&#x5FD7;&#x7528;&#x4E8E;&#x94FE;&#x63A5;&#x591A;&#x4E2A;&#x63CF;&#x8FF0;&#x7B26;&#x3002;</p>
</li>
<li>
<p><code>VRING_DESC_F_WRITE</code>&#xFF1A;&#x8868;&#x793A;&#x7F13;&#x51B2;&#x533A;&#x7528;&#x4E8E;&#x5199;&#x64CD;&#x4F5C;&#x3002;&#x5982;&#x679C;&#x8FD9;&#x4E2A;&#x6807;&#x5FD7;&#x88AB;&#x8BBE;&#x7F6E;&#xFF0C;&#x8BBE;&#x5907;&#x5C06;&#x628A;&#x6570;&#x636E;&#x5199;&#x5165;&#x7F13;&#x51B2;&#x533A;&#xFF1B;&#x5982;&#x679C;&#x6CA1;&#x6709;&#x8BBE;&#x7F6E;&#xFF0C;&#x8BBE;&#x5907;&#x5C06;&#x4ECE;&#x7F13;&#x51B2;&#x533A;&#x8BFB;&#x53D6;&#x6570;&#x636E;&#x3002;</p>
</li>
<li>
<p><code>VRING_DESC_F_INDIRECT</code>&#xFF1A;&#x8868;&#x793A;&#x63CF;&#x8FF0;&#x7B26;&#x4F7F;&#x7528;&#x95F4;&#x63A5;&#x5BFB;&#x5740;&#x3002;&#x8FD9;&#x610F;&#x5473;&#x7740; <code>addr</code> &#x548C; <code>len</code> &#x5B57;&#x6BB5;&#x5B9E;&#x9645;&#x4E0A;&#x6307;&#x5411;&#x53E6;&#x4E00;&#x4E2A;&#x63CF;&#x8FF0;&#x7B26;&#x8868;&#xFF0C;&#x800C;&#x4E0D;&#x662F;&#x6570;&#x636E;&#x7F13;&#x51B2;&#x533A;&#x3002;&#x95F4;&#x63A5;&#x5BFB;&#x5740;&#x7528;&#x4E8E;&#x51CF;&#x5C0F;&#x63CF;&#x8FF0;&#x7B26;&#x8868;&#x7684;&#x5927;&#x5C0F;&#xFF0C;&#x4EE5;&#x51CF;&#x5C11;&#x540C;&#x6B65;&#x5F00;&#x9500;&#x3002;</p>
</li>
<li>
<p>&#x6B64;&#x5916;&#x8FD9;&#x4E2A;flag&#x8FD8;&#x4F1A;&#x5305;&#x542B;&#x63CF;&#x8FF0;&#x7B26;&#x662F;&#x5426;&#x53EF;&#x7528;&#x7684;&#x6807;&#x8BB0;&#x4E3A;</p>
<pre><code class="language-cpp">          flags = cpu_to_le16(vq-&gt;packed.avail_used_flags |
                  (++c == total_sg ? 0 : VRING_DESC_F_NEXT) |
                  (n &lt; out_sgs ? 0 : VRING_DESC_F_WRITE));
          if (i == head)
              head_flags = flags;
          else
              desc[i].flags = flags;
</code></pre>
</li>
</ul>
</li>
</ol>
<p>&#x800C;<code>struct vring_virtqueue</code>-&gt;<code>struct vring_virtqueue_packed</code>&#x7684;<code>u16 avail_used_flags;</code>&#x5219;&#x662F;&#x7528;&#x6765;&#x6807;&#x8BB0;&#x8FD9;&#x4E2A;ring&#x662F;avail&#x8FD8;&#x662F;used&#x7684;&#x6807;&#x8BB0;&#x3002;</p>
<h4 id="242-%E4%BF%AE%E6%94%B9packed-desc%E7%8A%B6%E6%80%81">2.4.2-&#x4FEE;&#x6539;packed desc&#x72B6;&#x6001;</h4>
<p>&#x5BF9;&#x4E8E;<code>packed queue</code>&#x6765;&#x8BF4;&#xFF0C;&#x53EA;&#x6709;&#x4E00;&#x79CD;ring&#xFF0C;&#x4E0D;&#x7528;&#x50CF;<code>split queue</code>&#xFF1A;</p>
<ul>
<li>&#x524D;&#x7AEF;&#x9A71;&#x52A8;&#x5904;&#x7406;&#x5B8C;&#x540E;&#x6DFB;&#x52A0;&#x5230;<code>used</code>&#x533A;</li>
<li>&#x5728;&#x540E;&#x7AEF;&#x8BBE;&#x5907;&#x5904;&#x7406;&#x540E;&#x6DFB;&#x52A0;&#x5230;<code>available</code>&#x533A;</li>
</ul>
<p>&#x5728;&#x5185;&#x6838;&#x4E2D;&#xFF0C;&#x4FEE;&#x6539;<code>packed_desc</code>&#x72B6;&#x6001;&#x7684;api&#x5982;&#x4E0B;</p>
<pre><code class="language-cpp">static inline int virtqueue_add_packed(struct virtqueue *_vq,
				       struct scatterlist *sgs[],
				       unsigned int total_sg,
				       unsigned int out_sgs,
				       unsigned int in_sgs,
				       void *data,
				       void *ctx,
				       gfp_t gfp)
{
  ......
  // &#x83B7;&#x53D6;&#x4E0B;&#x4E00;&#x4E2A;&#x53EF;&#x7528;&#x63CF;&#x8FF0;&#x7B26;&#x7684;&#x7D22;&#x5F15;&#x548C;&#x5F53;&#x524D;&#x7684;&#x72B6;&#x6001;&#x6807;&#x5FD7;
  head = vq-&gt;packed.next_avail_idx;
  avail_used_flags = vq-&gt;packed.avail_used_flags;

  // &#x83B7;&#x53D6;&#x63CF;&#x8FF0;&#x7B26;&#x6570;&#x7EC4;&#x7684;&#x5F15;&#x7528;
  desc = vq-&gt;packed.vring.desc;
  i = head;
  descs_used = total_sg;

  // &#x904D;&#x5386; scatterlist&#xFF08;sgs&#xFF09;&#x6570;&#x7EC4;
  for (n = 0; n &lt; out_sgs + in_sgs; n++) {
      for (sg = sgs[n]; sg; sg = sg_next(sg)) {
          // ...

          // &#x8BBE;&#x7F6E;&#x63CF;&#x8FF0;&#x7B26;&#x7684; flags &#x5B57;&#x6BB5;
          // &#x8FD9;&#x91CC;&#x4F7F;&#x7528;&#x4E86; avail_used_flags &#x53D8;&#x91CF;&#x6765;&#x8BBE;&#x7F6E;&#x63CF;&#x8FF0;&#x7B26;&#x7684;&#x72B6;&#x6001;&#xFF08;&#x53EF;&#x7528;&#x6216;&#x5DF2;&#x7528;&#xFF09;
          flags = cpu_to_le16(vq-&gt;packed.avail_used_flags |
                  (++c == total_sg ? 0 : VRING_DESC_F_NEXT) |
                  (n &lt; out_sgs ? 0 : VRING_DESC_F_WRITE));
          if (i == head)
              head_flags = flags;
          else
              desc[i].flags = flags;
					
        	// &#x66F4;&#x65B0;&#x63CF;&#x8FF0;&#x7B26;&#x7684;&#x5176;&#x4ED6;&#x5173;&#x952E;&#x5B57;&#x6BB5;
          desc[i].addr = cpu_to_le64(addr);
					desc[i].len = cpu_to_le32(sg-&gt;length);
					desc[i].id = cpu_to_le16(id);
          //......

          // &#x5982;&#x679C;&#x5DF2;&#x7ECF;&#x904D;&#x5386;&#x5B8C;&#x6574;&#x4E2A;&#x73AF;&#xFF0C;&#x5C31;&#x5207;&#x6362; avail_used_flags &#x53D8;&#x91CF;&#x7684;&#x503C;
          // &#x8FD9;&#x4F1A;&#x6539;&#x53D8;&#x73AF;&#x4E2D;&#x63CF;&#x8FF0;&#x7B26;&#x7684;&#x72B6;&#x6001;&#xFF08;&#x53EF;&#x7528;&#x6216;&#x5DF2;&#x7528;&#xFF09;
          if ((unlikely(++i &gt;= vq-&gt;packed.vring.num))) {
              i = 0;
              vq-&gt;packed.avail_used_flags ^=
                  1 &lt;&lt; VRING_PACKED_DESC_F_AVAIL |
                  1 &lt;&lt; VRING_PACKED_DESC_F_USED;
          }
      }
  }

  // &#x5982;&#x679C;&#x73AF;&#x4E2D;&#x7684;&#x53EF;&#x7528;&#x63CF;&#x8FF0;&#x7B26;&#x5DF2;&#x7ECF;&#x904D;&#x5386;&#x5B8C;&#xFF0C;&#x5C31;&#x5207;&#x6362; avail_wrap_counter &#x53D8;&#x91CF;&#x7684;&#x503C;
  // &#x8FD9;&#x4F1A;&#x6539;&#x53D8;&#x73AF;&#x4E2D;&#x63CF;&#x8FF0;&#x7B26;&#x7684;&#x72B6;&#x6001;&#xFF08;&#x53EF;&#x7528;&#x6216;&#x5DF2;&#x7528;&#xFF09;
  if (i &lt;= head)
      vq-&gt;packed.avail_wrap_counter ^= 1;

  // &#x66F4;&#x65B0;&#x4E0B;&#x4E00;&#x4E2A;&#x53EF;&#x7528;&#x63CF;&#x8FF0;&#x7B26;&#x7684;&#x7D22;&#x5F15;
  vq-&gt;packed.next_avail_idx = i;
  ......
}
</code></pre>
<h2 id="3-virtio%E4%BB%A3%E7%A0%81">3-virtio&#x4EE3;&#x7801;</h2>
<p>&#x4EE5;&#x5E38;&#x89C1;&#x7684;pci&#x8BBE;&#x5907;+virtblk&#x4E3E;&#x4F8B;</p>
<h3 id="31-%E6%B3%A8%E5%86%8C">3.1-&#x6CE8;&#x518C;</h3>
<p>virtio&#x7684;&#x9A71;&#x52A8;&#x662F;&#x5728;&#x524D;&#x7AEF;&#x4E2D;&#x5B8C;&#x6210;&#xFF0C;&#x4E5F;&#x5C31;&#x662F;guest&#x5B50;&#x673A;&#x4E2D;&#x3002;</p>
<p>linux&#x5185;&#x6838;&#x4E2D;&#x9A71;&#x52A8;&#x662F;&#x5206;&#x4E3A;&#x4E09;&#x4E2A;&#x5C42;&#x7EA7;&#xFF1A;</p>
<ul>
<li>bus</li>
<li>device</li>
<li>driver</li>
</ul>
<p>&#x5728;&#x8FD9;&#x4E2A;&#x4F8B;&#x5B50;&#x4E2D;&#xFF0C;virtio_blk&#x5BF9;&#x5E94;&#x7684;&#x5C31;&#x662F;driver&#xFF0C;virtio-pci&#x5BF9;&#x5E94;&#x7684;&#x662F;device&#xFF0C;&#x4E8C;&#x8005;&#x5173;&#x8054;&#x662F;virtio_bus&#x3002;</p>
<pre><code class="language-bash"># tree /sys/bus/virtio/
/sys/bus/virtio/
&#x251C;&#x2500;&#x2500; devices
&#x2502;   &#x251C;&#x2500;&#x2500; virtio0 -&gt; ../../../devices/pci0000:00/0000:00:05.0/virtio0
&#x2502;   &#x251C;&#x2500;&#x2500; virtio1 -&gt; ../../../devices/pci0000:00/0000:00:06.0/virtio1
&#x2502;   &#x251C;&#x2500;&#x2500; virtio2 -&gt; ../../../devices/pci0000:00/0000:00:07.0/virtio2
&#x2502;   &#x2514;&#x2500;&#x2500; virtio3 -&gt; ../../../devices/pci0000:00/0000:00:08.0/virtio3
&#x251C;&#x2500;&#x2500; drivers
&#x2502;   &#x251C;&#x2500;&#x2500; virtio_balloon
&#x2502;   &#x2502;   &#x251C;&#x2500;&#x2500; bind
&#x2502;   &#x2502;   &#x251C;&#x2500;&#x2500; module -&gt; ../../../../module/virtio_balloon
&#x2502;   &#x2502;   &#x251C;&#x2500;&#x2500; uevent
&#x2502;   &#x2502;   &#x251C;&#x2500;&#x2500; unbind
&#x2502;   &#x2502;   &#x2514;&#x2500;&#x2500; virtio3 -&gt; ../../../../devices/pci0000:00/0000:00:08.0/virtio3
&#x2502;   &#x251C;&#x2500;&#x2500; virtio_blk
&#x2502;   &#x2502;   &#x251C;&#x2500;&#x2500; bind
&#x2502;   &#x2502;   &#x251C;&#x2500;&#x2500; module -&gt; ../../../../module/virtio_blk
&#x2502;   &#x2502;   &#x251C;&#x2500;&#x2500; uevent
&#x2502;   &#x2502;   &#x251C;&#x2500;&#x2500; unbind
&#x2502;   &#x2502;   &#x2514;&#x2500;&#x2500; virtio1 -&gt; ../../../../devices/pci0000:00/0000:00:06.0/virtio1
&#x2502;   &#x251C;&#x2500;&#x2500; virtio_console
&#x2502;   &#x2502;   &#x251C;&#x2500;&#x2500; bind
&#x2502;   &#x2502;   &#x251C;&#x2500;&#x2500; module -&gt; ../../../../module/virtio_console
&#x2502;   &#x2502;   &#x251C;&#x2500;&#x2500; uevent
&#x2502;   &#x2502;   &#x251C;&#x2500;&#x2500; unbind
&#x2502;   &#x2502;   &#x2514;&#x2500;&#x2500; virtio2 -&gt; ../../../../devices/pci0000:00/0000:00:07.0/virtio2
&#x2502;   &#x251C;&#x2500;&#x2500; virtio_net
&#x2502;   &#x2502;   &#x251C;&#x2500;&#x2500; bind
&#x2502;   &#x2502;   &#x251C;&#x2500;&#x2500; module -&gt; ../../../../module/virtio_net
&#x2502;   &#x2502;   &#x251C;&#x2500;&#x2500; uevent
&#x2502;   &#x2502;   &#x251C;&#x2500;&#x2500; unbind
&#x2502;   &#x2502;   &#x2514;&#x2500;&#x2500; virtio0 -&gt; ../../../../devices/pci0000:00/0000:00:05.0/virtio0
&#x2502;   &#x2514;&#x2500;&#x2500; virtio_rproc_serial
&#x2502;       &#x251C;&#x2500;&#x2500; bind
&#x2502;       &#x251C;&#x2500;&#x2500; module -&gt; ../../../../module/virtio_console
&#x2502;       &#x251C;&#x2500;&#x2500; uevent
&#x2502;       &#x2514;&#x2500;&#x2500; unbind
&#x251C;&#x2500;&#x2500; drivers_autoprobe
&#x251C;&#x2500;&#x2500; drivers_probe
&#x2514;&#x2500;&#x2500; uevent
</code></pre>
<ol>
<li><code>/sys/bus/virtio/devices</code>&#xFF1A;&#x8FD9;&#x4E2A;&#x76EE;&#x5F55;&#x5305;&#x542B;&#x4E86;&#x6240;&#x6709;&#x6CE8;&#x518C;&#x5230; virtio &#x5B50;&#x7CFB;&#x7EDF;&#x7684;&#x8BBE;&#x5907;&#x3002;&#x5728;&#x8FD9;&#x4E2A;&#x4F8B;&#x5B50;&#x4E2D;&#xFF0C;&#x6709;&#x56DB;&#x4E2A;&#x8BBE;&#x5907;&#xFF08;<code>virtio0</code>&#x3001;<code>virtio1</code>&#x3001;<code>virtio2</code> &#x548C; <code>virtio3</code>&#xFF09;&#xFF0C;&#x5B83;&#x4EEC;&#x5206;&#x522B;&#x5BF9;&#x5E94;&#x4E86;&#x4E0D;&#x540C;&#x7684; PCI &#x8BBE;&#x5907;&#x3002;&#x8FD9;&#x4E9B;&#x8BBE;&#x5907;&#x7684;&#x5177;&#x4F53;&#x4FE1;&#x606F;&#x53EF;&#x4EE5;&#x5728;&#x76F8;&#x5E94;&#x7684;&#x8BBE;&#x5907;&#x76EE;&#x5F55;&#xFF08;&#x4F8B;&#x5982; <code>/sys/devices/pci0000:00/0000:00:05.0/virtio0</code>&#xFF09;&#x4E2D;&#x627E;&#x5230;&#x3002;</li>
<li><code>/sys/bus/virtio/drivers</code>&#xFF1A;&#x8FD9;&#x4E2A;&#x76EE;&#x5F55;&#x5305;&#x542B;&#x4E86;&#x6240;&#x6709;&#x6CE8;&#x518C;&#x5230; virtio &#x5B50;&#x7CFB;&#x7EDF;&#x7684;&#x9A71;&#x52A8;&#x7A0B;&#x5E8F;&#x3002;&#x5728;&#x8FD9;&#x4E2A;&#x4F8B;&#x5B50;&#x4E2D;&#xFF0C;&#x6709;&#x4E94;&#x4E2A;&#x9A71;&#x52A8;&#x7A0B;&#x5E8F;&#xFF08;<code>virtio_balloon</code>&#x3001;<code>virtio_blk</code>&#x3001;<code>virtio_console</code>&#x3001;<code>virtio_net</code> &#x548C; <code>virtio_rproc_serial</code>&#xFF09;&#x3002;&#x6BCF;&#x4E2A;&#x9A71;&#x52A8;&#x7A0B;&#x5E8F;&#x76EE;&#x5F55;&#x4E0B;&#x90FD;&#x6709;&#x4E00;&#x4E9B;&#x6587;&#x4EF6;&#xFF0C;&#x5982; <code>bind</code>&#x3001;<code>unbind</code> &#x548C; <code>uevent</code>&#xFF0C;&#x5206;&#x522B;&#x7528;&#x4E8E;&#x7ED1;&#x5B9A;&#x8BBE;&#x5907;&#x3001;&#x89E3;&#x7ED1;&#x8BBE;&#x5907;&#x548C;&#x53D1;&#x9001;&#x8BBE;&#x5907;&#x4E8B;&#x4EF6;&#x3002;&#x6B64;&#x5916;&#xFF0C;&#x9A71;&#x52A8;&#x7A0B;&#x5E8F;&#x76EE;&#x5F55;&#x4E0B;&#x8FD8;&#x6709;&#x4E00;&#x4E2A;&#x540D;&#x4E3A; <code>module</code> &#x7684;&#x7B26;&#x53F7;&#x94FE;&#x63A5;&#xFF0C;&#x6307;&#x5411;&#x4E0E;&#x8BE5;&#x9A71;&#x52A8;&#x7A0B;&#x5E8F;&#x5173;&#x8054;&#x7684;&#x5185;&#x6838;&#x6A21;&#x5757;&#x76EE;&#x5F55;&#x3002;&#x8FD8;&#x6709;&#x4E00;&#x4E2A;&#x6216;&#x591A;&#x4E2A;&#x8BBE;&#x5907;&#x7684;&#x7B26;&#x53F7;&#x94FE;&#x63A5;&#xFF0C;&#x8868;&#x793A;&#x5F53;&#x524D;&#x4E0E;&#x8BE5;&#x9A71;&#x52A8;&#x7A0B;&#x5E8F;&#x7ED1;&#x5B9A;&#x7684;&#x8BBE;&#x5907;&#x3002;</li>
<li><code>/sys/bus/virtio/drivers_autoprobe</code>&#x3001;<code>/sys/bus/virtio/drivers_probe</code> &#x548C; <code>/sys/bus/virtio/uevent</code>&#xFF1A;&#x8FD9;&#x4E9B;&#x6587;&#x4EF6;&#x7528;&#x4E8E;&#x63A7;&#x5236;&#x9A71;&#x52A8;&#x7A0B;&#x5E8F;&#x7684;&#x81EA;&#x52A8;&#x63A2;&#x6D4B;&#x548C;&#x8BBE;&#x5907;&#x4E8B;&#x4EF6;&#x3002;&#x5728;&#x8FD9;&#x4E2A;&#x4F8B;&#x5B50;&#x4E2D;&#xFF0C;&#x5B83;&#x4EEC;&#x6CA1;&#x6709;&#x63D0;&#x4F9B;&#x989D;&#x5916;&#x7684;&#x4FE1;&#x606F;&#x3002;</li>
</ol>
<h4 id="311-%E6%B3%A8%E5%86%8C%E6%80%BB%E7%BA%BF">3.1.1-&#x6CE8;&#x518C;&#x603B;&#x7EBF;</h4>
<p>&#x9996;&#x5148;&#xFF0C;virtio&#x4F1A;&#x6839;&#x636E;&#x5B9A;&#x4E49;&#x597D;&#x7684;<code>virtio_bus</code>&#x7ED3;&#x6784;&#x4F53;&#xFF0C;&#x5229;&#x7528;&#x901A;&#x7528;&#x7684;<code>bus_register</code>&#x6CE8;&#x518C;&#x9A71;&#x52A8;</p>
<pre><code class="language-cpp">static struct bus_type virtio_bus = {
	.name  = &quot;virtio&quot;,
	.match = virtio_dev_match,
	.dev_groups = virtio_dev_groups,
	.uevent = virtio_uevent,
	.probe = virtio_dev_probe,
	.remove = virtio_dev_remove,
};

static int virtio_init(void)
{
	if (bus_register(&amp;virtio_bus) != 0)
		panic(&quot;virtio bus registration failed&quot;);
	virtio_debug_init();
	return 0;
}
</code></pre>
<p>&#x6CE8;&#x518C;&#x6210;&#x529F;&#x540E;&#xFF0C;&#x5C31;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;<code>/sys/bus</code>&#x4E2D;&#x67E5;&#x770B;&#x5230;&#x4E00;&#x4E2A;<code>virtio</code>&#x7C7B;&#x578B;&#x7684;&#x603B;&#x7EBF;&#x3002;</p>
<pre><code class="language-bash"># ls /sys/bus/virtio/
devices  drivers  drivers_autoprobe  drivers_probe  uevent
</code></pre>
<p><a href="https://m.elecfans.com/article/1306596.html?ref=korantli.com.cn">https://m.elecfans.com/article/1306596.html</a></p>
<h4 id="312-%E7%89%A9%E7%90%86%E6%80%BB%E7%BA%BF%E5%88%9D%E5%A7%8B%E5%8C%96">3.1.2-&#x7269;&#x7406;&#x603B;&#x7EBF;&#x521D;&#x59CB;&#x5316;</h4>
<p>&#x60F3;&#x8981;&#x521D;&#x59CB;&#x5316;&#x4E00;&#x4E2A;&#x5177;&#x4F53;&#x7684;&#x9A71;&#x52A8;&#x8BBE;&#x5907;&#x524D;&#xFF0C;&#x8981;&#x521D;&#x59CB;&#x5316;&#x597D;driver&#x7684;&#x5177;&#x4F53;&#x603B;&#x7EBF;&#xFF0C;virtio-blk&#x5BF9;&#x5E94;&#x7684;&#x662F;pci&#x8BBE;&#x5907;&#x3002;</p>
<p>&#x5F53;&#x63D2;&#x5165;&#x4E00;&#x4E2A;&#x865A;&#x62DF;pci&#x8BBE;&#x5907;&#x65F6;&#xFF0C;&#x6B64;&#x65F6;&#x4F1A;&#x6CE8;&#x518C;&#x4E3A;<code>vendor 0x1af4</code>&#x548C;<code>device id 0x1003</code>&#xFF0C;&#x6B64;&#x65F6;&#x4F1A;&#x901A;&#x8FC7;pci&#x7684;&#x603B;&#x7EBF;&#x4F1A;&#x6839;&#x636E;&#x8BBE;&#x5907;&#x53F7;&#x7B49;&#x4FE1;&#x606F;&#x8C03;&#x7528;<code>virtio_pci_probe</code>&#x8FDB;&#x4E00;&#x6B65;&#x521D;&#x59CB;&#x5316;&#x6210;&#x4E0A;&#x8FF0;&#x7684;&#x5177;&#x4F53;pci-device</p>
<pre><code class="language-cpp">/* Qumranet donated their vendor ID for devices 0x1000 thru 0x10FF. */
static const struct pci_device_id virtio_pci_id_table[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_REDHAT_QUMRANET, PCI_ANY_ID) },
	{ 0 }
};

static int virtio_pci_probe(struct pci_dev *pci_dev,
			    const struct pci_device_id *id)
{
	......
	if (force_legacy) {
		rc = virtio_pci_legacy_probe(vp_dev);
		/* Also try modern mode if we can&apos;t map BAR0 (no IO space). */
		if (rc == -ENODEV || rc == -ENOMEM)
			rc = virtio_pci_modern_probe(vp_dev);
		if (rc)
			goto err_probe;
	} else {
		rc = virtio_pci_modern_probe(vp_dev);
		if (rc == -ENODEV)
			rc = virtio_pci_legacy_probe(vp_dev);
		if (rc)
			goto err_probe;
	}
	......
	rc = register_virtio_device(&amp;vp_dev-&gt;vdev);
	......
}
</code></pre>
<h4 id="313-%E9%A9%B1%E5%8A%A8%E5%88%9D%E5%A7%8B%E5%8C%96">3.1.3-&#x9A71;&#x52A8;&#x521D;&#x59CB;&#x5316;</h4>
<p>&#x5F53;&#x6211;&#x4EEC;&#x63D2;&#x5165;virtio_blk ko&#x65F6;&#xFF0C;&#x9A71;&#x52A8;&#x4F1A;&#x5148;&#x5B9A;&#x4E49;&#x4E00;&#x4E2A;virtio_bus&#x7684;driver&#x7ED3;&#x6784;&#x4F53;</p>
<pre><code class="language-cpp">static struct virtio_driver virtio_blk = {
	.feature_table			= features,
	.feature_table_size		= ARRAY_SIZE(features),
	.feature_table_legacy		= features_legacy,
	.feature_table_size_legacy	= ARRAY_SIZE(features_legacy),
	.driver.name			= KBUILD_MODNAME,
	.id_table			= id_table,
	.probe				= virtblk_probe,
	.remove				= virtblk_remove,
	.config_changed			= virtblk_config_changed,
#ifdef CONFIG_PM_SLEEP
	.freeze				= virtblk_freeze,
	.restore			= virtblk_restore,
#endif
};
</code></pre>
<p>&#x5728;<code>virtio_blk.c</code>&#x4E2D;&#x901A;&#x8FC7;<code>virtio_blk_init</code>-&gt;<code>register_virtio_driver</code>-&gt;<code>__register_virtio_driver</code>-&gt;<code>driver_register</code>&#xFF0C;&#x5728;&#x8FD9;&#x91CC;&#x4F1A;&#x5C06;&#x81EA;&#x5DF1;&#x6CE8;&#x518C;&#x5230;virtio&#x7684;bus&#x603B;&#x7EBF;&#x4E2D;&#xFF0C;&#x5E76;&#x4E14;&#x6CE8;&#x518C;&#x4E3A;&#x4E00;&#x4E2A;<code>&#x9A71;&#x52A8; driver</code>&#x7C7B;&#x578B;&#x3002;</p>
<pre><code class="language-cpp">#define VIRTIO_ID_BLOCK			2 /* virtio block */

static const struct virtio_device_id id_table[] = {
	{ VIRTIO_ID_BLOCK, VIRTIO_DEV_ANY_ID },
	{ 0 },
};
</code></pre>
<p>&#x5F53;&#x51FA;&#x73B0;&#x5339;&#x914D;&#x7684;&#x8BBE;&#x5907;id&#x65F6;&#xFF0C;&#x5C31;&#x4F1A;&#x81EA;&#x52A8;&#x6267;&#x884C;<code>virtblk_probe</code>&#x7684;&#x903B;&#x8F91;&#xFF0C;&#x8FDB;&#x884C;&#x9A71;&#x52A8;&#x7684;&#x521D;&#x59CB;&#x5316;&#x3002;</p>
<h3 id="32-%E5%88%9B%E5%BB%BAvirtqueue">3.2-&#x521B;&#x5EFA;virtqueue</h3>
<p>&#x521D;&#x59CB;&#x5316;&#x4E2D;&#x4E00;&#x4E2A;&#x5F88;&#x91CD;&#x8981;&#x7684;&#x6D41;&#x7A0B;&#x5C31;&#x662F;&#x521D;&#x59CB;&#x5316;&#x5F53;&#x524D;&#x8BBE;&#x5907;&#x7684;<code>virtqueue</code></p>
<p><code>virtblk_probe</code>-&gt;<code>init_vq</code>-&gt;<code>virtio_find_vqs</code>-&gt;<code>vdev-&gt;config-&gt;find_vqs</code>-&gt;<code>vp_modern_find_vqs</code>(virtio_pci)</p>
<pre><code class="language-cpp">static int init_vq(struct virtio_blk *vblk)
{
	......
	err = virtio_cread_feature(vdev, VIRTIO_BLK_F_MQ,
				   struct virtio_blk_config, num_queues,
				   &amp;num_vqs);
	......
	num_vqs = min_t(unsigned int,
			min_not_zero(num_request_queues, nr_cpu_ids),
			num_vqs); //&#x53D6;&#x4E00;&#x4E2A;&#x6700;&#x5C0F;&#x503C;

	num_poll_vqs = min_t(unsigned int, poll_queues, num_vqs - 1);
	......
	vblk-&gt;vqs = kmalloc_array(num_vqs, sizeof(*vblk-&gt;vqs), GFP_KERNEL); // &#x4E3A;vqs&#x5206;&#x914D;&#x5B9E;&#x9645;&#x7684;&#x5185;&#x5B58;
	......
	/* Discover virtqueues and write information to configuration.  */
	err = virtio_find_vqs(vdev, num_vqs, vqs, callbacks, names, &amp;desc);
	......
}
</code></pre>
<p>&#x5728;virtio-pci&#x4E2D;<code>virtio_find_vqs</code>&#x4F1A;&#x6700;&#x7EC8;&#x8C03;&#x7528;&#x5230;<code>vp_modern_find_vqs</code>-&gt;<code>vp_find_vqs</code></p>
<p>&#x8FD9;&#x91CC;&#x4F1A;&#x4F18;&#x5148;&#x4E2D;msi-x&#x4E2D;&#x65AD;&#x7684;vqs&#xFF0C;&#x7136;&#x540E;&#x627E;&#x4E0D;&#x5230;msi-x&#x7684;&#x8BDD;&#x624D;&#x4F1A;&#x67E5;&#x627E;&#x4F20;&#x7EDF;&#x7684;int-x&#x7684;&#x4E2D;&#x65AD;&#x3002;</p>
<pre><code class="language-cpp">/* the config-&gt;find_vqs() implementation */
int vp_find_vqs(struct virtio_device *vdev, unsigned int nvqs,
		struct virtqueue *vqs[], vq_callback_t *callbacks[],
		const char * const names[], const bool *ctx,
		struct irq_affinity *desc)
{
	int err;

	/* Try MSI-X with one vector per queue. */
	err = vp_find_vqs_msix(vdev, nvqs, vqs, callbacks, names, true, ctx, desc);
	if (!err)
		return 0;
	/* Fallback: MSI-X with one vector for config, one shared for queues. */
	err = vp_find_vqs_msix(vdev, nvqs, vqs, callbacks, names, false, ctx, desc);
	if (!err)
		return 0;
	/* Is there an interrupt? If not give up. */
	if (!(to_vp_device(vdev)-&gt;pci_dev-&gt;irq))
		return err;
	/* Finally fall back to regular interrupts. */
	return vp_find_vqs_intx(vdev, nvqs, vqs, callbacks, names, ctx);
}
</code></pre>
<p>&#x200B;	&#x8FD9;&#x4E09;&#x4E2A;api&#x6700;&#x7EC8;&#x90FD;&#x4F1A;&#x8C03;&#x7528;&#x5230;<code>vp_setup_vq</code>&#x6765;&#x5B9E;&#x9645;&#x5EFA;&#x7ACB;<code>virtqueue</code>&#xFF0C;&#x800C;pci&#x8BBE;&#x5907;&#x7684;<code>setup_vq</code>&#x51FD;&#x6570;&#x88AB;&#x5B9A;&#x4E49;&#x5728;&#x4E86;<code>drivers\virtio\virtio_pci_modern.c</code>&#x4E2D;</p>
<pre><code class="language-cpp">static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev,
				  struct virtio_pci_vq_info *info,
				  unsigned int index,
				  void (*callback)(struct virtqueue *vq),
				  const char *name,
				  bool ctx,
				  u16 msix_vec)
{
  ......
	if (__virtio_test_bit(&amp;vp_dev-&gt;vdev, VIRTIO_F_NOTIFICATION_DATA))
		notify = vp_notify_with_data;
	else
		notify = vp_notify; // &#x6CE8;&#x518C;&#x901A;&#x77E5;&#x51FD;&#x6570;
	......
	/* Check if queue is either not available or already active. */
	num = vp_modern_get_queue_size(mdev, index); // &#x627E;&#x5230;queue&#x4E2D;vring&#x7684;&#x6570;&#x91CF;
	if (!num || vp_modern_get_queue_enable(mdev, index))
		return ERR_PTR(-ENOENT);

	info-&gt;msix_vector = msix_vec;

	/* &#x4E3A;virtqueue&#x521B;&#x5EFA;num&#x6570;&#x91CF;&#x7684;vring */
	vq = vring_create_virtqueue(index, num,
				    SMP_CACHE_BYTES, &amp;vp_dev-&gt;vdev,
				    true, true, ctx,
				    notify, callback, name);
	......
	err = vp_active_vq(vq, msix_vec); // &#x4F7F;&#x80FD;&#x5F53;&#x524D;&#x7684;virtqueue
	......
	return vq;
	......
}
</code></pre>
<h3 id="33-io%E6%B5%81%E7%A8%8B">3.3-I\O&#x6D41;&#x7A0B;</h3>
<p><a href="https://blog.csdn.net/flyingnosky/article/details/132724114?ref=korantli.com.cn">https://blog.csdn.net/flyingnosky/article/details/132724114</a></p>
<p><a href="https://blog.csdn.net/wing_7/article/details/138562337?ref=korantli.com.cn">https://blog.csdn.net/wing_7/article/details/138562337</a></p>
<p>virtio-blk&#x4F1A;&#x5728;&#x521D;&#x59CB;&#x5316;&#x6D41;&#x7A0B;&#x4E2D;&#x8BBE;&#x7F6E;&#x6807;&#x51C6;&#x7684;<code>blk-mq</code>&#x64CD;&#x4F5C;ops&#xFF0C;&#x4ECE;&#x800C;&#x5728;virtio-blk&#x8BBE;&#x5907;&#x4E2D;&#x6267;&#x884C;&#x6807;&#x51C6;&#x7684;io&#x64CD;&#x4F5C;&#x540E;&#xFF0C;&#x6267;&#x884C;&#x5177;&#x4F53;virtio-blk&#x903B;&#x8F91;&#xFF0C;&#x5C06;rq&#x586B;&#x5165;<code>virtqueue</code>&#x4E2D;&#xFF0C;&#x901A;&#x8FC7;&#x865A;&#x62DF;&#x5316;&#x53D1;&#x7ED9;&#x540E;&#x7AEF;&#x8BBE;&#x5907;(qemu)&#x3002;</p>
<pre><code class="language-cpp">static const struct blk_mq_ops virtio_mq_ops = {
	.queue_rq	= virtio_queue_rq,
	.queue_rqs	= virtio_queue_rqs,
	.commit_rqs	= virtio_commit_rqs,
	.complete	= virtblk_request_done,
	.map_queues	= virtblk_map_queues,
	.poll		= virtblk_poll,
};
</code></pre>
<p>&#x4F8B;&#x5982;&#xFF0C;&#x5F53;&#x524D;&#x7AEF;&#x8BBE;&#x5907;&#x5B8C;&#x6210;&#x4E00;&#x4E9B;&#x5217;io&#x64CD;&#x4F5C;&#xFF0C;&#x5728;&#x901A;&#x7528;&#x5757;&#x5C42;&#x7684;blk-mq&#x5B8C;&#x6210;rq&#x84C4;&#x6D41;&#x540E;&#xFF0C;&#x6700;&#x7EC8;&#x6267;&#x884C;rq&#x7684;&#x961F;&#x5217;&#x4E0B;&#x53D1;&#x65F6;&#x7684;&#x51FD;&#x6570;<code>queue_rqs</code>-&gt;<code>virtio_queue_rqs</code></p>
<pre><code class="language-cpp">static void virtio_queue_rqs(struct request **rqlist)
{
	......
	rq_list_for_each_safe(rqlist, req, next) { // &#x904D;&#x5386;&#x786C;&#x4EF6;&#x961F;&#x5217;&#xFF0C;&#x6328;&#x4E2A;&#x5C06;rq&#x586B;&#x5165;virtqueue
		struct virtio_blk_vq *vq = get_virtio_blk_vq(req-&gt;mq_hctx); // &#x83B7;&#x53D6;&#x8FD9;&#x4E2A;virtblk&#x8BBE;&#x5907;&#x6240;&#x521B;&#x5EFA;&#x7684;virtqueue
		bool kick;

		if (!virtblk_prep_rq_batch(req)) { // &#x51C6;&#x5907;&#x505A;&#x597D;&#x628A;request list&#x8F6C;&#x6362;&#x6210;virtqueue&#x7684;&#x51C6;&#x5907;
			rq_list_move(rqlist, &amp;requeue_list, req, prev);
			req = prev;
			if (!req)
				continue;
		}

		if (!next || req-&gt;mq_hctx != next-&gt;mq_hctx) {
			req-&gt;rq_next = NULL;
			kick = virtblk_add_req_batch(vq, rqlist); // &#x628A;rqlist&#x8F6C;&#x6362;&#x6210;virtqueue
			if (kick)
				virtqueue_notify(vq-&gt;vq);// &#x901A;&#x77E5;&#x540E;&#x7AEF;&#x8BBE;&#x5907;&#xFF08;host qemu&#xFF09;

			*rqlist = next;
			prev = NULL;
		} else
			prev = req;
	}

	*rqlist = requeue_list;
}
</code></pre>
<h4 id="331-%E5%89%8D%E7%AB%AF%E5%A1%AB%E5%85%A5">3.3.1-&#x524D;&#x7AEF;&#x586B;&#x5165;</h4>
<pre><code class="language-cpp">static bool virtblk_add_req_batch(struct virtio_blk_vq *vq,
					struct request **rqlist)
{
	......
	while (!rq_list_empty(*rqlist)) {// &#x904D;&#x5386;rqlist&#x91CC;&#x7684;&#x6BCF;&#x4E2A;request
		struct request *req = rq_list_pop(rqlist); // &#x5F39;&#x51FA;&#x5F53;&#x524D;rqlist&#x7684;&#x7B2C;&#x4E00;&#x4E2A;request
		struct virtblk_req *vbr = blk_mq_rq_to_pdu(req); // &#x83B7;&#x53D6;req&#x5BF9;&#x5E94;&#x7684;pdu&#xFF08;&#x534F;&#x8BAE;&#x6570;&#x636E;&#x5355;&#x5143;&#xFF09;

		err = virtblk_add_req(vq-&gt;vq, vbr); //&#x628A;&#x8FD9;&#x4E2A;vb reques&#x586B;&#x5165;virtequeue&#x91CC;
		......
	}

	kick = virtqueue_kick_prepare(vq-&gt;vq);
	spin_unlock_irqrestore(&amp;vq-&gt;lock, flags);

	return kick;
}
</code></pre>
<p>&#x800C;&#x8FD9;&#x91CC;&#x4F1A;&#x901A;&#x8FC7;<code>virtblk_add_req</code>&#x6765;&#x5B9E;&#x9645;&#x5C06;req&#x6DFB;&#x52A0;&#x5230;virtqueue&#x4E2D;</p>
<p>&#x51FD;&#x6570;&#x9996;&#x5148;&#x4F1A;&#x521D;&#x59CB;&#x5316;&#x597D;&#x9700;&#x8981;&#x586B;&#x5165;&#x7684;<code>scatterlist&#xFF08;&#x6563;&#x5C04;&#x5217;&#x8868;&#xFF09;</code></p>
<pre><code class="language-cpp">static int virtblk_add_req(struct virtqueue *vq, struct virtblk_req *vbr)
{
	struct scatterlist out_hdr, in_hdr, *sgs[3];
	unsigned int num_out = 0, num_in = 0;

	sg_init_one(&amp;out_hdr, &amp;vbr-&gt;out_hdr, sizeof(vbr-&gt;out_hdr));
	sgs[num_out++] = &amp;out_hdr; // &#x5C06; out_hdr &#x6DFB;&#x52A0;&#x5230; sgs &#x6570;&#x7EC4;&#xFF0C;&#x5E76;&#x589E;&#x52A0; num_out &#x8BA1;&#x6570;&#x3002;

	if (vbr-&gt;sg_table.nents) {
		if (vbr-&gt;out_hdr.type &amp; cpu_to_virtio32(vq-&gt;vdev, VIRTIO_BLK_T_OUT)) // &#x5982;&#x679C;&#x662F;&#x5199;&#x4E8B;&#x4EF6;
			sgs[num_out++] = vbr-&gt;sg_table.sgl; // &#x5219;&#x5C06;&#x6570;&#x636E;&#x7F13;&#x51B2;&#x533A;&#x7684;scatterlist&#x6DFB;&#x52A0;&#x5230; sgs &#x6570;&#x7EC4;
		else
			sgs[num_out + num_in++] = vbr-&gt;sg_table.sgl;// &#x8BFB;&#x4E8B;&#x4EF6;&#x8981;&#x6308;&#x5E26;num_in
	}

	sg_init_one(&amp;in_hdr, &amp;vbr-&gt;in_hdr.status, vbr-&gt;in_hdr_len);
	sgs[num_out + num_in++] = &amp;in_hdr; // &#x5C06; in_hdr &#x6DFB;&#x52A0;&#x5230; sgs &#x6570;&#x7EC4;&#xFF0C;&#x5E76;&#x589E;&#x52A0; num_in &#x8BA1;&#x6570;&#x3002;

	return virtqueue_add_sgs(vq, sgs, num_out, num_in, vbr, GFP_ATOMIC);
}
</code></pre>
<p>&#x7136;&#x540E;&#x901A;&#x8FC7;<code>virtqueue_add_sgs</code>-&gt;<code>virtqueue_add</code>-&gt;<code>virtqueue_add_packed</code>/<code>virtqueue_add_split</code>&#x6765;&#x586B;&#x5145;&#x4E0A;&#x8FF0;&#x51C6;&#x5907;sgs&#x3002;</p>
<h4 id="332-notify%E5%90%8E%E7%AB%AF">3.3.2-notify&#x540E;&#x7AEF;</h4>
<p>&#x8FD9;&#x91CC;&#x7684;<code>virtqueue_notify</code>&#x4F1A;&#x8C03;&#x7528;&#x5728;&#x521B;&#x5EFA;<code>virtqueue</code>&#x65F6;&#x901A;&#x8FC7;<code>setup_vq</code>&#x7ED1;&#x5B9A;&#x7684;&#x901A;&#x77E5;&#x51FD;&#x6570;<code>vq-&gt;notify</code></p>
<p>&#x901A;&#x8FC7;<code>iowrite16</code>&#x5411;&#x540E;&#x7AEF;&#x8BBE;&#x5907;&#x7684;pci&#x914D;&#x7F6E;&#x7A7A;&#x95F4;&#x7684;&#x901A;&#x77E5;&#x5BC4;&#x5B58;&#x5668;&#x5199;&#x503C;&#x3002;</p>
<pre><code class="language-cpp">
/* the notify function used when creating a virt queue */
bool vp_notify(struct virtqueue *vq)
{
	/* we write the queue&apos;s selector into the notification register to
	 * signal the other end */
	iowrite16(vq-&gt;index, (void __iomem *)vq-&gt;priv);
	return true;
}
</code></pre>
<p>&#x5176;&#x4E2D;&#xFF0C;<code>vq-&gt;priv = (void __force *)vp_dev-&gt;ldev.ioaddr + VIRTIO_PCI_QUEUE_NOTIFY;</code>&#xFF08;drivers/virtio/virtio_pci_legacy.c&#xFF09;</p>
<p>&#x5728;&#x5199;&#x5B8C;&#x6210;&#x8FD9;&#x4E2A;&#x503C;&#x540E;&#xFF0C;&#x5219;&#x4F1A;&#x89E6;&#x53D1;<code>kvm_exit</code>&#x4E8B;&#x4EF6;&#xFF0C;&#x7136;&#x540E;qemu&#x5C31;&#x4F1A;&#x8FDB;&#x4E00;&#x6B65;&#x6267;&#x884C;<code>virtio</code>&#x7684;&#x540E;&#x7AEF;&#x8BBE;&#x5907;&#x64CD;&#x4F5C;&#x3002;</p>
<h4 id="333-%E5%90%8E%E7%AB%AF%E8%AE%BE%E5%A4%87%E5%A4%84%E7%90%86">3.3.3-&#x540E;&#x7AEF;&#x8BBE;&#x5907;&#x5904;&#x7406;</h4>
<p>QEMU&#x8FDB;&#x7A0B;&#x7684;kvm_main_loop_cpu&#x5FAA;&#x73AF;&#x7B49;&#x5F85;KVM_EXIT&#x7684;&#x4EA7;&#x751F;&#x3002;&#x5F53;&#x6709;&#x9000;&#x51FA;&#x4EA7;&#x751F;&#x65F6;&#xFF0C;&#x8C03;&#x7528;KVM_RUN&#x51FD;&#x6570;&#x6765;&#x786E;&#x5B9A;&#x9000;&#x51FA;&#x7684;&#x539F;&#x56E0;&#xFF0C;&#x5BF9;&#x4E8E;IO&#x64CD;&#x4F5C;&#x7684;&#x9000;&#x51FA;&#xFF0C;KVM_EXIT&#x4E3A;KVM_EXIT_IO&#x3002;</p>
<p>&#x5F53;&#x8FDB;&#x5165;&#x5230;host&#x540E;&#xFF0C;qemu&#x4F1A;&#x901A;&#x8FC7;&#x6CE8;&#x518C;&#x597D;&#x7684;&#x51FD;&#x6570;&#x5BF9;&#x524D;&#x7AEF;pci&#x8BBE;&#x5907;&#x53D1;&#x9001;&#x8FC7;&#x6765;&#x7684;&#x8BF7;&#x6C42;&#x8FDB;&#x884C;&#x5904;&#x7406;</p>
<p>qemu&#x4EE3;&#x7801;&#xFF1A;<code>hw/virtio/virtio-pci.c</code></p>
<pre><code class="language-cpp">static const MemoryRegionOps notify_ops = {
    .read = virtio_pci_notify_read, // &#x901A;&#x77E5;&#x5BC4;&#x5B58;&#x5668;&#x662F;&#x8BFB;&#x64CD;&#x4F5C;&#x65F6;
    .write = virtio_pci_notify_write, // &#x901A;&#x77E5;&#x5BC4;&#x5B58;&#x5668;&#x662F;&#x5199;&#x64CD;&#x4F5C;&#x65F6;
    .impl = {
        .min_access_size = 1,
        .max_access_size = 4,
    },
    .endianness = DEVICE_LITTLE_ENDIAN,
};
</code></pre>
<p>&#x8FDB;&#x4E00;&#x6B65;&#x8C03;&#x7528;<code>virtio_pci_notify_write</code>-&gt;<code>virtio_queue_notify</code>-&gt;<code>vq-&gt;handle_output</code>&#xFF0C;&#x5728;virtblk&#x4E2D;&#x88AB;&#x5B9A;&#x4E49;&#x6210;<code>virtio_blk_handle_output</code>(<code>virtio_add_queue(vdev, conf-&gt;queue_size, virtio_blk_handle_output);</code>)&#x3002;</p>
<p>&#x5728;<code>hw/block/virtio-blk.c</code>&#x4E2D;<code>virtio_blk_handle_request</code></p>
<pre><code class="language-cpp">static int virtio_blk_handle_request(VirtIOBlockReq *req, MultiReqBuffer *mrb)
{
  	uint32_t type;
    ......
    type = virtio_ldl_p(vdev, &amp;req-&gt;out.type); // &#x83B7;&#x53D6;req&#x7684;&#x7C7B;&#x578B;
    /* VIRTIO_BLK_T_OUT defines the command direction. VIRTIO_BLK_T_BARRIER
     * is an optional flag. Although a guest should not send this flag if
     * not negotiated we ignored it in the past. So keep ignoring it. */
    switch (type &amp; ~(VIRTIO_BLK_T_OUT | VIRTIO_BLK_T_BARRIER)) {
    case VIRTIO_BLK_T_IN: // &#x521D;&#x59CB;&#x5316;&#x547D;&#x4EE4;
    {
       ......
    }
    case VIRTIO_BLK_T_FLUSH: // flush&#x8BF7;&#x6C42;&#x547D;&#x4EE4;
        virtio_blk_handle_flush(req, mrb); // &#x628A;virtioblk req&#x5237;&#x65B0;
        break;
    ......
    default:
        virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP);
        virtio_blk_free_request(req);
    }
    return 0;
}
</code></pre>
<p>&#x8FDB;&#x4E00;&#x6B65;&#x8C03;&#x7528;<code>virtio_blk_handle_flush</code>-&gt;<code>virtio_blk_submit_multireq</code>-&gt;<code>submit_requests</code>-&gt;<code>blk_aio_pwritev</code></p>
<p>&#x6700;&#x7EC8;qemu&#x4F1A;&#x901A;&#x8FC7;&#x6587;&#x4EF6;&#x7CFB;&#x7EDF;&#x901A;&#x7528;&#x7684;&#x63A5;&#x53E3;&#x5B9E;&#x73B0;&#x5728;&#x5BBF;&#x4E3B;&#x673A;&#x5185;&#x7684;&#x8BFB;&#x5199;&#x3002;</p>
<h4 id="334-blkdone">3.3.4-blk_done</h4>
<p>&#x5F53;&#x5BBF;&#x4E3B;&#x673A;&#x7684;&#x6807;&#x51C6;io&#x8BFB;&#x5199;&#x5B8C;&#x6210;&#x540E;&#xFF0C;&#x5219;&#x4F1A;&#x901A;&#x8FC7;&#x4E4B;&#x524D;&#x7ED1;&#x5B9A;&#x597D;&#x7684;<code>virtio_blk_rw_complete</code>&#x6765;&#x5B8C;&#x6210;&#x8FDB;&#x4E00;&#x6B65;&#x901A;&#x77E5;&#xFF0C; &#x5E76;&#x901A;&#x8FC7;virtio_notify&#x5199;&#x56DE;&#x901A;&#x77E5;&#x5BC4;&#x5B58;&#x5668;&#xFF0C;&#x5411;&#x865A;&#x62DF;&#x673A;&#x5199;&#x5165;&#x4E2D;&#x65AD;&#x3002;</p>
<p>&#x5F53;&#x865A;&#x62DF;&#x673A;&#x63A5;&#x6536;&#x4E2D;&#x65AD;&#x540E;&#xFF0C;&#x56DE;&#x901A;&#x8FC7;vring_interrupt&#x6765;&#x5904;&#x7406;&#x4E2D;&#x65AD;&#x903B;&#x8F91;&#xFF0C;&#x5E76;&#x6700;&#x7EC8;&#x8C03;&#x7528;virtblk_done&#x6765;&#x5B8C;&#x6210;&#x8BBE;&#x5907;&#x9A71;&#x52A8;&#x8C03;&#x7528;&#xFF0C;&#x6700;&#x7EC8;&#x8FD4;&#x56DE;&#x7ED9;&#x865A;&#x62DF;&#x673A;&#x5185;&#x7684;&#x901A;&#x7528;&#x5757;&#x5C42;&#xFF0C;&#x6700;&#x7EC8;&#x5B8C;&#x6210;&#x672C;&#x6B21;&#x5B50;&#x673A;&#x5185;&#x7684;IO&#x64CD;&#x4F5C;&#x3002;</p>
<p><a href="https://www.cnblogs.com/edver/p/16255243.html?ref=korantli.com.cn">https://www.cnblogs.com/edver/p/16255243.html</a></p>
]]></content:encoded></item><item><title><![CDATA[东江湖]]></title><description><![CDATA[<p>&#x4E0D;&#x662F;&#xFF0C;&#x8FD9;&#x4E5F;&#x592A;&#x597D;&#x770B;&#x4E86;</p><figure class="kg-card kg-gallery-card kg-width-wide"><div class="kg-gallery-container"><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="http://www.korantli.com.cn/content/images/2024/07/DSC02089.JPG" width="2000" height="2568" loading="lazy" alt srcset="http://www.korantli.com.cn/content/images/size/w600/2024/07/DSC02089.JPG 600w, http://www.korantli.com.cn/content/images/size/w1000/2024/07/DSC02089.JPG 1000w, http://www.korantli.com.cn/content/images/size/w1600/2024/07/DSC02089.JPG 1600w, http://www.korantli.com.cn/content/images/size/w2400/2024/07/DSC02089.JPG 2400w" sizes="(min-width: 720px) 720px"></div><div class="kg-gallery-image"><img src="http://www.korantli.com.cn/content/images/2024/07/DSC02100.JPG" width="2000" height="2480" loading="lazy" alt srcset="http://www.korantli.com.cn/content/images/size/w600/2024/07/DSC02100.JPG 600w, http://www.korantli.com.cn/content/images/size/w1000/2024/07/DSC02100.JPG 1000w, http://www.korantli.com.cn/content/images/size/w1600/2024/07/DSC02100.JPG 1600w, http://www.korantli.com.cn/content/images/size/w2400/2024/07/DSC02100.JPG 2400w" sizes="(min-width: 720px) 720px"></div><div class="kg-gallery-image"><img src="http://www.korantli.com.cn/content/images/2024/07/DSC02138-1.JPG" width="2000" height="1373" loading="lazy" alt srcset="http://www.korantli.com.cn/content/images/size/w600/2024/07/DSC02138-1.JPG 600w, http://www.korantli.com.cn/content/images/size/w1000/2024/07/DSC02138-1.JPG 1000w, http://www.korantli.com.cn/content/images/size/w1600/2024/07/DSC02138-1.JPG 1600w, http://www.korantli.com.cn/content/images/size/w2400/2024/07/DSC02138-1.JPG 2400w" sizes="(min-width: 720px) 720px"></div></div><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="http://www.korantli.com.cn/content/images/2024/07/DSC02140.JPG" width="2000" height="3000" loading="lazy" alt srcset="http://www.korantli.com.cn/content/images/size/w600/2024/07/DSC02140.JPG 600w, http://www.korantli.com.cn/content/images/size/w1000/2024/07/DSC02140.JPG 1000w, http://www.korantli.com.cn/content/images/size/w1600/2024/07/DSC02140.JPG 1600w, http://www.korantli.com.cn/content/images/size/w2400/2024/07/DSC02140.JPG 2400w" sizes="(min-width: 720px) 720px"></div><div class="kg-gallery-image"><img src="http://www.korantli.com.cn/content/images/2024/07/DSC02149-1.JPG" width="2000" height="1143" loading="lazy" alt srcset="http://www.korantli.com.cn/content/images/size/w600/2024/07/DSC02149-1.JPG 600w, http://www.korantli.com.cn/content/images/size/w1000/2024/07/DSC02149-1.JPG 1000w, http://www.korantli.com.cn/content/images/size/w1600/2024/07/DSC02149-1.JPG 1600w, http://www.korantli.com.cn/content/images/size/w2400/2024/07/DSC02149-1.JPG 2400w" sizes="(min-width: 720px) 720px"></div><div class="kg-gallery-image"><img src="http://www.korantli.com.cn/content/images/2024/07/DSC02155.JPG" width="2000" height="3000" loading="lazy" alt srcset="http://www.korantli.com.cn/content/images/size/w600/2024/07/DSC02155.JPG 600w, http://www.korantli.com.cn/content/images/size/w1000/2024/07/DSC02155.JPG 1000w, http://www.korantli.com.cn/content/images/size/w1600/2024/07/DSC02155.JPG 1600w, http://www.korantli.com.cn/content/images/size/w2400/2024/07/DSC02155.JPG 2400w" sizes="(min-width: 720px) 720px"></div></div></div></figure>]]></description><link>http://www.korantli.com.cn/dong-jiang-hu/</link><guid isPermaLink="false">669735d22bc2afda5bd2ed41</guid><category><![CDATA[摄影]]></category><dc:creator><![CDATA[李星辉]]></dc:creator><pubDate>Wed, 17 Jul 2024 03:11:05 GMT</pubDate><media:content url="http://www.korantli.com.cn/content/images/2024/07/DSC02149--------1.JPG" medium="image"/><content:encoded><![CDATA[<img src="http://www.korantli.com.cn/content/images/2024/07/DSC02149--------1.JPG" alt="&#x4E1C;&#x6C5F;&#x6E56;"><p>&#x4E0D;&#x662F;&#xFF0C;&#x8FD9;&#x4E5F;&#x592A;&#x597D;&#x770B;&#x4E86;</p><figure class="kg-card kg-gallery-card kg-width-wide"><div class="kg-gallery-container"><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="http://www.korantli.com.cn/content/images/2024/07/DSC02089.JPG" width="2000" height="2568" loading="lazy" alt="&#x4E1C;&#x6C5F;&#x6E56;" srcset="http://www.korantli.com.cn/content/images/size/w600/2024/07/DSC02089.JPG 600w, http://www.korantli.com.cn/content/images/size/w1000/2024/07/DSC02089.JPG 1000w, http://www.korantli.com.cn/content/images/size/w1600/2024/07/DSC02089.JPG 1600w, http://www.korantli.com.cn/content/images/size/w2400/2024/07/DSC02089.JPG 2400w" sizes="(min-width: 720px) 720px"></div><div class="kg-gallery-image"><img src="http://www.korantli.com.cn/content/images/2024/07/DSC02100.JPG" width="2000" height="2480" loading="lazy" alt="&#x4E1C;&#x6C5F;&#x6E56;" srcset="http://www.korantli.com.cn/content/images/size/w600/2024/07/DSC02100.JPG 600w, http://www.korantli.com.cn/content/images/size/w1000/2024/07/DSC02100.JPG 1000w, http://www.korantli.com.cn/content/images/size/w1600/2024/07/DSC02100.JPG 1600w, http://www.korantli.com.cn/content/images/size/w2400/2024/07/DSC02100.JPG 2400w" sizes="(min-width: 720px) 720px"></div><div class="kg-gallery-image"><img src="http://www.korantli.com.cn/content/images/2024/07/DSC02138-1.JPG" width="2000" height="1373" loading="lazy" alt="&#x4E1C;&#x6C5F;&#x6E56;" srcset="http://www.korantli.com.cn/content/images/size/w600/2024/07/DSC02138-1.JPG 600w, http://www.korantli.com.cn/content/images/size/w1000/2024/07/DSC02138-1.JPG 1000w, http://www.korantli.com.cn/content/images/size/w1600/2024/07/DSC02138-1.JPG 1600w, http://www.korantli.com.cn/content/images/size/w2400/2024/07/DSC02138-1.JPG 2400w" sizes="(min-width: 720px) 720px"></div></div><div class="kg-gallery-row"><div class="kg-gallery-image"><img src="http://www.korantli.com.cn/content/images/2024/07/DSC02140.JPG" width="2000" height="3000" loading="lazy" alt="&#x4E1C;&#x6C5F;&#x6E56;" srcset="http://www.korantli.com.cn/content/images/size/w600/2024/07/DSC02140.JPG 600w, http://www.korantli.com.cn/content/images/size/w1000/2024/07/DSC02140.JPG 1000w, http://www.korantli.com.cn/content/images/size/w1600/2024/07/DSC02140.JPG 1600w, http://www.korantli.com.cn/content/images/size/w2400/2024/07/DSC02140.JPG 2400w" sizes="(min-width: 720px) 720px"></div><div class="kg-gallery-image"><img src="http://www.korantli.com.cn/content/images/2024/07/DSC02149-1.JPG" width="2000" height="1143" loading="lazy" alt="&#x4E1C;&#x6C5F;&#x6E56;" srcset="http://www.korantli.com.cn/content/images/size/w600/2024/07/DSC02149-1.JPG 600w, http://www.korantli.com.cn/content/images/size/w1000/2024/07/DSC02149-1.JPG 1000w, http://www.korantli.com.cn/content/images/size/w1600/2024/07/DSC02149-1.JPG 1600w, http://www.korantli.com.cn/content/images/size/w2400/2024/07/DSC02149-1.JPG 2400w" sizes="(min-width: 720px) 720px"></div><div class="kg-gallery-image"><img src="http://www.korantli.com.cn/content/images/2024/07/DSC02155.JPG" width="2000" height="3000" loading="lazy" alt="&#x4E1C;&#x6C5F;&#x6E56;" srcset="http://www.korantli.com.cn/content/images/size/w600/2024/07/DSC02155.JPG 600w, http://www.korantli.com.cn/content/images/size/w1000/2024/07/DSC02155.JPG 1000w, http://www.korantli.com.cn/content/images/size/w1600/2024/07/DSC02155.JPG 1600w, http://www.korantli.com.cn/content/images/size/w2400/2024/07/DSC02155.JPG 2400w" sizes="(min-width: 720px) 720px"></div></div></div></figure>]]></content:encoded></item><item><title><![CDATA[内存屏障]]></title><description><![CDATA[<h2 id="1%E3%80%81%E6%A6%82%E8%BF%B0">1&#x3001;&#x6982;&#x8FF0;</h2>
<p>&#x53C2;&#x8003;&#xFF1A;<a href="https://zhuanlan.zhihu.com/p/96001570?ref=korantli.com.cn">&#x5BF9;&#x4F18;&#x5316;&#x8BF4;&#x4E0D; - Linux &#x4E2D;&#x7684; Barrier</a></p>
<h3 id="11-loadstore">1.1-load/store</h3>
<p>&#x5728;&#x4ECB;&#x7ECD;&#x5185;&#x5B58;&#x5C4F;&#x969C;&#x524D;&#xFF0C;&#x8981;&#x5148;&#x4E86;&#x89E3;cpu&#x4E2D;&#x7684;load&#x548C;store&#x6982;&#x5FF5;&#x3002;&#x6B63;&#x5E38;&#x6765;&#x8BF4;&#xFF0C;&#x64CD;&#x4F5C;&#x7CFB;</p>]]></description><link>http://www.korantli.com.cn/linux/nei-cun-ping-zhang/</link><guid isPermaLink="false">65c090ea2bc2afda5bd2ecf1</guid><category><![CDATA[linux内存管理]]></category><category><![CDATA[linux技术总结]]></category><dc:creator><![CDATA[李星辉]]></dc:creator><pubDate>Mon, 05 Feb 2024 07:41:21 GMT</pubDate><content:encoded><![CDATA[<h2 id="1%E3%80%81%E6%A6%82%E8%BF%B0">1&#x3001;&#x6982;&#x8FF0;</h2>
<p>&#x53C2;&#x8003;&#xFF1A;<a href="https://zhuanlan.zhihu.com/p/96001570?ref=korantli.com.cn">&#x5BF9;&#x4F18;&#x5316;&#x8BF4;&#x4E0D; - Linux &#x4E2D;&#x7684; Barrier</a></p>
<h3 id="11-loadstore">1.1-load/store</h3>
<p>&#x5728;&#x4ECB;&#x7ECD;&#x5185;&#x5B58;&#x5C4F;&#x969C;&#x524D;&#xFF0C;&#x8981;&#x5148;&#x4E86;&#x89E3;cpu&#x4E2D;&#x7684;load&#x548C;store&#x6982;&#x5FF5;&#x3002;&#x6B63;&#x5E38;&#x6765;&#x8BF4;&#xFF0C;&#x64CD;&#x4F5C;&#x7CFB;&#x7EDF;&#x4E2D;&#x7684;&#x6570;&#x636E;&#x7ED3;&#x6784;&#x662F;&#x5B58;&#x653E;&#x5728;&#x5185;&#x5B58;&#x4E0A;&#x7684;&#xFF0C;&#x800C;&#x5185;&#x5B58;&#x53C8;&#x5206;l1-l3 cache&#x548C;&#x4E3B;&#x5B58;&#xFF0C;&#x90A3;&#x4E48;&#x5F53;CPU&#x5BF9;&#x6570;&#x636E;&#x7ED3;&#x6784;&#x8FDB;&#x884C;&#x8BFB;&#x5199;&#x64CD;&#x4F5C;&#x7684;&#x65F6;&#x5019;&#xFF0C;&#x5C31;&#x9700;&#x8981;&#x5148;&#x5C06;&#x5185;&#x5B58;&#x4E2D;&#x7684;&#x6570;&#x636E;load&#x5230;cache&#x4E0A;&#xFF0C;&#x6700;&#x540E;&#x518D;load&#x5230;cpu&#x7684;&#x5BC4;&#x5B58;&#x5668;&#x5185;&#x3002;</p>
<p>&#x800C;&#x60F3;&#x8981;&#x4FEE;&#x6539;&#x6570;&#x636E;&#x65F6;&#xFF0C;&#x5219;&#x9700;&#x8981;&#x5C06;&#x7279;&#x5B9A;&#x5BC4;&#x5B58;&#x5668;&#x5185;&#x7684;&#x503C;&#x5199;&#x5165;&#x5230;&#x6307;&#x5B9A;&#x7684;cache&#x5730;&#x5740;&#x4E0A;&#xFF0C;&#x518D;&#x5728;&#x5408;&#x9002;&#x7684;&#x5B9E;&#x9645;&#x5C06;&#x4ED6;&#x5199;&#x56DE;&#x4E3B;&#x5B58;&#x4E2D;&#xFF0C;&#x8FD9;&#x5C31;&#x662F;store&#x64CD;&#x4F5C;&#x3002;</p>
<ul>
<li>Load&#xFF1A;Load&#x64CD;&#x4F5C;&#x662F;&#x5C06;&#x6570;&#x636E;&#x4ECE;&#x8BA1;&#x7B97;&#x673A;&#x7684;&#x5185;&#x5B58;&#x4E2D;&#x8BFB;&#x53D6;&#x5230;CPU&#x7684;&#x5BC4;&#x5B58;&#x5668;&#x4E2D;&#x3002;&#x8FD9;&#x662F;&#x4E00;&#x4E2A;&#x8BFB;&#x64CD;&#x4F5C;&#x3002;</li>
<li>Store&#xFF1A;Store&#x64CD;&#x4F5C;&#x662F;&#x5C06;&#x6570;&#x636E;&#x4ECE;CPU&#x7684;&#x5BC4;&#x5B58;&#x5668;&#x5199;&#x5165;&#x5230;&#x8BA1;&#x7B97;&#x673A;&#x7684;&#x5185;&#x5B58;&#x4E2D;&#x3002;&#x8FD9;&#x662F;&#x4E00;&#x4E2A;&#x5199;&#x64CD;&#x4F5C;&#x3002;</li>
</ul>
<p>&#x56E0;&#x6B64;&#x8FD9;&#x91CC;&#x5C31;&#x51FA;&#x73B0;&#x4E86;&#x663E;&#x800C;&#x6613;&#x89C1;&#x7684;&#x95EE;&#x9898;&#xFF1A;&#x5185;&#x5B58;&#x4E00;&#x81F4;&#x6027;&#x3002;</p>
<p>&#x5728;&#x5176;&#x4ED6;&#x6838;&#x5FC3;&#x8BFB;&#x5199;&#x4E00;&#x4E2A;&#x6570;&#x636E;&#x65F6;&#xFF0C;&#x53E6;&#x5916;&#x4E00;&#x4E2A;&#x6838;&#x5FC3;&#x53EF;&#x80FD;&#x4E5F;&#x5728;&#x540C;&#x6B65;&#x8BFB;&#x5199;&#xFF0C;&#x5E76;&#x4E14;&#x53EF;&#x80FD;&#x5DF2;&#x7ECF;&#x5C06;&#x4FEE;&#x6539;&#x540E;&#x7684;&#x6570;&#x636E;&#x5199;&#x5165;&#x5230;&#x4E86;&#x81EA;&#x5DF1;&#x8BFB;&#x4E66;&#x7684;cache&#x4E2D;&#x3002;&#x56E0;&#x6B64;&#xFF0C;&#x6211;&#x4EEC;&#x9700;&#x8981;&#x4E00;&#x79CD;&#x673A;&#x5236;&#x6765;&#x4FDD;&#x8BC1;&#x5185;&#x5B58;&#x4E00;&#x81F4;&#x6027;&#x3002;</p>
<h3 id="12-%E5%86%85%E5%AD%98%E6%A8%A1%E5%9E%8B">1.2-&#x5185;&#x5B58;&#x6A21;&#x578B;</h3>
<p>&#x6211;&#x4EEC;&#x4E86;&#x89E3;&#x4E86;&#x4E0A;&#x8FF0;&#x4E24;&#x79CD;&#x57FA;&#x7840;&#x7684;&#x547D;&#x4EE4;&#x64CD;&#x4F5C;&#x4F5C;&#x7528;&#xFF0C;&#x6839;&#x636E;&#x5BF9;load&#x548C;store&#x547D;&#x4EE4;&#x7684;&#x6267;&#x884C;&#x987A;&#x5E8F;&#x53EF;&#x4EE5;&#x5206;&#x4E24;&#x79CD;&#x6A21;&#x578B;&#xFF0C;&#x800C;&#x6070;&#x597D;x86&#x548C;arm64&#x5C31;&#x5206;&#x522B;&#x662F;&#x4E24;&#x79CD;&#x3002;</p>
<ul>
<li>&#x5F3A;&#x5185;&#x5B58;&#x5E8F;&#x6A21;&#x578B;&#xFF08;x86&#xFF09;&#xFF1A;&#x5728;&#x5F3A;&#x5185;&#x5B58;&#x5E8F;&#x6A21;&#x578B;&#x4E2D;&#xFF0C;&#x5904;&#x7406;&#x5668;&#x4FDD;&#x8BC1;&#x4E86;&#x5728;&#x5355;&#x4E2A;&#x5904;&#x7406;&#x5668;&#x4E0A;&#x770B;&#x5230;&#x7684;&#x5185;&#x5B58;&#x64CD;&#x4F5C;&#x7684;&#x987A;&#x5E8F;&#x4E0E;&#x7A0B;&#x5E8F;&#x4E2D;&#x6307;&#x5B9A;&#x7684;&#x987A;&#x5E8F;&#x4E00;&#x81F4;&#x3002;&#x8FD9;&#x610F;&#x5473;&#x7740;&#x5904;&#x7406;&#x5668;&#x548C;&#x7F16;&#x8BD1;&#x5668;&#x5728;&#x4F18;&#x5316;&#x65F6;&#xFF0C;&#x4E0D;&#x80FD;&#x6539;&#x53D8;&#x5728;&#x5355;&#x4E2A;&#x5904;&#x7406;&#x5668;&#x4E0A;&#x770B;&#x5230;&#x7684;&#x5185;&#x5B58;&#x64CD;&#x4F5C;&#x7684;&#x987A;&#x5E8F;&#x3002;&#x5373;load&#x548C;store&#x7684;&#x547D;&#x4EE4;&#x4E0D;&#x53EF;&#x4EE5;&#x968F;&#x673A;&#x4E92;&#x6362;&#xFF0C;&#x53EA;&#x6709;store&#x53EF;&#x4EE5;&#x5728;&#x5FC5;&#x8981;&#x7684;&#x65F6;&#x5019;&#x53EF;&#x4EE5;&#x88AB;load&#x547D;&#x4EE4;&#x63D0;&#x524D;&#x6267;&#x884C;&#x3002;</li>
<li>&#x5BBD;&#x677E;&#x5185;&#x5B58;&#x6A21;&#x578B;&#xFF08;arm64&#xFF09;&#xFF1A;&#x5728;&#x5BBD;&#x677E;&#xFF08;&#x6216;&#x5F31;&#xFF09;&#x5185;&#x5B58;&#x5E8F;&#x6A21;&#x578B;&#x4E2D;&#xFF0C;&#x5904;&#x7406;&#x5668;&#x548C;&#x7F16;&#x8BD1;&#x5668;&#x53EF;&#x4EE5;&#x5728;&#x4E00;&#x5B9A;&#x7A0B;&#x5EA6;&#x4E0A;&#x6539;&#x53D8;&#x5185;&#x5B58;&#x64CD;&#x4F5C;&#x7684;&#x987A;&#x5E8F;&#x3002;&#x4F8B;&#x5982;&#xFF0C;&#x5982;&#x679C;&#x4E24;&#x4E2A;&#x5185;&#x5B58;&#x64CD;&#x4F5C;&#x4E0D;&#x4F9D;&#x8D56;&#x4E8E;&#x5F7C;&#x6B64;&#xFF0C;&#x90A3;&#x4E48;&#x5904;&#x7406;&#x5668;&#x548C;&#x7F16;&#x8BD1;&#x5668;&#x53EF;&#x4EE5;&#x6539;&#x53D8;&#x5B83;&#x4EEC;&#x7684;&#x6267;&#x884C;&#x987A;&#x5E8F;&#xFF0C;&#x4EE5;&#x63D0;&#x9AD8;&#x6267;&#x884C;&#x6548;&#x7387;&#x3002;&#x5373;load&#x548C;store&#x7684;&#x547D;&#x4EE4;&#x53EF;&#x4EE5;&#x5728;&#x6709;&#x5FC5;&#x8981;&#x7684;&#x65F6;&#x5019;&#x4EFB;&#x610F;&#x4E92;&#x6362;&#x6267;&#x884C;&#x987A;&#x5E8F;&#x3002;</li>
</ul>
<p>&#x800C;&#x5BF9;&#x4E8E;&#x4E0A;&#x8FF0;&#x4E2D;&#x7684;&#x5FC5;&#x987B;&#x60C5;&#x51B5;&#x5C31;&#x662F;&#x662F;&#x5426;&#x5B58;&#x5728;<code>&#x4F9D;&#x8D56;&#x5173;&#x7CFB;</code>&#xFF0C;&#x5373;&#x4F8B;&#x5982;&#x4E0B;&#x5217;&#x60C5;&#x51B5;</p>
<pre><code class="language-cpp">x=1
y=x
</code></pre>
<p>&#x800C;&#x4F9D;&#x8D56;&#x5173;&#x7CFB;&#x53C8;&#x5927;&#x81F4;&#x5206;&#x4E3A;</p>
<ul>
<li>&#x6570;&#x636E;&#x4F9D;&#x8D56;&#xFF1A;&#x4E0A;&#x8FF0;&#x4F8B;&#x5B50;</li>
<li>&#x63A7;&#x5236;&#x4F9D;&#x8D56;&#xFF1A;if&#x5224;&#x65AD;</li>
<li>&#x8D44;&#x6E90;&#x4F9D;&#x8D56;&#xFF1A;&#x6307;&#x4EE4;&#x4F7F;&#x7528;&#x76F8;&#x540C;&#x7684;&#x786C;&#x4EF6;&#x8D44;&#x6E90;</li>
</ul>
<h3 id="13-%E5%86%85%E5%AD%98%E5%B1%8F%E9%9A%9C">1.3-&#x5185;&#x5B58;&#x5C4F;&#x969C;</h3>
<p>&#x5185;&#x6838;&#x4E2D;&#x5F88;&#x591A;&#x4EE3;&#x7801;&#x90FD;&#x5B58;&#x5728;&#x5185;&#x5B58;&#x5C4F;&#x969C;&#x7684;&#x8FD9;&#x4E2A;&#x6982;&#x5FF5;&#xFF0C;&#x5185;&#x5B58;&#x5C4F;&#x969C;&#x662F;&#x4E00;&#x79CD;&#x540C;&#x6B65;&#x539F;&#x8BED;&#xFF0C;&#x4E3B;&#x8981;&#x7528;&#x4E8E;&#x591A;&#x5904;&#x7406;&#x5668;&#x548C;&#x591A;&#x7EBF;&#x7A0B;&#x73AF;&#x5883;&#x4E2D;&#x5BF9;&#x5185;&#x5B58;&#x8BBF;&#x95EE;&#x7684;&#x987A;&#x5E8F;&#x8FDB;&#x884C;&#x63A7;&#x5236;&#x3002;&#x5185;&#x5B58;&#x5C4F;&#x969C;&#x53EF;&#x4EE5;&#x786E;&#x4FDD;&#x7279;&#x5B9A;&#x7684;&#x5185;&#x5B58;&#x64CD;&#x4F5C;&#x6309;&#x7167;&#x9884;&#x671F;&#x7684;&#x987A;&#x5E8F;&#x6267;&#x884C;&#xFF0C;&#x9632;&#x6B62;&#x7F16;&#x8BD1;&#x5668;&#x548C;&#x5904;&#x7406;&#x5668;&#x5BF9;&#x6307;&#x4EE4;&#x8FDB;&#x884C;&#x4E0D;&#x7B26;&#x5408;&#x9884;&#x671F;&#x7684;&#x4F18;&#x5316;&#x548C;&#x91CD;&#x6392;&#x5E8F;&#x3002;</p>
<p>&#x5728;&#x591A;&#x5904;&#x7406;&#x5668;&#x548C;&#x591A;&#x7EBF;&#x7A0B;&#x73AF;&#x5883;&#x4E2D;&#xFF0C;&#x7F16;&#x8BD1;&#x5668;&#x548C;&#x5904;&#x7406;&#x5668;&#x53EF;&#x80FD;&#x4F1A;&#x5BF9;&#x6307;&#x4EE4;&#x8FDB;&#x884C;&#x4F18;&#x5316;&#x548C;&#x91CD;&#x6392;&#x5E8F;&#xFF0C;&#x4EE5;&#x63D0;&#x9AD8;&#x6267;&#x884C;&#x6548;&#x7387;&#x3002;&#x7136;&#x800C;&#xFF0C;&#x8FD9;&#x79CD;&#x4F18;&#x5316;&#x548C;&#x91CD;&#x6392;&#x5E8F;&#x53EF;&#x80FD;&#x4F1A;&#x5BFC;&#x81F4;&#x5185;&#x5B58;&#x64CD;&#x4F5C;&#x7684;&#x987A;&#x5E8F;&#x4E0E;&#x7A0B;&#x5E8F;&#x5458;&#x539F;&#x672C;&#x9884;&#x671F;&#x7684;&#x987A;&#x5E8F;&#x4E0D;&#x4E00;&#x81F4;&#xFF0C;&#x4ECE;&#x800C;&#x5F15;&#x53D1;&#x7ADE;&#x6001;&#x6761;&#x4EF6;&#x548C;&#x5176;&#x4ED6;&#x540C;&#x6B65;&#x95EE;&#x9898;&#x3002;&#x4E3A;&#x4E86;&#x89E3;&#x51B3;&#x8FD9;&#x4E2A;&#x95EE;&#x9898;&#xFF0C;&#x5185;&#x5B58;&#x5C4F;&#x969C;&#x88AB;&#x5F15;&#x5165;&#xFF0C;&#x4F5C;&#x4E3A;&#x4E00;&#x79CD;&#x540C;&#x6B65;&#x673A;&#x5236;&#xFF0C;&#x786E;&#x4FDD;&#x5185;&#x5B58;&#x64CD;&#x4F5C;&#x6309;&#x7167;&#x9884;&#x671F;&#x7684;&#x987A;&#x5E8F;&#x6267;&#x884C;&#x3002;</p>
<p>&#x5185;&#x5B58;&#x5C4F;&#x969C;&#x4E3B;&#x8981;&#x5206;&#x4E3A;&#x4EE5;&#x4E0B;&#x51E0;&#x7C7B;&#xFF1A;</p>
<ol>
<li>Load&#xFF08;&#x8BFB;&#xFF09;&#x5C4F;&#x969C;&#xFF1A;&#x786E;&#x4FDD;&#x5C4F;&#x969C;&#x4E4B;&#x524D;&#x7684;&#x8BFB;&#x64CD;&#x4F5C;&#x5728;&#x5C4F;&#x969C;&#x4E4B;&#x540E;&#x7684;&#x8BFB;&#x64CD;&#x4F5C;&#x4E4B;&#x524D;&#x5B8C;&#x6210;&#x3002;</li>
<li>Store&#xFF08;&#x5199;&#xFF09;&#x5C4F;&#x969C;&#xFF1A;&#x786E;&#x4FDD;&#x5C4F;&#x969C;&#x4E4B;&#x524D;&#x7684;&#x5199;&#x64CD;&#x4F5C;&#x5728;&#x5C4F;&#x969C;&#x4E4B;&#x540E;&#x7684;&#x5199;&#x64CD;&#x4F5C;&#x4E4B;&#x524D;&#x5B8C;&#x6210;&#x3002;</li>
<li>Full&#xFF08;&#x5168;&#xFF09;&#x5C4F;&#x969C;&#xFF1A;&#x540C;&#x65F6;&#x5177;&#x6709;Load&#x5C4F;&#x969C;&#x548C;Store&#x5C4F;&#x969C;&#x7684;&#x529F;&#x80FD;&#xFF0C;&#x786E;&#x4FDD;&#x5C4F;&#x969C;&#x4E4B;&#x524D;&#x7684;&#x8BFB;&#x5199;&#x64CD;&#x4F5C;&#x5728;&#x5C4F;&#x969C;&#x4E4B;&#x540E;&#x7684;&#x8BFB;&#x5199;&#x64CD;&#x4F5C;&#x4E4B;&#x524D;&#x5B8C;&#x6210;&#x3002;</li>
</ol>
<p>&#x800C;&#x5185;&#x5B58;&#x5C4F;&#x969C;&#x7684;&#x5B9E;&#x73B0;&#x4E0E;CPU&#x7ED3;&#x6784;&#x76F8;&#x5173;&#xFF0C;&#x6211;&#x4EEC;&#x8FD9;&#x91CC;&#x4E3B;&#x8981;&#x5206;&#x6790;x86&#x548C;arm&#x4E24;&#x79CD;&#x3002;</p>
<h2 id="2%E3%80%81barrier%E7%BC%96%E8%AF%91%E5%B1%8F%E9%9A%9C">2&#x3001;<code>barrier()</code>&#x7F16;&#x8BD1;&#x5C4F;&#x969C;</h2>
<h3 id="21-%E5%8E%9F%E7%90%86">2.1-&#x539F;&#x7406;</h3>
<p>&#x6211;&#x4EEC;&#x8BF4;&#x5230;&#xFF0C;&#x5176;&#x5B9E;&#x6211;&#x4EEC;&#x5173;&#x5FC3;&#x7684;&#x5185;&#x5B58;&#x5C4F;&#x969C;&#x66F4;&#x591A;&#x662F;&#x5728;&#x591A;&#x6838;&#x7CFB;&#x7EDF;&#x4E2D;&#xFF0C;&#x4F46;&#x662F;&#x5728;&#x5185;&#x6838;&#x4E2D;&#x63D0;&#x4F9B;&#x4E86;&#x4E00;&#x7EC4;&#x975E;smp&#x67B6;&#x6784;&#x7684;&#x5185;&#x5B58;&#x5C4F;&#x969C;&#x63A5;&#x53E3;</p>
<pre><code class="language-cpp">#else	/* !CONFIG_SMP */

#ifndef smp_mb
#define smp_mb()	barrier()
#endif

#ifndef smp_rmb
#define smp_rmb()	barrier()
#endif

#ifndef smp_wmb
#define smp_wmb()	barrier()
#endif

#endif	/* CONFIG_SMP */
</code></pre>
<p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;&#x8FD9;&#x91CC;&#x6240;&#x6709;&#x7684;&#x8BFB;&#x5199;&#x5C4F;&#x969C;&#x6700;&#x7EC8;&#x90FD;&#x88AB;&#x5B9A;&#x4E49;&#x6210;&#x4E86;<code>barrier()</code></p>
<pre><code class="language-cpp"># define barrier() __asm__ __volatile__(&quot;&quot;: : :&quot;memory&quot;)
</code></pre>
<p>&#x53EF;&#x4EE5;&#x770B;&#x5230;<code>barrier</code>&#x7684;&#x5B9E;&#x73B0;&#x5C31;&#x662F;&#x4E00;&#x6761;<code>memory</code>&#x6C47;&#x7F16;&#xFF0C;&#x4F5C;&#x7528;&#x662F;&#x7F16;&#x8BD1;&#x5668;&#x5185;&#x5B58;&#x5C4F;&#x969C;&#xFF0C;&#x9632;&#x6B62;&#x7F16;&#x8BD1;&#x5668;&#x5BF9;&#x5176;&#x524D;&#x540E;&#x7684;&#x4EE3;&#x7801;&#x8FDB;&#x884C;&#x6307;&#x4EE4;&#x91CD;&#x6392;&#x5E8F;&#x4F18;&#x5316;&#x3002;&#x5728;&#x7F16;&#x8BD1;&#x7A0B;&#x5E8F;&#x65F6;&#xFF0C;&#x4E3A;&#x4E86;&#x63D0;&#x9AD8;&#x7A0B;&#x5E8F;&#x7684;&#x8FD0;&#x884C;&#x6548;&#x7387;&#xFF0C;&#x7F16;&#x8BD1;&#x5668;&#x4F1A;&#x5C1D;&#x8BD5;&#x5BF9;&#x4EE3;&#x7801;&#x8FDB;&#x884C;&#x4F18;&#x5316;&#xFF0C;&#x5176;&#x4E2D;&#x4E00;&#x79CD;&#x4F18;&#x5316;&#x624B;&#x6BB5;&#x5C31;&#x662F;&#x6307;&#x4EE4;&#x91CD;&#x6392;&#x5E8F;&#x3002;&#x800C;<code>memory</code>&#x6C47;&#x7F16;&#x5219;&#x4F1A;&#x5F3A;&#x5236;&#x7F16;&#x8BD1;&#x5668;&#x6309;&#x7167;C&#x8BED;&#x8A00;&#x4E2D;&#x4EE3;&#x7801;&#x5199;&#x7684;&#x987A;&#x5E8F;&#x7F16;&#x8BD1;&#x3002;</p>
<p><code>: : : &quot;memory&quot;</code>&#x8FD9;&#x662F;&#x5185;&#x8054;&#x6C47;&#x7F16;&#x7684;&#x8F93;&#x5165;&#x3001;&#x8F93;&#x51FA;&#x548C;&#x6C47;&#x7F16;&#x7EA6;&#x675F;&#x90E8;&#x5206;&#x3002;&#x8FD9;&#x6BB5;&#x4EE3;&#x7801;&#x6CA1;&#x6709;&#x8F93;&#x5165;&#x548C;&#x8F93;&#x51FA;&#xFF0C;&#x4F46;&#x63D0;&#x4F9B;&#x4E86;&#x4E00;&#x4E2A;&#x6C47;&#x7F16;&#x7EA6;&#x675F;&quot;memory&quot;&#x3002;&quot;memory&quot;&#x7EA6;&#x675F;&#x544A;&#x8BC9;&#x7F16;&#x8BD1;&#x5668;&#xFF0C;&#x8FD9;&#x4E2A;&#x5185;&#x8054;&#x6C47;&#x7F16;&#x6307;&#x4EE4;&#x53EF;&#x80FD;&#x4F1A;&#x8BFB;&#x5199;&#x5185;&#x5B58;&#xFF0C;&#x56E0;&#x6B64;&#x7F16;&#x8BD1;&#x5668;&#x5FC5;&#x987B;&#x786E;&#x4FDD;&#x5728;&#x8FD9;&#x4E2A;&#x6307;&#x4EE4;&#x4E4B;&#x524D;&#x7684;&#x6240;&#x6709;&#x5185;&#x5B58;&#x8BBF;&#x95EE;&#x5DF2;&#x7ECF;&#x5B8C;&#x6210;&#xFF0C;&#x540C;&#x65F6;&#x5728;&#x8FD9;&#x4E2A;&#x6307;&#x4EE4;&#x4E4B;&#x540E;&#x7684;&#x6240;&#x6709;&#x5185;&#x5B58;&#x8BBF;&#x95EE;&#x8FD8;&#x6CA1;&#x6709;&#x5F00;&#x59CB;&#x3002;&#x8FD9;&#x5C31;&#x521B;&#x5EFA;&#x4E86;&#x4E00;&#x4E2A;&#x7F16;&#x8BD1;&#x5668;&#x5C4F;&#x969C;&#xFF0C;&#x963B;&#x6B62;&#x4E86;&#x7F16;&#x8BD1;&#x5668;&#x5BF9;&#x524D;&#x540E;&#x4EE3;&#x7801;&#x8FDB;&#x884C;&#x91CD;&#x6392;&#x5E8F;&#x4F18;&#x5316;&#x3002;</p>
<h3 id="22-%E6%A0%97%E5%AD%90">2.2-&#x6817;&#x5B50;</h3>
<pre><code class="language-cpp">int flag = 0;
int data = 0;

void thread1() {
    data = 1;
    flag = 1;
}

void thread2() {
    if (flag == 1) {
        printf(&quot;%d\n&quot;, data);
    }
}
</code></pre>
<p>&#x8FD9;&#x6BB5;&#x4EE3;&#x7801;&#x4E2D;&#x6211;&#x4EEC;&#x6765;&#x662F;&#x671F;&#x671B;<code>data=1</code>&#x4E4B;&#x540E;<code>flag=1</code>&#xFF0C;&#x90A3;&#x4E48;&#x6B64;&#x65F6;&#x8BC1;&#x660E;&#x53EA;&#x8981;&#x901A;&#x8FC7;<code>flag == 1</code>&#x7684;&#x65F6;&#x5019;&#x6253;&#x5370;&#x7684;&#x5185;&#x5BB9;&#x90FD;&#x662F;<code>1</code>&#x3002;</p>
<p>&#x7136;&#x800C;&#xFF0C;&#x7531;&#x4E8E;&#x7F16;&#x8BD1;&#x5668;&#x5B58;&#x5728;&#x4F18;&#x5316;&#x7684;&#x53EF;&#x80FD;&#xFF0C;&#x90A3;&#x4E48;&#x53EF;&#x80FD;<code>flag=1</code>&#x88AB;&#x8C03;&#x6574;&#x5230;&#x4E86;<code>data=1</code>&#x4E4B;&#x524D;&#xFF0C;&#x90A3;&#x4E48;&#x6B64;&#x65F6;&#x6253;&#x5370;&#x7684;&#x5185;&#x5BB9;&#x5C31;&#x4F1A;&#x51FA;&#x73B0;&#x95EE;&#x9898;&#x3002;&#x56E0;&#x6B64;&#x6211;&#x4EEC;&#x5728;&#x5173;&#x952E;&#x7684;&#x8282;&#x70B9;&#x4E2D;&#x9700;&#x8981;</p>
<pre><code class="language-cpp">void thread1() {
    data = 1;
    barrier();
    flag = 1;
}
</code></pre>
<p>&#x8FD9;&#x6837;&#xFF0C;barrier()&#x5C31;&#x786E;&#x4FDD;&#x4E86;data = 1;&#x8FD9;&#x6761;&#x8BED;&#x53E5;&#x5728;flag = 1;&#x4E4B;&#x524D;&#x6267;&#x884C;&#xFF0C;&#x9632;&#x6B62;&#x4E86;&#x7F16;&#x8BD1;&#x5668;&#x7684;&#x91CD;&#x6392;&#x5E8F;&#x3002;&#x8FD9;&#x6837;&#x6211;&#x4EEC;&#x5C31;&#x53EF;&#x4EE5;&#x786E;&#x4FDD;&#xFF0C;&#x5F53;thread2&#x770B;&#x5230;flag&#x4E3A;1&#x65F6;&#xFF0C;data&#x5DF2;&#x7ECF;&#x88AB;&#x8BBE;&#x7F6E;&#x4E3A;1&#xFF0C;&#x4ECE;&#x800C;&#x6253;&#x5370;&#x51FA;&#x6B63;&#x786E;&#x7684;&#x503C;&#x3002;</p>
<h2 id="3%E3%80%81%E5%85%A8%E5%B1%80%E5%86%85%E5%AD%98%E6%8C%87%E4%BB%A4%E5%B1%8F%E9%9A%9C">3&#x3001;&#x5168;&#x5C40;&#x5185;&#x5B58;&#x6307;&#x4EE4;&#x5C4F;&#x969C;</h2>
<p>&#x5BF9;&#x4E8E;&#x5F3A;&#x5236;&#x5168;&#x5C40;CPU&#x4E2D;&#x7684;&#x5185;&#x5B58;&#x6307;&#x4EE4;&#x7684;&#x6267;&#x884C;&#x987A;&#x5E8F;&#xFF0C;&#x5185;&#x6838;&#x63D0;&#x4F9B;&#x4E86;&#x8FD9;&#x6837;&#x4E00;&#x5957;&#x901A;&#x7528;&#x63A5;&#x53E3;</p>
<pre><code class="language-cpp">#ifdef __mb
#define mb()	do { kcsan_mb(); __mb(); } while (0)
#endif

#ifdef __rmb
#define rmb()	do { kcsan_rmb(); __rmb(); } while (0)
#endif

#ifdef __wmb
#define wmb()	do { kcsan_wmb(); __wmb(); } while (0)
#endif
</code></pre>
<p>&#x5176;&#x4E2D;&#x5982;&#x679C;&#x5F00;&#x542F;&#x4E86;<code>KCSAN</code>&#xFF08;KCSAN&#x662F;&#x4E00;&#x4E2A;&#x7528;&#x4E8E;&#x68C0;&#x6D4B;&#x5185;&#x6838;&#x4E2D;&#x6570;&#x636E;&#x7ADE;&#x4E89;&#x7684;&#x52A8;&#x6001;&#x5206;&#x6790;&#x5DE5;&#x5177;&#x3002;&#xFF09;&#x529F;&#x80FD;&#x7684;&#x64CD;&#x4F5C;&#x7CFB;&#x7EDF;&#xFF0C;&#x5219;&#x4F1A;&#x5F3A;&#x5236;&#x5237;&#x65B0;&#x5B58;&#x50A8;&#x5668;&#x5C4F;&#x969C;&#xFF0C;&#x786E;&#x4FDD;&#x5185;&#x5B58;&#x64CD;&#x4F5C;&#x6309;&#x7167;&#x9884;&#x671F;&#x987A;&#x5E8F;&#x6267;&#x884C;&#x3002;&#xFF08;&#x914D;&#x7F6E;CONFIG_KCSAN=y&#xFF09;</p>
<h3 id="31-x86">3.1-x86</h3>
<p>&#x5BF9;&#x4E8E;x86-64&#x6765;&#x8BF4;&#xFF0C;&#x8FD9;&#x79CD;&#x63A5;&#x53E3;&#x6700;&#x7EC8;&#x5B9E;&#x73B0;&#x5982;&#x4E0B;</p>
<pre><code class="language-cpp">#define __mb()	asm volatile(&quot;mfence&quot;:::&quot;memory&quot;)
#define __rmb()	asm volatile(&quot;lfence&quot;:::&quot;memory&quot;)
#define __wmb()	asm volatile(&quot;sfence&quot; ::: &quot;memory&quot;)
</code></pre>
<ol>
<li><code>MFENCE</code> (Memory Fence)&#xFF1A;&#x8FD9;&#x662F;&#x4E00;&#x4E2A;&#x5168;&#x5185;&#x5B58;&#x5C4F;&#x969C;&#xFF0C;&#x5B83;&#x786E;&#x4FDD;&#x6240;&#x6709;&#x4E4B;&#x524D;&#x7684;&#x8BFB;&#x53D6;&#xFF08;load&#xFF09;&#x548C;&#x5199;&#x5165;&#xFF08;store&#xFF09;&#x64CD;&#x4F5C;&#x5728;<code>MFENCE</code>&#x4E4B;&#x540E;&#x7684;&#x8BFB;&#x53D6;&#x548C;&#x5199;&#x5165;&#x64CD;&#x4F5C;&#x4E4B;&#x524D;&#x5B8C;&#x6210;&#x3002;&#x6362;&#x53E5;&#x8BDD;&#x8BF4;&#xFF0C;<code>MFENCE</code>&#x4FDD;&#x8BC1;&#x4E86;&#x5728;&#x6240;&#x6709;&#x5904;&#x7406;&#x5668;&#x4E0A;&#x770B;&#x5230;&#x7684;&#x5185;&#x5B58;&#x64CD;&#x4F5C;&#x987A;&#x5E8F;&#x4E0E;&#x5C4F;&#x969C;&#x4E4B;&#x524D;&#x7684;&#x64CD;&#x4F5C;&#x987A;&#x5E8F;&#x4E00;&#x81F4;&#x3002;&#x8FD9;&#x4E2A;&#x6307;&#x4EE4;&#x901A;&#x5E38;&#x7528;&#x4E8E;&#x5B9E;&#x73B0;&#x5F3A;&#x5185;&#x5B58;&#x987A;&#x5E8F;&#x3002;</li>
<li><code>LFENCE</code> (Load Fence)&#xFF1A;&#x8FD9;&#x662F;&#x4E00;&#x4E2A;&#x8BFB;&#x53D6;&#xFF08;load&#xFF09;&#x5C4F;&#x969C;&#xFF0C;&#x5B83;&#x786E;&#x4FDD;&#x6240;&#x6709;&#x4E4B;&#x524D;&#x7684;&#x8BFB;&#x53D6;&#x64CD;&#x4F5C;&#x5728;<code>LFENCE</code>&#x4E4B;&#x540E;&#x7684;&#x8BFB;&#x53D6;&#x64CD;&#x4F5C;&#x4E4B;&#x524D;&#x5B8C;&#x6210;&#x3002;&#x8FD9;&#x4E2A;&#x6307;&#x4EE4;&#x4E3B;&#x8981;&#x7528;&#x4E8E;&#x963B;&#x6B62;&#x8BFB;&#x53D6;&#x64CD;&#x4F5C;&#x7684;&#x91CD;&#x6392;&#x5E8F;&#x3002;</li>
<li><code>SFENCE</code> (Store Fence)&#xFF1A;&#x8FD9;&#x662F;&#x4E00;&#x4E2A;&#x5199;&#x5165;&#xFF08;store&#xFF09;&#x5C4F;&#x969C;&#xFF0C;&#x5B83;&#x786E;&#x4FDD;&#x6240;&#x6709;&#x4E4B;&#x524D;&#x7684;&#x5199;&#x5165;&#x64CD;&#x4F5C;&#x5728;<code>SFENCE</code>&#x4E4B;&#x540E;&#x7684;&#x5199;&#x5165;&#x64CD;&#x4F5C;&#x4E4B;&#x524D;&#x5B8C;&#x6210;&#x3002;&#x8FD9;&#x4E2A;&#x6307;&#x4EE4;&#x4E3B;&#x8981;&#x7528;&#x4E8E;&#x963B;&#x6B62;&#x5199;&#x5165;&#x64CD;&#x4F5C;&#x7684;&#x91CD;&#x6392;&#x5E8F;</li>
</ol>
<h3 id="32-arm64">3.2-arm64</h3>
<p>&#x800C;&#x5BF9;&#x4E8E;arm64&#x6765;&#x8BF4;&#xFF0C;&#x547D;&#x4EE4;&#x5B9A;&#x4E49;&#x5219;&#x662F;&#x5982;&#x4E0B;</p>
<pre><code class="language-cpp">#define __mb()		dsb(sy)
#define __rmb()		dsb(ld)
#define __wmb()		dsb(st)

#define dsb(opt)	asm volatile(&quot;dsb &quot; #opt : : : &quot;memory&quot;)
</code></pre>
<p>&#x800C;&#x5BF9;&#x4E8E;arm64&#x6765;&#x8BF4;&#x5B9E;&#x73B0;&#x7684;&#x65B9;&#x6CD5;&#x5219;&#x662F;&#x4F7F;&#x7528;<code>dsb</code>&#xFF08;Data Synchronization Barrier&#xFF09;&#x6307;&#x4EE4;&#x3002;</p>
<p>&#x5176;&#x4E2D;<code>sy</code>&#x6307;&#x4EE3;<code>system</code>&#xFF0C;<code>ld</code>&#x6307;&#x4EE3;<code>load</code>&#xFF0C;<code>st</code>&#x6307;&#x4EE3;<code>store</code>&#x3002;</p>
<ol>
<li><code>__mb()</code>&#xFF1A;&#x5168;&#x5185;&#x5B58;&#x5C4F;&#x969C;&#xFF0C;&#x53C2;&#x6570;&#x662F;<code>sy</code>&#xFF08;system&#xFF09;&#xFF0C;&#x8868;&#x793A;&#x6240;&#x6709;&#x7C7B;&#x578B;&#x7684;&#x5185;&#x5B58;&#x64CD;&#x4F5C;&#x90FD;&#x4E0D;&#x80FD;&#x91CD;&#x6392;&#x5E8F;&#x3002;&#x8FD9;&#x4E2A;&#x5B8F;&#x786E;&#x4FDD;&#x6240;&#x6709;&#x4E4B;&#x524D;&#x7684;&#x8BFB;&#x53D6;&#xFF08;load&#xFF09;&#x548C;&#x5199;&#x5165;&#xFF08;store&#xFF09;&#x64CD;&#x4F5C;&#x5728;<code>__mb()</code>&#x4E4B;&#x540E;&#x7684;&#x8BFB;&#x53D6;&#x548C;&#x5199;&#x5165;&#x64CD;&#x4F5C;&#x4E4B;&#x524D;&#x5B8C;&#x6210;&#x3002;</li>
<li><code>__rmb()</code>&#xFF1A;&#x8BFB;&#x53D6;&#xFF08;load&#xFF09;&#x5C4F;&#x969C;&#xFF0C;&#x53C2;&#x6570;&#x662F;<code>ld</code>&#xFF08;load&#xFF09;&#xFF0C;&#x8868;&#x793A;&#x8BFB;&#x53D6;&#x64CD;&#x4F5C;&#x4E0D;&#x80FD;&#x91CD;&#x6392;&#x5E8F;&#x3002;&#x8FD9;&#x4E2A;&#x5B8F;&#x786E;&#x4FDD;&#x6240;&#x6709;&#x4E4B;&#x524D;&#x7684;&#x8BFB;&#x53D6;&#x64CD;&#x4F5C;&#x5728;<code>__rmb()</code>&#x4E4B;&#x540E;&#x7684;&#x8BFB;&#x53D6;&#x64CD;&#x4F5C;&#x4E4B;&#x524D;&#x5B8C;&#x6210;&#x3002;</li>
<li><code>__wmb()</code>&#xFF1A;&#x5199;&#x5165;&#xFF08;store&#xFF09;&#x5C4F;&#x969C;&#xFF0C;&#x53C2;&#x6570;&#x662F;<code>st</code>&#xFF08;store&#xFF09;&#xFF0C;&#x8868;&#x793A;&#x5199;&#x5165;&#x64CD;&#x4F5C;&#x4E0D;&#x80FD;&#x91CD;&#x6392;&#x5E8F;&#x3002;&#x8FD9;&#x4E2A;&#x5B8F;&#x786E;&#x4FDD;&#x6240;&#x6709;&#x4E4B;&#x524D;&#x7684;&#x5199;&#x5165;&#x64CD;&#x4F5C;&#x5728;<code>__wmb()</code>&#x4E4B;&#x540E;&#x7684;&#x5199;&#x5165;&#x64CD;&#x4F5C;&#x4E4B;&#x524D;&#x5B8C;&#x6210;&#x3002;</li>
</ol>
<h2 id="4%E3%80%81%E5%A4%9A%E6%A0%B8%E5%86%85%E5%AD%98%E6%8C%87%E4%BB%A4%E5%B1%8F%E9%9A%9C">4&#x3001;&#x591A;&#x6838;&#x5185;&#x5B58;&#x6307;&#x4EE4;&#x5C4F;&#x969C;</h2>
<p>&#x5728;<code>include/asm-generic/barrier.h</code>&#x4E2D;&#x5B9A;&#x4E49;&#x4E86;&#x901A;&#x7528;&#x7684;smp&#x7ED3;&#x6784;&#x7684;&#x8BFB;&#x5199;&#x5C4F;&#x969C;</p>
<pre><code class="language-cpp">#ifdef CONFIG_SMP

#ifndef smp_mb
#define smp_mb()	do { kcsan_mb(); __smp_mb(); } while (0)
#endif

#ifndef smp_rmb
#define smp_rmb()	do { kcsan_rmb(); __smp_rmb(); } while (0)
#endif

#ifndef smp_wmb
#define smp_wmb()	do { kcsan_wmb(); __smp_wmb(); } while (0)
#endif
</code></pre>
<h3 id="41-x86">4.1-x86</h3>
<pre><code class="language-cpp">#define __dma_rmb()	barrier()
#define __dma_wmb()	barrier()

#define __smp_mb()	asm volatile(&quot;lock; addl $0,-4(%%&quot; _ASM_SP &quot;)&quot; ::: &quot;memory&quot;, &quot;cc&quot;)

#define __smp_rmb()	dma_rmb()
#define __smp_wmb()	barrier()
</code></pre>
<p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#x8BFB;&#x5199;&#x7684;&#x5C4F;&#x969C;&#x90FD;&#x662F;&#x6700;&#x7EC8;&#x88AB;&#x5B9A;&#x4E49;&#x6210;&#x4E86;<code>barrier()</code>&#x7F16;&#x8BD1;&#x5C4F;&#x969C;&#x3002;</p>
<p>&#x800C;&#x5168;&#x5C4F;&#x969C;&#x8FD9;&#x6BB5;&#x6C47;&#x7F16;&#x4EE3;&#x7801;&#x6267;&#x884C;&#x4E86;&#x4E00;&#x4E2A;lock&#x524D;&#x7F00;&#x7684;addl&#x6307;&#x4EE4;&#xFF0C;&#x5C06;<code>0</code>&#x52A0;&#x5230;&#x6808;&#x9876;&#x7684;&#x4E0A;&#x4E00;&#x4E2A;&#x4F4D;&#x7F6E;<code>&#xFF08;-4(%esp)</code>&#x6216;<code>-4(%rsp)&#xFF09;</code>&#x3002;lock&#x524D;&#x7F00;&#x5728;x86&#x67B6;&#x6784;&#x4E2D;&#x7528;&#x4E8E;&#x5B9E;&#x73B0;&#x539F;&#x5B50;&#x64CD;&#x4F5C;&#xFF0C;&#x5B83;&#x786E;&#x4FDD;&#x6307;&#x4EE4;&#x5728;&#x591A;&#x5904;&#x7406;&#x5668;&#x73AF;&#x5883;&#x4E2D;&#x6309;&#x987A;&#x5E8F;&#x6267;&#x884C;&#xFF0C;&#x5E76;&#x963B;&#x6B62;&#x5176;&#x4ED6;&#x5904;&#x7406;&#x5668;&#x8BBF;&#x95EE;&#x88AB;&#x64CD;&#x4F5C;&#x7684;&#x5185;&#x5B58;&#x5730;&#x5740;&#x3002;&#x5728;&#x8FD9;&#x6BB5;&#x4EE3;&#x7801;&#x4E2D;&#xFF0C;<code>lock; addl $0,-4(%%&quot; _ASM_SP &quot;)&quot;</code>&#x5B9E;&#x9645;&#x4E0A;&#x662F;&#x4E00;&#x4E2A;&#x4E0D;&#x4F1A;&#x6539;&#x53D8;&#x4EFB;&#x4F55;&#x5B9E;&#x8D28;&#x5185;&#x5BB9;&#x7684;&#x539F;&#x5B50;&#x64CD;&#x4F5C;&#xFF0C;&#x56E0;&#x4E3A;&#x5B83;&#x53EA;&#x662F;&#x5C06;0&#x52A0;&#x5230;&#x6808;&#x9876;&#x7684;&#x4E0A;&#x4E00;&#x4E2A;&#x4F4D;&#x7F6E;&#x3002;&#x8FD9;&#x4E2A;&#x64CD;&#x4F5C;&#x7684;&#x4E3B;&#x8981;&#x76EE;&#x7684;&#x662F;&#x901A;&#x8FC7;<code>lock</code>&#x524D;&#x7F00;&#x5B9E;&#x73B0;&#x5185;&#x5B58;&#x5C4F;&#x969C;&#x7684;&#x529F;&#x80FD;&#x3002;</p>
<h3 id="42-arm64">4.2-arm64</h3>
<pre><code class="language-cpp">#define __smp_mb()	dmb(ish)
#define __smp_rmb()	dmb(ishld)
#define __smp_wmb()	dmb(ishst)

#define dmb(opt)	asm volatile(&quot;dmb &quot; #opt : : : &quot;memory&quot;)
</code></pre>
<p>&#x4E0A;&#x8FF0;&#x547D;&#x4EE4;&#x4F7F;&#x7528;&#x4E86;ARM&#x7684;<code>dmb</code>&#xFF08;Data Memory Barrier&#xFF09;&#x6307;&#x4EE4;&#xFF0C;&#x5E94;&#x7528;&#x4E8E;&#x540C;&#x4E00;&#x5185;&#x90E8;&#x5171;&#x4EAB;&#x57DF;&#x4E2D;&#x7684;cpu&#x4E4B;&#x95F4;&#x7684;&#x8BFB;\&#x5199;&#x64CD;&#x4F5C;</p>
<ol>
<li><code>__smp_mb()</code>&#xFF1A;&#x5904;&#x7406;&#x5668;&#x95F4;&#x5168;&#x5185;&#x5B58;&#x5C4F;&#x969C;&#xFF0C;&#x53C2;&#x6570;&#x662F;<code>ish</code>&#xFF08;Inner SHareable&#xFF09;&#x3002;&#x8FD9;&#x4E2A;&#x5B8F;&#x786E;&#x4FDD;&#x6240;&#x6709;&#x4E4B;&#x524D;&#x7684;&#x8BFB;&#x53D6;&#xFF08;load&#xFF09;&#x548C;&#x5199;&#x5165;&#xFF08;store&#xFF09;&#x64CD;&#x4F5C;&#x5728;<code>__smp_mb()</code>&#x4E4B;&#x540E;&#x7684;&#x8BFB;&#x53D6;&#x548C;&#x5199;&#x5165;&#x64CD;&#x4F5C;&#x4E4B;&#x524D;&#x5B8C;&#x6210;&#x3002;</li>
<li><code>__smp_rmb()</code>&#xFF1A;&#x5904;&#x7406;&#x5668;&#x95F4;&#x8BFB;&#x53D6;&#xFF08;load&#xFF09;&#x5C4F;&#x969C;&#xFF0C;&#x53C2;&#x6570;&#x662F;<code>ishld</code>&#xFF08;Inner SHareable Load&#xFF09;&#x3002;&#x8FD9;&#x4E2A;&#x5B8F;&#x786E;&#x4FDD;&#x6240;&#x6709;&#x4E4B;&#x524D;&#x7684;&#x8BFB;&#x53D6;&#x64CD;&#x4F5C;&#x5728;<code>__smp_rmb()</code>&#x4E4B;&#x540E;&#x7684;&#x8BFB;&#x53D6;&#x64CD;&#x4F5C;&#x4E4B;&#x524D;&#x5B8C;&#x6210;&#x3002;</li>
<li><code>__smp_wmb()</code>&#xFF1A;&#x5904;&#x7406;&#x5668;&#x95F4;&#x5199;&#x5165;&#xFF08;store&#xFF09;&#x5C4F;&#x969C;&#xFF0C;&#x53C2;&#x6570;&#x662F;<code>ishst</code>&#xFF08;Inner SHareable Store&#xFF09;&#x3002;&#x8FD9;&#x4E2A;&#x5B8F;&#x786E;&#x4FDD;&#x6240;&#x6709;&#x4E4B;&#x524D;&#x7684;&#x5199;&#x5165;&#x64CD;&#x4F5C;&#x5728;<code>__smp_wmb()</code>&#x4E4B;&#x540E;&#x7684;&#x5199;&#x5165;&#x64CD;&#x4F5C;&#x4E4B;&#x524D;&#x5B8C;&#x6210;&#x3002;</li>
</ol>
<p>&#x8865;&#x5145;&#xFF1A;</p>
<ol>
<li><a href="https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/memory-access-ordering-part-3---memory-access-ordering-in-the-arm-architecture?ref=korantli.com.cn">DSB&#x4E0E;DMB&#x5173;&#x7CFB;</a></li>
<li><a href="https://aijishu.com/a/1060000000207845?ref=korantli.com.cn">ARM&#x5171;&#x4EAB;&#x57DF;</a></li>
</ol>
<h2 id="5%E3%80%81%E5%85%A8%E5%B1%80%E4%B8%8Esmp%E7%9A%84%E5%8C%BA%E5%88%AB">5&#x3001;&#x5168;&#x5C40;&#x4E0E;SMP__&#x7684;&#x533A;&#x522B;</h2>
<h3 id="51-x86">5.1-x86</h3>
<p>&#x8FD9;&#x662F;&#x4E00;&#x4E2A;&#x5B58;&#x7591;&#x70B9;&#xFF0C;&#x76EE;&#x524D;&#x8FD8;&#x6CA1;&#x7406;&#x89E3;&#x5230;&#x5728;x86&#x4E0A;&#x5E26;smp&#x7684;&#x5185;&#x5B58;&#x5C4F;&#x853D;&#x533A;&#x522B;&#x5728;&#x54EA;&#x91CC;&#xFF0C;smp&#x7684;&#x5168;&#x5C4F;&#x853D;&#x770B;&#x8D77;&#x6765;&#x53EA;&#x662F;&#x4F7F;&#x7528;&#x4E86;<code>lock</code>&#x539F;&#x5B50;&#x64CD;&#x4F5C;&#xFF0C;&#x538B;&#x4E86;&#x4E00;&#x4E2A;&#x7A7A;&#x6808;&#xFF0C;&#x5E76;&#x6CA1;&#x6709;&#x771F;&#x6B63;&#x7684;&#x6267;&#x884C;&#x5185;&#x5B58;&#x5C4F;&#x969C;&#x3002;&#x5E76;&#x4E0D;&#x662F;&#x5F88;&#x6E05;&#x695A;&#x5E26;&#x4E0D;&#x5E26;smp&#x7684;&#x529F;&#x80FD;&#x4E0A;&#x5177;&#x4F53;&#x533A;&#x522B;&#x3002;</p>
<h3 id="52-arm64">5.2-arm64</h3>
<p>&#x4E3B;&#x8981;&#x7684;&#x533A;&#x522B;&#x662F;&#x4F7F;&#x7528;<code>dsb</code>&#x547D;&#x4EE4;&#x8FD8;&#x662F;<code>dmb</code>&#x547D;&#x4EE4;&#x3002;</p>
<p>&#x4E8C;&#x8005;&#x7684;&#x4F5C;&#x7528;&#x4E0E;&#x4E0D;&#x540C;&#xFF0C;<code>dsb</code>&#x662F;&#x5168;&#x5C40;&#x7684;&#xFF0C;&#x800C;<code>dmb</code>&#x662F;&#x5171;&#x4EAB;&#x57DF;&#x5185;&#x7684;CPU&#x3002;&#x53E6;&#x5916;DSB&#x6307;&#x4EE4;&#x8981;&#x6BD4;DMB&#x6307;&#x4EE4;&#x4E25;&#x683C;&#x5F97;&#x591A;&#x3002;DSB&#x540E;&#x9762;&#x7684;&#x4EFB;&#x4F55;&#x6307;&#x4EE4;&#x5FC5;&#x987B;&#x6EE1;&#x8DB3;&#x4E0B;&#x9762;&#x4E24;&#x4E2A;&#x6761;&#x4EF6;&#x624D;&#x80FD;&#x5F00;&#x59CB;&#x6267;&#x884C;&#x3002;</p>
<ul>
<li>DSB&#x6307;&#x4EE4;&#x524D;&#x9762;&#x7684;&#x6240;&#x6709;&#x6570;&#x636E;&#x8BBF;&#x95EE;&#x6307;&#x4EE4;&#xFF08;&#x5185;&#x5B58;&#x8BBF;&#x95EE;&#x6307;&#x4EE4;&#xFF09;&#x5FC5;&#x987B;&#x6267;&#x884C;&#x5B8C;&#x3002;</li>
<li>DSB&#x6307;&#x4EE4;&#x524D;&#x9762;&#x7684;&#x9AD8;&#x901F;&#x7F13;&#x5B58;&#x3001;&#x5206;&#x652F;&#x9884;&#x6D4B;&#x3001;TLB&#x7B49;&#x7EF4;&#x62A4;&#x6307;&#x4EE4;&#x4E5F;&#x5FC5;&#x987B;&#x6267;&#x884C;&#x5B8C;&#x3002;</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[内存管理1_物理内存分配]]></title><description><![CDATA[<h2 id="0%E3%80%81%E5%89%8D%E8%A8%80">0&#x3001;&#x524D;&#x8A00;</h2>
<p>&#x4E3B;&#x8981;&#x5206;&#x6790;&#x5185;&#x5B58;&#x7684;&#x5206;&#x914D;&#x673A;&#x5236;</p>
<p><a href="https://blog.csdn.net/m0_65931372/article/details/126234314?ref=korantli.com.cn">https://blog.csdn.net/m0_65931372/article/details/126234314</a></p>
<h2 id="1%E3%80%81%E5%86%85%E5%AD%98%E7%BB%93%E6%9E%84">1&#x3001;&#x5185;&#x5B58;&#x7ED3;&#x6784;</h2>
<p><img src="http://www.korantli.com.cn/content/images/2024/01/65bff17bb17b46df8847c2b7d552a225.png" alt="65bff17bb17b46df8847c2b7d552a225.png" loading="lazy"></p>
<p>&#x5F15;&#x81EA;<a href="https://blog.csdn.net/weixin_45337360/article/details/126940438?ref=korantli.com.cn">Linux &#x7269;&#x7406;&#x5185;&#x5B58;&#x7BA1;&#x7406;&#x6D89;&#x53CA;&#x7684;&#x4E09;&#x5927;&#x7ED3;&#x6784;&#x4F53;&#x4E4B;struct page</a></p>]]></description><link>http://www.korantli.com.cn/nei-cun-guan-li-_1wu-li-nei-cun-fen-pei-md/</link><guid isPermaLink="false">65940b5b2bc2afda5bd2ec7f</guid><category><![CDATA[linux内存管理]]></category><category><![CDATA[linux内存管理文章]]></category><dc:creator><![CDATA[李星辉]]></dc:creator><pubDate>Tue, 02 Jan 2024 13:13:26 GMT</pubDate><media:content url="http://www.korantli.com.cn/content/images/2024/01/DALL-E-2024-01-02-21.06.49-4.jpg" medium="image"/><content:encoded><![CDATA[<h2 id="0%E3%80%81%E5%89%8D%E8%A8%80">0&#x3001;&#x524D;&#x8A00;</h2>
<img src="http://www.korantli.com.cn/content/images/2024/01/DALL-E-2024-01-02-21.06.49-4.jpg" alt="&#x5185;&#x5B58;&#x7BA1;&#x7406;1_&#x7269;&#x7406;&#x5185;&#x5B58;&#x5206;&#x914D;"><p>&#x4E3B;&#x8981;&#x5206;&#x6790;&#x5185;&#x5B58;&#x7684;&#x5206;&#x914D;&#x673A;&#x5236;</p>
<p><a href="https://blog.csdn.net/m0_65931372/article/details/126234314?ref=korantli.com.cn">https://blog.csdn.net/m0_65931372/article/details/126234314</a></p>
<h2 id="1%E3%80%81%E5%86%85%E5%AD%98%E7%BB%93%E6%9E%84">1&#x3001;&#x5185;&#x5B58;&#x7ED3;&#x6784;</h2>
<p><img src="http://www.korantli.com.cn/content/images/2024/01/65bff17bb17b46df8847c2b7d552a225.png" alt="&#x5185;&#x5B58;&#x7BA1;&#x7406;1_&#x7269;&#x7406;&#x5185;&#x5B58;&#x5206;&#x914D;" loading="lazy"></p>
<p>&#x5F15;&#x81EA;<a href="https://blog.csdn.net/weixin_45337360/article/details/126940438?ref=korantli.com.cn">Linux &#x7269;&#x7406;&#x5185;&#x5B58;&#x7BA1;&#x7406;&#x6D89;&#x53CA;&#x7684;&#x4E09;&#x5927;&#x7ED3;&#x6784;&#x4F53;&#x4E4B;struct page</a></p>
<h3 id="11-%E9%A1%B5-page">1.1 &#x9875; page</h3>
<p>&#x5728;linux kernel&#x4E2D;&#xFF0C;&#x5185;&#x5B58;&#x5206;&#x914D;&#x7684;&#x6700;&#x57FA;&#x672C;&#x5355;&#x4F4D;&#x4E3A;&#x9875;&#xFF0C;&#x4E5F;&#x5C31;&#x662F;&#x6570;&#x636E;&#x7ED3;&#x6784;<code>struct page</code>&#xFF0C;&#x53EF;&#x4EE5;&#x7406;&#x89E3;&#x4E3A;&#x6BCF;&#x4E00;&#x4E2A;&#x9875;&#x5BF9;&#x5E94;&#x7740;&#x4E00;&#x4E2A;&#x7269;&#x7406;&#x5185;&#x5B58;&#x5355;&#x5143;&#xFF0C;&#x901A;&#x5E38;&#x4E3A;4KB&#x3002;</p>
<p>&#x4E0B;&#x8FB9;&#x662F;<code>linux/mm_types.h</code>&#x5B9A;&#x4E49;&#x7684;&#x6570;&#x636E;&#x539F;&#x578B;&#xFF0C;&#x5728;&#x5FFD;&#x7565;&#x4E00;&#x90E8;&#x5206;&#x5185;&#x5BB9;&#x540E;&#xFF0C;&#x5177;&#x4F53;&#x7684;&#x4EE3;&#x7801;&#x5982;&#x4E0B;&#x3002;</p>
<pre><code class="language-cpp">struct page {
	unsigned long flags;		/* Atomic flags, some possibly
					 * updated asynchronously */
	/*
	 * Five words (20/40 bytes) are available in this union.
	 * WARNING: bit 0 of the first word is used for PageTail(). That
	 * means the other users of this union MUST NOT use the bit to
	 * avoid collision and false-positive PageTail().
	 */
	union {
    struct list_head lru;
    /* See page-flags.h for PAGE_MAPPING_FLAGS */
    struct address_space *mapping;
    pgoff_t index;		/* Our offset within mapping. */
    /**
     * @private: Mapping-private opaque data.
     * Usually used for buffer_heads if PagePrivate.
     * Used for swp_entry_t if PageSwapCache.
     * Indicates order in the buddy system if PageBuddy.
     */
    unsigned long private;
		......
	};
	union {		/* This union is 4 bytes in size. */
    /*	
		 * If the page can be mapped to userspace, encodes the number
		 * of times this page is referenced by a page table.
		 */
    atomic_t _mapcount;
		.....
	};

	/* Usage count. *DO NOT USE DIRECTLY*. See page_ref.h */
	atomic_t _refcount;
	......
#if defined(WANT_PAGE_VIRTUAL)
	void *virtual;			/* Kernel virtual address (NULL if
					   not kmapped, ie. highmem) */
#endif /* WANT_PAGE_VIRTUAL */
	......
} _struct_page_alignment;
</code></pre>
<p>&#x5176;&#x4E2D;&#x5404;&#x4E2A;&#x57DF;&#x7684;&#x542B;&#x4E49;&#x5982;&#x4E0B;&#xFF1A;</p>
<ul>
<li>flags&#xFF1A;&#x8868;&#x793A;&#x5F53;&#x524D;&#x9875;&#x7684;&#x72B6;&#x6001;&#x3002;</li>
<li>lru&#xFF1A;&#x5F53;&#x524D;&#x9875;&#x8868;&#x4E2D;&#x7684;lru&#xFF08;Least Recently Used&#xFF0C;&#x6700;&#x8FD1;&#x6700;&#x5C11;&#x4F7F;&#x7528;&#xFF09;&#x94FE;&#x8868;&#xFF0C;&#x7528;&#x6765;&#x4F5C;&#x4E3A;&#x9875;&#x66FF;&#x6362;&#x7684;&#x4F9D;&#x636E;&#x3002;</li>
<li>mapping&#xFF1A;&#x4F5C;&#x4E3A;page cache&#x65F6;page&#x7684;&#x5177;&#x4F53;&#x5730;&#x5740;&#xFF08;&#x6307;&#x5411;&#x548C;&#x8FD9;&#x4E2A;&#x9875;&#x5173;&#x8054;&#x7684;addresss_space&#xFF09;&#x3002;</li>
<li>_mapcount&#xFF1A;&#x88AB;&#x6620;&#x5C04;&#x7684;&#x8BA1;&#x6570;&#x3002;</li>
<li>_refcount&#xFF1A;&#x9875;&#x7684;&#x5F15;&#x7528;&#x8BA1;&#x6570;&#xFF0C;&#x8868;&#x793A;&#x5F53;&#x524D;&#x8FD9;&#x6BB5;&#x5185;&#x5B58;&#x4E5F;&#x6B63;&#x5728;&#x88AB;&#x591A;&#x5C11;&#x8FDB;&#x7A0B;&#x5F15;&#x7528;&#x3002;</li>
<li>virtual&#xFF1A;&#x9875;&#x5728;&#x865A;&#x62DF;&#x5185;&#x5B58;&#x4E2D;&#x7684;&#x5730;&#x5740;&#x3002;</li>
</ul>
<p>&#x6B64;&#x5916;&#xFF0C;&#x53EF;&#x4EE5;&#x628A;&#x6BCF;&#x4E00;&#x4E2A;&#x7269;&#x7406;&#x9875;&#x7684;&#x57FA;&#x672C;&#x5355;&#x4F4D;&#x662F;&#x7269;&#x7406;&#x9875;&#x5E27;&#xFF0C;&#x800C;&#x6BCF;&#x4E00;&#x4E2A;&#x7269;&#x7406;&#x9875;&#x5E27;&#x90FD;&#x6709;&#x81EA;&#x5DF1;&#x7684;pfn&#x7269;&#x7406;&#x9875;&#x5E27;&#x53F7;&#xFF0C;&#x4E0B;&#x8FB9;&#x662F;&#x7269;&#x7406;&#x9875;&#x5E27;&#x53F7;&#x548C;page&#x4EE5;&#x53CA;&#x7269;&#x7406;&#x9875;&#x5730;&#x5740;&#x7684;&#x8F6C;&#x6362;&#x5173;&#x7CFB;</p>
<pre><code class="language-cpp">#define __pfn_to_page(pfn)	(mem_map + ((pfn) - ARCH_PFN_OFFSET))
#define __page_to_pfn(page)	((unsigned long)((page) - mem_map) + \
				 ARCH_PFN_OFFSET)
</code></pre>
<h3 id="12-%E5%8C%BA-zone">1.2 &#x533A; zone</h3>
<p>&#x5185;&#x5B58;&#x5206;&#x533A;&#x7684;&#x539F;&#x56E0;&#x5728;&#x4E8E;&#xFF0C;&#x4E0D;&#x540C;&#x7684;&#x786C;&#x4EF6;&#x53EA;&#x80FD;&#x8BBF;&#x95EE;&#x7279;&#x5B9A;&#x8303;&#x56F4;&#x7684;&#x5185;&#x5B58;&#xFF0C;&#x6BD4;&#x5982;ISA&#x603B;&#x7EBF;&#x7684;DMA&#x5C31;&#x8981;&#x6C42;&#x53EA;&#x80FD;&#x8BBF;&#x95EE;&#x524D;16MB&#x7684;&#x5185;&#x5B58;&#x3002;</p>
<p>&#x56E0;&#x6B64;&#x57FA;&#x4E8E;&#x786C;&#x4EF6;&#x7684;&#x9650;&#x5236;&#xFF0C;linux kernel&#x5185;&#x5B58;&#x6574;&#x4F53;&#x5206;&#x4E3A;&#x5982;&#x4E0B;&#x51E0;&#x4E2A;&#x533A;&#xFF1A;(&#x88AB;&#x5B9A;&#x4E49;&#x5728;&#x4E86;<code>include/linux/mmzone.h</code>&#x7684;<code>enum zone_type</code>&#x4E2D;)</p>
<ul>
<li>
<p>ZONE_DMA&#xFF08;0~16MB&#xFF09;</p>
<p>&#x8FD9;&#x4E2A;&#x533A;&#x57DF;&#x5305;&#x542B;&#x4E86;&#x9002;&#x7528;&#x4E8E;&#x76F4;&#x63A5;&#x5185;&#x5B58;&#x8BBF;&#x95EE;&#xFF08;Direct Memory Access, DMA&#xFF09;&#x7684;&#x5185;&#x5B58;&#x3002;DMA&#x662F;&#x4E00;&#x79CD;&#x6570;&#x636E;&#x4F20;&#x8F93;&#x65B9;&#x5F0F;&#xFF0C;&#x53EF;&#x4EE5;&#x5728;&#x4E0D;&#x7ECF;&#x8FC7;CPU&#x7684;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x76F4;&#x63A5;&#x5728;&#x5185;&#x5B58;&#x548C;&#x5916;&#x8BBE;&#x4E4B;&#x95F4;&#x4F20;&#x8F93;&#x6570;&#x636E;&#x3002;ZONE_DMA&#x901A;&#x5E38;&#x5305;&#x542B;&#x8F83;&#x4F4E;&#x7684;&#x7269;&#x7406;&#x5730;&#x5740;&#x7A7A;&#x95F4;&#xFF0C;&#x8FD9;&#x662F;&#x56E0;&#x4E3A;&#x8BB8;&#x591A;&#x65E9;&#x671F;&#x7684;&#x5916;&#x8BBE;&#x53EA;&#x652F;&#x6301;&#x6709;&#x9650;&#x7684;&#x5730;&#x5740;&#x8303;&#x56F4;&#x8FDB;&#x884C;DMA&#x4F20;&#x8F93;&#x3002;</p>
</li>
<li>
<p>ZONE_DMA32</p>
<p>&#x8FD9;&#x4E2A;&#x533A;&#x57DF;&#x5305;&#x542B;&#x4E86;&#x9002;&#x7528;&#x4E8E;32&#x4F4D;DMA&#x8BBE;&#x5907;&#x7684;&#x5185;&#x5B58;&#x3002;&#x8FD9;&#x4E9B;&#x8BBE;&#x5907;&#x53EF;&#x4EE5;&#x8BBF;&#x95EE;&#x8F83;&#x5927;&#x7684;&#x5730;&#x5740;&#x8303;&#x56F4;&#xFF0C;&#x901A;&#x5E38;&#x9AD8;&#x8FBE;4GB&#x3002;ZONE_DMA32&#x4E3B;&#x8981;&#x7528;&#x4E8E;64&#x4F4D;&#x7CFB;&#x7EDF;&#xFF0C;&#x56E0;&#x4E3A;&#x5728;32&#x4F4D;&#x7CFB;&#x7EDF;&#x4E2D;&#xFF0C;ZONE_NORMAL&#x901A;&#x5E38;&#x5C31;&#x8DB3;&#x4EE5;&#x6EE1;&#x8DB3;DMA&#x8BBE;&#x5907;&#x7684;&#x9700;&#x6C42;&#x3002;</p>
</li>
<li>
<p>ZONE_NORMAL&#xFF08;16MB~896MB&#xFF09;</p>
<p><a href="https://stackoverflow.com/questions/8252785/why-linux-kernel-zone-normal-is-limited-to-896-mb?ref=korantli.com.cn">Why Linux Kernel ZONE_NORMAL is limited to 896 MB?</a></p>
<p>&#x8FD9;&#x4E2A;&#x533A;&#x57DF;&#x5305;&#x542B;&#x4E86;&#x5E38;&#x89C4;&#x5185;&#x5B58;&#xFF0C;&#x53EF;&#x4EE5;&#x88AB;&#x5185;&#x6838;&#x548C;&#x7528;&#x6237;&#x7A7A;&#x95F4;&#x8FDB;&#x7A0B;&#x4F7F;&#x7528;&#x3002;&#x5B83;&#x4E0D;&#x5305;&#x62EC;&#x7528;&#x4E8E;DMA&#x7684;&#x5185;&#x5B58;&#xFF0C;&#x56E0;&#x6B64;&#x53EF;&#x4EE5;&#x907F;&#x514D;&#x4E0E;&#x9700;&#x8981;&#x7279;&#x5B9A;&#x5730;&#x5740;&#x8303;&#x56F4;&#x7684;DMA&#x8BBE;&#x5907;&#x53D1;&#x751F;&#x51B2;&#x7A81;&#x3002;&#x5728;32&#x4F4D;&#x7CFB;&#x7EDF;&#x4E2D;&#xFF0C;ZONE_NORMAL&#x901A;&#x5E38;&#x5305;&#x542B;&#x4E86;&#x9664;ZONE_DMA&#x4E4B;&#x5916;&#x7684;&#x6240;&#x6709;&#x5185;&#x5B58;&#x3002;</p>
</li>
<li>
<p>ZONE_HIGHEM&#xFF08;896MB~4GB&#xFF09;</p>
<p>&#x8FD9;&#x4E2A;&#x533A;&#x57DF;&#x5305;&#x542B;&#x4E86;&#x9AD8;&#x7AEF;&#x5185;&#x5B58;&#xFF08;high memory&#xFF09;&#xFF0C;&#x5373;&#x90A3;&#x4E9B;&#x4E0D;&#x80FD;&#x88AB;&#x5185;&#x6838;&#x76F4;&#x63A5;&#x6620;&#x5C04;&#x5230;&#x5176;&#x7EBF;&#x6027;&#x5730;&#x5740;&#x7A7A;&#x95F4;&#x7684;&#x5185;&#x5B58;&#x3002;&#x5728;&#x5177;&#x6709;&#x5927;&#x91CF;&#x7269;&#x7406;&#x5185;&#x5B58;&#x7684;32&#x4F4D;&#x7CFB;&#x7EDF;&#x4E0A;&#xFF0C;&#x5185;&#x6838;&#x5730;&#x5740;&#x7A7A;&#x95F4;&#x53EF;&#x80FD;&#x4E0D;&#x8DB3;&#x4EE5;&#x6620;&#x5C04;&#x6240;&#x6709;&#x5185;&#x5B58;&#xFF0C;&#x56E0;&#x6B64;&#x9700;&#x8981;&#x5C06;&#x90E8;&#x5206;&#x5185;&#x5B58;&#x653E;&#x5165;ZONE_HIGHMEM&#x3002;64&#x4F4D;&#x7CFB;&#x7EDF;&#x901A;&#x5E38;&#x4E0D;&#x9700;&#x8981;&#x4F7F;&#x7528;&#x8FD9;&#x4E2A;&#x533A;&#x57DF;&#xFF0C;&#x56E0;&#x4E3A;&#x5B83;&#x4EEC;&#x5177;&#x6709;&#x8DB3;&#x591F;&#x5927;&#x7684;&#x5730;&#x5740;&#x7A7A;&#x95F4;&#x3002;</p>
</li>
<li>
<p>ZONE_MOVABLE</p>
<p>&#x8FD9;&#x4E2A;&#x533A;&#x57DF;&#x5305;&#x542B;&#x4E86;&#x53EF;&#x79FB;&#x52A8;&#x5185;&#x5B58;&#x3002;&#x5F53;&#x7CFB;&#x7EDF;&#x9700;&#x8981;&#x8FDE;&#x7EED;&#x7684;&#x7269;&#x7406;&#x5185;&#x5B58;&#x5757;&#x65F6;&#xFF0C;&#x5185;&#x6838;&#x53EF;&#x4EE5;&#x5C06;ZONE_MOVABLE&#x4E2D;&#x7684;&#x9875;&#x9762;&#x8FC1;&#x79FB;&#x5230;&#x5176;&#x4ED6;&#x533A;&#x57DF;&#xFF0C;&#x4ECE;&#x800C;&#x817E;&#x51FA;&#x8FDE;&#x7EED;&#x7684;&#x5185;&#x5B58;&#x7A7A;&#x95F4;&#x3002;&#x8FD9;&#x5BF9;&#x4E8E;&#x652F;&#x6301;&#x5185;&#x5B58;&#x70ED;&#x63D2;&#x62D4;&#xFF08;hotplug&#xFF09;&#x548C;&#x5927;&#x5185;&#x5B58;&#x5206;&#x914D;&#x7684;&#x7CFB;&#x7EDF;&#x975E;&#x5E38;&#x6709;&#x7528;&#x3002;</p>
</li>
<li>
<p>CONFIG_ZONE_DEVICE</p>
<p>&#x7528;&#x4E8E;&#x652F;&#x6301;&#x8BBE;&#x5907;&#x4E13;&#x7528;&#x5185;&#x5B58;&#xFF08;device memory&#xFF09;&#x3002;&#x8FD9;&#x79CD;&#x5185;&#x5B58;&#x901A;&#x5E38;&#x4E0D;&#x662F;&#x7531;&#x901A;&#x7528;&#x5185;&#x5B58;&#x5B50;&#x7CFB;&#x7EDF;&#x7BA1;&#x7406;&#x7684;&#xFF0C;&#x800C;&#x662F;&#x7531;&#x7279;&#x5B9A;&#x7684;&#x8BBE;&#x5907;&#x9A71;&#x52A8;&#x7A0B;&#x5E8F;&#x7BA1;&#x7406;&#x3002;&#x5C06;&#x8BBE;&#x5907;&#x5185;&#x5B58;&#x7EB3;&#x5165;ZONE_DEVICE&#x5141;&#x8BB8;&#x5185;&#x6838;&#x5C06;&#x8FD9;&#x4E9B;&#x8BBE;&#x5907;&#x5185;&#x5B58;&#x7EB3;&#x5165;&#x5185;&#x5B58;&#x7BA1;&#x7406;&#x5B50;&#x7CFB;&#x7EDF;&#xFF0C;&#x4ECE;&#x800C;&#x53EF;&#x4EE5;&#x5728;&#x9700;&#x8981;&#x65F6;&#x5C06;&#x5176;&#x7528;&#x4E8E;&#x5176;&#x4ED6;&#x76EE;&#x7684;&#xFF0C;&#x8BBE;&#x5907;&#x4E13;&#x7528;&#x5185;&#x5B58;&#x7684;&#x4E00;&#x4E2A;&#x4F8B;&#x5B50;&#x662F;&#x663E;&#x5361;&#x7684;&#x663E;&#x5B58;&#x3002;</p>
</li>
</ul>
<h3 id="13-%E8%8A%82%E7%82%B9-node">1.3 &#x8282;&#x70B9; node</h3>
<p>&#x5BF9;&#x4E8E;NUMA&#x67B6;&#x6784;&#x7684;&#x7CFB;&#x7EDF;&#x4E2D;&#xFF0C;&#x8FD8;&#x4F1A;&#x5C06;&#x5185;&#x5B58;&#x7684;&#x7BA1;&#x7406;&#x589E;&#x52A0;&#x4E00;&#x4E2A;node&#x8282;&#x70B9;&#xFF0C;node&#x8282;&#x70B9;&#x662F;&#x6BD4;zone&#x66F4;&#x9AD8;&#x7EA7;&#x7684;&#x7BA1;&#x7406;&#x5C42;&#x7EA7;&#x3002;&#x4ECE;&#x4E0B;&#x8FB9;&#x7684;&#x6570;&#x636E;&#x7ED3;&#x6784;&#x4E2D;&#x53EF;&#x4EE5;&#x770B;&#x51FA;&#xFF0C;&#x8868;&#x793A;&#x5B58;&#x653E;<code>node</code>&#x7684;&#x6570;&#x636E;&#x7ED3;&#x6784;<code>pglist_data</code>&#x4E2D;&#x524D;&#x51E0;&#x4E2A;&#x57DF;&#x90FD;&#x662F;&#x7528;&#x6765;&#x8BB0;&#x5F55;zone&#x7684;&#x3002;&#x800C;&#x5BF9;&#x4E8E;uma&#x7684;&#x7CFB;&#x7EDF;&#xFF0C;&#x76F8;&#x5F53;&#x4E8E;&#x53EA;&#x6709;&#x4E00;&#x4E2A;node&#x8282;&#x70B9;&#x7684;&#x7CFB;&#x7EDF;&#xFF0C;&#x6545;&#x53EA;&#x6709;&#x4E00;&#x4E2A;pglist_data&#x6570;&#x636E;&#x7ED3;&#x6784;&#x3002;</p>
<p>&#x5BF9;&#x4E8E;&#x5E38;&#x89C1;&#x7684;&#x7CFB;&#x7EDF;&#x7684;&#x6765;&#x8BF4;&#xFF0C;&#x4F1A;&#x5B58;&#x5728;<code>numa0</code>&#x548C;<code>numa1</code>&#x4E24;&#x4E2A;node&#x3002;</p>
<p>&#x4F46;&#x662F;&#x533A;&#x5206;&#x4E8E;&#x5185;&#x5B58;&#x4E2D;&#x7684;zone&#xFF0C;node&#x7684;&#x7ED3;&#x6784;&#x5728;linux&#x5185;&#x662F;&#x7531;&#x8F6F;&#x4EF6;&#x533A;&#x5206;&#x7684;&#xFF0C;&#x800C;&#x4E0D;&#x662F;&#x6BCF;&#x4E00;&#x4E2A;node&#x5B9E;&#x9645;&#x7531;&#x81EA;&#x5DF1;&#x7684;&#x5404;&#x4E2A;&#x5185;&#x5B58;zone&#x3002;</p>
<pre><code class="language-cpp">/*
 * On NUMA machines, each NUMA node would have a pg_data_t to describe
 * it&apos;s memory layout. On UMA machines there is a single pglist_data which
 * describes the whole memory.
 *
 * Memory statistics and page replacement data structures are maintained on a
 * per-zone basis.
 */
typedef struct pglist_data {
	/*
	 * node_zones contains just the zones for THIS node. Not all of the
	 * zones may be populated, but it is the full list. It is referenced by
	 * this node&apos;s node_zonelists as well as other node&apos;s node_zonelists.
	 */
	struct zone node_zones[MAX_NR_ZONES]; // &#x7BA1;&#x7406;&#x533A;&#x63CF;&#x8FF0;&#x7B26;&#x7684;&#x6570;&#x7EC4;

	/*
	 * node_zonelists contains references to all zones in all nodes.
	 * Generally the first zones will be references to this node&apos;s
	 * node_zones.
	 */
	struct zonelist node_zonelists[MAX_ZONELISTS]; // &#x9875;&#x5206;&#x914D;&#x5668;&#x6240;&#x4F7F;&#x7528;&#x7684;&#x6570;&#x7EC4;

	int nr_zones; /* &#x7BA1;&#x7406;&#x533A;&#x7684;&#x6570;&#x76EE; */
#ifdef CONFIG_FLATMEM	/* means !SPARSEMEM */
	struct page *node_mem_map; // &#x8282;&#x70B9;&#x4E2D;&#x9875;&#x63CF;&#x8FF0;&#x7B26;&#x6570;&#x7EC4;
	......
#endif
#if defined(CONFIG_MEMORY_HOTPLUG) || defined(CONFIG_DEFERRED_STRUCT_PAGE_INIT)
	......
#endif
	unsigned long node_start_pfn; // &#x8282;&#x70B9;&#x4E2D;&#x7B2C;&#x4E00;&#x4E2A;&#x9875;&#x6846;&#x7684;&#x4E0B;&#x6807;
	unsigned long node_present_pages; /* total number of physical pages */
	unsigned long node_spanned_pages; /* total size of physical page
					     range, including holes */
	int node_id; // &#x8282;&#x70B9;&#x8868;&#x793A;&#x7B26;
	wait_queue_head_t kswapd_wait; // kswapd&#x9875;&#x6362;&#x51FA;&#x5B88;&#x62A4;&#x8FDB;&#x7A0B;&#x7684;&#x7B49;&#x5F85;&#x961F;&#x5217;
    ......
	struct task_struct *kswapd;	/* &#x5185;&#x6838;&#x7684;kswapd&#x8FDB;&#x7A0B;&#x63CF;&#x8FF0;&#x7B26; */
	int kswapd_order; // kswapd&#x8981;&#x521B;&#x5EFA;&#x7684;&#x7A7A;&#x95F2;&#x5757;&#x5927;&#x5C0F;
	......
#ifdef CONFIG_COMPACTION
    ......
#endif
	......
#ifdef CONFIG_NUMA
	/*
	 * node reclaim becomes active if more unmapped pages exist.
	 */
	unsigned long		min_unmapped_pages;
	unsigned long		min_slab_pages;
#endif /* CONFIG_NUMA */

	/* Write-intensive fields used by page reclaim */
	CACHELINE_PADDING(_pad1_);

#ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT
	......
#endif /* CONFIG_DEFERRED_STRUCT_PAGE_INIT */
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
	struct deferred_split deferred_split_queue;
#endif

#ifdef CONFIG_NUMA_BALANCING
	......
#endif
	......
	/* Per-node vmstats */
	struct per_cpu_nodestat __percpu *per_cpu_nodestats; // &#x7528;&#x6765;&#x63CF;&#x8FF0;node&#x72B6;&#x6001;&#x7684;&#x6570;&#x636E;
	atomic_long_t		vm_stat[NR_VM_NODE_STAT_ITEMS];
	......
} pg_data_t;
</code></pre>
<p>&#x5728;X86&#x4E2D;&#xFF0C;&#x4F7F;&#x7528;node_data&#x6765;&#x5B58;&#x50A8;&#x6240;&#x6709;node&#x4E2D;&#x7684;pglist_data&#x6570;&#x636E;&#x7ED3;&#x6784;&#xFF0C;&#x5176;&#x4E2D;nid&#x5C31;&#x662F;&#x8868;&#x793A;numa&#x7684;id&#x3002;</p>
<pre><code class="language-cpp">extern struct pglist_data *node_data[];
#define NODE_DATA(nid)		(node_data[nid])
</code></pre>
<h2 id="2%E3%80%81%E9%A1%B5%E5%88%86%E9%85%8D%E5%87%BD%E6%95%B0">2&#x3001;&#x9875;&#x5206;&#x914D;&#x51FD;&#x6570;</h2>
<h3 id="21-%E8%AF%B7%E6%B1%82page">2.1 &#x8BF7;&#x6C42;page</h3>
<p><code>alloc_pages</code>&#x4F7F;&#x7528;&#x6765;&#x5206;&#x914D;&#x5BF9;&#x5E94;&#x7684;&#x7269;&#x7406;&#x9875;&#x5E27;&#x7684;&#x51FD;&#x6570;&#xFF0C;&#x5B9E;&#x9645;&#x4E0A;&#x5927;&#x90E8;&#x5206;&#x90E8;&#x5206;&#x64CD;&#x4F5C;&#x662F;&#x4E0D;&#x9700;&#x8981;&#x53BB;&#x5206;&#x914D;&#x7269;&#x7406;&#x5185;&#x5B58;&#x7684;&#xFF0C;&#x56E0;&#x4E3A;&#x7269;&#x7406;&#x5185;&#x5B58;&#x5DF2;&#x7ECF;&#x5206;&#x914D;&#x597D;&#xFF0C;&#x76F4;&#x63A5;&#x4ECE;&#x5185;&#x5B58;&#x6C60;&#x4E2D;&#x76F4;&#x63A5;&#x62FF;&#x5373;&#x53EF;&#xFF08;&#x540E;&#x8FB9;&#x4F1A;&#x8BE6;&#x7EC6;&#x5206;&#x6790;&#xFF09;&#x3002;</p>
<pre><code class="language-cpp">#ifdef CONFIG_NUMA
struct page *alloc_pages(gfp_t gfp, unsigned int order);
......
#else
static inline struct page *alloc_pages(gfp_t gfp_mask, unsigned int order)
{
	return alloc_pages_node(numa_node_id(), gfp_mask, order);
}
#endif
</code></pre>
<p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;&#x5BF9;&#x4E8E;NUMA&#x7684;&#x7CFB;&#x7EDF;&#x6765;&#x8BF4;&#xFF0C;&#x5728;&#x8FDB;&#x884C;&#x9875;&#x9762;&#x5206;&#x914D;&#x7684;&#x65F6;&#xFF0C;&#x4F1A;&#x6839;&#x636E;mempolicy&#x6267;&#x884C;&#x4E09;&#x79CD;&#x4E0D;&#x540C;&#x7684;&#x5206;&#x914D;&#x903B;&#x8F91;&#xFF0C;&#x800C;&#x8BE5;&#x7B56;&#x7565;&#x4E3B;&#x8981;&#x662F;&#x5B9A;&#x4E49;&#x5728;&#x5F53;&#x524D;&#x8FD0;&#x884C;&#x7684;&#x8FDB;&#x7A0B;&#x4E2D;&#x3002;</p>
<ul>
<li>
<p><code>MPOL_INTERLEAVE</code></p>
<p>&#x8868;&#x793A;&#x4EA4;&#x9519;&#x5185;&#x5B58;&#x5206;&#x914D;&#x7B56;&#x7565;&#x3002;&#x5728;&#x8FD9;&#x79CD;&#x7B56;&#x7565;&#x4E0B;&#xFF0C;&#x5185;&#x6838;&#x4F1A;&#x5728;&#x6307;&#x5B9A;&#x7684;&#x4E00;&#x7EC4;NUMA&#x8282;&#x70B9;&#x95F4;&#x4EA4;&#x9519;&#x5206;&#x914D;&#x5185;&#x5B58;&#x3002;&#x8FD9;&#x610F;&#x5473;&#x7740;&#x8FDE;&#x7EED;&#x7684;&#x5185;&#x5B58;&#x9875;&#x4F1A;&#x88AB;&#x5206;&#x6563;&#x5230;&#x4E0D;&#x540C;&#x7684;NUMA&#x8282;&#x70B9;&#x4E0A;&#xFF0C;&#x4ECE;&#x800C;&#x5B9E;&#x73B0;&#x5185;&#x5B58;&#x8BBF;&#x95EE;&#x8D1F;&#x8F7D;&#x7684;&#x5747;&#x8861;&#x3002;&#x8FD9;&#x79CD;&#x7B56;&#x7565;&#x9002;&#x7528;&#x4E8E;&#x8BBF;&#x95EE;&#x6A21;&#x5F0F;&#x4E3A;&#x987A;&#x5E8F;&#x8BBF;&#x95EE;&#x7684;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#xFF0C;&#x4F8B;&#x5982;&#x6D41;&#x5F0F;&#x5904;&#x7406;&#xFF08;streaming&#xFF09;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#xFF0C;&#x56E0;&#x4E3A;&#x5B83;&#x53EF;&#x4EE5;&#x6709;&#x6548;&#x5730;&#x5229;&#x7528;&#x591A;&#x4E2A;&#x8282;&#x70B9;&#x7684;&#x5185;&#x5B58;&#x5E26;&#x5BBD;&#xFF0C;&#x540C;&#x65F6;&#x51CF;&#x5C0F;&#x5355;&#x4E2A;&#x8282;&#x70B9;&#x7684;&#x5185;&#x5B58;&#x8BBF;&#x95EE;&#x538B;&#x529B;&#x3002;</p>
</li>
<li>
<p><code>MPOL_PREFERRED_MANY</code></p>
<p>&#x8868;&#x793A;&#x4F18;&#x5148;&#x591A;&#x8282;&#x70B9;&#x5185;&#x5B58;&#x5206;&#x914D;&#x7B56;&#x7565;&#x3002;&#x5728;&#x8FD9;&#x79CD;&#x7B56;&#x7565;&#x4E0B;&#xFF0C;&#x5185;&#x6838;&#x4F1A;&#x4F18;&#x5148;&#x5728;&#x6307;&#x5B9A;&#x7684;&#x591A;&#x4E2A;NUMA&#x8282;&#x70B9;&#x4E2D;&#x5206;&#x914D;&#x5185;&#x5B58;&#x3002;&#x5F53;&#x5185;&#x5B58;&#x9700;&#x6C42;&#x65E0;&#x6CD5;&#x5728;&#x4F18;&#x5148;&#x8282;&#x70B9;&#x4E0A;&#x5F97;&#x5230;&#x6EE1;&#x8DB3;&#x65F6;&#xFF0C;&#x5185;&#x6838;&#x4F1A;&#x5C1D;&#x8BD5;&#x5728;&#x5176;&#x4ED6;&#x8282;&#x70B9;&#x4E0A;&#x5206;&#x914D;&#x5185;&#x5B58;&#x3002;&#x8FD9;&#x79CD;&#x7B56;&#x7565;&#x9002;&#x7528;&#x4E8E;&#x5BF9;&#x5185;&#x5B58;&#x8BBF;&#x95EE;&#x5EF6;&#x8FDF;&#x654F;&#x611F;&#x7684;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#xFF0C;&#x56E0;&#x4E3A;&#x5B83;&#x53EF;&#x4EE5;&#x786E;&#x4FDD;&#x5185;&#x5B58;&#x5206;&#x914D;&#x5C3D;&#x53EF;&#x80FD;&#x5730;&#x9760;&#x8FD1;&#x4F18;&#x5148;&#x7684;NUMA&#x8282;&#x70B9;&#xFF0C;&#x4ECE;&#x800C;&#x51CF;&#x5C0F;&#x5185;&#x5B58;&#x8BBF;&#x95EE;&#x5EF6;&#x8FDF;&#x3002;</p>
</li>
</ul>
<pre><code class="language-cpp">struct page *alloc_pages(gfp_t gfp, unsigned order)
{
	struct mempolicy *pol = &amp;default_policy;
	struct page *page;

	if (!in_interrupt() &amp;&amp; !(gfp &amp; __GFP_THISNODE))
		pol = get_task_policy(current);

	/*
	 * No reference counting needed for current-&gt;mempolicy
	 * nor system default_policy
	 */
	if (pol-&gt;mode == MPOL_INTERLEAVE)
		page = alloc_page_interleave(gfp, order, interleave_nodes(pol));
	else if (pol-&gt;mode == MPOL_PREFERRED_MANY)
		page = alloc_pages_preferred_many(gfp, order,
				  policy_node(gfp, pol, numa_node_id()), pol);
	else
		page = __alloc_pages(gfp, order,
				policy_node(gfp, pol, numa_node_id()),
				policy_nodemask(gfp, pol));

	return page;
}
EXPORT_SYMBOL(alloc_pages);

</code></pre>
<p>&#x5982;&#x679C;&#x662F;&#x4E00;&#x4E2A;&#x4E0D;&#x652F;&#x6301;NUMA&#x7684;&#x7CFB;&#x7EDF;&#xFF0C;&#x5219;&#x901A;&#x8FC7;&#x4E00;&#x5217;&#x8C03;&#x7528;&#xFF0C;&#x6700;&#x7EC8;&#x4F1A;&#x8C03;&#x7528;&#x5230;<code>alloc_pages</code>-&gt;<code>alloc_pages_node</code>-&gt;<code>__alloc_pages_node</code>-&gt;<code>__alloc_pages</code>&#xFF0C;&#x5176;&#x5B9E;&#x6700;&#x7EC8;&#x7684;&#x5DEE;&#x522B;&#x5C31;&#x662F;&#x53EA;&#x4E3A;&#x4E86;&#x4E00;&#x4E2A;NUMA&#x8FDB;&#x884C;&#x5206;&#x914D;&#x3002;</p>
<p>&#x901A;&#x8FC7;&#x6CE8;&#x91CA;&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;alloc&#x5176;&#x5B9E;&#x662F;&#x4ECE;&#x4F19;&#x4F34;&#x7CFB;&#x7EDF;&#x6838;&#x5FC3;&#x90E8;&#x5206;&#xFF0C;&#x5B83;&#x7528;&#x4E8E;&#x5206;&#x914D;&#x8FDE;&#x7EED;&#x7684;&#x7269;&#x7406;&#x5185;&#x5B58;&#x9875;&#x3002;</p>
<pre><code class="language-cpp">/*
 * This is the &apos;heart&apos; of the zoned buddy allocator.
 */
struct page *__alloc_pages(gfp_t gfp, unsigned int order, int preferred_nid,
							nodemask_t *nodemask)
{
	......
	/*
	 * Apply scoped allocation constraints. This is mainly about GFP_NOFS
	 * resp. GFP_NOIO which has to be inherited for all allocation requests
	 * from a particular context which has been marked by
	 * memalloc_no{fs,io}_{save,restore}. And PF_MEMALLOC_PIN which ensures
	 * movable zones are not used during allocation.
	 */
	gfp = current_gfp_context(gfp); // &#x83B7;&#x53D6;&#x5F53;&#x524D;&#x7684;&#x8BF7;&#x6C42;&#x9875;&#x6846;&#x7684;&#x6807;&#x5FD7;
	alloc_gfp = gfp;
	......

	/* First allocation attempt */
	page = get_page_from_freelist(alloc_gfp, order, alloc_flags, &amp;ac); // &#x5C1D;&#x8BD5;&#x76F4;&#x63A5;&#x4ECE;&#x4F19;&#x4F34;&#x7CFB;&#x7EDF;&#x4E2D;&#x62FF;&#x5230;&#x7A7A;&#x95F2;&#x9875;
	if (likely(page))
		goto out;
	......
	page = __alloc_pages_slowpath(alloc_gfp, order, &amp;ac); // &#x4F19;&#x4F34;&#x7CFB;&#x7EDF;&#x4E2D;&#x6CA1;&#x627E;&#x5230;&#x5219;&#x8FDB;&#x884C;&#x6162;&#x901F;&#x5206;&#x914D;
out:
	......
	return page;
}
EXPORT_SYMBOL(__alloc_pages);
</code></pre>
<p>&#x8BF7;&#x6C42;&#x9875;&#x7684;&#x6807;&#x5FD7;&#x4F4D;&#x88AB;&#x5B9A;&#x4E49;&#x5728;&#x4E86;<code>include/linux/gfp_types.h</code></p>
<pre><code class="language-cpp">#define __GFP_RECLAIMABLE ((__force gfp_t)___GFP_RECLAIMABLE)
#define __GFP_WRITE	((__force gfp_t)___GFP_WRITE)
#define __GFP_HARDWALL   ((__force gfp_t)___GFP_HARDWALL)
#define __GFP_THISNODE	((__force gfp_t)___GFP_THISNODE)
#define __GFP_ACCOUNT	((__force gfp_t)___GFP_ACCOUNT)
#define __GFP_RECLAIMABLE ((__force gfp_t)___GFP_RECLAIMABLE)
#define __GFP_WRITE	((__force gfp_t)___GFP_WRITE)
#define __GFP_HARDWALL   ((__force gfp_t)___GFP_HARDWALL)
#define __GFP_THISNODE	((__force gfp_t)___GFP_THISNODE)
#define __GFP_ACCOUNT	((__force gfp_t)___GFP_ACCOUNT)
......
</code></pre>
<p>&#x5176;&#x7528;&#x9014;&#x4E3B;&#x8981;&#x662F;&#x7528;&#x6765;&#x6307;&#x660E;&#x4ECE;&#x54EA;&#x91CC;&#x5982;&#x4F55;&#x5BFB;&#x627E;&#x7A7A;&#x95F2;&#x7684;&#x9875;&#x6846;&#xFF0C;&#x5305;&#x62EC;&#x7269;&#x7406;&#x5185;&#x5B58;&#x7684;&#x533A;&#x57DF;&#xFF0C;&#x5982;<code>__GFP_DMA</code>&#x542B;&#x4E49;&#x662F;&#x4ECE;DMA&#x533A;&#x83B7;&#x53D6;&#x7A7A;&#x95F2;&#x9875;&#xFF0C;&#x6BCF;&#x4E00;&#x5177;&#x4F53;&#x7684;&#x5B9A;&#x4E49;&#x5728;&#x5185;&#x6838;&#x6709;&#x8BE6;&#x7EC6;&#x7684;&#x6CE8;&#x91CA;&#x8FDB;&#x884C;&#x8BF4;&#x660E;&#x3002;</p>
<p>&#x5185;&#x6838;&#x4E2D;&#x5B9E;&#x9645;&#x4E0A;&#x4F7F;&#x7528;&#x5404;&#x79CD;&#x6807;&#x5FD7;&#x7684;&#x7EC4;&#x5408;&#x8FDB;&#x884C;&#x5185;&#x5B58;&#x5206;&#x914D;&#xFF0C;&#x6BD4;&#x8F83;&#x5E38;&#x7528;&#x7684;&#x51E0;&#x79CD;&#x5177;&#x4F53;flag&#x5982;&#x4E0B;</p>
<pre><code class="language-cpp">#define GFP_ATOMIC	(__GFP_HIGH|__GFP_KSWAPD_RECLAIM)
#define GFP_KERNEL	(__GFP_RECLAIM | __GFP_IO | __GFP_FS)
#define GFP_KERNEL_ACCOUNT (GFP_KERNEL | __GFP_ACCOUNT)
#define GFP_NOWAIT	(__GFP_KSWAPD_RECLAIM)
#define GFP_NOIO	(__GFP_RECLAIM)
#define GFP_NOFS	(__GFP_RECLAIM | __GFP_IO)
#define GFP_USER	(__GFP_RECLAIM | __GFP_IO | __GFP_FS | __GFP_HARDWALL)
#define GFP_DMA		__GFP_DMA
#define GFP_DMA32	__GFP_DMA32
#define GFP_HIGHUSER	(GFP_USER | __GFP_HIGHMEM)
#define GFP_HIGHUSER_MOVABLE	(GFP_HIGHUSER | __GFP_MOVABLE | __GFP_SKIP_KASAN)
#define GFP_TRANSHUGE_LIGHT	((GFP_HIGHUSER_MOVABLE | __GFP_COMP | \
			 __GFP_NOMEMALLOC | __GFP_NOWARN) &amp; ~__GFP_RECLAIM)
#define GFP_TRANSHUGE	(GFP_TRANSHUGE_LIGHT | __GFP_DIRECT_RECLAIM)
</code></pre>
<p>&#x800C;&#x5728;&#x5206;&#x914D;&#x7684;&#x5B9E;&#x9645;&#x8FC7;&#x7A0B;&#x4E2D;&#xFF0C;&#x5185;&#x6838;&#x9996;&#x5148;&#x4F1A;&#x5C1D;&#x8BD5;&#x4ECE;&#x4F19;&#x4F34;&#x7CFB;&#x7EDF;&#x7684;&#x7A7A;&#x95F2;&#x9875;&#x94FE;&#x8868;&#x4E2D;&#x5206;&#x914D;&#x5185;&#x5B58;&#x9875;&#xFF0C;&#x5982;&#x679C;&#x5931;&#x8D25;&#x4E86;&#x6570;&#x8FDB;&#x884C;&#x6162;&#x901F;&#x8DEF;&#x5F84;&#x5206;&#x914D;&#x3002;&#x8FD9;&#x4E2A;&#x8FC7;&#x7A0B;&#x53EF;&#x80FD;&#x4F1A;&#x89E6;&#x53D1;&#x5185;&#x5B58;&#x56DE;&#x6536;&#x3001;&#x5185;&#x5B58;&#x538B;&#x7F29;&#x7B49;&#x64CD;&#x4F5C;&#xFF0C;&#x4EE5;&#x4FBF;&#x5728;&#x5185;&#x5B58;&#x7D27;&#x5F20;&#x7684;&#x60C5;&#x51B5;&#x4E0B;&#x627E;&#x5230;&#x8DB3;&#x591F;&#x7684;&#x7A7A;&#x95F2;&#x9875;&#x3002;&#x4F19;&#x4F34;&#x7CFB;&#x7EDF;&#x7684;&#x90E8;&#x5206;&#x540E;&#x8FB9;&#x8BE6;&#x7EC6;&#x5206;&#x6790;&#xFF0C;&#x8FD9;&#x91CC;&#x76F4;&#x63A5;&#x5173;&#x6CE8;&#x6162;&#x901F;&#x5206;&#x914D;&#x8DEF;&#x5F84;&#x3002;</p>
<p>&#x5177;&#x4F53;&#x7684;&#x64CD;&#x4F5C;&#x5728;&#x4EE3;&#x7801;&#x4E2D;&#x8FDB;&#x884C;&#x6CE8;&#x91CA;&#x3002;&#x4EE3;&#x7801;&#x5F88;&#x957F;&#xFF0C;&#x7701;&#x7565;&#x4E86;&#x4E00;&#x4E9B;&#x4EE3;&#x7801;&#xFF0C;&#x5176;&#x4E2D;&#x5FFD;&#x7565;&#x4E86;&#x4E00;&#x4E9B;&#x5206;&#x914D;&#x5185;&#x5B58;&#x6807;&#x5FD7;&#x7684;&#x68C0;&#x67E5;&#xFF0C;&#x5728;&#x72B6;&#x6001;&#x4E0D;&#x7B26;&#x5408;&#x6211;&#x4EEC;&#x8BBE;&#x5B9A;&#x7684;&#x72B6;&#x6001;&#x63CF;&#x8FF0;&#x7B26;&#x65F6;&#xFF0C;&#x5219;&#x4F1A;&#x76F4;&#x63A5;&#x8FD4;&#x56DE;&#xFF0C;&#x4F8B;&#x5982;&#x6211;&#x4EEC;&#x6807;&#x8BB0;&#x4E86;<code>PF_MEMALLOC</code>&#x90A3;&#x4E48;&#x5219;&#x4E0D;&#x4F1A;&#x5C1D;&#x8BD5;&#x8FDB;&#x884C;&#x5185;&#x5B58;&#x538B;&#x7F29;&#x5206;&#x914D;&#x3002;</p>
<pre><code class="language-cpp">static inline struct page *
__alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
						struct alloc_context *ac)
{
	......
restart:
  /*&#x521D;&#x59CB;&#x5316;&#x53D8;&#x91CF;&#xFF0C;&#x4F8B;&#x5982;&#x91CD;&#x8BD5;&#x8BA1;&#x6570;&#x5668;&#x3001;&#x4F18;&#x5148;&#x7EA7;&#x7B49;&#x3002;*/
	compaction_retries = 0;
	......

	/*
	 * &#x6839;&#x636E;GFP&#x6807;&#x5FD7;&#x548C;order&#x8C03;&#x6574;alloc_flags
	 */
	alloc_flags = gfp_to_alloc_flags(gfp_mask, order);
	......
	if (alloc_flags &amp; ALLOC_KSWAPD)
		wake_all_kswapds(order, gfp_mask, ac); // &#x5982;&#x679C;&#x88AB;&#x6807;&#x8BB0;&#x4E86;kswapd&#x7684;&#x56DE;&#x6536;
 
	// &#x8FD8;&#x662F;&#x9996;&#x5148;&#x5C1D;&#x8BD5;&#x4ECE;&#x4F19;&#x4F34;&#x7CFB;&#x7EDF;&#x91CC;&#x76F4;&#x63A5;&#x62FF;&#x7A7A;&#x95F2;&#x9875;
	page = get_page_from_freelist(gfp_mask, order, alloc_flags, ac);
	if (page)
		goto got_pg;

	/*
	 * &#x5982;&#x679C;&#x53EF;&#x4EE5;&#x76F4;&#x63A5;&#x56DE;&#x6536;&#x5E76;&#x4E14;&#x5206;&#x914D;&#x7684;order&#x8F83;&#x9AD8;&#x6216;&#x8005;&#x975E;MIGRATE_MOVABLE&#x7C7B;&#x578B;&#xFF0C;
	 * &#x5C1D;&#x8BD5;&#x76F4;&#x63A5;&#x538B;&#x7F29;&#x5185;&#x5B58;&#xFF0C;&#x7136;&#x540E;&#x5206;&#x914D;
	 */
	if (can_direct_reclaim &amp;&amp;
			(costly_order ||
			   (order &gt; 0 &amp;&amp; ac-&gt;migratetype != MIGRATE_MOVABLE))
			&amp;&amp; !gfp_pfmemalloc_allowed(gfp_mask)) {
		page = __alloc_pages_direct_compact(gfp_mask, order,
						alloc_flags, ac,
						INIT_COMPACT_PRIORITY,
						&amp;compact_result);
		if (page)
			goto got_pg;

		/*
		 * &#x68C0;&#x67E5;&#x6807;&#x8BB0;&#x662F;&#x4E0D;&#x662F;&#x9AD8;&#x6D88;&#x8017;&#x7684;&#x64CD;&#x4F5C;&#xFF0C;&#x4F8B;&#x5982;&#x900F;&#x660E;&#x5927;&#x9875;&#x7684;&#x5206;&#x914D;&#x64CD;&#x4F5C;
		 */
		if (costly_order &amp;&amp; (gfp_mask &amp; __GFP_NORETRY)) {
			if (compact_result == COMPACT_SKIPPED ||
			    compact_result == COMPACT_DEFERRED)
				goto nopage;

			compact_priority = INIT_COMPACT_PRIORITY;
		}
	}

retry:
	/* Ensure kswapd doesn&apos;t accidentally go to sleep as long as we loop */
	if (alloc_flags &amp; ALLOC_KSWAPD)
		wake_all_kswapds(order, gfp_mask, ac); // &#x5728;retry&#x4E2D;&#x518D;&#x6B21;&#x6267;&#x884C;&#x4E00;&#x6B21;kswapd
	......
	/* &#x5C1D;&#x8BD5;&#x4ECE;&#x7A7A;&#x95F2;&#x5217;&#x8868;&#x4E2D;&#x5206;&#x914D;&#x5185;&#x5B58;&#x9875;*/
	page = get_page_from_freelist(gfp_mask, order, alloc_flags, ac);
	if (page)
		goto got_pg;
	.......
	/* &#x6267;&#x884C;&#x56DE;&#x6536;page&#xFF0C;&#x518D;&#x5206;&#x914D; */
	page = __alloc_pages_direct_reclaim(gfp_mask, order, alloc_flags, ac,
							&amp;did_some_progress);
	if (page)
		goto got_pg;

	/* &#x6267;&#x884C;&#x538B;&#x7F29;page&#xFF0C;&#x5728;&#x5206;&#x914D; */
	page = __alloc_pages_direct_compact(gfp_mask, order, alloc_flags, ac,
					compact_priority, &amp;compact_result);
	if (page)
		goto got_pg;
	......
  /*&#x6839;&#x636E;&#x56DE;&#x6536;&#x538B;&#x7F29;&#x7684;&#x6548;&#x679C;&#xFF0C;&#x5224;&#x65AD;&#x662F;&#x5426;&#x8981;&#x6267;&#x884C;retry*/
	if (should_reclaim_retry(gfp_mask, order, ac, alloc_flags,
				 did_some_progress &gt; 0, &amp;no_progress_loops))
		goto retry;

	if (did_some_progress &gt; 0 &amp;&amp;
			should_compact_retry(ac, order, alloc_flags,
				compact_result, &amp;compact_priority,
				&amp;compaction_retries))
		goto retry;

	/*
	 * &#x63A5;&#x4E0B;&#x6765;&#x5C31;&#x8981;&#x6267;&#x884C;oom&#x4E86;&#xFF0C;&#x518D;&#x6B21;&#x4E4B;&#x524D;&#x8981;&#x518D;&#x786E;&#x8BA4;&#x4E0B;&#x662F;&#x4E0D;&#x662F;&#x6709;&#x5176;&#x4ED6;&#x7684;zone&#x6216;&#x8005;set&#x53EF;&#x4EE5;&#x5206;&#x914D;
	 */
	if (check_retry_cpuset(cpuset_mems_cookie, ac) ||
	    check_retry_zonelist(zonelist_iter_cookie))
		goto restart;

	/* &#x5982;&#x679C;&#x524D;&#x8FB9;&#x7684;&#x64CD;&#x4F5C;&#x90FD;&#x5931;&#x8D25;&#x4E86;&#xFF0C;&#x90A3;&#x4E48;&#x5C31;&#x4F1A;&#x5C1D;&#x8BD5;&#x6267;&#x884C;oom&#x6E05;&#x7406;&#x4E00;&#x4E9B;&#x8FDB;&#x7A0B;&#x6765;&#x56DE;&#x6536;&#x5185;&#x5B58; */
	page = __alloc_pages_may_oom(gfp_mask, order, ac, &amp;did_some_progress);
	if (page)
		goto got_pg;
  ......
	/* oom&#x7684;&#x65F6;&#x5019;&#x4F1A;&#x6807;&#x8BB0;did_some_progress&#xFF0C;&#x90A3;&#x4E48;&#x6B64;&#x65F6;&#x6211;&#x4EEC;&#x5C31;&#x5FAA;&#x73AF;&#x6267;&#x884C;&#x5206;&#x914D;*/
	if (did_some_progress) { 
		no_progress_loops = 0;
		goto retry;
	}

nopage:
	/*
	 * &#x786E;&#x8BA4;&#x4E0B;&#x662F;&#x4E0D;&#x662F;&#x6709;&#x5176;&#x4ED6;&#x7684;zone&#x6216;&#x8005;set&#x53EF;&#x4EE5;&#x5206;&#x914D;&#x5185;&#x5B58;
	 */
	if (check_retry_cpuset(cpuset_mems_cookie, ac) ||
	    check_retry_zonelist(zonelist_iter_cookie))
		goto restart;

	...... // &#x5FFD;&#x7565;&#x4E86;&#x6839;&#x636E;&#x63CF;&#x8FF0;&#x7B26;&#x8FDB;&#x884C;&#x7684;&#x4E00;&#x4E9B;&#x9519;&#x8BEF;&#x5904;&#x7406;&#x8F93;&#x51FA;

		/*&#x5728;&#x5185;&#x5B58;&#x4FDD;&#x7559;&#x533A;&#x57DF;&#x4E2D;&#x5206;&#x914D;&#x5185;&#x5B58;*/
		page = __alloc_pages_cpuset_fallback(gfp_mask, order, ALLOC_MIN_RESERVE, ac);
		if (page)
			goto got_pg;

		cond_resched(); // &#x5982;&#x679C;&#x8FD8;&#x662F;&#x5931;&#x8D25;&#xFF0C;&#x90A3;&#x4E48;&#x9996;&#x5148;&#x4F1A;&#x5148;&#x8BA9;&#x51FA;cpu&#xFF0C;&#x540E;&#x8FB9;&#x5C1D;&#x8BD5;&#x518D;&#x6B21;&#x5206;&#x914D;
		goto retry;
	}
fail:
	warn_alloc(gfp_mask, ac-&gt;nodemask,
			&quot;page allocation failure: order:%u&quot;, order);
got_pg:
	return page;
}
</code></pre>
<h3 id="23-%E9%87%8A%E6%94%BEpage">2.3 &#x91CA;&#x653E;page</h3>
<p>&#x5185;&#x6838;&#x4E2D;&#x6709;&#x51E0;&#x4E2A;&#x51FD;&#x6570;&#x7528;&#x4E8E;&#x91CA;&#x653E;&#x5206;&#x914D;&#x597D;&#x7684;&#x7269;&#x7406;&#x9875;&#x6846;</p>
<ul>
<li><code>__free_pages</code></li>
<li><code>fress_pages</code></li>
<li><code>__free_page</code></li>
<li><code>free_page</code></li>
</ul>
<p>&#x4E0D;&#x5E26;s&#x7684;api&#x4E3B;&#x8981;&#x662F;&#x91CA;&#x653E;&#x5355;&#x72EC;&#x7684;&#x9875;&#x9762;&#xFF0C;&#x800C;&#x5E26;s&#x5219;&#x662F;&#x91CA;&#x653E;&#x8FDE;&#x7EED;&#x7684;page&#x3002;</p>
<p><code>fress_pages</code>&#x5219;&#x4F1A;&#x8C03;&#x7528;&#x5230;<code>__free_pages</code>&#xFF0C;&#x5B83;&#x5C06;&#x8FDE;&#x7EED;&#x7684;&#x5185;&#x5B58;&#x9875;&#x5F52;&#x8FD8;&#x7ED9;&#x4F19;&#x4F34;&#x7CFB;&#x7EDF;&#xFF08;buddy allocator&#xFF09;&#xFF0C;&#x4EE5;&#x4FBF;&#x5728;&#x540E;&#x7EED;&#x7684;&#x5185;&#x5B58;&#x5206;&#x914D;&#x4E2D;&#x91CD;&#x590D;&#x4F7F;&#x7528;&#x8FD9;&#x4E9B;&#x5185;&#x5B58;&#x9875;&#x3002;</p>
<pre><code class="language-cpp">void __free_pages(struct page *page, unsigned int order)
{
	/* get PageHead before we drop reference */
	int head = PageHead(page);

	if (put_page_testzero(page)) // &#x9012;&#x51CF;page&#x7684;&#x5F15;&#x7528;&#x8BA1;&#x6570;
		free_the_page(page, order); // &#x5C06;page&#x8FD8;&#x7ED9;&#x4F19;&#x4F34;&#x7CFB;&#x7EDF;
	else if (!head)// &#x5982;&#x679C;&#x4E0D;&#x662F;&#x9875;&#x7684;&#x5934;&#x90E8;&#xFF0C;&#x5219;&#x5FAA;&#x73AF;&#x56DE;&#x6536;&#x590D;&#x5408;&#x9875;&#x5176;&#x4ED6;&#x9875;
		while (order-- &gt; 0)
			free_the_page(page + (1 &lt;&lt; order), order);
}
EXPORT_SYMBOL(__free_pages);
</code></pre>
<p>&#x503C;&#x5F97;&#x8BF4;&#x7684;&#x662F;<code>PageHead(page)</code>&#x5B8F;&#x6765;&#x68C0;&#x67E5;&#x7ED9;&#x5B9A;&#x7684;<code>page</code>&#x662F;&#x5426;&#x4E3A;&#x590D;&#x5408;&#x9875;&#xFF08;compound page&#xFF09;&#x7684;&#x5934;&#x90E8;&#x3002;&#x5C06;&#x7ED3;&#x679C;&#x5B58;&#x50A8;&#x5728;<code>head</code>&#x53D8;&#x91CF;&#x4E2D;&#x3002;&#x590D;&#x5408;&#x9875;&#x662F;&#x4E00;&#x79CD;&#x7528;&#x4E8E;&#x8868;&#x793A;&#x8F83;&#x5927;&#x8FDE;&#x7EED;&#x5185;&#x5B58;&#x5757;&#x7684;&#x673A;&#x5236;&#xFF0C;&#x5B83;&#x5C06;&#x591A;&#x4E2A;&#x8FDE;&#x7EED;&#x7684;&#x7269;&#x7406;&#x9875;&#x7EC4;&#x5408;&#x6210;&#x4E00;&#x4E2A;&#x903B;&#x8F91;&#x4E0A;&#x7684;&#x5927;&#x9875;&#x3002;</p>
<p>&#x5728;&#x5177;&#x4F53;&#x91CA;&#x653E;&#x7684;&#x8FC7;&#x7A0B;&#x4E2D;&#xFF0C;&#x8FD8;&#x4F1A;&#x533A;&#x5206;&#x662F;&#x4E0D;&#x662F;per_cpu&#x9875;</p>
<pre><code class="language-cpp">static inline void free_the_page(struct page *page, unsigned int order)
{
	if (pcp_allowed_order(order))		/* Via pcp? */
		free_unref_page(page, order); // &#x91CA;&#x653E;per_cpu&#x9875;&#x7ED9;CPU cache
	else
		__free_pages_ok(page, order, FPI_NONE); // &#x91CA;&#x653E;&#x6B63;&#x5E38;&#x9875;
}
</code></pre>
<p>&#x63A5;&#x4E0B;&#x6765;&#x5C31;&#x4F1A;&#x904D;&#x5386;&#x5FAA;&#x73AF;<code>order</code>&#x53D8;&#x91CF;&#xFF0C;&#x5C06;page&#x6362;&#x4E2A;&#x4F19;&#x4F34;&#x7CFB;&#x7EDF;&#xFF0C;&#x5177;&#x4F53;&#x8BE6;&#x7EC6;&#x7684;&#x90E8;&#x5206;&#x6211;&#x4EEC;&#x540E;&#x8FB9;&#x5206;&#x6790;&#x4F19;&#x4F34;&#x7CFB;&#x7EDF;&#x65F6;&#x8FDB;&#x4E00;&#x6B65;&#x8BA8;&#x8BBA;&#x3002;</p>
]]></content:encoded></item><item><title><![CDATA[内存管理2_伙伴系统]]></title><description><![CDATA[<h2 id="1%E3%80%81%E8%83%8C%E6%99%AF%E5%88%86%E6%9E%90">1&#x3001;&#x80CC;&#x666F;&#x5206;&#x6790;</h2>
<p>Linux&#x5185;&#x6838;&#x9700;&#x8981;&#x6709;&#x6548;&#x5730;&#x7BA1;&#x7406;&#x5185;&#x5B58;&#xFF0C;&#x4EE5;&#x652F;&#x6301;&#x5404;&#x79CD;&#x7C7B;&#x578B;&#x7684;&#x5E94;&#x7528;&#x548C;&#x670D;&#x52A1;&#x3002;&#x4F20;&#x7EDF;&#x7684;&#x5185;&#x5B58;&#x5206;&#x914D;&#x65B9;&#x6CD5;&#xFF08;&#x5982;&#x8FDE;&#x7EED;&#x5185;&#x5B58;&#x5206;&#x914D;</p>]]></description><link>http://www.korantli.com.cn/nei-cun-guan-li-2_huo-ban-xi-tong/</link><guid isPermaLink="false">655c79eab936e6d99568cc42</guid><category><![CDATA[linux内存管理]]></category><category><![CDATA[linux内存管理文章]]></category><dc:creator><![CDATA[李星辉]]></dc:creator><pubDate>Tue, 21 Nov 2023 09:36:27 GMT</pubDate><media:content url="http://www.korantli.com.cn/content/images/2024/01/DALL-E-2024-01-02-21.06.49-3.jpg" medium="image"/><content:encoded><![CDATA[<h2 id="1%E3%80%81%E8%83%8C%E6%99%AF%E5%88%86%E6%9E%90">1&#x3001;&#x80CC;&#x666F;&#x5206;&#x6790;</h2>
<img src="http://www.korantli.com.cn/content/images/2024/01/DALL-E-2024-01-02-21.06.49-3.jpg" alt="&#x5185;&#x5B58;&#x7BA1;&#x7406;2_&#x4F19;&#x4F34;&#x7CFB;&#x7EDF;"><p>Linux&#x5185;&#x6838;&#x9700;&#x8981;&#x6709;&#x6548;&#x5730;&#x7BA1;&#x7406;&#x5185;&#x5B58;&#xFF0C;&#x4EE5;&#x652F;&#x6301;&#x5404;&#x79CD;&#x7C7B;&#x578B;&#x7684;&#x5E94;&#x7528;&#x548C;&#x670D;&#x52A1;&#x3002;&#x4F20;&#x7EDF;&#x7684;&#x5185;&#x5B58;&#x5206;&#x914D;&#x65B9;&#x6CD5;&#xFF08;&#x5982;&#x8FDE;&#x7EED;&#x5185;&#x5B58;&#x5206;&#x914D;&#xFF09;&#x5B58;&#x5728;&#x4E00;&#x4E9B;&#x4E0D;&#x8DB3;&#xFF0C;&#x4F8B;&#x5982;&#x5185;&#x5B58;&#x788E;&#x7247;&#x548C;&#x5206;&#x914D;&#x6548;&#x7387;&#x4F4E;&#x4E0B;&#x3002;&#x9891;&#x7E41;&#x7684;&#x7533;&#x8BF7;&#x548C;&#x91CA;&#x653E;&#x4E0D;&#x540C;&#x5927;&#x5C0F;&#x7684;&#x8FDE;&#x7EED;&#x9875;&#x6846;&#x5FC5;&#x7136;&#x4F1A;&#x5BFC;&#x81F4;&#x5DF2;&#x5206;&#x914D;&#x7684;&#x9875;&#x6846;&#x5757;&#x5206;&#x6563;&#x4E86;&#x8BB8;&#x591A;&#x5C0F;&#x5757;&#x7684;&#x7A7A;&#x95F2;&#x9875;&#x6846;&#xFF0C;&#x53EF;&#x80FD;&#x4F1A;&#x4EA7;&#x751F;&#x7684;&#x95EE;&#x9898;&#x5C31;&#x662F;&#xFF1A;&#x5373;&#x4F7F;&#x5185;&#x5B58;&#x9875;&#x6846;&#x662F;&#x5145;&#x8DB3;&#x7684;&#xFF0C;&#x4F46;&#x8981;&#x7533;&#x8BF7;&#x4E00;&#x4E2A;&#x5927;&#x7684;&#x9875;&#x6846;&#x53EF;&#x80FD;&#x4E5F;&#x4F1A;&#x56E0;&#x4E3A;&#x6CA1;&#x6709;&#x8DB3;&#x591F;&#x7684;&#x8FDE;&#x7EED;&#x9875;&#x6846;&#x800C;&#x5931;&#x8D25;&#x3002;</p>
<p>&#x4E3A;&#x4E86;&#x907F;&#x514D;&#x5185;&#x5B58;&#x788E;&#x7247;&#x5316;&#x800C;&#x5F15;&#x53D1;&#x4E0A;&#x8FF0;&#x95EE;&#x9898;&#xFF0C;&#x901A;&#x5E38;&#x53EF;&#x4EE5;&#x6709;&#x4E24;&#x79CD;&#x65B9;&#x6CD5;&#xFF1A;</p>
<ol>
<li>&#x4F7F;&#x7528;&#x5206;&#x9875;&#x5355;&#x5143;&#x628A;&#x4E0D;&#x8FDE;&#x7EED;&#x7684;&#x9875;&#x6846;&#x6620;&#x5C04;&#x5230;&#x8FDE;&#x7EED;&#x7684;&#x7EBF;&#x6027;&#x7A7A;&#x95F4;&#x3002;</li>
<li>&#x4F7F;&#x7528;&#x4E00;&#x79CD;&#x9002;&#x5F53;&#x7684;&#x6280;&#x672F;&#x7528;&#x4EE5;&#x8BB0;&#x5F55;&#x5F53;&#x524D;&#x8FDE;&#x7EED;&#x9875;&#x6846;&#x7684;&#x60C5;&#x51B5;&#xFF0C;&#x907F;&#x514D;&#x5206;&#x914D;&#x5C0F;&#x7EC4;&#x8FDE;&#x7EED;&#x9875;&#x6846;&#x7684;&#x65F6;&#x5019;&#x5BF9;&#x5927;&#x7684;&#x9875;&#x6846;&#x8FDB;&#x884C;&#x5207;&#x5272;&#x3002;</li>
</ol>
<p>&#x4E3A;&#x4E86;&#x89E3;&#x51B3;&#x4E0A;&#x8FF0;&#x95EE;&#x9898;&#xFF0C;Linux&#x5185;&#x6838;&#x5F15;&#x5165;&#x4E86;&#x4F19;&#x4F34;&#x7CFB;&#x7EDF;&#xFF08;Buddy System&#xFF09;&#x3002;&#x8FD9;&#x4E3B;&#x8981;&#x662F;&#x56E0;&#x4E3A;&#x5185;&#x6838;&#x4E2D;&#x786E;&#x5B9E;&#x9700;&#x8981;&#x8FDE;&#x7EED;&#x9875;&#x6846;&#xFF0C;&#x5E76;&#x4E14;&#x8FDE;&#x7EED;&#x9875;&#x6846;&#x7684;&#x5B58;&#x5728;&#x6709;&#x52A9;&#x4E8E;&#x4FDD;&#x6301;CPU Cache&#x4E2D;&#x7684;TLB&#x547D;&#x4E2D;&#x7387;&#x3002;</p>
<h2 id="2%E3%80%81%E4%BC%99%E4%BC%B4%E7%B3%BB%E7%BB%9F%E5%8E%9F%E7%90%86">2&#x3001;&#x4F19;&#x4F34;&#x7CFB;&#x7EDF;&#x539F;&#x7406;</h2>
<p>&#x4F19;&#x4F34;&#x7CFB;&#x7EDF;&#x901A;&#x8FC7;&#x5C06;&#x5185;&#x5B58;&#x5206;&#x6210;&#x591A;&#x4E2A;&#x5927;&#x5C0F;&#x76F8;&#x7B49;&#x7684;&#x5757;&#xFF08;block&#xFF09;&#xFF0C;&#x6309;2&#x7684;&#x5E42;&#x6B21;&#x65B9;&#x89C4;&#x5212;&#xFF08;&#x79F0;&#x4E3A;&#x201C;order&#x201D;&#xFF09;&#xFF0C;&#x5E76;&#x7EF4;&#x62A4;&#x4E0D;&#x540C;order&#x7684;&#x7A7A;&#x95F2;&#x5757;&#x94FE;&#x8868;&#x6765;&#x5DE5;&#x4F5C;&#x3002;&#x8FD9;&#x79CD;&#x65B9;&#x6CD5;&#x4F7F;&#x5F97;&#x5185;&#x5B58;&#x7684;&#x5206;&#x914D;&#x548C;&#x91CA;&#x653E;&#x66F4;&#x52A0;&#x9AD8;&#x6548;&#xFF0C;&#x51CF;&#x5C11;&#x4E86;&#x5185;&#x5B58;&#x788E;&#x7247;&#x3002;</p>
<p>&#x4F19;&#x4F34;&#x7CFB;&#x7EDF;&#x5427;&#x5185;&#x5B58;&#x5206;&#x6210;&#x4E86;11&#x4E2A;&#x5757;&#x94FE;&#x8868;&#xFF0C;&#x6BCF;&#x4E2A;&#x94FE;&#x8868;&#x5305;&#x542B;1&#x3001;2&#x3001;4&#x3001;8&#x3001;16&#x3001;32&#x3001;64&#x3001;128&#x3001;256&#x3001;512&#x548C;1024&#x4E2A;&#x8FDE;&#x7EED;&#x9875;&#x6846;&#x5373;2<sup>0~10</sup>&#xFF0C;&#x6700;&#x5927;&#x7684;1024&#x4E2A;&#x9875;&#x6846;&#x5757;&#x5219;&#x662F;4MB&#x7684;&#x5185;&#x5B58;&#x5927;&#x5C0F;&#x3002;</p>
<h3 id="21-%E5%85%B3%E9%94%AE%E6%AD%A5%E9%AA%A4">2.1-&#x5173;&#x952E;&#x6B65;&#x9AA4;</h3>
<ol>
<li><strong>&#x521D;&#x59CB;&#x5316;</strong>&#xFF1A;&#x5185;&#x5B58;&#x5728;&#x7CFB;&#x7EDF;&#x542F;&#x52A8;&#x65F6;&#x88AB;&#x5206;&#x6210;&#x5757;&#xFF0C;&#x6309;order&#x7EC4;&#x7EC7;&#x6210;&#x94FE;&#x8868;&#x3002;</li>
<li><strong>&#x5206;&#x914D;</strong>&#xFF1A;&#x6839;&#x636E;&#x9700;&#x6C42;&#x9009;&#x62E9;&#x5408;&#x9002;&#x5927;&#x5C0F;&#x7684;&#x5757;&#xFF0C;&#x5982;&#x65E0;&#x5408;&#x9002;&#x5757;&#xFF0C;&#x5219;&#x5206;&#x5272;&#x66F4;&#x5927;&#x5757;&#x3002;</li>
<li><strong>&#x91CA;&#x653E;</strong>&#xFF1A;&#x91CA;&#x653E;&#x7684;&#x5757;&#x8FD4;&#x56DE;&#x94FE;&#x8868;&#xFF0C;&#x76F8;&#x90BB;&#x7A7A;&#x95F2;&#x5757;&#x5408;&#x5E76;&#x3002;</li>
</ol>
<h2 id="3%E3%80%81%E4%BC%99%E4%BC%B4%E7%B3%BB%E7%BB%9F%E5%9C%A8linux%E4%B8%AD%E7%9A%84%E5%AE%9E%E7%8E%B0">3&#x3001;&#x4F19;&#x4F34;&#x7CFB;&#x7EDF;&#x5728;linux&#x4E2D;&#x7684;&#x5B9E;&#x73B0;</h2>
<h3 id="31-freearea">3.1-<code>free_area</code></h3>
<ul>
<li><code>struct free_area</code>&#xFF1A;&#x5B9A;&#x4E49;&#x7A7A;&#x95F2;&#x5757;&#x94FE;&#x8868;&#x3002;</li>
</ul>
<pre><code class="language-cpp">struct free_area {
	struct list_head	free_list[MIGRATE_TYPES]; // &#x8FDE;&#x7EED;&#x9875;&#x6846;&#x7684;&#x5177;&#x4F53;&#x5730;&#x5740;
	unsigned long		nr_free; // &#x6709;&#x591A;&#x5C11;&#x4E2A;&#x7A7A;&#x95F2;&#x7684;&#x5BF9;&#x5E94;&#x5927;&#x5C0F;&#x7684;&#x9875;&#x6846;
};
</code></pre>
<p>&#x800C;&#x4E0A;&#x8FF0;&#x7ED3;&#x6784;&#x4F53;&#x88AB;&#x5B9A;&#x4E49;&#x5728;&#x4E86;<code>zone</code>&#x7684;&#x7ED3;&#x6784;&#x4F53;&#x4E4B;&#x4E2D;&#xFF0C;&#x53EF;&#x4EE5;&#x770B;&#x5230;&#x6BCF;&#x4E00;&#x4E2A;&#x5185;&#x5B58;&#x533A;&#x91CC;&#x90FD;&#x6709;11&#x4E2A;<code>free_area</code>&#x7ED3;&#x6784;&#x4F53;&#x3002;</p>
<pre><code class="language-cpp">#define MAX_ORDER 10

struct zone {
  ......
	/* free areas of different sizes */
	struct free_area	free_area[MAX_ORDER + 1];
  ......
}
</code></pre>
<p>&#x53EF;&#x4EE5;&#x770B;&#x5230;&#xFF0C;<code>free_area</code>&#x4E2D;&#x7B2C;K&#x4E2A;&#x5143;&#x7D20;&#xFF0C;&#x5BF9;&#x5E94;&#x8FD9;&#x4E2A;2<sup>k</sup>&#x5927;&#x5C0F;&#x7684;&#x8FDE;&#x7EED;&#x9875;&#x9762;&#xFF0C;&#x5982;&#x4E0A;&#x6587;&#x539F;&#x7406;&#x5206;&#x6790;&#xFF0C;&#x6700;&#x591A;&#x662F;2<sup>10</sup>&#x7684;&#x4E5F;&#x5C31;&#x662F;1024&#x4E2A;&#x8FDE;&#x7EED;&#x9875;&#x6846;&#x3002;</p>
<h3 id="32-%E5%88%86%E9%85%8D%E5%87%BD%E6%95%B0">3.2-&#x5206;&#x914D;&#x51FD;&#x6570;</h3>
<p>&#x524D;&#x4E00;&#x7BC7;&#x6587;&#x7AE0;&#x4E2D;&#x6211;&#x4EEC;&#x5206;&#x6790;&#x5230;&#x5185;&#x5B58;&#x7533;&#x8BF7;&#x548C;&#x91CA;&#x653E;&#x9875;&#x6846;&#x8FC7;&#x7A0B;&#x4E2D;&#x662F;&#x5B58;&#x5728;&#x4ECE;&#x4F19;&#x4F34;&#x7CFB;&#x7EDF;&#x76F4;&#x63A5;&#x83B7;&#x53D6;&#x6216;&#x8FD8;&#x539F;&#x7684;&#xFF0C;&#x6240;&#x4EE5;&#x76F4;&#x63A5;&#x5207;&#x5165;&#x5230;&#x8FD9;&#x90E8;&#x5206;&#x4EE3;&#x7801;&#xFF1A;</p>
<pre><code class="language-cpp">/*
 * get_page_from_freelist goes through the zonelist trying to allocate
 * a page.
 */
static struct page *
get_page_from_freelist(gfp_t gfp_mask, unsigned int order, int alloc_flags,
						const struct alloc_context *ac)
{
	......
retry:
	no_fallback = alloc_flags &amp; ALLOC_NOFRAGMENT;
	z = ac-&gt;preferred_zoneref;
  // &#x904D;&#x5386;&#x6240;&#x6709;&#x5185;&#x5B58;&#x533A;&#x57DF;&#xFF08;zones&#xFF09;&#xFF0C;&#x5BFB;&#x627E;&#x6EE1;&#x8DB3;&#x7A7A;&#x95F2;&#x9875;&#x9762;&#x9700;&#x6C42;&#x7684;&#x533A;&#x57DF;&#x3002;
	for_next_zone_zonelist_nodemask(zone, z, ac-&gt;highest_zoneidx,
					ac-&gt;nodemask) {
		struct page *page;
		unsigned long mark;

    // &#x5982;&#x679C;&#x5F53;&#x524D;&#x7684;zone&#x4E0D;&#x53EF;&#x4EE5;&#x7528;&#x7684;&#x8BDD;&#x5219;&#x76F4;&#x63A5;&#x9000;&#x51FA;&#x5F53;&#x524D;&#x7684;&#x904D;&#x5386;
		if (cpusets_enabled() &amp;&amp;
			(alloc_flags &amp; ALLOC_CPUSET) &amp;&amp;
			!__cpuset_zone_allowed(zone, gfp_mask))
				continue;
		......
    // &#x5728;NUMA&#x67B6;&#x6784;&#x4E2D;&#xFF0C;&#x5C3D;&#x91CF;&#x907F;&#x514D;&#x8FDC;&#x7AEF;&#x5185;&#x5B58;&#x7684;&#x5206;&#x914D;&#xFF0C;&#x5982;&#x679C;&#x53D1;&#x73B0;&#x4E0D;&#x662F;&#x672C;&#x5730;&#x7684;&#x5185;&#x5B58;&#x5C31;&#x518D;&#x627E;&#x4E00;&#x6B21;
    // &#x5373;&#x4F7F;&#x4EE3;&#x4EF7;&#x662F;&#x9020;&#x6210;&#x5185;&#x5B58;&#x788E;&#x7247;&#x5316;
		if (no_fallback &amp;&amp; nr_online_nodes &gt; 1 &amp;&amp;
		    zone != ac-&gt;preferred_zoneref-&gt;zone) {
			int local_nid;

			local_nid = zone_to_nid(ac-&gt;preferred_zoneref-&gt;zone);
			if (zone_to_nid(zone) != local_nid) {
				alloc_flags &amp;= ~ALLOC_NOFRAGMENT;
				goto retry;
			}
		}

		/* &#x68C0;&#x67E5;&#x6C34;&#x4F4D;&#x7EBF;&#xFF0C;&#x907F;&#x514D;&#x5185;&#x5B58;&#x8017;&#x5C3D;&#x4E86; */
		if (test_bit(ZONE_BELOW_HIGH, &amp;zone-&gt;flags))
			goto check_alloc_wmark;

		mark = high_wmark_pages(zone);
		if (zone_watermark_fast(zone, order, mark,
					ac-&gt;highest_zoneidx, alloc_flags,
					gfp_mask))
			goto try_this_zone;
		else
			set_bit(ZONE_BELOW_HIGH, &amp;zone-&gt;flags);

// &#x7701;&#x7565;&#x90E8;&#x5206;&#x4E3B;&#x8981;&#x662F;&#x5728;&#x68C0;&#x67E5;&#x6C34;&#x4F4D;&#x7EBF;&#x5931;&#x8D25;&#x65F6;&#x7684;&#x5176;&#x4ED6;&#x5904;&#x7406;&#x903B;&#x8F91;
check_alloc_wmark:
	......
try_this_zone:
    /* &#x5173;&#x952E;&#x7684;&#x5206;&#x914D;&#x51FD;&#x6570;&#xFF0C;&#x5C1D;&#x8BD5;&#x4ECE;&#x5F53;&#x524D;zone&#x533A;&#x57DF;&#x7684;freelist&#x4E2D;&#x5206;&#x914D;page&#x3002;*/
		page = rmqueue(ac-&gt;preferred_zoneref-&gt;zone, zone, order,
				gfp_mask, alloc_flags, ac-&gt;migratetype);
	......
	return NULL;
}
</code></pre>
<p>&#x8FDB;&#x4E00;&#x6B65;&#x4F1A;&#x8C03;&#x7528;&#x5230;<code>rmqueue_buddy</code>-&gt;<code>__rmqueue</code>-&gt;<code>__rmqueue_cma_fallback</code>-&gt;<code>__rmqueue_smallest</code>&#x6267;&#x884C;&#x9875;&#x7684;&#x83B7;&#x53D6;&#x3002;</p>
<pre><code class="language-cpp">/*
 * Go through the free lists for the given migratetype and remove
 * the smallest available page from the freelists
 */
static __always_inline
struct page *__rmqueue_smallest(struct zone *zone, unsigned int order,
						int migratetype)
{
	unsigned int current_order;
	struct free_area *area;
	struct page *page;

	/* Find a page of the appropriate size in the preferred list */
	for (current_order = order; current_order &lt;= MAX_ORDER; ++current_order) { // &#x4ECE;&#x8BF7;&#x6C42;order&#x5F00;&#x59CB;&#x904D;&#x5386;free_area
		area = &amp;(zone-&gt;free_area[current_order]);
		page = get_page_from_free_area(area, migratetype); // &#x4ECE;&#x5F53;&#x524D;&#x7684;&#x4F19;&#x4F34;&#x7CFB;&#x7EDF;&#x91CC;&#x8BD5;&#x7740;&#x62FF;&#x51FA;&#x4E00;&#x4E2A;free&#x5757;
		if (!page)
			continue; // &#x6CA1;&#x62FF;&#x5230;&#x7684;&#x8BDD;&#x5C31;&#x518D;&#x627E;&#x4E0B;&#x4E00;&#x4E2A;&#x5927;&#x5C0F;&#x7684;free_area
		del_page_from_free_list(page, zone, current_order); // &#x628A;&#x5F53;&#x524D;&#x7684;&#x5185;&#x5B58;&#x7EC4;&#x4ECE;free list&#x5220;&#x9664;
		expand(zone, page, order, current_order, migratetype);// &#x5982;&#x679C;&#x627E;&#x5230;&#x7684;&#x9875;&#x9762;&#x5927;&#x4E8E;&#x8BF7;&#x6C42;&#x7684;order&#xFF0C;&#x5C06;&#x5176;&#x62C6;&#x5206;&#x4E3A;&#x66F4;&#x5C0F;&#x7684;&#x5757;
		set_pcppage_migratetype(page, migratetype); // &#x8BBE;&#x7F6E;&#x9875;&#x9762;&#x7684;&#x8FC1;&#x79FB;&#x7C7B;&#x578B;&#x3002;
		trace_mm_page_alloc_zone_locked(page, order, migratetype,
				pcp_allowed_order(order) &amp;&amp;
				migratetype &lt; MIGRATE_PCPTYPES);
		return page;
	}

	return NULL;
}
</code></pre>
<p>&#x800C;&#x5F53;&#x6211;&#x4EEC;&#x5728;&#x66F4;&#x5927;&#x7684;&#x9875;&#x6846;&#x7EC4;&#x62C6;&#x5206;&#x7684;&#x65F6;&#x5019;&#xFF0C;&#x5219;&#x4F1A;&#x628A;&#x591A;&#x4F59;&#x7684;&#x9875;&#x6846;&#x7EC4;&#x63D2;&#x5230;&#x5176;&#x4ED6;<code>free_area</code>&#x4E2D;&#xFF0C;&#x5E76;&#x628A;&#x76EE;&#x6807;&#x7684;<code>order</code>&#x548C;<code>current_order</code>&#x4F5C;&#x5BF9;&#x6BD4;&#x3002;</p>
<pre><code class="language-cpp">static inline void expand(struct zone *zone, struct page *page,
	int low, int high, int migratetype)
{
	unsigned long size = 1 &lt;&lt; high; // &#x8981;&#x88AB;&#x62C6;&#x5206;&#x7684;&#x9875;&#x5927;&#x5C0F;

	while (high &gt; low) {
		high--; // &#x628A;current_order&#x9012;&#x51CF;&#x5230;&#x5B9E;&#x9645;&#x7684;&#x9700;&#x6C42;order
		size &gt;&gt; = 1;
		VM_BUG_ON_PAGE(bad_range(zone, &amp;page[size]), &amp;page[size]); // &#x6309;&#x7167;&#x5F53;&#x524D;&#x7684;size&#x628A;&#x539F;&#x59CB;&#x5927;&#x5C0F;&#x7684;&#x9875;&#x6846;&#x7EC4;&#x62C6;&#x5206;

		/*
		 * Mark as guard pages (or page), that will allow to
		 * merge back to allocator when buddy will be freed.
		 * Corresponding page table entries will not be touched,
		 * pages will stay not present in virtual address space
		 */
		if (set_page_guard(zone, &amp;page[size], high, migratetype))
			continue;

		add_to_free_list(&amp;page[size], zone, high, migratetype); // &#x628A;&#x62C6;&#x5206;&#x51FA;&#x6765;&#x7684;&#x76F4;&#x63A5;&#x52A0;&#x56DE;&#x5230;&#x65B0;&#x7684;free list&#x4E2D;
		set_buddy_order(&amp;page[size], high);
	}
}
</code></pre>
<h3 id="33-%E9%87%8A%E6%94%BE%E5%87%BD%E6%95%B0">3.3-&#x91CA;&#x653E;&#x51FD;&#x6570;</h3>
<p>&#x5F53;&#x7CFB;&#x7EDF;&#x8C03;&#x7528;free_page&#x7684;&#x65F6;&#x5019;&#xFF0C;&#x4F19;&#x4F34;&#x7CFB;&#x7EDF;&#x4F1A;&#x5C1D;&#x8BD5;&#x628A;&#x5F53;&#x524D;&#x7684;&#x9875;&#x9762;&#x8FD8;&#x539F;&#x7ED9;&#x5927;&#x7684;order&#x7EC4;&#xFF0C;&#x8FD9;&#x6837;&#x7684;&#x64CD;&#x4F5C;&#x53EF;&#x4EE5;&#x6709;&#x6548;&#x51CF;&#x5C11;&#x5185;&#x5B58;&#x7684;&#x788E;&#x7247;&#x5316;&#x3002;</p>
<pre><code class="language-cpp">static inline void __free_one_page(struct page *page,
		unsigned long pfn,
		struct zone *zone, unsigned int order,
		int migratetype, fpi_t fpi_flags)
{
	......
	VM_BUG_ON(!zone_is_initialized(zone)); // &#x786E;&#x4FDD;&#x4F20;&#x5165;&#x7684;zone&#x5DF2;&#x7ECF;&#x521D;&#x59CB;&#x5316;
	VM_BUG_ON_PAGE(page-&gt;flags &amp; PAGE_FLAGS_CHECK_AT_PREP, page);

	VM_BUG_ON(migratetype == -1);
	if (likely(!is_migrate_isolate(migratetype)))
		__mod_zone_freepage_state(zone, 1 &lt;&lt; order, migratetype); // &#x68C0;&#x67E5;migratetype&#x662F;&#x5426;&#x4E3A;MIGRATE_ISOLATE

	VM_BUG_ON_PAGE(pfn &amp; ((1 &lt;&lt; order) - 1), page); // &#x786E;&#x4FDD;&#x4F20;&#x5165;&#x7684;pfn&#x4E0E;order&#x5339;&#x914D;
	VM_BUG_ON_PAGE(bad_range(zone, page), page);

  /* &#x5C1D;&#x8BD5;&#x5BFB;&#x627E;&#x5E76;&#x5408;&#x5E76;&#x5F53;&#x524D;&#x9875;&#x9762;&#x7684;&#x4F19;&#x4F34;&#x9875;&#x9762; */
	while (order &lt; MAX_ORDER) { 
		......
		buddy = find_buddy_page_pfn(page, pfn, order, &amp;buddy_pfn); // &#x67E5;&#x627E;&#x5F53;&#x524D;&#x9875;&#x7684;buddy
		if (!buddy)
			goto done_merging;
		......
		/*
		 * Our buddy is free or it is CONFIG_DEBUG_PAGEALLOC guard page,
		 * merge with it and move up one order.
		 */
		if (page_is_guard(buddy)) // &#x67E5;&#x770B;&#x662F;&#x5426;&#x627E;&#x5230;&#x4E86;&#x5F53;&#x524D;page&#x7684;&#x4F19;&#x4F34;&#x7CFB;&#x7EDF;&#x662F;&#x5426;&#x662F;&#x5B88;&#x62A4;&#x9875;
			clear_page_guard(zone, buddy, order, migratetype); // &#x5982;&#x679C;&#x4F19;&#x4F34;&#x9875;&#x9762;&#x662F;&#x5B88;&#x536B;&#x9875;&#xFF0C;&#x8FD9;&#x4E00;&#x6B65;&#x4F1A;&#x6E05;&#x9664;&#x5B88;&#x536B;&#x9875;&#x7684;&#x72B6;&#x6001;&#xFF0C;&#x51C6;&#x5907;&#x5B83;&#x4EEC;&#x8FDB;&#x884C;&#x5408;&#x5E76;
		else
			del_page_from_free_list(buddy, zone, order); // &#x4E0D;&#x662F;&#x5B88;&#x536B;&#x9875;&#xFF0C;&#x5C06;&#x4F19;&#x4F34;&#x9875;&#x9762;&#x4ECE;free list&#x4E2D;&#x79FB;&#x9664;&#xFF0C;&#x4EE5;&#x4FBF;&#x5C06;&#x5176;&#x4E0E;&#x5F53;&#x524D;&#x9875;&#x9762;&#x5408;&#x5E76;&#x3002;
		combined_pfn = buddy_pfn &amp; pfn;
		page = page + (combined_pfn - pfn);
		pfn = combined_pfn;
		order++;
	}

done_merging:
	set_buddy_order(page, order); // &#x8BBE;&#x7F6E;&#x5408;&#x5E76;&#x540E;&#x7684;&#x9875;order

  /* &#x51FD;&#x6570;&#x6839;&#x636E;fpi_flags&#x548C;&#x5176;&#x4ED6;&#x6761;&#x4EF6;&#x51B3;&#x5B9A;&#x5C06;&#x5408;&#x5E76;&#x540E;&#x7684;&#x9875;&#x6DFB;&#x52A0;&#x5230;zone&#x7684;free list&#x7684;&#x5934;&#x90E8;&#x8FD8;&#x662F;&#x5C3E;&#x90E8; */
	if (fpi_flags &amp; FPI_TO_TAIL)
		to_tail = true;
	else if (is_shuffle_order(order))
		to_tail = shuffle_pick_tail();
	else
		to_tail = buddy_merge_likely(pfn, buddy_pfn, page, order);

	if (to_tail)
		add_to_free_list_tail(page, zone, order, migratetype);
	else
		add_to_free_list(page, zone, order, migratetype);

	/* Notify page reporting subsystem of freed page */
	if (!(fpi_flags &amp; FPI_SKIP_REPORT_NOTIFY))
		page_reporting_notify_free(order);
}
</code></pre>
<p>&#x8FD9;&#x91CC;&#x4E3B;&#x8981;&#x6267;&#x884C;<code>find_buddy_page_pfn</code>&#x67E5;&#x627E;&#x5408;&#x9002;&#x7684;&#x4F19;&#x4F34;&#x7CFB;&#x7EDF;&#x9875;&#x9762;&#x7684;&#x539F;&#x56E0;</p>
<ol>
<li>
<p><strong>&#x5408;&#x5E76;&#x5185;&#x5B58;&#x5757;</strong>&#xFF1A;</p>
<p>&#x5F53;&#x9875;&#x9762;&#x88AB;&#x91CA;&#x653E;&#x65F6;&#xFF0C;&#x7CFB;&#x7EDF;&#x5C1D;&#x8BD5;&#x627E;&#x5230;&#x5B83;&#x7684;&#x4F19;&#x4F34;&#x9875;&#x9762;&#xFF0C;&#x4EE5;&#x5224;&#x65AD;&#x662F;&#x5426;&#x53EF;&#x4EE5;&#x5C06;&#x8FD9;&#x4E24;&#x4E2A;&#x9875;&#x9762;&#x5408;&#x5E76;&#x6210;&#x4E00;&#x4E2A;&#x66F4;&#x5927;&#x7684;&#x5185;&#x5B58;&#x5757;&#x3002;&#x8FD9;&#x79CD;&#x5408;&#x5E76;&#x51CF;&#x5C11;&#x4E86;&#x5185;&#x5B58;&#x788E;&#x7247;&#x5316;&#xFF0C;&#x63D0;&#x9AD8;&#x4E86;&#x5185;&#x5B58;&#x5229;&#x7528;&#x7387;&#x3002;</p>
</li>
<li>
<p><strong>&#x7EF4;&#x6301;&#x4F19;&#x4F34;&#x7CFB;&#x7EDF;&#x7684;&#x5B8C;&#x6574;&#x6027;</strong>&#xFF1A;</p>
<p>&#x4F19;&#x4F34;&#x7CFB;&#x7EDF;&#x57FA;&#x4E8E;&#x6210;&#x5BF9;&#x7684;&#x9875;&#x9762;&#x5757;&#x8FDB;&#x884C;&#x5DE5;&#x4F5C;&#x3002;&#x6BCF;&#x6B21;&#x5206;&#x914D;&#x6216;&#x91CA;&#x653E;&#x65F6;&#xFF0C;&#x90FD;&#x5FC5;&#x987B;&#x7EF4;&#x62A4;&#x8FD9;&#x79CD;&#x914D;&#x5BF9;&#x5173;&#x7CFB;&#xFF0C;&#x4EE5;&#x786E;&#x4FDD;&#x7CFB;&#x7EDF;&#x7684;&#x9AD8;&#x6548;&#x548C;&#x4E00;&#x81F4;&#x6027;&#x3002;</p>
</li>
<li>
<p><strong>&#x4F18;&#x5316;&#x5185;&#x5B58;&#x5206;&#x914D;</strong>&#xFF1A;</p>
<p>&#x901A;&#x8FC7;&#x5408;&#x5E76;&#x91CA;&#x653E;&#x7684;&#x9875;&#x9762;&#x548C;&#x5176;&#x4F19;&#x4F34;&#x9875;&#x9762;&#xFF0C;&#x4F19;&#x4F34;&#x7CFB;&#x7EDF;&#x53EF;&#x4EE5;&#x4E3A;&#x672A;&#x6765;&#x7684;&#x5927;&#x5757;&#x5185;&#x5B58;&#x5206;&#x914D;&#x8BF7;&#x6C42;&#x63D0;&#x4F9B;&#x66F4;&#x591A;&#x7684;&#x8FDE;&#x7EED;&#x5185;&#x5B58;&#xFF0C;&#x4ECE;&#x800C;&#x63D0;&#x9AD8;&#x5185;&#x5B58;&#x5206;&#x914D;&#x7684;&#x6548;&#x7387;&#x3002;</p>
</li>
</ol>
<pre><code class="language-cpp">static inline struct page *find_buddy_page_pfn(struct page *page,
			unsigned long pfn, unsigned int order, unsigned long *buddy_pfn)
{
	unsigned long __buddy_pfn = __find_buddy_pfn(pfn, order); // &#x67E5;&#x627E;&#x5F53;&#x524D;order&#x5BF9;&#x5E94;&#x4F19;&#x4F34;&#x9875;&#x9762;&#x7684;&#x9875;&#x9762;&#x5E27;&#x53F7;&#xFF08;PFN&#xFF09;
	struct page *buddy;

	buddy = page + (__buddy_pfn - pfn); // &#x901A;&#x8FC7;&#x8BA1;&#x7B97;&#x5F97;&#x5230;&#x7684;PFN&#x5B9A;&#x4F4D;&#x4F19;&#x4F34;&#x9875;&#x9762;
	if (buddy_pfn)
		*buddy_pfn = __buddy_pfn;

	if (page_is_buddy(page, buddy, order)) // &#x68C0;&#x67E5;&#x662F;&#x5426;&#x4E3A;&#x6709;&#x6548;&#x4F19;&#x4F34;&#x9875;&#x9762;
		return buddy;
	return NULL;
}
</code></pre>
]]></content:encoded></item></channel></rss>