【转】What is the kernel parameters related to maximum size of physical I/O requests?

本文介绍了如何在Linux系统中调整最大物理I/O请求的大小,通过修改/sys/block/<device>/queue/max_sectors_kb参数实现。文章详细解释了max_sectors_kb和max_hw_sectors_kb的区别,并提供了持久化设置的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

https://access.redhat.com/solutions/43861

What is the kernel parameters related to maximum size of physical I/O requests?

 SOLUTION 已验证 - 已更新 2018年八月22日02:23 - 

English 

环境

  • Red Hat Enterprise Linux 7
  • Red Hat Enterprise Linux 6
  • Red Hat Enterprise Linux 5

问题

  • What is the kernel parameters related to maximum size of physical I/O requests?
  • How do I adjust the maximum I/O transfer size on RHEL?
  • How do I set the maximum block device I/O transfer size on RHEL?
  • How to set custom values for /sys/block/<device>/queue/max_sectors_kb parameters?
  • Default max_sectors_kb setting
  • Do you have a proper way (reboot persistent, applies to current disks (devices), applies to disks (devices) that are added before next reboot) to change the default max_sectors_kb?

决议

Linux has the two values in the /sys file system relating to this:

  1. max_hw_sectors_kb (read-only)

    • This is the maximum number of kilobytes supported in a single data transfer by the underlying device. This value is read-only — it is set by the driver to reflect the driver/hardware limit. The block layer will also enforce this limit and so it will take the minimum of the max_hw_sectors_kb and the kernel default block limit (512kb in RHEL4/5) to make sure all I/O requests are within the size limit that the hardware/driver can support.
  2. max_sectors_kb (read/write)

    • This is the maximum number of kilobytes that the block layer will allow for a filesystem request. This value could be overwritten, but it must be smaller than or equal to the maximum size allowed by the hardware. The default kernel value on RHEL4/5 is 512kb.
    • To adjust or set the maximum transfer size, set the device's max_sectors_kb to the desired value. That value must be less than the kernel's maximum of 512kb. For example, say a storage vendor recommends limiting the I/O transfer size to their storage at or below 128kb per request. Then you would perform the following command for each such storage device:

Raw

$ echo 128 > /sys/block/sdz/queue/max_sectors_kb

Making max_sectors_kb tuning persistent

Changes to /sys entries do not persist across reboots.

An easy way of making a tuned max_sectors_kb setting persistent is to place the tuning command(s) in /etc/rc.d/rc.local. This will only work for storage devices that are present during system boot.

To make tuned max_sectors_kb settings persistent for dynamically added storage devices, they can be incorporated in udev rules which are executed when the device is added. For example, to set a 128 KB limit for HP EVA storage, use a udev rule

Raw

ACTION=="add|change", SUBSYSTEM=="block", ENV{ID_VENDOR}=="HP", ENV{ID_MODEL}=="HSV*", RUN+="/bin/sh -c '/bin/echo 128 > /sys%p/queue/max_sectors_kb'"

Please note that the above filesystem requests can be achieved in RHEL native filesystems such as ext4xfs etc. If the maximum number of kilobytes that the block layer will allow for a filesystem request can't be achieved even after max_sectors_kb is changed for the device, then check if it is formatted with any other third party filesystem. If yes, then kindly contact the vendor of the filesystem for support.

Refer to What is udev and how do you write custom udev rules? for more background on udev.

诊断步骤

Example of normal SATA internal drive:

Raw

$ cat /sys/block/sda/queue/max_sectors_kb
512
$ cat /sys/block/sda/queue/max_hw_sectors_kb
32767

Example of a usb drive, which has a lower hardware limit than the block layer default:

Raw

$ cat /sys/block/sdb/queue/max_sectors_kb
120
$ cat /sys/block/sdb/queue/max_hw_sectors_kb
120

In both cases, the max_sectors_kb has been set to the minimum of the block layer default and the hardware/driver value.

We can see examples of two different transfer sizes in action using simple dd and iostat commands.

Raw

$ echo 512 > /sys/block/sda/queue/max_sectors_kb
$ dd if=/dev/sda5 of=/dev/null iflag=direct bs=4M count=250 &

 
Output from iostat -tkx 1 shows the average request size (avgrq-sz) never exceeds 1024 sectors or 512kb as expected.

Raw


Device:         rrqm/s   wrqm/s   r/s   w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util
sda5              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sda5              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sda5              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sda5              0.00     0.00 109.00  0.00 55808.00     0.00  1024.00     3.39   29.36   6.46  70.40
sda5              0.00     0.00 181.19  0.00 92768.32     0.00  1024.00     4.50   25.42   5.42  98.22
sda5              0.00     0.00 195.00  0.00 99840.00     0.00  1024.00     4.56   23.57   5.13 100.00
Note: the dd command uses the iflag=direct to force 4MB io into the kernel block/scheduler layer where that size is reduced to the maximum transfer size allowed by the target device. Because this single large io request is broken down into smaller sized ones, we see this reflected in the average queue size being greater than 1.

 

 

Raw

$ echo 128 > /sys/block/sda/queue/max_sectors_kb
$ dd if=/dev/sda5 of=/dev/null iflag=direct bs=4M count=250 &

 

Output from iostat -tkx 1 now shows the average request size (avgrq-sz) never exceeds 256 sectors or 128kb as expected.

Raw


Device:         rrqm/s   wrqm/s   r/s   w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util
sda5              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sda5              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sda5              0.00     0.00 169.00  0.00 21632.00     0.00   256.00     5.74   31.81   1.96  33.20
sda5              0.00     0.00 539.60  0.00 69069.31     0.00   256.00    16.49   30.58   1.83  98.61
sda5              0.00     0.00 587.00  0.00 75136.00     0.00   256.00    15.67   26.39   1.70  99.60
sda5              0.00     0.00 495.00  0.00 63360.00     0.00   256.00    16.25   33.66   2.03 100.40
资源下载链接为: https://pan.quark.cn/s/f989b9092fc5 今天给大家分享一个关于C#自定义字符串替换方法的实例,希望能对大家有所帮助。具体介绍如下: 之前我遇到了一个算法题,题目要求将一个字符串中的某些片段替换为指定的新字符串片段。例如,对于源字符串“abcdeabcdfbcdefg”,需要将其中的“cde”替换为“12345”,最终得到的结果字符串是“ab12345abcdfb12345fg”,即从“abcdeabcdfbcdefg”变为“ab12345abcdfb12345fg”。 经过分析,我发现不能直接使用C#自带的string.Replace方法来实现这个功能。于是,我决定自定义一个方法来完成这个任务。这个方法的参数包括:原始字符串originalString、需要被替换的字符串片段strToBeReplaced以及用于替换的新字符串片段newString。 在实现过程中,我首先遍历原始字符串,查找需要被替换的字符串片段strToBeReplaced出现的位置。找到后,就将其替换为新字符串片段newString。需要注意的是,在替换过程中,要确保替换操作不会影响后续的查找和替换,避免遗漏或重复替换的情况发生。 以下是实现代码的大概逻辑: 初始化一个空的字符串result,用于存储最终替换后的结果。 使用IndexOf方法在原始字符串中查找strToBeReplaced的位置。 如果找到了,就将originalString中从开头到strToBeReplaced出现位置之前的部分,以及newString拼接到result中,然后将originalString的查找范围更新为strToBeReplaced之后的部分。 如果没有找到,就直接将剩余的originalString拼接到result中。 重复上述步骤,直到originalStr
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值