QoS/Bdev: add RPC support for Read/Write separate bandwidth limits

This patch adds the RPC support for the Read/Write separate
bandwidth limit controls. The basic usage as following:

usage:
rpc.py set_bdev_qos_limit [-h] [--rw_ios_per_sec RW_IOS_PER_SEC]
                               [--rw_mbytes_per_sec RW_MBYTES_PER_SEC]
                               [--r_mbytes_per_sec R_MBYTES_PER_SEC]
                               [--w_mbytes_per_sec W_MBYTES_PER_SEC]
                               name

positional arguments:
  name       Blockdev name to set QoS. Example: Malloc0

optional arguments:
  -h, --help show this help message and exit
  --rw_ios_per_sec RW_IOS_PER_SEC
             R/W IOs per second limit (>=10000, example: 20000).
             0 means unlimited.
  --rw_mbytes_per_sec RW_MBYTES_PER_SEC
             R/W megabytes per second limit (>=10, example: 100).
             0 means unlimited.
  --r_mbytes_per_sec R_MBYTES_PER_SEC
             Read megabytes per second limit (>=10, example: 100).
             0 means unlimited.
  --w_mbytes_per_sec W_MBYTES_PER_SEC
             Write megabytes per second limit (>=10, example: 100).
             0 means unlimited.

Change-Id: I822ec4814d21adff9826ce03a6af3783b1b98f44
Signed-off-by: GangCao <gang.cao@intel.com>
Reviewed-on: https://review.gerrithub.io/c/417650
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
GangCao 2018-06-21 22:15:02 -04:00 committed by Ben Walker
parent 316cb3b150
commit 05b43152b2
5 changed files with 42 additions and 7 deletions

View File

@ -676,6 +676,8 @@ Name | Optional | Type | Description
name | Required | string | Block device name
rw_ios_per_sec | Optional | number | Number of R/W I/Os per second to allow. 0 means unlimited.
rw_mbytes_per_sec | Optional | number | Number of R/W megabytes per second to allow. 0 means unlimited.
r_mbytes_per_sec | Optional | number | Number of Read megabytes per second to allow. 0 means unlimited.
w_mbytes_per_sec | Optional | number | Number of Write megabytes per second to allow. 0 means unlimited.
### Example
@ -689,6 +691,8 @@ Example request:
"name": "Malloc0"
"rw_ios_per_sec": 20000
"rw_mbytes_per_sec": 100
"r_mbytes_per_sec": 50
"w_mbytes_per_sec": 50
}
}
~~~

View File

@ -522,6 +522,16 @@ static const struct spdk_json_object_decoder rpc_set_bdev_qos_limit_decoders[] =
limits[SPDK_BDEV_QOS_RW_BPS_RATE_LIMIT]),
spdk_json_decode_uint64, true
},
{
"r_mbytes_per_sec", offsetof(struct rpc_set_bdev_qos_limit,
limits[SPDK_BDEV_QOS_R_BPS_RATE_LIMIT]),
spdk_json_decode_uint64, true
},
{
"w_mbytes_per_sec", offsetof(struct rpc_set_bdev_qos_limit,
limits[SPDK_BDEV_QOS_W_BPS_RATE_LIMIT]),
spdk_json_decode_uint64, true
},
};
static void

View File

@ -447,7 +447,9 @@ if __name__ == "__main__":
rpc.bdev.set_bdev_qos_limit(args.client,
name=args.name,
rw_ios_per_sec=args.rw_ios_per_sec,
rw_mbytes_per_sec=args.rw_mbytes_per_sec)
rw_mbytes_per_sec=args.rw_mbytes_per_sec,
r_mbytes_per_sec=args.r_mbytes_per_sec,
w_mbytes_per_sec=args.w_mbytes_per_sec)
p = subparsers.add_parser('set_bdev_qos_limit', help='Set QoS rate limit on a blockdev')
p.add_argument('name', help='Blockdev name to set QoS. Example: Malloc0')
@ -457,6 +459,12 @@ if __name__ == "__main__":
p.add_argument('--rw_mbytes_per_sec',
help="R/W megabytes per second limit (>=10, example: 100). 0 means unlimited.",
type=int, required=False)
p.add_argument('--r_mbytes_per_sec',
help="Read megabytes per second limit (>=10, example: 100). 0 means unlimited.",
type=int, required=False)
p.add_argument('--w_mbytes_per_sec',
help="Write megabytes per second limit (>=10, example: 100). 0 means unlimited.",
type=int, required=False)
p.set_defaults(func=set_bdev_qos_limit)
def bdev_inject_error(args):

View File

@ -518,13 +518,21 @@ def set_bdev_qd_sampling_period(client, name, period):
return client.call('set_bdev_qd_sampling_period', params)
def set_bdev_qos_limit(client, name, rw_ios_per_sec=None, rw_mbytes_per_sec=None):
def set_bdev_qos_limit(
client,
name,
rw_ios_per_sec=None,
rw_mbytes_per_sec=None,
r_mbytes_per_sec=None,
w_mbytes_per_sec=None):
"""Set QoS rate limit on a block device.
Args:
name: name of block device
rw_ios_per_sec: R/W IOs per second limit (>=10000, example: 20000). 0 means unlimited.
rw_mbytes_per_sec: R/W megabytes per second limit (>=10, example: 100). 0 means unlimited.
r_mbytes_per_sec: Read megabytes per second limit (>=10, example: 100). 0 means unlimited.
w_mbytes_per_sec: Write megabytes per second limit (>=10, example: 100). 0 means unlimited.
"""
params = {}
params['name'] = name
@ -532,6 +540,10 @@ def set_bdev_qos_limit(client, name, rw_ios_per_sec=None, rw_mbytes_per_sec=None
params['rw_ios_per_sec'] = rw_ios_per_sec
if rw_mbytes_per_sec is not None:
params['rw_mbytes_per_sec'] = rw_mbytes_per_sec
if r_mbytes_per_sec is not None:
params['r_mbytes_per_sec'] = r_mbytes_per_sec
if w_mbytes_per_sec is not None:
params['w_mbytes_per_sec'] = w_mbytes_per_sec
return client.call('set_bdev_qos_limit', params)

View File

@ -20,7 +20,7 @@ function check_qos_works_well() {
start_io_count=$($rpc_py get_bdevs_iostat -b $3 | jq -r '.[1].bytes_read')
fi
$fio_py 512 64 randread 5
$fio_py 1024 128 randread 5
if [ $LIMIT_TYPE = IOPS ]; then
end_io_count=$($rpc_py get_bdevs_iostat -b $3 | jq -r '.[1].num_read_ops')
@ -61,7 +61,8 @@ timing_enter qos
MALLOC_BDEV_SIZE=64
MALLOC_BLOCK_SIZE=512
IOPS_LIMIT=20000
BANDWIDTH_LIMIT=10
BANDWIDTH_LIMIT=20
READ_BANDWIDTH_LIMIT=10
LIMIT_TYPE=IOPS
rpc_py="$rootdir/scripts/rpc.py"
fio_py="$rootdir/scripts/fio.py"
@ -114,9 +115,9 @@ check_qos_works_well true $BANDWIDTH_LIMIT Malloc0
$rpc_py set_bdev_qos_limit Malloc0 --rw_mbytes_per_sec 0
check_qos_works_well false $BANDWIDTH_LIMIT Malloc0
# Limit the I/O bandwidth rate again.
$rpc_py set_bdev_qos_limit Malloc0 --rw_mbytes_per_sec $BANDWIDTH_LIMIT
check_qos_works_well true $BANDWIDTH_LIMIT Malloc0
# Limit the I/O bandwidth rate again with both read/write and read/only.
$rpc_py set_bdev_qos_limit Malloc0 --rw_mbytes_per_sec $BANDWIDTH_LIMIT --r_mbytes_per_sec $READ_BANDWIDTH_LIMIT
check_qos_works_well true $READ_BANDWIDTH_LIMIT Malloc0
echo "I/O bandwidth limiting tests successful"
iscsicleanup