<div>Hi,</div><div>About 2 months ago, I asked one problem in XFS, see here(<span style="line-height: 1.5;">http://oss.sgi.com/archives/xfs/2015-02/msg00197.html).</span></div><div><span style="line-height: 1.5;"><br></span></div><div><span style="line-height: 1.5;">After that, I use direct IO in MySQL, see here(</span>https://dev.mysql.com/doc/refman/5.5/en/innodb-parameters.html#sysvar_innodb_flush_method).<span id="_editor_bookmark_start_2" style="display: none; line-height: 0px;"></span></div><div><br></div><div>However, I found that MySQL performance is still poor sometimes. I use some tools(https://github.com/brendangregg/perf-tools<span id="_editor_bookmark_start_3" style="display: none; line-height: 0px;"></span>) to trace the kernel, I found some problems:</div><div><br></div><div><div># ./funccount -i 1 "xfs_f*"</div><div>Tracing "xfs_f*"... Ctrl-C to end.</div><div>FUNC COUNT</div><div>xfs_file_aio_read 15591</div><div>xfs_flushinval_pages 15591</div><div>xfs_find_bdev_for_inode 31182<span id="_editor_bookmark_start_5" style="display: none; line-height: 0px;"></span></div></div><div><br></div><div>As we can see, <span style="line-height: 1.5;">xfs_file_aio_read each will call <span id="_editor_bookmark_start_6" style="display: none; line-height: 0px;"></span></span><span style="line-height: 1.5;">xfs_flushinval_pages. </span></div><div><span style="line-height: 1.5;">Note that I used direct IO!!!<span id="_editor_bookmark_start_7" style="display: none; line-height: 0px;"></span></span></div><div><br></div><div>xfs_flushinval_pages will call truncate_inode_pages_range, from here(https://bitbucket.org/hustcat/kernel-2.6.32/src/0e5d90ed6f3ef8a3b5fe62a04cc6766a721c70f8/fs/xfs/linux-2.6/xfs_fs_subr.c?at=master#cl-56<span id="_editor_bookmark_start_10" style="display: none; line-height: 0px;"></span>)<span id="_editor_bookmark_start_9" style="display: none; line-height: 0px;"></span><span id="_editor_bookmark_start_8" style="display: none; line-height: 0px;"></span></div><div><br></div><div>Indeed that,</div><div><div># ./funccount -i 1 "truncate_inode_page*"</div><div>Tracing "truncate_inode_page*"... Ctrl-C to end.</div><div>FUNC COUNT</div><div>truncate_inode_page 4</div><div>truncate_inode_pages 176</div><div>truncate_inode_pages_range 15474</div><div>FUNC COUNT</div><div>truncate_inode_page 1</div><div>truncate_inode_pages 5</div><div>truncate_inode_pages_range 15566<span id="_editor_bookmark_start_11" style="display: none; line-height: 0px;"></span></div></div><div><br></div><div>As we can see, <span style="line-height: 1.5;">truncate_inode_pages_range called times as many as <span id="_editor_bookmark_start_12" style="display: none; line-height: 0px;"></span></span><span style="line-height: 1.5;">xfs_flushinval_pages,<span id="_editor_bookmark_start_13" style="display: none; line-height: 0px;"></span></span></div><div>However, I found that <span style="line-height: 1.5;">truncate_inode_pages_range didn't call <span id="_editor_bookmark_start_15" style="display: none; line-height: 0px;"></span></span><span style="line-height: 1.5;">truncate_inode_page:<span id="_editor_bookmark_start_16" style="display: none; line-height: 0px;"></span></span></div><div><span style="line-height: 1.5;"><br></span></div><div><div># ./funcgraph truncate_inode_pages_range</div><div>Tracing "truncate_inode_pages_range"... Ctrl-C to end.</div><div> 2) 1.020 us | finish_task_switch();</div><div> 2) | truncate_inode_pages_range() {</div><div> 2) | pagevec_lookup() {</div><div> 2) 0.413 us | find_get_pages();</div><div> 2) 1.033 us | }</div><div> 2) 0.238 us | _cond_resched();</div><div> 2) | pagevec_lookup() {</div><div> 2) 0.234 us | find_get_pages();</div><div> 2) 0.690 us | }</div><div> 2) 3.362 us | }</div><div> 2) | truncate_inode_pages_range() {</div><div> 2) | pagevec_lookup() {</div><div> 2) 0.266 us | find_get_pages();</div><div> 2) 0.745 us | }</div><div> 2) 0.238 us | _cond_resched();</div><div> 2) | pagevec_lookup() {</div><div> 2) 0.248 us | find_get_pages();</div><div> 2) 0.701 us | }</div><div> 2) 2.844 us | }</div><div> 2) | truncate_inode_pages_range() {</div><div> 2) | pagevec_lookup() {</div><div> 2) 0.262 us | find_get_pages();</div><div> 2) 0.740 us | }</div><div> 2) 0.238 us | _cond_resched();</div><div> 2) | pagevec_lookup() {</div><div> 2) 0.251 us | find_get_pages();</div><div> 2) 0.705 us | }</div><div> 2) 2.767 us | }<span id="_editor_bookmark_start_17" style="display: none; line-height: 0px;"></span></div></div><div><br></div><div>This will canse inode->i_mapping->nrpages > 0 always, and xfs_file_aio_read/xfs_file_dio_aio_write will always call xfs_flushinval_pages. Even worse, <span style="line-height: 1.5;">xfs_file_dio_aio_write will use EXCL lock:<span id="_editor_bookmark_start_21" style="display: none; line-height: 0px;"></span></span><span id="_editor_bookmark_start_20" style="display: none; line-height: 0px;"></span><span id="_editor_bookmark_start_19" style="display: none; line-height: 0px;"></span></div><div><span style="line-height: 1.5;"><br></span></div><div><pre style="margin-top: 0px; margin-bottom: 0px; padding: 0px; font-family: Consolas, Menlo, 'Liberation Mono', Courier, monospace; font-size: 12px; line-height: 1.4; color: rgb(51, 51, 51);"> <span class="k" style="font-weight: bold;">if</span> <span class="p">(</span><span class="n">mapping</span><span class="o" style="font-weight: bold;">-></span><span class="n">nrpages</span> <span class="o" style="font-weight: bold;">&&</span> <span class="n">iolock</span> <span class="o" style="font-weight: bold;">==</span> <span class="n">XFS_IOLOCK_SHARED</span><span class="p">)</span> <span class="p">{</span>
<a name="cl-658" style="color: rgb(53, 114, 176);"></a> <span class="n">xfs_rw_iunlock</span><span class="p">(</span><span class="n">ip</span><span class="p">,</span> <span class="n">iolock</span><span class="p">);</span>
<a name="cl-659" style="color: rgb(53, 114, 176); display: block; position: absolute; left: 0px; height: 16px; width: 1167px; z-index: -1; background-color: rgb(235, 242, 249);"></a> <span class="n">iolock</span> <span class="o" style="font-weight: bold;">=</span> <span class="n">XFS_IOLOCK_EXCL</span><span class="p">;</span>
<a name="cl-660" style="color: rgb(53, 114, 176);"></a> <span class="n">xfs_rw_ilock</span><span class="p">(</span><span class="n">ip</span><span class="p">,</span> <span class="n">iolock</span><span class="p">);</span>
<a name="cl-661" style="color: rgb(53, 114, 176);"></a> <span class="p">}</span>
</pre></div><div><br></div><div>see here(https://bitbucket.org/hustcat/kernel-2.6.32/src/0e5d90ed6f3ef8a3b5fe62a04cc6766a721c70f8/fs/xfs/linux-2.6/xfs_file.c?at=master#cl-659<span id="_editor_bookmark_start_23" style="display: none; line-height: 0px;"></span>).</div><div><br></div><div>This will cause bad performance, even direct IO. I still don't understand why not <span style="line-height: 1.5;">truncate_inode_page called?<span id="_editor_bookmark_start_24" style="display: none; line-height: 0px;"></span></span></div><div><span style="line-height: 1.5;"><br></span></div><div>Every time, after I run this:</div><div>echo 1 > /proc/sys/vm/drop_caches</div><div><br></div><div>Immediately enhance performance.</div><div><br></div><div>Ye,</div><div>Thanks.</div><div><br></div><div><span style="line-height: 1.5;"><br></span></div>