Web updates

git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@3660 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Vladislav Bolkhovitin
2011-07-07 19:52:17 +00:00
parent 43c366ecf3
commit 8bfb6b40d7

View File

@@ -93,156 +93,6 @@
page cache, namely, locking issues related to it. They should be carefully
investigated.</p>
<A NAME="DYN_FLOW"></A><h3>Dynamic I/O flow control</h3>
<p>At the moment, if an initiator or several initiators simultaneously send to
target too many commands, especially in seek intensive workloads, target can get
overloaded and not able to finish commands on time. In such cases you can see on
the initiator(s) messages about aborting commands or resetting the target. See in SCST core
README section "What if target's backstorage is too slow" for more details.
To fix this problem it is necessary to implement a dynamic I/O flow control in
SCST core.</p>
<p>The flow control, generally, is quite simple. Each SCST command has timeout value,
which is set by the corresponding dev handler. SCST core should keep device's queue depth
at the level that the worst command's execution time, i.e. time between scst_rx_cmd()
and scst_finish_cmd(), would be between something like timeout/10 and timeout/5.
So, commands execution time should be checked and:</p>
<ul>
<li><span>If it's > timeout/5, then the new queue depth should be set to max(1,
cur_depth/2)</span></li>
<li><span>If it's < timeout/10, then new queue depth should be set to min(MAX_DEPTH,
cur_depth+1). This shouldn't be done too often, once in a few minutes should be
sufficient</span></li>
</ul>
<p>The above is, of course, an oversimplification to let you see the idea.
Implementation considering real life cases should be as the following:</p>
<p>1. There are several parameters:</p>
<ul>
<li><span>P - load watch period. During this period all the statistic is
gathered and processed.</span></li>
<li><span>MN - underload ratio divisor, which sets the underload portion of
timeout. If the longest execution time among all commands completed
during period P is below timeout/MN, the corresponding device considered
underloaded.</span></li>
<li><span>MX - overload ratio divisor, which sets the overload portion of
timeout. If the longest execution time among all commands completed
during period P is above timeout/MX, the corresponding device considered
overloaded.</span></li>
<li><span>I - step on which device's queue size will be increased if device
considered underloaded.</span></li>
<li><span>D - divisor on which device's queue size will be decreased if device
considered overloaded.</span></li>
<li><span>QI - quick fall interval. See description of Q parameter.</span></li>
<li><span>Q - quick fall ratio divisor. If the longest execution time of a
completed command is above timeout/Q and time from the previous quick
fall is smaller than QI, the corresponding device considered heavily
overloaded. The quick fall is needed to handle cases when load on device
is instantly increased on the way, where it can't handle it properly.</span></li>
<li><span>QD - divisor on which device's queue size will be decreased if
device considered heavily overloaded.</span></li>
</ul>
<p>The default values should be something like: P=15 sec., MN=20, MX=10, Q=3,
I=1, D=2, QI=5 sec., QD=10.</p>
<p>2. There are the following new variables in struct scst_device:</p>
<ul>
<li><span>queue_depth - current queue depth.</span></li>
<li><span>max_exec_ratio - maximum commands timeout/(execution time).</span></li>
<li><span>queue_was_full - flag, marking that the queue was at least once full
during period P.</span></li>
<li><span>quick_fall_time - time of the last quick fall.</span></li>
<li><span>flow_lock - protects flow control related variables, where needed.</span></li>
<li><span>...</span></li>
</ul>
<p>3. The commands processing path should be as the following:</p>
<ul>
<li><span>In scst_rx_cmd() the start time of the command is recorded (already done).</span></li>
<li><span>In __scst_init_cmd(), if dev->dev_cmd_count == dev->queue_depth,
dev->queue_was_full set to true.</span></li>
<li><span>In scst_finish_cmd() dev->max_exec_ratio set to max(dev->max_exec_ratio,
(cmd's exec_time)*100/cmd->timeout).</span></li>
<li><font color="#666666">If in scst_finish_cmd() cmd's exec time is above cmd->timeout/Q and
time from the latest quick fall is above QI, then:</font>
<ul>
<li><span>dev->queue_depth set to max(1, dev->queue_depth/QD).</span></li>
<li><span>Flow control period reset, i.e. started again, including setting
dev->max_exec_ratio to 0 and dev->quick_fall_time to jiffies.</span></li>
</ul>
</li>
</ul>
<p>4. There should be a work, which once in a P seconds will check
dev->max_exec_ratio, then:</p>
<ul>
<li><span>If device neither underloaded, nor overloaded. i.e. max_exec_ratio
between defined by MN and MX, do nothing.</span></li>
<li><font color="#666666">If device was underloaded:</font>
<ul>
<li><span>if dev->queue_was_full is false, then do nothing.</span></li>
<li><span>if dev->queue_was_full is true, then set dev->queue_depth to
min(SCST_MAX_DEV_COMMANDS, dev->queue_depth + I).</span></li>
</ul>
</li>
<li><span>If device was overloaded, then set dev->queue_depth to max(1,
dev->queue_depth/D).</span></li>
</ul>
<p>Then the flow control period is reset, i.e. started again, including
setting dev->max_exec_ratio to 0 and dev->quick_fall_time to jiffies.</p>
<p>That's all. Then only support for initiators, like iSCSI,
which don't handle QUEUE FULL to decrease amount of queued
commands, should be added. Such initiators expect target to control size of
the queue, via, e.g., through MAX_SN for iSCSI.</p>
<p>For it at the stage 2 of the dynamic flow control development
the following should be done:</p>
<ul>
<li><span>New callback on_queue_depth_adjustment() should be added to struct
scst_tgt_template.</span></li>
<li><span>If target driver defined it, each time after dev->queue_depth changed
on_queue_depth_adjustment() should be called. In this callback target
driver should change internal queue_depth to, e.g. for iSCSI target, set
max_sn in the replies correctly.</span></li>
</ul>
<p>Then, at the latest stage of the development, logic to not schedule the
flow control work on idle devices should be added.</p>
<A NAME="O_DIRECT"></A><h3>Support for O_DIRECT in scst_vdisk handler</h3>
<p>At the moment, scst_vdisk handler doesn't support O_DIRECT option and possibility to set it